| 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 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 // An overflowing range is always inaccessible. | 310 // An overflowing range is always inaccessible. |
| 311 EXPECT_EQ(test_array + 3, test_shadow.FindFirstPoisonedByte( | 311 EXPECT_EQ(test_array + 3, test_shadow.FindFirstPoisonedByte( |
| 312 test_array + 3, static_cast<size_t>(-3))); | 312 test_array + 3, static_cast<size_t>(-3))); |
| 313 | 313 |
| 314 for (size_t i = 0; i < size; ++i) { | 314 for (size_t i = 0; i < size; ++i) { |
| 315 // Try valid ranges at every starting position inside the unpoisoned | 315 // Try valid ranges at every starting position inside the unpoisoned |
| 316 // range. | 316 // range. |
| 317 EXPECT_EQ(nullptr, | 317 EXPECT_EQ(nullptr, |
| 318 test_shadow.FindFirstPoisonedByte(test_array + i, size - i)); | 318 test_shadow.FindFirstPoisonedByte(test_array + i, size - i)); |
| 319 | 319 |
| 320 // Try valid ranges ending at every poisition inside the unpoisoned range. | 320 // Try valid ranges ending at every position inside the unpoisoned range. |
| 321 EXPECT_EQ(nullptr, | 321 EXPECT_EQ(nullptr, |
| 322 test_shadow.FindFirstPoisonedByte(test_array, size - i)); | 322 test_shadow.FindFirstPoisonedByte(test_array, size - i)); |
| 323 } | 323 } |
| 324 | 324 |
| 325 for (size_t i = 1; i < kShadowRatio; ++i) { | 325 for (size_t i = 1; i < kShadowRatio; ++i) { |
| 326 // Try invalid ranges at starting positions outside the unpoisoned range. | 326 // Try invalid ranges at starting positions outside the unpoisoned range. |
| 327 EXPECT_EQ(test_array - i, | 327 EXPECT_EQ(test_array - i, |
| 328 test_shadow.FindFirstPoisonedByte(test_array - i, size)); | 328 test_shadow.FindFirstPoisonedByte(test_array - i, size)); |
| 329 | 329 |
| 330 // Try invalid ranges at ending positions outside the unpoisoned range. | 330 // Try invalid ranges at ending positions outside the unpoisoned range. |
| 331 EXPECT_EQ(test_array + size, | 331 EXPECT_EQ(test_array + size, |
| 332 test_shadow.FindFirstPoisonedByte(test_array, size + i)); | 332 test_shadow.FindFirstPoisonedByte(test_array, size + i)); |
| 333 } | 333 } |
| 334 } | 334 } |
| 335 test_shadow.Unpoison(aligned_test_array, aligned_array_length); | 335 test_shadow.Unpoison(aligned_test_array, aligned_array_length); |
| 336 } | 336 } |
| 337 | 337 |
| 338 TEST_F(ShadowTest, MarkAsFreed) { | 338 TEST_F(ShadowTest, MarkAsFreed) { |
| 339 BlockLayout l0 = {}, l1 = {}; | 339 BlockLayout l0 = {}, l1 = {}; |
| 340 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 16, 30, 30, &l1)); | 340 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 16, 30, 30, &l1)); |
| 341 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, | 341 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, |
| 342 l1.block_size + 2 * kShadowRatio, 30, 30, &l0)); | 342 l1.block_size + 2 * kShadowRatio, 30, 30, &l0)); |
| 343 | 343 |
| 344 uint8_t* data = new uint8_t[l0.block_size]; | 344 uint8_t* data = new uint8_t[l0.block_size]; |
| 345 | 345 |
| 346 uint8_t* d0 = data; | 346 uint8_t* d0 = data; |
| 347 BlockInfo i0 = {}; | 347 BlockInfo i0 = {}; |
| 348 BlockInitialize(l0, d0, false, &i0); | 348 BlockInitialize(l0, d0, &i0); |
| 349 test_shadow.PoisonAllocatedBlock(i0); | 349 test_shadow.PoisonAllocatedBlock(i0); |
| 350 | 350 |
| 351 uint8_t* d1 = i0.RawBody() + kShadowRatio; | 351 uint8_t* d1 = i0.RawBody() + kShadowRatio; |
| 352 BlockInfo i1 = {}; | 352 BlockInfo i1 = {}; |
| 353 BlockInitialize(l1, d1, true, &i1); | 353 BlockInitialize(l1, d1, &i1); |
| 354 test_shadow.PoisonAllocatedBlock(i1); | 354 test_shadow.PoisonAllocatedBlock(i1); |
| 355 | 355 |
| 356 test_shadow.MarkAsFreed(i0.body, i0.body_size); | 356 test_shadow.MarkAsFreed(i0.body, i0.body_size); |
| 357 for (uint8_t* p = i0.RawBlock(); p < i0.RawBlock() + i0.block_size; ++p) { | 357 for (uint8_t* p = i0.RawBlock(); p < i0.RawBlock() + i0.block_size; ++p) { |
| 358 if (p >= i0.RawBlock() && p < i0.RawBody()) { | 358 if (p >= i0.RawBlock() && p < i0.RawBody()) { |
| 359 EXPECT_TRUE(test_shadow.IsLeftRedzone(p)); | 359 EXPECT_TRUE(test_shadow.IsLeftRedzone(p)); |
| 360 } else if (p >= i0.RawBody() && | 360 } else if (p >= i0.RawBody() && |
| 361 p < i0.RawTrailerPadding()) { | 361 p < i0.RawTrailerPadding()) { |
| 362 if (p >= i1.RawBlock() && p < i1.RawBody()) { | 362 if (p >= i1.RawBlock() && p < i1.RawBody()) { |
| 363 EXPECT_TRUE(test_shadow.IsLeftRedzone(p)); | 363 EXPECT_TRUE(test_shadow.IsLeftRedzone(p)); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 380 test_shadow.Unpoison(data, l0.block_size); | 380 test_shadow.Unpoison(data, l0.block_size); |
| 381 delete [] data; | 381 delete [] data; |
| 382 } | 382 } |
| 383 | 383 |
| 384 TEST_F(ShadowTest, PoisonAllocatedBlock) { | 384 TEST_F(ShadowTest, PoisonAllocatedBlock) { |
| 385 BlockLayout layout = {}; | 385 BlockLayout layout = {}; |
| 386 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 15, 22, 0, &layout)); | 386 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 15, 22, 0, &layout)); |
| 387 | 387 |
| 388 uint8_t* data = new uint8_t[layout.block_size]; | 388 uint8_t* data = new uint8_t[layout.block_size]; |
| 389 BlockInfo info = {}; | 389 BlockInfo info = {}; |
| 390 BlockInitialize(layout, data, false, &info); | 390 BlockInitialize(layout, data, &info); |
| 391 | 391 |
| 392 test_shadow.PoisonAllocatedBlock(info); | 392 test_shadow.PoisonAllocatedBlock(info); |
| 393 EXPECT_EQ(test_shadow.GetShadowMarkerForAddress(data + 0 * 8), | 393 EXPECT_EQ(test_shadow.GetShadowMarkerForAddress(data + 0 * 8), |
| 394 kHeapBlockStartMarker0 | 7); | 394 kHeapBlockStartMarker0 | 7); |
| 395 EXPECT_EQ(test_shadow.GetShadowMarkerForAddress(data + 1 * 8), | 395 EXPECT_EQ(test_shadow.GetShadowMarkerForAddress(data + 1 * 8), |
| 396 kHeapLeftPaddingMarker); | 396 kHeapLeftPaddingMarker); |
| 397 EXPECT_EQ(test_shadow.GetShadowMarkerForAddress(data + 2 * 8), | 397 EXPECT_EQ(test_shadow.GetShadowMarkerForAddress(data + 2 * 8), |
| 398 kHeapLeftPaddingMarker); | 398 kHeapLeftPaddingMarker); |
| 399 EXPECT_EQ(test_shadow.GetShadowMarkerForAddress(data + 3 * 8), | 399 EXPECT_EQ(test_shadow.GetShadowMarkerForAddress(data + 3 * 8), |
| 400 0); | 400 0); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 423 EXPECT_FALSE(test_shadow.IsAccessible(cursor)); | 423 EXPECT_FALSE(test_shadow.IsAccessible(cursor)); |
| 424 test_shadow.Unpoison(info.RawBlock(), info.block_size); | 424 test_shadow.Unpoison(info.RawBlock(), info.block_size); |
| 425 | 425 |
| 426 delete [] data; | 426 delete [] data; |
| 427 } | 427 } |
| 428 | 428 |
| 429 TEST_F(ShadowTest, ScanLeftAndRight) { | 429 TEST_F(ShadowTest, ScanLeftAndRight) { |
| 430 size_t offset = test_shadow.length() / 2; | 430 size_t offset = test_shadow.length() / 2; |
| 431 size_t l = 0; | 431 size_t l = 0; |
| 432 test_shadow.shadow_[offset + 0] = kHeapBlockStartMarker0; | 432 test_shadow.shadow_[offset + 0] = kHeapBlockStartMarker0; |
| 433 test_shadow.shadow_[offset + 1] = kHeapNestedBlockStartMarker0; | 433 test_shadow.shadow_[offset + 1] = kHeapAddressableMarker; |
| 434 test_shadow.shadow_[offset + 2] = kHeapAddressableMarker; | 434 test_shadow.shadow_[offset + 2] = kHeapBlockEndMarker; |
| 435 test_shadow.shadow_[offset + 3] = kHeapNestedBlockEndMarker; | |
| 436 test_shadow.shadow_[offset + 4] = kHeapBlockEndMarker; | |
| 437 | 435 |
| 438 EXPECT_TRUE(test_shadow.ScanLeftForBracketingBlockStart(0, offset + 0, &l)); | 436 EXPECT_TRUE(test_shadow.ScanLeftForBracketingBlockStart(offset + 0, &l)); |
| 439 EXPECT_EQ(offset, l); | 437 EXPECT_EQ(offset, l); |
| 440 EXPECT_TRUE(test_shadow.ScanLeftForBracketingBlockStart(0, offset + 1, &l)); | 438 EXPECT_TRUE(test_shadow.ScanLeftForBracketingBlockStart(offset + 1, &l)); |
| 441 EXPECT_EQ(offset + 1, l); | 439 EXPECT_EQ(offset, l); |
| 442 EXPECT_TRUE(test_shadow.ScanLeftForBracketingBlockStart(0, offset + 2, &l)); | 440 EXPECT_TRUE(test_shadow.ScanLeftForBracketingBlockStart(offset + 2, &l)); |
| 443 EXPECT_EQ(offset + 1, l); | |
| 444 EXPECT_TRUE(test_shadow.ScanLeftForBracketingBlockStart(0, offset + 3, &l)); | |
| 445 EXPECT_EQ(offset + 1, l); | |
| 446 EXPECT_TRUE(test_shadow.ScanLeftForBracketingBlockStart(0, offset + 4, &l)); | |
| 447 EXPECT_EQ(offset, l); | 441 EXPECT_EQ(offset, l); |
| 448 | 442 |
| 449 EXPECT_FALSE(test_shadow.ScanLeftForBracketingBlockStart(1, offset + 0, &l)); | 443 EXPECT_TRUE(test_shadow.ScanRightForBracketingBlockEnd(offset + 0, &l)); |
| 450 EXPECT_TRUE(test_shadow.ScanLeftForBracketingBlockStart(1, offset + 1, &l)); | 444 EXPECT_EQ(offset + 2, l); |
| 451 EXPECT_EQ(offset, l); | 445 EXPECT_TRUE(test_shadow.ScanRightForBracketingBlockEnd(offset + 1, &l)); |
| 452 EXPECT_TRUE(test_shadow.ScanLeftForBracketingBlockStart(1, offset + 2, &l)); | 446 EXPECT_EQ(offset + 2, l); |
| 453 EXPECT_EQ(offset, l); | 447 EXPECT_TRUE(test_shadow.ScanRightForBracketingBlockEnd(offset + 2, &l)); |
| 454 EXPECT_TRUE(test_shadow.ScanLeftForBracketingBlockStart(1, offset + 3, &l)); | 448 EXPECT_EQ(offset + 2, l); |
| 455 EXPECT_EQ(offset, l); | |
| 456 EXPECT_FALSE(test_shadow.ScanLeftForBracketingBlockStart(1, offset + 4, &l)); | |
| 457 | |
| 458 EXPECT_FALSE(test_shadow.ScanLeftForBracketingBlockStart(2, offset + 0, &l)); | |
| 459 EXPECT_FALSE(test_shadow.ScanLeftForBracketingBlockStart(2, offset + 1, &l)); | |
| 460 EXPECT_FALSE(test_shadow.ScanLeftForBracketingBlockStart(2, offset + 2, &l)); | |
| 461 EXPECT_FALSE(test_shadow.ScanLeftForBracketingBlockStart(2, offset + 3, &l)); | |
| 462 EXPECT_FALSE(test_shadow.ScanLeftForBracketingBlockStart(2, offset + 4, &l)); | |
| 463 | |
| 464 EXPECT_TRUE(test_shadow.ScanRightForBracketingBlockEnd(0, offset + 0, &l)); | |
| 465 EXPECT_EQ(offset + 4, l); | |
| 466 EXPECT_TRUE(test_shadow.ScanRightForBracketingBlockEnd(0, offset + 1, &l)); | |
| 467 EXPECT_EQ(offset + 3, l); | |
| 468 EXPECT_TRUE(test_shadow.ScanRightForBracketingBlockEnd(0, offset + 2, &l)); | |
| 469 EXPECT_EQ(offset + 3, l); | |
| 470 EXPECT_TRUE(test_shadow.ScanRightForBracketingBlockEnd(0, offset + 3, &l)); | |
| 471 EXPECT_EQ(offset + 3, l); | |
| 472 EXPECT_TRUE(test_shadow.ScanRightForBracketingBlockEnd(0, offset + 4, &l)); | |
| 473 EXPECT_EQ(offset + 4, l); | |
| 474 | |
| 475 EXPECT_FALSE(test_shadow.ScanRightForBracketingBlockEnd(1, offset + 0, &l)); | |
| 476 EXPECT_TRUE(test_shadow.ScanRightForBracketingBlockEnd(1, offset + 1, &l)); | |
| 477 EXPECT_EQ(offset + 4, l); | |
| 478 EXPECT_TRUE(test_shadow.ScanRightForBracketingBlockEnd(1, offset + 2, &l)); | |
| 479 EXPECT_EQ(offset + 4, l); | |
| 480 EXPECT_TRUE(test_shadow.ScanRightForBracketingBlockEnd(1, offset + 3, &l)); | |
| 481 EXPECT_EQ(offset + 4, l); | |
| 482 EXPECT_FALSE(test_shadow.ScanRightForBracketingBlockEnd(1, offset + 4, &l)); | |
| 483 | |
| 484 EXPECT_FALSE(test_shadow.ScanRightForBracketingBlockEnd(2, offset + 0, &l)); | |
| 485 EXPECT_FALSE(test_shadow.ScanRightForBracketingBlockEnd(2, offset + 1, &l)); | |
| 486 EXPECT_FALSE(test_shadow.ScanRightForBracketingBlockEnd(2, offset + 2, &l)); | |
| 487 EXPECT_FALSE(test_shadow.ScanRightForBracketingBlockEnd(2, offset + 3, &l)); | |
| 488 EXPECT_FALSE(test_shadow.ScanRightForBracketingBlockEnd(2, offset + 4, &l)); | |
| 489 | 449 |
| 490 ::memset(test_shadow.shadow_ + offset, 0, 5); | 450 ::memset(test_shadow.shadow_ + offset, 0, 5); |
| 491 } | 451 } |
| 492 | 452 |
| 493 TEST_F(ShadowTest, ScanRightPerfTest) { | 453 TEST_F(ShadowTest, ScanRightPerfTest) { |
| 494 size_t offset = test_shadow.length() / 2; | 454 size_t offset = test_shadow.length() / 2; |
| 495 size_t length = 1 * 1024 * 1024; | 455 size_t length = 1 * 1024 * 1024; |
| 496 | 456 |
| 497 ::memset(test_shadow.shadow_ + offset, 0, length); | 457 ::memset(test_shadow.shadow_ + offset, 0, length); |
| 498 | 458 |
| 499 test_shadow.shadow_[offset + 0] = kHeapBlockStartMarker0; | 459 test_shadow.shadow_[offset + 0] = kHeapBlockStartMarker0; |
| 500 // A nested block with freed contents. | 460 // The end of the block. |
| 501 test_shadow.shadow_[offset + 50] = kHeapNestedBlockStartMarker0; | |
| 502 ::memset(test_shadow.shadow_ + offset + 51, kHeapFreedMarker, 8); | |
| 503 test_shadow.shadow_[offset + 60] = kHeapNestedBlockEndMarker; | |
| 504 // A nested block with a nested block. | |
| 505 test_shadow.shadow_[offset + 100000] = kHeapNestedBlockStartMarker0; | |
| 506 test_shadow.shadow_[offset + 100100] = kHeapNestedBlockStartMarker0; | |
| 507 test_shadow.shadow_[offset + 100400] = kHeapNestedBlockEndMarker; | |
| 508 test_shadow.shadow_[offset + 200000] = kHeapNestedBlockEndMarker; | |
| 509 // The end of the outer block. | |
| 510 test_shadow.shadow_[offset + length - 1] = kHeapBlockEndMarker; | 461 test_shadow.shadow_[offset + length - 1] = kHeapBlockEndMarker; |
| 511 | 462 |
| 512 uint64_t tnet = 0; | 463 uint64_t tnet = 0; |
| 513 for (size_t i = 0; i < 100; ++i) { | 464 for (size_t i = 0; i < 100; ++i) { |
| 514 size_t l = 0; | 465 size_t l = 0; |
| 515 uint64_t t0 = ::__rdtsc(); | 466 uint64_t t0 = ::__rdtsc(); |
| 516 test_shadow.ScanRightForBracketingBlockEnd(0, offset + 1, &l); | 467 test_shadow.ScanRightForBracketingBlockEnd(offset + 1, &l); |
| 517 uint64_t t1 = ::__rdtsc(); | 468 uint64_t t1 = ::__rdtsc(); |
| 518 tnet += t1 - t0; | 469 tnet += t1 - t0; |
| 519 } | 470 } |
| 520 testing::EmitMetric("Syzygy.Asan.Shadow.ScanRightForBracketingBlockEnd", | 471 testing::EmitMetric("Syzygy.Asan.Shadow.ScanRightForBracketingBlockEnd", |
| 521 tnet); | 472 tnet); |
| 522 | 473 |
| 523 // Reset the shadow memory. | 474 // Reset the shadow memory. |
| 524 ::memset(test_shadow.shadow_ + offset, 0, length); | 475 ::memset(test_shadow.shadow_ + offset, 0, length); |
| 525 } | 476 } |
| 526 | 477 |
| 527 TEST_F(ShadowTest, IsLeftOrRightRedzone) { | 478 TEST_F(ShadowTest, IsLeftOrRightRedzone) { |
| 528 BlockLayout layout = {}; | 479 BlockLayout layout = {}; |
| 529 const size_t kAllocSize = 15; | 480 const size_t kAllocSize = 15; |
| 530 ASSERT_NE(0U, kAllocSize % kShadowRatio); | 481 ASSERT_NE(0U, kAllocSize % kShadowRatio); |
| 531 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, kAllocSize, 0, 0, | 482 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, kAllocSize, 0, 0, |
| 532 &layout)); | 483 &layout)); |
| 533 | 484 |
| 534 std::unique_ptr<uint8_t[]> data(new uint8_t[layout.block_size]); | 485 std::unique_ptr<uint8_t[]> data(new uint8_t[layout.block_size]); |
| 535 BlockInfo info = {}; | 486 BlockInfo info = {}; |
| 536 BlockInitialize(layout, data.get(), false, &info); | 487 BlockInitialize(layout, data.get(), &info); |
| 537 | 488 |
| 538 test_shadow.PoisonAllocatedBlock(info); | 489 test_shadow.PoisonAllocatedBlock(info); |
| 539 uint8_t* block = reinterpret_cast<uint8_t*>(info.header); | 490 uint8_t* block = reinterpret_cast<uint8_t*>(info.header); |
| 540 uint8_t* cursor = block; | 491 uint8_t* cursor = block; |
| 541 | 492 |
| 542 for (; cursor < info.RawBody(); ++cursor) { | 493 for (; cursor < info.RawBody(); ++cursor) { |
| 543 EXPECT_TRUE(test_shadow.IsLeftRedzone(cursor)); | 494 EXPECT_TRUE(test_shadow.IsLeftRedzone(cursor)); |
| 544 EXPECT_FALSE(test_shadow.IsRightRedzone(cursor)); | 495 EXPECT_FALSE(test_shadow.IsRightRedzone(cursor)); |
| 545 } | 496 } |
| 546 for (; cursor < info.RawBody() + info.body_size; ++cursor) { | 497 for (; cursor < info.RawBody() + info.body_size; ++cursor) { |
| 547 EXPECT_FALSE(test_shadow.IsLeftRedzone(cursor)); | 498 EXPECT_FALSE(test_shadow.IsLeftRedzone(cursor)); |
| 548 EXPECT_FALSE(test_shadow.IsRightRedzone(cursor)); | 499 EXPECT_FALSE(test_shadow.IsRightRedzone(cursor)); |
| 549 } | 500 } |
| 550 for (; cursor < block + info.block_size; ++cursor) { | 501 for (; cursor < block + info.block_size; ++cursor) { |
| 551 EXPECT_FALSE(test_shadow.IsLeftRedzone(cursor)); | 502 EXPECT_FALSE(test_shadow.IsLeftRedzone(cursor)); |
| 552 EXPECT_TRUE(test_shadow.IsRightRedzone(cursor)); | 503 EXPECT_TRUE(test_shadow.IsRightRedzone(cursor)); |
| 553 } | 504 } |
| 554 | 505 |
| 555 test_shadow.Unpoison(block, info.block_size); | 506 test_shadow.Unpoison(block, info.block_size); |
| 556 } | 507 } |
| 557 | 508 |
| 558 namespace { | 509 namespace { |
| 559 | 510 |
| 560 void TestBlockInfoFromShadow(Shadow* shadow, | 511 void TestBlockInfoFromShadow(Shadow* shadow, const BlockLayout& block_layout) { |
| 561 const BlockLayout& outer, | |
| 562 const BlockLayout& nested) { | |
| 563 ASSERT_TRUE(shadow != nullptr); | 512 ASSERT_TRUE(shadow != nullptr); |
| 564 ASSERT_LE(nested.block_size, outer.body_size); | |
| 565 | 513 |
| 566 uint8_t* data = new uint8_t[outer.block_size]; | 514 uint8_t* data = new uint8_t[block_layout.block_size]; |
| 567 | 515 |
| 568 // Try recovering the block from every position within it when no nested | |
| 569 // block exists. Expect finding a nested block to fail. | |
| 570 BlockInfo info = {}; | 516 BlockInfo info = {}; |
| 571 BlockInitialize(outer, data, false, &info); | 517 BlockInitialize(block_layout, data, &info); |
| 572 shadow->PoisonAllocatedBlock(info); | 518 shadow->PoisonAllocatedBlock(info); |
| 573 BlockInfo info_recovered = {}; | 519 BlockInfo info_recovered = {}; |
| 574 for (size_t i = 0; i < info.block_size; ++i) { | 520 for (size_t i = 0; i < info.block_size; ++i) { |
| 575 EXPECT_TRUE(shadow->BlockInfoFromShadow( | 521 EXPECT_TRUE(shadow->BlockInfoFromShadow( |
| 576 info.RawBlock() + i, &info_recovered)); | 522 info.RawBlock() + i, &info_recovered)); |
| 577 EXPECT_EQ(0, ::memcmp(&info, &info_recovered, sizeof(info))); | 523 EXPECT_EQ(0, ::memcmp(&info, &info_recovered, sizeof(info))); |
| 578 | |
| 579 // This block should have no parent block as its not nested. | |
| 580 EXPECT_FALSE(shadow->ParentBlockInfoFromShadow( | |
| 581 info, &info_recovered)); | |
| 582 } | 524 } |
| 583 | 525 |
| 584 // Place a nested block and try the recovery from every position again. | |
| 585 size_t padding = ::common::AlignDown(info.body_size - nested.block_size, | |
| 586 kShadowRatio * 2); | |
| 587 uint8_t* nested_begin = info.RawBody() + padding / 2; | |
| 588 uint8_t* nested_end = nested_begin + nested.block_size; | |
| 589 BlockInfo nested_info = {}; | |
| 590 BlockInitialize(nested, nested_begin, true, &nested_info); | |
| 591 nested_info.header->is_nested = true; | |
| 592 shadow->PoisonAllocatedBlock(nested_info); | |
| 593 for (size_t i = 0; i < info.block_size; ++i) { | |
| 594 uint8_t* pos = info.RawBlock() + i; | |
| 595 EXPECT_TRUE(shadow->BlockInfoFromShadow(pos, &info_recovered)); | |
| 596 | |
| 597 BlockInfo parent_info = {}; | |
| 598 bool found_parent = shadow->ParentBlockInfoFromShadow( | |
| 599 info_recovered, &parent_info); | |
| 600 | |
| 601 if (pos >= nested_begin && pos < nested_end) { | |
| 602 EXPECT_EQ(0, ::memcmp(&nested_info, &info_recovered, | |
| 603 sizeof(nested_info))); | |
| 604 EXPECT_TRUE(found_parent); | |
| 605 EXPECT_EQ(0, ::memcmp(&info, &parent_info, sizeof(info))); | |
| 606 } else { | |
| 607 EXPECT_EQ(0, ::memcmp(&info, &info_recovered, sizeof(info))); | |
| 608 EXPECT_FALSE(found_parent); | |
| 609 } | |
| 610 } | |
| 611 shadow->Unpoison(info.header, info.block_size); | |
| 612 | |
| 613 delete [] data; | 526 delete [] data; |
| 614 } | 527 } |
| 615 | 528 |
| 616 } // namespace | 529 } // namespace |
| 617 | 530 |
| 618 TEST_F(ShadowTest, BlockInfoFromShadow) { | 531 TEST_F(ShadowTest, BlockInfoFromShadow) { |
| 619 // This is a simple layout that will be nested inside of another block. | |
| 620 BlockLayout layout0 = {}; | 532 BlockLayout layout0 = {}; |
| 621 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 6, 0, 0, &layout0)); | 533 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 6, 0, 0, &layout0)); |
| 622 | 534 |
| 623 // Plan two layouts, one with padding and another with none. The first has | 535 uint8_t* data = new uint8_t[layout0.block_size]; |
| 624 // exactly enough space for the nested block, while the second has room to | |
| 625 // spare. | |
| 626 BlockLayout layout1 = {}; | |
| 627 BlockLayout layout2 = {}; | |
| 628 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, | |
| 629 static_cast<uint32_t>( | |
| 630 ::common::AlignUp(layout0.block_size, kShadowRatio) + 4), 0, 0, | |
| 631 &layout1)); | |
| 632 ASSERT_EQ(0u, layout1.header_padding_size); | |
| 633 ASSERT_EQ(0u, layout1.trailer_padding_size); | |
| 634 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, | |
| 635 layout0.block_size + 2 * kShadowRatio, 32, 13, &layout2)); | |
| 636 ASSERT_LT(0u, layout2.header_padding_size); | |
| 637 ASSERT_LT(0u, layout2.trailer_padding_size); | |
| 638 | 536 |
| 639 EXPECT_NO_FATAL_FAILURE(TestBlockInfoFromShadow( | 537 BlockInfo info = {}; |
| 640 &test_shadow, layout1, layout0)); | 538 BlockInitialize(layout0, data, &info); |
| 641 EXPECT_NO_FATAL_FAILURE(TestBlockInfoFromShadow( | 539 test_shadow.PoisonAllocatedBlock(info); |
| 642 &test_shadow, layout2, layout0)); | 540 BlockInfo info_recovered = {}; |
| 541 for (size_t i = 0; i < info.block_size; ++i) { |
| 542 EXPECT_TRUE( |
| 543 test_shadow.BlockInfoFromShadow(info.RawBlock() + i, &info_recovered)); |
| 544 EXPECT_EQ(0, ::memcmp(&info, &info_recovered, sizeof(info))); |
| 545 } |
| 546 delete[] data; |
| 643 } | 547 } |
| 644 | 548 |
| 645 TEST_F(ShadowTest, IsBeginningOfBlockBody) { | 549 TEST_F(ShadowTest, IsBeginningOfBlockBody) { |
| 646 BlockLayout l = {}; | 550 BlockLayout l = {}; |
| 647 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 7, 0, 0, &l)); | 551 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 7, 0, 0, &l)); |
| 648 | 552 |
| 649 size_t data_size = l.block_size; | 553 size_t data_size = l.block_size; |
| 650 std::unique_ptr<uint8_t[]> data(new uint8_t[data_size]); | 554 std::unique_ptr<uint8_t[]> data(new uint8_t[data_size]); |
| 651 | 555 |
| 652 BlockInfo block_info = {}; | 556 BlockInfo block_info = {}; |
| 653 BlockInitialize(l, data.get(), false, &block_info); | 557 BlockInitialize(l, data.get(), &block_info); |
| 654 | 558 |
| 655 test_shadow.PoisonAllocatedBlock(block_info); | 559 test_shadow.PoisonAllocatedBlock(block_info); |
| 656 | 560 |
| 657 EXPECT_TRUE(test_shadow.IsBeginningOfBlockBody(block_info.body)); | 561 EXPECT_TRUE(test_shadow.IsBeginningOfBlockBody(block_info.body)); |
| 658 EXPECT_FALSE(test_shadow.IsBeginningOfBlockBody(data.get())); | 562 EXPECT_FALSE(test_shadow.IsBeginningOfBlockBody(data.get())); |
| 659 | 563 |
| 660 block_info.header->state = QUARANTINED_BLOCK; | 564 block_info.header->state = QUARANTINED_BLOCK; |
| 661 test_shadow.MarkAsFreed(block_info.body, block_info.body_size); | 565 test_shadow.MarkAsFreed(block_info.body, block_info.body_size); |
| 662 | 566 |
| 663 EXPECT_TRUE(test_shadow.IsBeginningOfBlockBody(block_info.body)); | 567 EXPECT_TRUE(test_shadow.IsBeginningOfBlockBody(block_info.body)); |
| 664 EXPECT_FALSE(test_shadow.IsBeginningOfBlockBody(data.get())); | 568 EXPECT_FALSE(test_shadow.IsBeginningOfBlockBody(data.get())); |
| 665 | 569 |
| 666 test_shadow.Unpoison(data.get(), data_size); | 570 test_shadow.Unpoison(data.get(), data_size); |
| 667 } | 571 } |
| 668 | 572 |
| 669 TEST_F(ShadowTest, IsBeginningOfBlockBodyForBlockOfSizeZero) { | 573 TEST_F(ShadowTest, IsBeginningOfBlockBodyForBlockOfSizeZero) { |
| 670 BlockLayout l = {}; | 574 BlockLayout l = {}; |
| 671 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 0, 0, 0, &l)); | 575 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 0, 0, 0, &l)); |
| 672 | 576 |
| 673 size_t data_size = l.block_size; | 577 size_t data_size = l.block_size; |
| 674 std::unique_ptr<uint8_t[]> data(new uint8_t[data_size]); | 578 std::unique_ptr<uint8_t[]> data(new uint8_t[data_size]); |
| 675 | 579 |
| 676 BlockInfo block_info = {}; | 580 BlockInfo block_info = {}; |
| 677 BlockInitialize(l, data.get(), false, &block_info); | 581 BlockInitialize(l, data.get(), &block_info); |
| 678 | 582 |
| 679 test_shadow.PoisonAllocatedBlock(block_info); | 583 test_shadow.PoisonAllocatedBlock(block_info); |
| 680 | 584 |
| 681 EXPECT_TRUE(test_shadow.IsBeginningOfBlockBody(block_info.body)); | 585 EXPECT_TRUE(test_shadow.IsBeginningOfBlockBody(block_info.body)); |
| 682 EXPECT_FALSE(test_shadow.IsBeginningOfBlockBody(data.get())); | 586 EXPECT_FALSE(test_shadow.IsBeginningOfBlockBody(data.get())); |
| 683 | 587 |
| 684 block_info.header->state = QUARANTINED_FLOODED_BLOCK; | 588 block_info.header->state = QUARANTINED_FLOODED_BLOCK; |
| 685 test_shadow.MarkAsFreed(block_info.body, block_info.body_size); | 589 test_shadow.MarkAsFreed(block_info.body, block_info.body_size); |
| 686 | 590 |
| 687 EXPECT_TRUE(test_shadow.IsBeginningOfBlockBody(block_info.body)); | 591 EXPECT_TRUE(test_shadow.IsBeginningOfBlockBody(block_info.body)); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 | 655 |
| 752 // A fixture for shadow walker tests. | 656 // A fixture for shadow walker tests. |
| 753 class ShadowWalkerTest : public testing::Test { | 657 class ShadowWalkerTest : public testing::Test { |
| 754 public: | 658 public: |
| 755 TestShadow test_shadow; | 659 TestShadow test_shadow; |
| 756 }; | 660 }; |
| 757 | 661 |
| 758 } // namespace | 662 } // namespace |
| 759 | 663 |
| 760 TEST_F(ShadowWalkerTest, WalkEmptyRange) { | 664 TEST_F(ShadowWalkerTest, WalkEmptyRange) { |
| 761 ShadowWalker w(&test_shadow, true, &test_shadow, &test_shadow); | 665 ShadowWalker w(&test_shadow, &test_shadow, &test_shadow); |
| 762 BlockInfo i = {}; | 666 BlockInfo i = {}; |
| 763 EXPECT_FALSE(w.Next(&i)); | 667 EXPECT_FALSE(w.Next(&i)); |
| 764 } | 668 } |
| 765 | 669 |
| 766 TEST_F(ShadowWalkerTest, WalkRangeAtEndOfAddressSpace) { | 670 TEST_F(ShadowWalkerTest, WalkRangeAtEndOfAddressSpace) { |
| 767 TestShadow ts1(4, 30); // 4GB. | 671 TestShadow ts1(4, 30); // 4GB. |
| 768 ShadowWalker w( | 672 ShadowWalker w(&ts1, reinterpret_cast<const void*>(ts1.memory_size() - 100), |
| 769 &ts1, true, | 673 reinterpret_cast<const void*>(ts1.memory_size())); |
| 770 reinterpret_cast<const void*>(ts1.memory_size() - 100), | |
| 771 reinterpret_cast<const void*>(ts1.memory_size())); | |
| 772 BlockInfo i = {}; | 674 BlockInfo i = {}; |
| 773 EXPECT_FALSE(w.Next(&i)); | 675 EXPECT_FALSE(w.Next(&i)); |
| 774 } | 676 } |
| 775 | 677 |
| 776 TEST_F(ShadowWalkerTest, WalksNonNestedBlocks) { | 678 TEST_F(ShadowWalkerTest, WalksBlocks) { |
| 777 BlockLayout l = {}; | 679 BlockLayout l = {}; |
| 778 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 7, 0, 0, &l)); | 680 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 7, 0, 0, &l)); |
| 779 | 681 |
| 780 size_t data_size = l.block_size * 3 + kShadowRatio; | 682 size_t data_size = l.block_size * 3 + kShadowRatio; |
| 781 uint8_t* data = new uint8_t[data_size]; | 683 uint8_t* data = new uint8_t[data_size]; |
| 782 uint8_t* data0 = data; | 684 uint8_t* data0 = data; |
| 783 uint8_t* data1 = data0 + l.block_size + kShadowRatio; | 685 uint8_t* data1 = data0 + l.block_size + kShadowRatio; |
| 784 uint8_t* data2 = data1 + l.block_size; | 686 uint8_t* data2 = data1 + l.block_size; |
| 785 | 687 |
| 786 BlockInfo i0 = {}, i1 = {}, i2 = {}; | 688 BlockInfo i0 = {}, i1 = {}, i2 = {}; |
| 787 BlockInitialize(l, data0, false, &i0); | 689 BlockInitialize(l, data0, &i0); |
| 788 BlockInitialize(l, data1, false, &i1); | 690 BlockInitialize(l, data1, &i1); |
| 789 BlockInitialize(l, data2, false, &i2); | 691 BlockInitialize(l, data2, &i2); |
| 790 | 692 |
| 791 test_shadow.PoisonAllocatedBlock(i0); | 693 test_shadow.PoisonAllocatedBlock(i0); |
| 792 test_shadow.PoisonAllocatedBlock(i1); | 694 test_shadow.PoisonAllocatedBlock(i1); |
| 793 test_shadow.PoisonAllocatedBlock(i2); | 695 test_shadow.PoisonAllocatedBlock(i2); |
| 794 | 696 |
| 795 i2.header->state = QUARANTINED_BLOCK; | 697 i2.header->state = QUARANTINED_BLOCK; |
| 796 test_shadow.MarkAsFreed(i2.body, i2.body_size); | 698 test_shadow.MarkAsFreed(i2.body, i2.body_size); |
| 797 | 699 |
| 798 // Do a non-recursive walk through the shadow. | 700 // Do a non-recursive walk through the shadow. |
| 799 BlockInfo i = {}; | 701 BlockInfo i = {}; |
| 800 ShadowWalker w0(&test_shadow, false, data, data + data_size); | 702 ShadowWalker w0(&test_shadow, data, data + data_size); |
| 801 EXPECT_EQ(-1, w0.nesting_depth()); | |
| 802 EXPECT_TRUE(w0.Next(&i)); | 703 EXPECT_TRUE(w0.Next(&i)); |
| 803 EXPECT_EQ(0, w0.nesting_depth()); | |
| 804 EXPECT_TRUE(w0.Next(&i)); | 704 EXPECT_TRUE(w0.Next(&i)); |
| 805 EXPECT_EQ(0, w0.nesting_depth()); | |
| 806 EXPECT_TRUE(w0.Next(&i)); | 705 EXPECT_TRUE(w0.Next(&i)); |
| 807 EXPECT_EQ(0, w0.nesting_depth()); | |
| 808 EXPECT_FALSE(w0.Next(&i)); | 706 EXPECT_FALSE(w0.Next(&i)); |
| 809 EXPECT_EQ(-1, w0.nesting_depth()); | |
| 810 | |
| 811 // Walk recursively through the shadow and expect the same results. | |
| 812 ShadowWalker w1(&test_shadow, true, data, data + data_size); | |
| 813 EXPECT_EQ(-1, w1.nesting_depth()); | |
| 814 EXPECT_TRUE(w1.Next(&i)); | |
| 815 EXPECT_EQ(0, w1.nesting_depth()); | |
| 816 EXPECT_EQ(0, ::memcmp(&i, &i0, sizeof(i))); | |
| 817 EXPECT_TRUE(w1.Next(&i)); | |
| 818 EXPECT_EQ(0, w1.nesting_depth()); | |
| 819 EXPECT_EQ(0, ::memcmp(&i, &i1, sizeof(i))); | |
| 820 EXPECT_TRUE(w1.Next(&i)); | |
| 821 EXPECT_EQ(0, w1.nesting_depth()); | |
| 822 EXPECT_EQ(0, ::memcmp(&i, &i2, sizeof(i))); | |
| 823 EXPECT_FALSE(w1.Next(&i)); | |
| 824 EXPECT_EQ(-1, w1.nesting_depth()); | |
| 825 | 707 |
| 826 test_shadow.Unpoison(data, data_size); | 708 test_shadow.Unpoison(data, data_size); |
| 827 delete [] data; | 709 delete [] data; |
| 828 } | |
| 829 | |
| 830 TEST_F(ShadowWalkerTest, WalksNestedBlocks) { | |
| 831 BlockLayout b0 = {}, b1 = {}, b2 = {}, b00 = {}, b01 = {}, b10 = {}, | |
| 832 b100 = {}; | |
| 833 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 15, 30, 30, &b00)); | |
| 834 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 7, 0, 0, &b01)); | |
| 835 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, | |
| 836 b00.block_size + b01.block_size + kShadowRatio, 0, 0, &b0)); | |
| 837 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 7, 0, 0, &b100)); | |
| 838 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, b100.block_size, 0, 0, | |
| 839 &b10)); | |
| 840 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, b10.block_size, 0, 0, | |
| 841 &b1)); | |
| 842 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 100, 0, 0, &b2)); | |
| 843 | |
| 844 size_t data_size = b0.block_size + b1.block_size + kShadowRatio + | |
| 845 b2.block_size; | |
| 846 uint8_t* data = new uint8_t[data_size]; | |
| 847 | |
| 848 // Initialize the depth 0 blocks. | |
| 849 uint8_t* d0 = data; | |
| 850 uint8_t* d1 = d0 + b0.block_size; | |
| 851 uint8_t* d2 = d1 + b1.block_size + kShadowRatio; | |
| 852 BlockInfo i0 = {}, i1 = {}, i2 = {}; | |
| 853 BlockInitialize(b0, d0, false, &i0); | |
| 854 BlockInitialize(b1, d1, false, &i1); | |
| 855 BlockInitialize(b2, d2, false, &i2); | |
| 856 test_shadow.PoisonAllocatedBlock(i0); | |
| 857 test_shadow.PoisonAllocatedBlock(i1); | |
| 858 test_shadow.PoisonAllocatedBlock(i2); | |
| 859 | |
| 860 // Initialize depth 1 blocks. | |
| 861 uint8_t* d00 = i0.RawBody(); | |
| 862 uint8_t* d01 = d00 + b00.block_size + kShadowRatio; | |
| 863 uint8_t* d10 = i1.RawBody(); | |
| 864 BlockInfo i00 = {}, i01 = {}, i10 = {}; | |
| 865 BlockInitialize(b00, d00, true, &i00); | |
| 866 BlockInitialize(b01, d01, true, &i01); | |
| 867 BlockInitialize(b10, d10, true, &i10); | |
| 868 test_shadow.PoisonAllocatedBlock(i00); | |
| 869 test_shadow.PoisonAllocatedBlock(i01); | |
| 870 test_shadow.PoisonAllocatedBlock(i10); | |
| 871 | |
| 872 // Initialize depth 2 blocks. | |
| 873 uint8_t* d100 = i10.RawBody(); | |
| 874 BlockInfo i100 = {}; | |
| 875 BlockInitialize(b100, d100, true, &i100); | |
| 876 test_shadow.PoisonAllocatedBlock(i100); | |
| 877 i100.header->state = QUARANTINED_FLOODED_BLOCK; | |
| 878 test_shadow.MarkAsFreed(i100.body, i100.body_size); | |
| 879 | |
| 880 // Do a non-recursive walk through the shadow. | |
| 881 BlockInfo i = {}; | |
| 882 ShadowWalker w0(&test_shadow, false, data, data + data_size); | |
| 883 EXPECT_EQ(-1, w0.nesting_depth()); | |
| 884 EXPECT_TRUE(w0.Next(&i)); | |
| 885 EXPECT_EQ(0, w0.nesting_depth()); | |
| 886 EXPECT_EQ(0, ::memcmp(&i, &i0, sizeof(i))); | |
| 887 EXPECT_TRUE(w0.Next(&i)); | |
| 888 EXPECT_EQ(0, w0.nesting_depth()); | |
| 889 EXPECT_EQ(0, ::memcmp(&i, &i1, sizeof(i))); | |
| 890 EXPECT_TRUE(w0.Next(&i)); | |
| 891 EXPECT_EQ(0, w0.nesting_depth()); | |
| 892 EXPECT_EQ(0, ::memcmp(&i, &i2, sizeof(i))); | |
| 893 EXPECT_FALSE(w0.Next(&i)); | |
| 894 EXPECT_EQ(-1, w0.nesting_depth()); | |
| 895 | |
| 896 // Walk recursively through the shadow. | |
| 897 ShadowWalker w1(&test_shadow, true, data, data + data_size); | |
| 898 EXPECT_EQ(-1, w1.nesting_depth()); | |
| 899 EXPECT_TRUE(w1.Next(&i)); | |
| 900 EXPECT_EQ(0, w1.nesting_depth()); | |
| 901 EXPECT_EQ(0, ::memcmp(&i, &i0, sizeof(i))); | |
| 902 EXPECT_TRUE(w1.Next(&i)); | |
| 903 EXPECT_EQ(1, w1.nesting_depth()); | |
| 904 EXPECT_EQ(0, ::memcmp(&i, &i00, sizeof(i))); | |
| 905 EXPECT_TRUE(w1.Next(&i)); | |
| 906 EXPECT_EQ(1, w1.nesting_depth()); | |
| 907 EXPECT_EQ(0, ::memcmp(&i, &i01, sizeof(i))); | |
| 908 EXPECT_TRUE(w1.Next(&i)); | |
| 909 EXPECT_EQ(0, w1.nesting_depth()); | |
| 910 EXPECT_EQ(0, ::memcmp(&i, &i1, sizeof(i))); | |
| 911 EXPECT_TRUE(w1.Next(&i)); | |
| 912 EXPECT_EQ(1, w1.nesting_depth()); | |
| 913 EXPECT_EQ(0, ::memcmp(&i, &i10, sizeof(i))); | |
| 914 EXPECT_TRUE(w1.Next(&i)); | |
| 915 EXPECT_EQ(2, w1.nesting_depth()); | |
| 916 EXPECT_EQ(0, ::memcmp(&i, &i100, sizeof(i))); | |
| 917 EXPECT_TRUE(w1.Next(&i)); | |
| 918 EXPECT_EQ(0, w1.nesting_depth()); | |
| 919 EXPECT_EQ(0, ::memcmp(&i, &i2, sizeof(i))); | |
| 920 EXPECT_FALSE(w1.Next(&i)); | |
| 921 EXPECT_EQ(-1, w1.nesting_depth()); | |
| 922 | |
| 923 test_shadow.Unpoison(data, data_size); | |
| 924 delete [] data; | |
| 925 } | 710 } |
| 926 | 711 |
| 927 TEST_F(ShadowWalkerTest, WalkShadowWithUncommittedRanges) { | 712 TEST_F(ShadowWalkerTest, WalkShadowWithUncommittedRanges) { |
| 928 // Create a 512k memory block. | 713 // Create a 512k memory block. |
| 929 const size_t kMemorySize = 512 * 1024; | 714 const size_t kMemorySize = 512 * 1024; |
| 930 uint8_t memory_block[kMemorySize]; | 715 uint8_t memory_block[kMemorySize]; |
| 931 const size_t shadow_size = Shadow::RequiredLength(); | 716 const size_t shadow_size = Shadow::RequiredLength(); |
| 932 | 717 |
| 933 // Allocate the shadow memory, only reserve the memory. | 718 // Allocate the shadow memory, only reserve the memory. |
| 934 uint8_t* shadow_memory = static_cast<uint8_t*>( | 719 uint8_t* shadow_memory = static_cast<uint8_t*>( |
| (...skipping 25 matching lines...) Expand all Loading... |
| 960 ::common::AlignDown(shadow_address, GetPageSize()); | 745 ::common::AlignDown(shadow_address, GetPageSize()); |
| 961 // Commit the shadow memory for this block. | 746 // Commit the shadow memory for this block. |
| 962 EXPECT_EQ(static_cast<void*>(shadow_address_page_begin), | 747 EXPECT_EQ(static_cast<void*>(shadow_address_page_begin), |
| 963 ::VirtualAlloc(shadow_address, GetPageSize(), MEM_COMMIT, | 748 ::VirtualAlloc(shadow_address, GetPageSize(), MEM_COMMIT, |
| 964 PAGE_READWRITE)); | 749 PAGE_READWRITE)); |
| 965 | 750 |
| 966 // Address of the memory for this block. | 751 // Address of the memory for this block. |
| 967 uint8_t* page_address = ::common::AlignUp( | 752 uint8_t* page_address = ::common::AlignUp( |
| 968 memory_block + i * GetPageSize() * kShadowRatio, kShadowRatio); | 753 memory_block + i * GetPageSize() * kShadowRatio, kShadowRatio); |
| 969 BlockInfo block_info = {}; | 754 BlockInfo block_info = {}; |
| 970 BlockInitialize(l, page_address, false, &block_info); | 755 BlockInitialize(l, page_address, &block_info); |
| 971 block_info_vec.push_back(block_info); | 756 block_info_vec.push_back(block_info); |
| 972 | 757 |
| 973 // Poison the block. | 758 // Poison the block. |
| 974 ts1.PoisonAllocatedBlock(block_info); | 759 ts1.PoisonAllocatedBlock(block_info); |
| 975 } | 760 } |
| 976 | 761 |
| 977 size_t block_count = 0; | 762 size_t block_count = 0; |
| 978 ShadowWalker w(&ts1, true, memory_block, memory_block + kMemorySize); | 763 ShadowWalker w(&ts1, memory_block, memory_block + kMemorySize); |
| 979 BlockInfo i = {}; | 764 BlockInfo i = {}; |
| 980 while (w.Next(&i)) { | 765 while (w.Next(&i)) { |
| 981 EXPECT_LT(block_count, block_info_vec.size()); | 766 EXPECT_LT(block_count, block_info_vec.size()); |
| 982 EXPECT_EQ(block_info_vec[block_count].header, i.header); | 767 EXPECT_EQ(block_info_vec[block_count].header, i.header); |
| 983 EXPECT_EQ(block_info_vec[block_count].body, i.body); | 768 EXPECT_EQ(block_info_vec[block_count].body, i.body); |
| 984 EXPECT_EQ(block_info_vec[block_count].trailer, i.trailer); | 769 EXPECT_EQ(block_info_vec[block_count].trailer, i.trailer); |
| 985 block_count++; | 770 block_count++; |
| 986 } | 771 } |
| 987 EXPECT_EQ(block_info_vec.size(), block_count); | 772 EXPECT_EQ(block_info_vec.size(), block_count); |
| 988 EXPECT_FALSE(w.Next(&i)); | 773 EXPECT_FALSE(w.Next(&i)); |
| 989 | 774 |
| 990 EXPECT_GT(::VirtualFree(shadow_memory, 0, MEM_RELEASE), 0U); | 775 EXPECT_GT(::VirtualFree(shadow_memory, 0, MEM_RELEASE), 0U); |
| 991 } | 776 } |
| 992 | 777 |
| 993 } // namespace asan | 778 } // namespace asan |
| 994 } // namespace agent | 779 } // namespace agent |
| OLD | NEW |