OLD | NEW |
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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 } | 83 } |
84 | 84 |
85 TestShadow(size_t digits, size_t power) | 85 TestShadow(size_t digits, size_t power) |
86 : Shadow(digits << (power - kShadowRatioLog)) { | 86 : Shadow(digits << (power - kShadowRatioLog)) { |
87 } | 87 } |
88 | 88 |
89 // We'll simulate memory as being 1GB in size. | 89 // We'll simulate memory as being 1GB in size. |
90 static const size_t kDefaultTestShadowSize = | 90 static const size_t kDefaultTestShadowSize = |
91 (1 * 1024 * 1024 * 1024) >> kShadowRatioLog; | 91 (1 * 1024 * 1024 * 1024) >> kShadowRatioLog; |
92 | 92 |
| 93 TestShadow(void* shadow, size_t length) : Shadow(shadow, length) {} |
| 94 |
93 // Protected functions that we want to unittest directly. | 95 // Protected functions that we want to unittest directly. |
94 using Shadow::Reset; | 96 using Shadow::Reset; |
95 using Shadow::ScanLeftForBracketingBlockStart; | 97 using Shadow::ScanLeftForBracketingBlockStart; |
96 using Shadow::ScanRightForBracketingBlockEnd; | 98 using Shadow::ScanRightForBracketingBlockEnd; |
97 using Shadow::shadow_; | 99 using Shadow::shadow_; |
98 }; | 100 }; |
99 | 101 |
100 // A fixture for shadow memory tests. | 102 // A fixture for shadow memory tests. |
101 class ShadowTest : public testing::Test { | 103 class ShadowTest : public testing::Test { |
102 public: | 104 public: |
(...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
913 EXPECT_TRUE(w1.Next(&i)); | 915 EXPECT_TRUE(w1.Next(&i)); |
914 EXPECT_EQ(0, w1.nesting_depth()); | 916 EXPECT_EQ(0, w1.nesting_depth()); |
915 EXPECT_EQ(0, ::memcmp(&i, &i2, sizeof(i))); | 917 EXPECT_EQ(0, ::memcmp(&i, &i2, sizeof(i))); |
916 EXPECT_FALSE(w1.Next(&i)); | 918 EXPECT_FALSE(w1.Next(&i)); |
917 EXPECT_EQ(-1, w1.nesting_depth()); | 919 EXPECT_EQ(-1, w1.nesting_depth()); |
918 | 920 |
919 test_shadow.Unpoison(data, data_size); | 921 test_shadow.Unpoison(data, data_size); |
920 delete [] data; | 922 delete [] data; |
921 } | 923 } |
922 | 924 |
| 925 TEST_F(ShadowWalkerTest, WalkShadowWithUncommittedRanges) { |
| 926 // Create a 512k memory block. |
| 927 const size_t kMemorySize = 512 * 1024; |
| 928 uint8_t memory_block[kMemorySize]; |
| 929 const size_t shadow_size = Shadow::RequiredLength(); |
| 930 |
| 931 // Allocate the shadow memory, only reserve the memory. |
| 932 uint8_t* shadow_memory = static_cast<uint8_t*>( |
| 933 ::VirtualAlloc(nullptr, shadow_size, MEM_RESERVE, PAGE_READWRITE)); |
| 934 EXPECT_NE(nullptr, shadow_memory); |
| 935 |
| 936 uint8_t* memory_block_shadow_start = |
| 937 shadow_memory + reinterpret_cast<size_t>(memory_block) / kShadowRatio; |
| 938 |
| 939 TestShadow ts1(shadow_memory, Shadow::RequiredLength()); |
| 940 |
| 941 std::vector<BlockInfo> block_info_vec; |
| 942 BlockLayout l = {}; |
| 943 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 7, 0, 0, &l)); |
| 944 EXPECT_LT(l.block_size, GetPageSize() * kShadowRatio); |
| 945 |
| 946 // Calculate the size of the shadow necessary to cover this block |
| 947 // as well as the number of pages in it. |
| 948 const size_t kBlockShadowSize = kMemorySize / kShadowRatio; |
| 949 size_t shadow_page_count = kBlockShadowSize / GetPageSize(); |
| 950 |
| 951 // Allocate a block that will fit on every other pages of the shadow. |
| 952 for (size_t i = 0; i < shadow_page_count; ++i) { |
| 953 if (i % 2 == 0) |
| 954 continue; |
| 955 // Address of the shadow memory for this page. |
| 956 uint8_t* shadow_address = memory_block_shadow_start + i * GetPageSize(); |
| 957 uint8_t* shadow_address_page_begin = |
| 958 ::common::AlignDown(shadow_address, GetPageSize()); |
| 959 // Commit the shadow memory for this block. |
| 960 EXPECT_EQ(static_cast<void*>(shadow_address_page_begin), |
| 961 ::VirtualAlloc(shadow_address, GetPageSize(), MEM_COMMIT, |
| 962 PAGE_READWRITE)); |
| 963 |
| 964 // Address of the memory for this block. |
| 965 uint8_t* page_address = ::common::AlignUp( |
| 966 memory_block + i * GetPageSize() * kShadowRatio, kShadowRatio); |
| 967 BlockInfo block_info = {}; |
| 968 BlockInitialize(l, page_address, false, &block_info); |
| 969 block_info_vec.push_back(block_info); |
| 970 |
| 971 // Poison the block. |
| 972 ts1.PoisonAllocatedBlock(block_info); |
| 973 } |
| 974 |
| 975 size_t block_count = 0; |
| 976 ShadowWalker w(&ts1, true, memory_block, memory_block + kMemorySize); |
| 977 BlockInfo i = {}; |
| 978 while (w.Next(&i)) { |
| 979 EXPECT_LT(block_count, block_info_vec.size()); |
| 980 EXPECT_EQ(block_info_vec[block_count].header, i.header); |
| 981 EXPECT_EQ(block_info_vec[block_count].body, i.body); |
| 982 EXPECT_EQ(block_info_vec[block_count].trailer, i.trailer); |
| 983 block_count++; |
| 984 } |
| 985 EXPECT_EQ(block_info_vec.size(), block_count); |
| 986 EXPECT_FALSE(w.Next(&i)); |
| 987 |
| 988 EXPECT_GT(::VirtualFree(shadow_memory, 0, MEM_RELEASE), 0U); |
| 989 } |
| 990 |
923 } // namespace asan | 991 } // namespace asan |
924 } // namespace agent | 992 } // namespace agent |
OLD | NEW |