Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: syzygy/agent/asan/shadow.cc

Issue 2508333002: Remove the is_nested bit from the BlockInfo structure. (Closed)
Patch Set: Address Siggi's comments. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « syzygy/agent/asan/shadow.h ('k') | syzygy/agent/asan/shadow_marker.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 Google Inc. All Rights Reserved. 1 // Copyright 2012 Google Inc. All Rights Reserved.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License. 4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 // Determine the distribution of bytes in the shadow. 651 // Determine the distribution of bytes in the shadow.
652 size_t left_redzone_bytes = info.TotalHeaderSize() / kShadowRatio; 652 size_t left_redzone_bytes = info.TotalHeaderSize() / kShadowRatio;
653 size_t body_bytes = (info.body_size + kShadowRatio - 1) / kShadowRatio; 653 size_t body_bytes = (info.body_size + kShadowRatio - 1) / kShadowRatio;
654 size_t block_bytes = info.block_size / kShadowRatio; 654 size_t block_bytes = info.block_size / kShadowRatio;
655 size_t right_redzone_bytes = block_bytes - left_redzone_bytes - body_bytes; 655 size_t right_redzone_bytes = block_bytes - left_redzone_bytes - body_bytes;
656 656
657 // Determine the marker byte for the header. This encodes the length of the 657 // Determine the marker byte for the header. This encodes the length of the
658 // body of the allocation modulo the shadow ratio, so that the exact length 658 // body of the allocation modulo the shadow ratio, so that the exact length
659 // can be inferred from inspecting the shadow memory. 659 // can be inferred from inspecting the shadow memory.
660 uint8_t body_size_mod = info.body_size % kShadowRatio; 660 uint8_t body_size_mod = info.body_size % kShadowRatio;
661 ShadowMarker header_marker = ShadowMarkerHelper::BuildBlockStart( 661 ShadowMarker header_marker =
662 true, info.header->is_nested, body_size_mod); 662 ShadowMarkerHelper::BuildBlockStart(true, body_size_mod);
663 663
664 // Determine the marker byte for the trailer. 664 // Determine the marker byte for the trailer.
665 ShadowMarker trailer_marker = 665 ShadowMarker trailer_marker = ShadowMarkerHelper::BuildBlockEnd(true);
666 ShadowMarkerHelper::BuildBlockEnd(true, info.header->is_nested);
667 666
668 // Poison the header and left padding. 667 // Poison the header and left padding.
669 uint8_t* cursor = shadow_ + index; 668 uint8_t* cursor = shadow_ + index;
670 ::memset(cursor, header_marker, 1); 669 ::memset(cursor, header_marker, 1);
671 ::memset(cursor + 1, kHeapLeftPaddingMarker, left_redzone_bytes - 1); 670 ::memset(cursor + 1, kHeapLeftPaddingMarker, left_redzone_bytes - 1);
672 cursor += left_redzone_bytes; 671 cursor += left_redzone_bytes;
673 ::memset(cursor, kHeapAddressableMarker, body_bytes); 672 ::memset(cursor, kHeapAddressableMarker, body_bytes);
674 cursor += body_bytes; 673 cursor += body_bytes;
675 674
676 // Poison the right padding and the trailer. 675 // Poison the right padding and the trailer.
677 if (body_size_mod > 0) 676 if (body_size_mod > 0)
678 cursor[-1] = body_size_mod; 677 cursor[-1] = body_size_mod;
679 ::memset(cursor, kHeapRightPaddingMarker, right_redzone_bytes - 1); 678 ::memset(cursor, kHeapRightPaddingMarker, right_redzone_bytes - 1);
680 ::memset(cursor + right_redzone_bytes - 1, trailer_marker, 1); 679 ::memset(cursor + right_redzone_bytes - 1, trailer_marker, 1);
681 680
682 SetShadowMemory(info.header, 681 SetShadowMemory(info.header,
683 info.TotalHeaderSize(), 682 info.TotalHeaderSize(),
684 kHeapLeftPaddingMarker); 683 kHeapLeftPaddingMarker);
685 SetShadowMemory(info.body, info.body_size, kHeapAddressableMarker); 684 SetShadowMemory(info.body, info.body_size, kHeapAddressableMarker);
686 SetShadowMemory(info.trailer_padding, 685 SetShadowMemory(info.trailer_padding,
687 info.TotalTrailerSize(), 686 info.TotalTrailerSize(),
688 kHeapRightPaddingMarker); 687 kHeapRightPaddingMarker);
689 } 688 }
690 689
691 bool Shadow::BlockIsNested(const BlockInfo& info) const {
692 uint8_t marker = GetShadowMarkerForAddress(info.header);
693 DCHECK(ShadowMarkerHelper::IsActiveBlockStart(marker));
694 return ShadowMarkerHelper::IsNestedBlockStart(marker);
695 }
696
697 bool Shadow::BlockInfoFromShadow( 690 bool Shadow::BlockInfoFromShadow(
698 const void* addr, CompactBlockInfo* info) const { 691 const void* addr, CompactBlockInfo* info) const {
699 DCHECK_NE(static_cast<void*>(NULL), addr); 692 DCHECK_NE(static_cast<void*>(NULL), addr);
700 DCHECK_NE(static_cast<CompactBlockInfo*>(NULL), info); 693 DCHECK_NE(static_cast<CompactBlockInfo*>(NULL), info);
701 if (!BlockInfoFromShadowImpl(0, addr, info)) 694 if (!BlockInfoFromShadowImpl(addr, info))
702 return false; 695 return false;
703 return true; 696 return true;
704 } 697 }
705 698
706 bool Shadow::BlockInfoFromShadow(const void* addr, BlockInfo* info) const { 699 bool Shadow::BlockInfoFromShadow(const void* addr, BlockInfo* info) const {
707 DCHECK_NE(static_cast<void*>(NULL), addr); 700 DCHECK_NE(static_cast<void*>(NULL), addr);
708 DCHECK_NE(static_cast<BlockInfo*>(NULL), info); 701 DCHECK_NE(static_cast<BlockInfo*>(NULL), info);
709 CompactBlockInfo compact = {}; 702 CompactBlockInfo compact = {};
710 if (!BlockInfoFromShadow(addr, &compact)) 703 if (!BlockInfoFromShadow(addr, &compact))
711 return false; 704 return false;
712 ConvertBlockInfo(compact, info); 705 ConvertBlockInfo(compact, info);
713 return true; 706 return true;
714 } 707 }
715 708
716 bool Shadow::ParentBlockInfoFromShadow(const BlockInfo& nested,
717 BlockInfo* info) const {
718 DCHECK_NE(static_cast<BlockInfo*>(NULL), info);
719 if (!BlockIsNested(nested))
720 return false;
721 CompactBlockInfo compact = {};
722 if (!BlockInfoFromShadowImpl(1, nested.header, &compact))
723 return false;
724 ConvertBlockInfo(compact, info);
725 return true;
726 }
727
728 bool Shadow::IsBeginningOfBlockBody(const void* addr) const { 709 bool Shadow::IsBeginningOfBlockBody(const void* addr) const {
729 DCHECK_NE(static_cast<void*>(NULL), addr); 710 DCHECK_NE(static_cast<void*>(NULL), addr);
730 // If the block has a non-zero body size then the beginning of the body will 711 // If the block has a non-zero body size then the beginning of the body will
731 // be accessible or tagged as freed. 712 // be accessible or tagged as freed.
732 // If the block has an empty body then the beginning of the body will be a 713 // If the block has an empty body then the beginning of the body will be a
733 // right redzone. 714 // right redzone.
734 if (IsAccessible(addr) || IsRightRedzone(addr) || 715 if (IsAccessible(addr) || IsRightRedzone(addr) ||
735 GetShadowMarkerForAddress(addr) == kHeapFreedMarker) { 716 GetShadowMarkerForAddress(addr) == kHeapFreedMarker) {
736 return IsLeftRedzone(reinterpret_cast<const uint8_t*>(addr) - 1); 717 return IsLeftRedzone(reinterpret_cast<const uint8_t*>(addr) - 1);
737 } 718 }
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
840 void Shadow::AppendShadowMemoryText( 821 void Shadow::AppendShadowMemoryText(
841 const void* addr, std::string* output) const { 822 const void* addr, std::string* output) const {
842 base::StringAppendF(output, "Shadow bytes around the buggy address:\n"); 823 base::StringAppendF(output, "Shadow bytes around the buggy address:\n");
843 AppendShadowArrayText(addr, output); 824 AppendShadowArrayText(addr, output);
844 base::StringAppendF(output, "Shadow byte legend (one shadow byte represents " 825 base::StringAppendF(output, "Shadow byte legend (one shadow byte represents "
845 "8 application bytes):\n"); 826 "8 application bytes):\n");
846 base::StringAppendF(output, " Addressable: 00\n"); 827 base::StringAppendF(output, " Addressable: 00\n");
847 base::StringAppendF(output, " Partially addressable: 01 - 07\n"); 828 base::StringAppendF(output, " Partially addressable: 01 - 07\n");
848 base::StringAppendF(output, " Block start redzone: %02x - %02x\n", 829 base::StringAppendF(output, " Block start redzone: %02x - %02x\n",
849 kHeapBlockStartMarker0, kHeapBlockStartMarker7); 830 kHeapBlockStartMarker0, kHeapBlockStartMarker7);
850 base::StringAppendF(output, " Nested block start: %02x - %02x\n",
851 kHeapNestedBlockStartMarker0,
852 kHeapNestedBlockStartMarker7);
853 base::StringAppendF(output, " Asan memory byte: %02x\n", 831 base::StringAppendF(output, " Asan memory byte: %02x\n",
854 kAsanMemoryMarker); 832 kAsanMemoryMarker);
855 base::StringAppendF(output, " Invalid address: %02x\n", 833 base::StringAppendF(output, " Invalid address: %02x\n",
856 kInvalidAddressMarker); 834 kInvalidAddressMarker);
857 base::StringAppendF(output, " User redzone: %02x\n", 835 base::StringAppendF(output, " User redzone: %02x\n",
858 kUserRedzoneMarker); 836 kUserRedzoneMarker);
859 base::StringAppendF(output, " Block end redzone: %02x\n", 837 base::StringAppendF(output, " Block end redzone: %02x\n",
860 kHeapBlockEndMarker); 838 kHeapBlockEndMarker);
861 base::StringAppendF(output, " Nested block end: %02x\n",
862 kHeapNestedBlockEndMarker);
863 base::StringAppendF(output, " Heap left redzone: %02x\n", 839 base::StringAppendF(output, " Heap left redzone: %02x\n",
864 kHeapLeftPaddingMarker); 840 kHeapLeftPaddingMarker);
865 base::StringAppendF(output, " Heap right redzone: %02x\n", 841 base::StringAppendF(output, " Heap right redzone: %02x\n",
866 kHeapRightPaddingMarker); 842 kHeapRightPaddingMarker);
867 base::StringAppendF(output, " Asan reserved byte: %02x\n", 843 base::StringAppendF(output, " Asan reserved byte: %02x\n",
868 kAsanReservedMarker); 844 kAsanReservedMarker);
869 base::StringAppendF(output, " Freed heap region: %02x\n", 845 base::StringAppendF(output, " Freed heap region: %02x\n",
870 kHeapFreedMarker); 846 kHeapFreedMarker);
871 } 847 }
872 848
873 size_t Shadow::GetAllocSize(const uint8_t* mem) const { 849 size_t Shadow::GetAllocSize(const uint8_t* mem) const {
874 BlockInfo block_info = {}; 850 BlockInfo block_info = {};
875 if (!Shadow::BlockInfoFromShadow(mem, &block_info)) 851 if (!Shadow::BlockInfoFromShadow(mem, &block_info))
876 return 0; 852 return 0;
877 return block_info.block_size; 853 return block_info.block_size;
878 } 854 }
879 855
880 bool Shadow::ScanLeftForBracketingBlockStart( 856 bool Shadow::ScanLeftForBracketingBlockStart(size_t cursor,
881 size_t initial_nesting_depth, size_t cursor, size_t* location) const { 857 size_t* location) const {
882 DCHECK_NE(static_cast<size_t*>(NULL), location); 858 DCHECK_NE(static_cast<size_t*>(NULL), location);
883 859
884 static const size_t kLowerBound = kAddressLowerBound / kShadowRatio; 860 static const size_t kLowerBound = kAddressLowerBound / kShadowRatio;
885 861
886 size_t left = cursor; 862 size_t left = cursor;
887 int nesting_depth = static_cast<int>(initial_nesting_depth);
888 863
889 MEMORY_BASIC_INFORMATION memory_info = {}; 864 MEMORY_BASIC_INFORMATION memory_info = {};
890 SIZE_T ret = 865 SIZE_T ret =
891 ::VirtualQuery(&shadow_[left], &memory_info, sizeof(memory_info)); 866 ::VirtualQuery(&shadow_[left], &memory_info, sizeof(memory_info));
892 DCHECK_GT(ret, 0u); 867 DCHECK_GT(ret, 0u);
893 if (memory_info.State != MEM_COMMIT) 868 if (memory_info.State != MEM_COMMIT)
894 return false; 869 return false;
895 870
896 if (ShadowMarkerHelper::IsBlockEnd(shadow_[left]))
897 --nesting_depth;
898 while (true) { 871 while (true) {
899 if (&shadow_[left] < static_cast<const uint8_t*>(memory_info.BaseAddress)) { 872 if (&shadow_[left] < static_cast<const uint8_t*>(memory_info.BaseAddress)) {
900 ret = ::VirtualQuery(&shadow_[left], &memory_info, sizeof(memory_info)); 873 ret = ::VirtualQuery(&shadow_[left], &memory_info, sizeof(memory_info));
901 DCHECK_GT(ret, 0u); 874 DCHECK_GT(ret, 0u);
902 if (memory_info.State != MEM_COMMIT) 875 if (memory_info.State != MEM_COMMIT)
903 return false; 876 return false;
904 } 877 }
905 if (ShadowMarkerHelper::IsBlockStart(shadow_[left])) { 878 if (ShadowMarkerHelper::IsBlockStart(shadow_[left])) {
906 if (nesting_depth == 0) { 879 *location = left;
907 *location = left; 880 return true;
908 return true;
909 }
910 // If this is not a nested block then there's no hope of finding a
911 // block containing the original cursor.
912 if (!ShadowMarkerHelper::IsNestedBlockStart(shadow_[left]))
913 return false;
914 --nesting_depth;
915 } else if (ShadowMarkerHelper::IsBlockEnd(shadow_[left])) {
916 ++nesting_depth;
917
918 // If we encounter the end of a non-nested block there's no way for
919 // a block to bracket us.
920 if (nesting_depth > 0 &&
921 !ShadowMarkerHelper::IsNestedBlockEnd(shadow_[left])) {
922 return false;
923 }
924 } 881 }
925 if (left <= kLowerBound) 882 if (left <= kLowerBound)
926 return false; 883 return false;
927 --left; 884 --left;
928 } 885 }
929 886
930 NOTREACHED(); 887 NOTREACHED();
931 } 888 }
932 889
933 namespace { 890 namespace {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1004 return pos; 961 return pos;
1005 } 962 }
1006 pos += 8; 963 pos += 8;
1007 } 964 }
1008 965
1009 return pos; 966 return pos;
1010 } 967 }
1011 968
1012 } // namespace 969 } // namespace
1013 970
1014 bool Shadow::ScanRightForBracketingBlockEnd( 971 bool Shadow::ScanRightForBracketingBlockEnd(size_t cursor,
1015 size_t initial_nesting_depth, size_t cursor, size_t* location) const { 972 size_t* location) const {
1016 DCHECK_NE(static_cast<size_t*>(NULL), location); 973 DCHECK_NE(static_cast<size_t*>(NULL), location);
1017 974
1018 const uint8_t* shadow_end = shadow_ + length_; 975 const uint8_t* shadow_end = shadow_ + length_;
1019 const uint8_t* pos = shadow_ + cursor; 976 const uint8_t* pos = shadow_ + cursor;
1020 int nesting_depth = static_cast<int>(initial_nesting_depth);
1021 if (ShadowMarkerHelper::IsBlockStart(*pos))
1022 --nesting_depth;
1023 while (pos < shadow_end) { 977 while (pos < shadow_end) {
1024 // Skips past as many addressable and freed bytes as possible. 978 // Skips past as many addressable and freed bytes as possible.
1025 pos = ScanRightForPotentialHeaderBytes(pos, shadow_end); 979 pos = ScanRightForPotentialHeaderBytes(pos, shadow_end);
1026 if (pos == shadow_end) 980 if (pos == shadow_end)
1027 return false; 981 return false;
1028 982
1029 // When the above loop exits early then somewhere in the next 8 bytes 983 // When the above loop exits early then somewhere in the next 8 bytes
1030 // there's non-addressable data that isn't 'freed'. Look byte by byte to 984 // there's non-addressable data that isn't 'freed'. Look byte by byte to
1031 // see what's up. 985 // see what's up.
1032 986
1033 if (ShadowMarkerHelper::IsBlockEnd(*pos)) { 987 if (ShadowMarkerHelper::IsBlockEnd(*pos)) {
1034 if (nesting_depth == 0) { 988 *location = pos - shadow_;
1035 *location = pos - shadow_; 989 return true;
1036 return true;
1037 }
1038 if (!ShadowMarkerHelper::IsNestedBlockEnd(*pos))
1039 return false;
1040 --nesting_depth;
1041 } else if (ShadowMarkerHelper::IsBlockStart(*pos)) {
1042 ++nesting_depth;
1043
1044 // If we encounter the beginning of a non-nested block then there's
1045 // clearly no way for any block to bracket us.
1046 if (nesting_depth > 0 &&
1047 !ShadowMarkerHelper::IsNestedBlockStart(*pos)) {
1048 return false;
1049 }
1050 } 990 }
1051 ++pos; 991 ++pos;
1052 } 992 }
1053 return false; 993 return false;
1054 } 994 }
1055 995
1056 bool Shadow::BlockInfoFromShadowImpl( 996 bool Shadow::BlockInfoFromShadowImpl(
1057 size_t initial_nesting_depth,
1058 const void* addr, 997 const void* addr,
1059 CompactBlockInfo* info) const { 998 CompactBlockInfo* info) const {
1060 DCHECK_NE(static_cast<void*>(NULL), addr); 999 DCHECK_NE(static_cast<void*>(NULL), addr);
1061 DCHECK_NE(static_cast<CompactBlockInfo*>(NULL), info); 1000 DCHECK_NE(static_cast<CompactBlockInfo*>(NULL), info);
1062 1001
1063 // Convert the address to an offset in the shadow memory. 1002 // Convert the address to an offset in the shadow memory.
1064 size_t left = reinterpret_cast<uintptr_t>(addr) / kShadowRatio; 1003 size_t left = reinterpret_cast<uintptr_t>(addr) / kShadowRatio;
1065 size_t right = left; 1004 size_t right = left;
1066 1005
1067 if (!ScanLeftForBracketingBlockStart(initial_nesting_depth, left, &left)) 1006 if (!ScanLeftForBracketingBlockStart(left, &left))
1068 return false; 1007 return false;
1069 if (!ScanRightForBracketingBlockEnd(initial_nesting_depth, right, &right)) 1008 if (!ScanRightForBracketingBlockEnd(right, &right))
1070 return false; 1009 return false;
1071 ++right; 1010 ++right;
1072 1011
1073 uint8_t* block = reinterpret_cast<uint8_t*>(left * kShadowRatio); 1012 uint8_t* block = reinterpret_cast<uint8_t*>(left * kShadowRatio);
1074 info->header = reinterpret_cast<BlockHeader*>(block); 1013 info->header = reinterpret_cast<BlockHeader*>(block);
1075 info->block_size = static_cast<uint32_t>((right - left) * kShadowRatio); 1014 info->block_size = static_cast<uint32_t>((right - left) * kShadowRatio);
1076 1015
1077 // Get the length of the body modulo the shadow ratio. 1016 // Get the length of the body modulo the shadow ratio.
1078 size_t body_size_mod = ShadowMarkerHelper::GetBlockStartData(shadow_[left]); 1017 size_t body_size_mod = ShadowMarkerHelper::GetBlockStartData(shadow_[left]);
1079 info->is_nested = ShadowMarkerHelper::IsNestedBlockStart(shadow_[left]);
1080 1018
1081 // Find the beginning of the body (end of the left redzone). 1019 // Find the beginning of the body (end of the left redzone).
1082 ++left; 1020 ++left;
1083 while (left < right && shadow_[left] == kHeapLeftPaddingMarker) 1021 while (left < right && shadow_[left] == kHeapLeftPaddingMarker)
1084 ++left; 1022 ++left;
1085 1023
1086 // Find the beginning of the right redzone (end of the body). 1024 // Find the beginning of the right redzone (end of the body).
1087 --right; 1025 --right;
1088 while (right > left && shadow_[right - 1] == kHeapRightPaddingMarker) 1026 while (right > left && shadow_[right - 1] == kHeapRightPaddingMarker)
1089 --right; 1027 --right;
1090 1028
1091 // Calculate the body location and size. 1029 // Calculate the body location and size.
1092 uint8_t* body = reinterpret_cast<uint8_t*>(left * kShadowRatio); 1030 uint8_t* body = reinterpret_cast<uint8_t*>(left * kShadowRatio);
1093 size_t body_size = (right - left) * kShadowRatio; 1031 size_t body_size = (right - left) * kShadowRatio;
1094 if (body_size_mod > 0) { 1032 if (body_size_mod > 0) {
1095 DCHECK_LE(8u, body_size); 1033 DCHECK_LE(8u, body_size);
1096 body_size = body_size - kShadowRatio + body_size_mod; 1034 body_size = body_size - kShadowRatio + body_size_mod;
1097 } 1035 }
1098 1036
1099 // Fill out header and trailer sizes. 1037 // Fill out header and trailer sizes.
1100 info->header_size = body - block; 1038 info->header_size = body - block;
1101 info->trailer_size = info->block_size - body_size - info->header_size; 1039 info->trailer_size = info->block_size - body_size - info->header_size;
1102 1040
1103 return true; 1041 return true;
1104 } 1042 }
1105 1043
1106 ShadowWalker::ShadowWalker(const Shadow* shadow, 1044 ShadowWalker::ShadowWalker(const Shadow* shadow,
1107 bool recursive,
1108 const void* lower_bound, 1045 const void* lower_bound,
1109 const void* upper_bound) 1046 const void* upper_bound)
1110 : shadow_(shadow), recursive_(recursive), lower_index_(0), upper_index_(0), 1047 : shadow_(shadow),
1111 shadow_cursor_(nullptr), nesting_depth_(0) { 1048 lower_index_(0),
1049 upper_index_(0),
1050 shadow_cursor_(nullptr) {
1112 DCHECK_NE(static_cast<Shadow*>(nullptr), shadow); 1051 DCHECK_NE(static_cast<Shadow*>(nullptr), shadow);
1113 DCHECK_LE(Shadow::kAddressLowerBound, reinterpret_cast<size_t>(lower_bound)); 1052 DCHECK_LE(Shadow::kAddressLowerBound, reinterpret_cast<size_t>(lower_bound));
1114 1053
1115 // Get the bounds as shadow indices, being careful to deal with overflow 1054 // Get the bounds as shadow indices, being careful to deal with overflow
1116 // of |upper_bound|. 1055 // of |upper_bound|.
1117 lower_index_ = reinterpret_cast<uintptr_t>(lower_bound) >> kShadowRatioLog; 1056 lower_index_ = reinterpret_cast<uintptr_t>(lower_bound) >> kShadowRatioLog;
1118 upper_index_ = reinterpret_cast<size_t>(::common::AlignUp( 1057 upper_index_ = reinterpret_cast<size_t>(::common::AlignUp(
1119 reinterpret_cast<const uint8_t*>(upper_bound), kShadowRatio)); 1058 reinterpret_cast<const uint8_t*>(upper_bound), kShadowRatio));
1120 upper_index_--; 1059 upper_index_--;
1121 upper_index_ >>= kShadowRatioLog; 1060 upper_index_ >>= kShadowRatioLog;
1122 upper_index_++; 1061 upper_index_++;
1123 1062
1124 DCHECK_LE(lower_index_, upper_index_); 1063 DCHECK_LE(lower_index_, upper_index_);
1125 DCHECK_GE(shadow->length(), upper_index_ - lower_index_); 1064 DCHECK_GE(shadow->length(), upper_index_ - lower_index_);
1126 1065
1127 Reset(); 1066 Reset();
1128 } 1067 }
1129 1068
1130 void ShadowWalker::Reset() { 1069 void ShadowWalker::Reset() {
1131 nesting_depth_ = -1;
1132 shadow_cursor_ = shadow_->shadow() + lower_index_; 1070 shadow_cursor_ = shadow_->shadow() + lower_index_;
1133 } 1071 }
1134 1072
1135 bool ShadowWalker::Next(BlockInfo* info) { 1073 bool ShadowWalker::Next(BlockInfo* info) {
1136 DCHECK_NE(static_cast<BlockInfo*>(NULL), info); 1074 DCHECK_NE(static_cast<BlockInfo*>(NULL), info);
1137 1075
1138 auto shadow_upper_bound = shadow_->shadow() + upper_index_; 1076 auto shadow_upper_bound = shadow_->shadow() + upper_index_;
1139 1077
1140 while (shadow_cursor_ < shadow_upper_bound) { 1078 while (shadow_cursor_ < shadow_upper_bound) {
1141 // Skip uncommitted ranges of memory. This is possible when using a sparse 1079 // Skip uncommitted ranges of memory. This is possible when using a sparse
(...skipping 26 matching lines...) Expand all
1168 } else { 1106 } else {
1169 end_of_region = std::min(shadow_upper_bound, end_of_region); 1107 end_of_region = std::min(shadow_upper_bound, end_of_region);
1170 } 1108 }
1171 1109
1172 // Scan this committed portion of the shadow. 1110 // Scan this committed portion of the shadow.
1173 while (shadow_cursor_ < end_of_region) { 1111 while (shadow_cursor_ < end_of_region) {
1174 uint8_t marker = *shadow_cursor_; 1112 uint8_t marker = *shadow_cursor_;
1175 1113
1176 // Update the nesting depth when block end markers are encountered. 1114 // Update the nesting depth when block end markers are encountered.
1177 if (ShadowMarkerHelper::IsBlockEnd(marker)) { 1115 if (ShadowMarkerHelper::IsBlockEnd(marker)) {
1178 DCHECK_LE(0, nesting_depth_);
1179 --nesting_depth_;
1180 ++shadow_cursor_; 1116 ++shadow_cursor_;
1181 continue; 1117 continue;
1182 } 1118 }
1183 1119
1184 // Look for a block start marker. 1120 // Look for a block start marker.
1185 if (ShadowMarkerHelper::IsBlockStart(marker)) { 1121 if (ShadowMarkerHelper::IsBlockStart(marker)) {
1186 // Update the nesting depth when block start bytes are encountered. 1122 // This can only fail if the shadow memory is malformed.
1187 ++nesting_depth_; 1123 size_t block_index = shadow_cursor_ - shadow_->shadow();
1124 void* block_address =
1125 reinterpret_cast<void*>(block_index << kShadowRatioLog);
1126 CHECK(shadow_->BlockInfoFromShadow(block_address, info));
1188 1127
1189 // Non-nested blocks should only be encountered at depth 0. 1128 // We skip directly to the end marker.
1190 bool is_nested = ShadowMarkerHelper::IsNestedBlockStart(marker); 1129 auto block_end =
1191 DCHECK(is_nested || nesting_depth_ == 0); 1130 reinterpret_cast<const uint8_t*>(info->header) + info->block_size;
1131 shadow_cursor_ = shadow_->GetShadowMemoryForAddress(block_end) - 1;
1192 1132
1193 // Determine if the block is to be reported. 1133 // A block has been found and its |info| is parsed. Return to the
1194 if (!is_nested || recursive_) { 1134 // caller.
1195 // This can only fail if the shadow memory is malformed. 1135 return true;
1196 size_t block_index = shadow_cursor_ - shadow_->shadow();
1197 void* block_address = reinterpret_cast<void*>(
1198 block_index << kShadowRatioLog);
1199 CHECK(shadow_->BlockInfoFromShadow(block_address, info));
1200
1201 // In a recursive descent we have to process body contents.
1202 if (recursive_) {
1203 // Jump straight to the body of the nested block.
1204 shadow_cursor_ = shadow_->GetShadowMemoryForAddress(
1205 info->body);
1206 } else {
1207 // Otherwise we can skip the body of the block we just reported.
1208 // We skip directly to the end marker (but not past it so that depth
1209 // bookkeeping works properly).
1210 auto block_end = reinterpret_cast<const uint8_t*>(info->header) +
1211 info->block_size;
1212 shadow_cursor_ = shadow_->GetShadowMemoryForAddress(block_end) - 1;
1213 }
1214
1215 // A block has been found and its |info| is parsed. Return to the
1216 // caller.
1217 return true;
1218 }
1219 } 1136 }
1220 1137
1221 // Advance the shadow cursor. 1138 // Advance the shadow cursor.
1222 ++shadow_cursor_; 1139 ++shadow_cursor_;
1223 } // while (shadow_cursor_ < end_of_region) 1140 } // while (shadow_cursor_ < end_of_region)
1224 } 1141 }
1225 1142
1226 return false; 1143 return false;
1227 } 1144 }
1228 1145
1229 } // namespace asan 1146 } // namespace asan
1230 } // namespace agent 1147 } // namespace agent
OLDNEW
« no previous file with comments | « syzygy/agent/asan/shadow.h ('k') | syzygy/agent/asan/shadow_marker.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698