Coverage for /Syzygy/block_graph/block_graph_unittest.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%7557550.C++test

Line-by-line coverage:

   1    :  // Copyright 2012 Google Inc. All Rights Reserved.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (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
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  
  15    :  #include "syzygy/block_graph/block_graph.h"
  16    :  
  17    :  #include "gmock/gmock.h"
  18    :  #include "gtest/gtest.h"
  19    :  #include "syzygy/block_graph/typed_block.h"
  20    :  #include "syzygy/block_graph/unittest_util.h"
  21    :  #include "syzygy/core/unittest_util.h"
  22    :  
  23    :  namespace block_graph {
  24    :  
  25    :  using core::ByteVector;
  26    :  using core::CreateByteInStream;
  27    :  using core::CreateByteOutStream;
  28    :  using core::NativeBinaryInArchive;
  29    :  using core::NativeBinaryOutArchive;
  30    :  using core::RelativeAddress;
  31    :  using core::ScopedInStreamPtr;
  32    :  using core::ScopedOutStreamPtr;
  33    :  
  34    :  const size_t kPtrSize = sizeof(core::RelativeAddress);
  35    :  
  36  E :  TEST(SectionTest, CreationAndProperties) {
  37  E :    BlockGraph::Section section(0, "foo", 1);
  38  E :    ASSERT_EQ(0, section.id());
  39  E :    ASSERT_EQ("foo", section.name());
  40  E :    ASSERT_EQ(1u, section.characteristics());
  41    :  
  42  E :    section.set_name("bar");
  43  E :    ASSERT_EQ("bar", section.name());
  44    :  
  45  E :    section.set_characteristic((1 << 5) | (1 << 6));
  46  E :    ASSERT_EQ((1u | (1 << 5) | (1 << 6)), section.characteristics());
  47    :  
  48  E :    section.clear_characteristic(1 | (1<<5));
  49  E :    ASSERT_EQ(1u << 6, section.characteristics());
  50    :  
  51  E :    section.set_characteristics(0);
  52  E :    ASSERT_EQ(0u, section.characteristics());
  53  E :  }
  54    :  
  55  E :  TEST(SectionTest, Comparison) {
  56  E :    BlockGraph::Section section0(0, "foo", 0);
  57  E :    BlockGraph::Section section1(0, "foo", 0);
  58  E :    BlockGraph::Section section2(1, "bar", 1);
  59    :  
  60  E :    EXPECT_EQ(section0, section1);
  61  E :    EXPECT_NE(section0, section2);
  62  E :  }
  63    :  
  64  E :  TEST(SectionTest, Serialization) {
  65  E :    BlockGraph::Section section0(0, "foo", 0);
  66  E :    EXPECT_TRUE(testing::TestSerialization(section0));
  67  E :  }
  68    :  
  69    :  class BlockTest: public testing::Test {
  70    :   public:
  71  E :    virtual void SetUp() {
  72  E :      block_ = image_.AddBlock(kBlockType, kBlockSize, kBlockName);
  73  E :      ASSERT_TRUE(block_ != NULL);
  74  E :    }
  75    :  
  76    :   protected:
  77    :    static const BlockGraph::BlockType kBlockType = BlockGraph::CODE_BLOCK;
  78    :    static const size_t kBlockSize = 0x20;
  79    :    static const char* kBlockName;
  80    :    static const uint8 kTestData[];
  81    :  
  82    :    BlockGraph image_;
  83    :    BlockGraph::Block* block_;
  84    :  };
  85    :  
  86    :  const char* BlockTest::kBlockName = "block";
  87    :  const uint8 BlockTest::kTestData[] = "who's your daddy?";
  88    :  
  89  E :  TEST(ReferenceTest, Initialization) {
  90  E :    BlockGraph::Block block(0, BlockGraph::CODE_BLOCK, 10, "foo");
  91  E :    BlockGraph::Reference ref(BlockGraph::RELATIVE_REF, 4, &block, 0, 0);
  92  E :    ASSERT_EQ(BlockGraph::RELATIVE_REF, ref.type());
  93  E :    ASSERT_EQ(4u, ref.size());
  94  E :    ASSERT_EQ(&block, ref.referenced());
  95  E :    ASSERT_EQ(0, ref.offset());
  96  E :    ASSERT_EQ(0, ref.base());
  97  E :    ASSERT_TRUE(ref.IsValid());
  98  E :    ASSERT_TRUE(ref.IsDirect());
  99  E :  }
 100    :  
 101  E :  TEST(ReferenceTest, IndirectReference) {
 102  E :    BlockGraph::Block block(0, BlockGraph::CODE_BLOCK, 10, "foo");
 103  E :    BlockGraph::Reference ref(BlockGraph::RELATIVE_REF, 4, &block, -8, 4);
 104  E :    ASSERT_TRUE(ref.IsValid());
 105  E :    ASSERT_FALSE(ref.IsDirect());
 106  E :  }
 107    :  
 108  E :  TEST(LabelTest, Initialization) {
 109  E :    BlockGraph::Label label;
 110  E :    ASSERT_TRUE(label.name().empty());
 111  E :    ASSERT_EQ(0u, label.attributes());
 112  E :  }
 113    :  
 114  E :  TEST(LabelTest, InitializationFullConstructor) {
 115  E :    BlockGraph::Label label("foo", BlockGraph::CODE_LABEL);
 116  E :    ASSERT_EQ(std::string("foo"), label.name());
 117  E :    ASSERT_EQ(BlockGraph::CODE_LABEL, label.attributes());
 118  E :  }
 119    :  
 120  E :  TEST(LabelTest, Attributes) {
 121  E :    BlockGraph::Label label;
 122  E :    ASSERT_EQ(0u, label.attributes());
 123    :  
 124  E :    label.set_attribute(BlockGraph::CODE_LABEL);
 125  E :    ASSERT_EQ(BlockGraph::CODE_LABEL, label.attributes());
 126    :  
 127  E :    label.set_attribute(BlockGraph::JUMP_TABLE_LABEL);
 128    :    ASSERT_EQ(BlockGraph::CODE_LABEL | BlockGraph::JUMP_TABLE_LABEL,
 129  E :              label.attributes());
 130    :  
 131    :    ASSERT_TRUE(label.has_attributes(
 132  E :        BlockGraph::CODE_LABEL | BlockGraph::JUMP_TABLE_LABEL));
 133  E :    ASSERT_TRUE(label.has_attributes(BlockGraph::CODE_LABEL));
 134  E :    ASSERT_TRUE(label.has_attributes(BlockGraph::JUMP_TABLE_LABEL));
 135  E :    ASSERT_FALSE(label.has_attributes(BlockGraph::DATA_LABEL));
 136    :  
 137    :    ASSERT_TRUE(label.has_any_attributes(
 138  E :        BlockGraph::CODE_LABEL | BlockGraph::DATA_LABEL));
 139    :  
 140  E :    label.set_attributes(BlockGraph::CASE_TABLE_LABEL);
 141  E :    ASSERT_EQ(BlockGraph::CASE_TABLE_LABEL, label.attributes());
 142    :  
 143  E :    label.clear_attribute(BlockGraph::CASE_TABLE_LABEL);
 144  E :    ASSERT_EQ(0u, label.attributes());
 145  E :  }
 146    :  
 147  E :  TEST(LabelTest, IsValid) {
 148  E :    BlockGraph::Label label;
 149    :  
 150    :    // A label must have some attributes.
 151  E :    ASSERT_FALSE(label.IsValid());
 152    :  
 153    :    // A code label is fine on its own and also with debug and scope labels, but
 154    :    // not with anything else.
 155  E :    label.set_attribute(BlockGraph::CODE_LABEL);
 156  E :    ASSERT_TRUE(label.IsValid());
 157  E :    label.set_attribute(BlockGraph::DEBUG_START_LABEL);
 158  E :    ASSERT_TRUE(label.IsValid());
 159  E :    label.set_attribute(BlockGraph::DEBUG_END_LABEL);
 160  E :    ASSERT_TRUE(label.IsValid());
 161  E :    label.set_attribute(BlockGraph::SCOPE_START_LABEL);
 162  E :    ASSERT_TRUE(label.IsValid());
 163  E :    label.set_attribute(BlockGraph::SCOPE_END_LABEL);
 164  E :    ASSERT_TRUE(label.IsValid());
 165  E :    label.set_attribute(BlockGraph::JUMP_TABLE_LABEL);
 166  E :    ASSERT_FALSE(label.IsValid());
 167    :  
 168    :    // A jump table must be with a data label and nothing else.
 169  E :    label.set_attributes(BlockGraph::JUMP_TABLE_LABEL);
 170  E :    ASSERT_FALSE(label.IsValid());
 171  E :    label.set_attribute(BlockGraph::DATA_LABEL);
 172  E :    ASSERT_TRUE(label.IsValid());
 173  E :    label.set_attribute(BlockGraph::CODE_LABEL);
 174  E :    ASSERT_FALSE(label.IsValid());
 175    :  
 176    :    // A case table must be with a data label and nothing else.
 177  E :    label.set_attributes(BlockGraph::CASE_TABLE_LABEL);
 178  E :    ASSERT_FALSE(label.IsValid());
 179  E :    label.set_attribute(BlockGraph::DATA_LABEL);
 180  E :    ASSERT_TRUE(label.IsValid());
 181  E :    label.set_attribute(BlockGraph::CODE_LABEL);
 182  E :    ASSERT_FALSE(label.IsValid());
 183    :  
 184    :    // A data label with no case or jump table must be on its own.
 185  E :    label.set_attributes(BlockGraph::DATA_LABEL);
 186  E :    ASSERT_TRUE(label.IsValid());
 187  E :    label.set_attribute(BlockGraph::CODE_LABEL);
 188  E :    ASSERT_FALSE(label.IsValid());
 189  E :  }
 190    :  
 191  E :  TEST_F(BlockTest, Initialization) {
 192    :    // Test initialization.
 193  E :    ASSERT_EQ(kBlockType, block_->type());
 194  E :    ASSERT_EQ(kBlockSize, block_->size());
 195  E :    ASSERT_EQ(1, block_->alignment());
 196  E :    ASSERT_STREQ(kBlockName, block_->name().c_str());
 197  E :    ASSERT_EQ(kInvalidAddress, block_->addr());
 198  E :    ASSERT_EQ(BlockGraph::kInvalidSectionId, block_->section());
 199  E :    ASSERT_EQ(0, block_->attributes());
 200  E :    ASSERT_EQ(NULL, block_->data());
 201  E :    ASSERT_EQ(0, block_->data_size());
 202  E :    ASSERT_FALSE(block_->owns_data());
 203  E :  }
 204    :  
 205  E :  TEST_F(BlockTest, Accessors) {
 206  E :    ASSERT_NE(BlockGraph::DATA_BLOCK, block_->type());
 207  E :    block_->set_type(BlockGraph::DATA_BLOCK);
 208  E :    ASSERT_EQ(BlockGraph::DATA_BLOCK, block_->type());
 209    :  
 210  E :    ASSERT_NE(0x10U, block_->size());
 211  E :    block_->set_size(0x10);
 212  E :    ASSERT_EQ(0x10U, block_->size());
 213    :  
 214  E :    ASSERT_STRNE("foo", block_->name().c_str());
 215  E :    block_->set_name("foo");
 216  E :    ASSERT_STREQ("foo", block_->name().c_str());
 217    :  
 218  E :    ASSERT_NE(16U, block_->alignment());
 219  E :    block_->set_alignment(16);
 220  E :    ASSERT_EQ(16U, block_->alignment());
 221    :  
 222    :    // Test accessors.
 223  E :    block_->set_attribute(0x20);
 224  E :    ASSERT_EQ(0x20, block_->attributes());
 225  E :    block_->set_attribute(0x10);
 226  E :    ASSERT_EQ(0x30, block_->attributes());
 227  E :    block_->clear_attribute(0x20);
 228  E :    ASSERT_EQ(0x10, block_->attributes());
 229    :  
 230  E :    block_->set_size(sizeof(kTestData));
 231  E :    block_->SetData(kTestData, sizeof(kTestData));
 232  E :    ASSERT_EQ(kTestData, block_->data());
 233  E :    ASSERT_EQ(sizeof(kTestData), block_->data_size());
 234  E :    ASSERT_FALSE(block_->owns_data());
 235  E :  }
 236    :  
 237  E :  TEST_F(BlockTest, AllocateData) {
 238    :    // Test AllocateData.
 239  E :    const size_t kBlockSize = 0x20;
 240  E :    uint8* data = block_->AllocateData(block_->size());
 241  E :    ASSERT_TRUE(block_->owns_data());
 242  E :    ASSERT_EQ(block_->size(), block_->data_size());
 243  E :    ASSERT_EQ(data, block_->data());
 244    :  
 245    :    static const uint8 zeros[kBlockSize] = {};
 246  E :    ASSERT_EQ(0, memcmp(&zeros[0], data, block_->size()));
 247  E :  }
 248    :  
 249  E :  TEST_F(BlockTest, CopyData) {
 250    :    // Test CopyData.
 251  E :    uint8* data = block_->CopyData(sizeof(kTestData), kTestData);
 252  E :    ASSERT_TRUE(block_->owns_data());
 253  E :    ASSERT_EQ(sizeof(kTestData), block_->data_size());
 254  E :    ASSERT_EQ(data, block_->data());
 255  E :    ASSERT_EQ(0, memcmp(kTestData, data, block_->data_size()));
 256  E :  }
 257    :  
 258  E :  TEST_F(BlockTest, ResizeData) {
 259    :    // Set the block's data.
 260  E :    block_->SetData(kTestData, sizeof(kTestData));
 261    :  
 262    :    // Shrinking the data should not take ownership.
 263  E :    const uint8* data = block_->ResizeData(sizeof(kTestData) / 2);
 264  E :    ASSERT_TRUE(data != NULL);
 265  E :    ASSERT_TRUE(data == kTestData);
 266  E :    ASSERT_FALSE(block_->owns_data());
 267    :  
 268    :    // Growing the data must always take ownership.
 269  E :    data = block_->ResizeData(sizeof(kTestData));
 270  E :    ASSERT_TRUE(data != NULL);
 271  E :    ASSERT_TRUE(data != kTestData);
 272  E :    ASSERT_TRUE(block_->owns_data());
 273    :    // The head of the data should be identical to the input.
 274  E :    ASSERT_EQ(0, memcmp(data, kTestData, sizeof(kTestData) / 2));
 275    :    // And the tail should be zeros.
 276    :    static const uint8 kZeros[sizeof(kTestData) - sizeof(kTestData) / 2] = {};
 277  E :    ASSERT_EQ(0, memcmp(data + sizeof(kTestData) / 2, kZeros, sizeof(kZeros)));
 278    :  
 279    :    // Now grow it from non-owned.
 280  E :    block_->SetData(kTestData, sizeof(kTestData));
 281  E :    data = block_->ResizeData(sizeof(kTestData) + sizeof(kZeros));
 282  E :    ASSERT_TRUE(data != NULL);
 283  E :    ASSERT_TRUE(data != kTestData);
 284  E :    ASSERT_TRUE(block_->owns_data());
 285    :  
 286    :    // The head of the data should be identical to the input.
 287  E :    ASSERT_EQ(0, memcmp(data, kTestData, sizeof(kTestData)));
 288    :    // And the tail should be zeros.
 289  E :    ASSERT_EQ(0, memcmp(data + sizeof(kTestData), kZeros, sizeof(kZeros)));
 290  E :  }
 291    :  
 292  E :  TEST_F(BlockTest, GetMutableData) {
 293    :    // Set the block's data.
 294  E :    block_->SetData(kTestData, sizeof(kTestData));
 295    :  
 296    :    // Getting a mutable pointer should copy the data to heap.
 297  E :    uint8* data = block_->GetMutableData();
 298  E :    ASSERT_TRUE(data != NULL);
 299  E :    ASSERT_TRUE(data != kTestData);
 300  E :    ASSERT_TRUE(block_->owns_data());
 301  E :    ASSERT_EQ(sizeof(kTestData), block_->data_size());
 302  E :    ASSERT_EQ(data, block_->data());
 303  E :    ASSERT_EQ(0, memcmp(kTestData, data, block_->data_size()));
 304    :  
 305    :    // Getting the data a second time should return the same pointer.
 306  E :    ASSERT_EQ(data, block_->GetMutableData());
 307  E :  }
 308    :  
 309  E :  TEST_F(BlockTest, InsertData) {
 310    :    // Create a block with a labelled array of pointers. Explicitly initialize
 311    :    // the last one with some data and let the block be longer than its
 312    :    // explicitly initialized length.
 313    :    BlockGraph::Block* block1 = image_.AddBlock(
 314  E :        BlockGraph::CODE_BLOCK, 4 * kPtrSize, "Block1");
 315  E :    block1->AllocateData(3 * kPtrSize);
 316    :    block1->source_ranges().Push(BlockGraph::Block::DataRange(0, 4 * kPtrSize),
 317    :                                 BlockGraph::Block::SourceRange(
 318  E :                                 core::RelativeAddress(0), 4 * kPtrSize));
 319    :    BlockGraph::Reference outgoing_ref(BlockGraph::RELATIVE_REF,
 320    :                                       kPtrSize,
 321    :                                       block_,
 322  E :                                       0, 0);
 323  E :    block1->SetReference(0, outgoing_ref);
 324  E :    block1->SetReference(kPtrSize, outgoing_ref);
 325  E :    block1->SetLabel(0, "Pointer1", BlockGraph::DATA_LABEL);
 326  E :    block1->SetLabel(kPtrSize, "Pointer2", BlockGraph::DATA_LABEL);
 327  E :    block1->SetLabel(2 * kPtrSize, "Pointer3", BlockGraph::DATA_LABEL);
 328  E :    TypedBlock<uint32> data1;
 329  E :    ASSERT_TRUE(data1.Init(0, block1));
 330  E :    data1[0] = 0xAAAAAAAA;
 331  E :    data1[1] = 0xBBBBBBBB;
 332  E :    data1[2] = 0xCCCCCCCC;
 333    :  
 334    :    // Create a block with a pointer to the first entry of block1.
 335    :    BlockGraph::Block* block2 = image_.AddBlock(
 336  E :        BlockGraph::CODE_BLOCK, kPtrSize, "Block2");
 337    :    block2->SetReference(0, BlockGraph::Reference(BlockGraph::RELATIVE_REF,
 338    :                                                  kPtrSize,
 339    :                                                  block1,
 340  E :                                                  0, 0));
 341    :  
 342    :    // Create a block with a pointer to the second entry of block1.
 343    :    BlockGraph::Block* block3 = image_.AddBlock(
 344  E :        BlockGraph::CODE_BLOCK, kPtrSize, "Block3");
 345    :    block3->SetReference(0, BlockGraph::Reference(BlockGraph::RELATIVE_REF,
 346    :                                                  kPtrSize,
 347    :                                                  block1,
 348  E :                                                  kPtrSize, kPtrSize));
 349    :  
 350    :    // Insert a new pointer entry in between the first and second entries.
 351  E :    block1->InsertData(kPtrSize, kPtrSize, false);
 352    :  
 353    :    // Ensure the data_size and block size are as expected.
 354  E :    EXPECT_EQ(5 * kPtrSize, block1->size());
 355  E :    EXPECT_EQ(4 * kPtrSize, block1->data_size());
 356    :  
 357    :    // Ensure the source ranges are as expected.
 358  E :    BlockGraph::Block::SourceRanges expected_src_ranges;
 359    :    expected_src_ranges.Push(
 360    :        BlockGraph::Block::DataRange(0, kPtrSize),
 361  E :        BlockGraph::Block::SourceRange(core::RelativeAddress(0), kPtrSize));
 362    :    expected_src_ranges.Push(
 363    :        BlockGraph::Block::DataRange(2 * kPtrSize, 3 * kPtrSize),
 364    :        BlockGraph::Block::SourceRange(core::RelativeAddress(kPtrSize),
 365  E :                                       3 * kPtrSize));
 366    :    EXPECT_THAT(expected_src_ranges.range_pairs(),
 367  E :                testing::ContainerEq(block1->source_ranges().range_pairs()));
 368    :  
 369    :    // Ensure that the contents of the block's data are as expected.
 370  E :    EXPECT_EQ(0xAAAAAAAAu, data1[0]);
 371  E :    EXPECT_EQ(0x00000000u, data1[1]);
 372  E :    EXPECT_EQ(0xBBBBBBBBu, data1[2]);
 373  E :    EXPECT_EQ(0xCCCCCCCCu, data1[3]);
 374    :  
 375    :    // Ensure that the labels have been shifted appropriately.
 376  E :    BlockGraph::Block::LabelMap expected_labels;
 377    :    expected_labels.insert(std::make_pair(
 378    :        0 * kPtrSize,
 379  E :        BlockGraph::Label("Pointer1", BlockGraph::DATA_LABEL)));
 380    :    expected_labels.insert(std::make_pair(
 381    :        2 * kPtrSize,
 382  E :        BlockGraph::Label("Pointer2", BlockGraph::DATA_LABEL)));
 383    :    expected_labels.insert(std::make_pair(
 384    :        3 * kPtrSize,
 385  E :        BlockGraph::Label("Pointer3", BlockGraph::DATA_LABEL)));
 386  E :    EXPECT_THAT(expected_labels, testing::ContainerEq(block1->labels()));
 387    :  
 388    :    // Ensure that the referrers are as expected.
 389  E :    BlockGraph::Block::ReferrerSet expected_referrers;
 390  E :    expected_referrers.insert(std::make_pair(block2, 0));
 391  E :    expected_referrers.insert(std::make_pair(block3, 0));
 392  E :    EXPECT_THAT(expected_referrers, testing::ContainerEq(block1->referrers()));
 393    :  
 394    :    BlockGraph::Reference expected_ref(BlockGraph::RELATIVE_REF,
 395    :                                       kPtrSize,
 396    :                                       block1,
 397  E :                                       0, 0);
 398  E :    BlockGraph::Reference actual_ref;
 399  E :    EXPECT_TRUE(block2->GetReference(0, &actual_ref));
 400  E :    EXPECT_EQ(expected_ref, actual_ref);
 401    :  
 402    :    expected_ref = BlockGraph::Reference(BlockGraph::RELATIVE_REF,
 403    :                                         kPtrSize,
 404    :                                         block1,
 405  E :                                         2 * kPtrSize, 2 * kPtrSize);
 406  E :    EXPECT_TRUE(block3->GetReference(0, &actual_ref));
 407  E :    EXPECT_EQ(expected_ref, actual_ref);
 408    :  
 409    :    // Ensure that the references have been shifted appropriately.
 410  E :    BlockGraph::Block::ReferenceMap expected_references;
 411  E :    expected_references.insert(std::make_pair(0, outgoing_ref));
 412  E :    expected_references.insert(std::make_pair(2 * kPtrSize, outgoing_ref));
 413  E :    EXPECT_EQ(expected_references, block1->references());
 414  E :  }
 415    :  
 416  E :  TEST_F(BlockTest, InsertDataImplicit) {
 417    :    BlockGraph::Block* block1 = image_.AddBlock(
 418  E :        BlockGraph::CODE_BLOCK, 40, "Block1");
 419  E :    block1->AllocateData(30);
 420    :  
 421    :    // Do an insert data in the implicitly initialized portion of the block.
 422  E :    block1->InsertData(30, 10, false);
 423    :  
 424    :    // We expect the block to have grown, but the data size should still be the
 425    :    // same.
 426  E :    EXPECT_EQ(50u, block1->size());
 427  E :    EXPECT_EQ(30u, block1->data_size());
 428  E :  }
 429    :  
 430  E :  TEST_F(BlockTest, InsertDataImplicitForceAllocation) {
 431    :    BlockGraph::Block* block1 = image_.AddBlock(
 432  E :        BlockGraph::CODE_BLOCK, 40, "Block1");
 433  E :    block1->AllocateData(30);
 434    :  
 435    :    // Do an insert data in the implicitly initialized portion of the block, but
 436    :    // force data to be allocated.
 437  E :    block1->InsertData(30, 10, true);
 438    :  
 439    :    // We expect the block to have grown, as well as the data size.
 440  E :    EXPECT_EQ(50u, block1->size());
 441  E :    EXPECT_EQ(40u, block1->data_size());
 442  E :  }
 443    :  
 444  E :  TEST_F(BlockTest, InsertDataForceAllocateDoesNotShorten) {
 445    :    BlockGraph::Block* block1 = image_.AddBlock(
 446  E :        BlockGraph::CODE_BLOCK, 40, "Block1");
 447  E :    block1->AllocateData(30);
 448    :  
 449    :    // Insert data in the allocated region, but request allocation to be forced.
 450  E :    block1->InsertData(0, 10, true);
 451    :  
 452  E :    EXPECT_EQ(50u, block1->size());
 453  E :    EXPECT_EQ(40u, block1->data_size());
 454  E :  }
 455    :  
 456  E :  TEST_F(BlockTest, InsertDataWithSelfReference) {
 457    :    BlockGraph::Block* block1 = image_.AddBlock(
 458  E :        BlockGraph::CODE_BLOCK, 40, "Block1");
 459    :  
 460  E :    BlockGraph::Reference ref(BlockGraph::ABSOLUTE_REF, kPtrSize, block1, 0, 0);
 461    :    // Insert a self-reference to the block.
 462  E :    block1->SetReference(20, ref);
 463    :  
 464    :    // Insert some data before the reference.
 465  E :    block1->InsertData(10, 10, false);
 466    :  
 467  E :    BlockGraph::Reference moved_ref;
 468  E :    ASSERT_TRUE(block1->GetReference(30, &moved_ref));
 469  E :    ASSERT_EQ(ref, moved_ref);
 470    :  
 471  E :    BlockGraph::Block::ReferrerSet expected;
 472  E :    expected.insert(std::make_pair(block1, 30));
 473  E :    ASSERT_EQ(block1->referrers(), expected);
 474  E :  }
 475    :  
 476  E :  TEST_F(BlockTest, RemoveData) {
 477    :    // Create a block with a labelled array of pointers. Explicitly initialize
 478    :    // the last one with some data and let the block be longer than its
 479    :    // explicitly initialized length.
 480    :    BlockGraph::Block* block1 = image_.AddBlock(
 481  E :        BlockGraph::CODE_BLOCK, 6 * kPtrSize, "Block1");
 482  E :    block1->AllocateData(3 * kPtrSize);
 483    :    block1->source_ranges().Push(BlockGraph::Block::DataRange(0, 6 * kPtrSize),
 484    :                                 BlockGraph::Block::SourceRange(
 485  E :                                     core::RelativeAddress(0), 6 * kPtrSize));
 486    :    BlockGraph::Reference outgoing_ref(BlockGraph::RELATIVE_REF,
 487    :                                       kPtrSize,
 488    :                                       block_,
 489  E :                                       0, 0);
 490  E :    block1->SetReference(0, outgoing_ref);
 491  E :    block1->SetReference(2 * kPtrSize, outgoing_ref);
 492  E :    block1->SetReference(5 * kPtrSize, outgoing_ref);
 493  E :    block1->SetLabel(0, "Pointer1", BlockGraph::DATA_LABEL);
 494  E :    block1->SetLabel(2 * kPtrSize, "Pointer3", BlockGraph::DATA_LABEL);
 495  E :    block1->SetLabel(3 * kPtrSize, "EndOfPointers", BlockGraph::DATA_LABEL);
 496  E :    TypedBlock<uint32> data1;
 497  E :    ASSERT_TRUE(data1.Init(0, block1));
 498  E :    data1[0] = 0xAAAAAAAA;
 499  E :    data1[1] = 0xBBBBBBBB;
 500  E :    data1[2] = 0xCCCCCCCC;
 501    :  
 502    :    // Create a block with a pointer to the first entry of block1.
 503    :    BlockGraph::Block* block2 = image_.AddBlock(
 504  E :        BlockGraph::CODE_BLOCK, kPtrSize, "Block2");
 505    :    block2->SetReference(0, BlockGraph::Reference(BlockGraph::RELATIVE_REF,
 506    :                                                  kPtrSize,
 507    :                                                  block1,
 508  E :                                                  0, 0));
 509    :  
 510    :    // Create a block with a pointer to the third entry of block1.
 511    :    BlockGraph::Block* block3 = image_.AddBlock(
 512  E :        BlockGraph::CODE_BLOCK, kPtrSize, "Block4");
 513    :    block3->SetReference(0, BlockGraph::Reference(BlockGraph::RELATIVE_REF,
 514    :                                                  kPtrSize,
 515    :                                                  block1,
 516  E :                                                  2 * kPtrSize, 2 * kPtrSize));
 517    :  
 518    :    // Create a block with a pointer to the fifth entry of block1.
 519    :    BlockGraph::Block* block4 = image_.AddBlock(
 520  E :        BlockGraph::CODE_BLOCK, kPtrSize, "Block3");
 521    :    block4->SetReference(0, BlockGraph::Reference(BlockGraph::RELATIVE_REF,
 522    :                                                  kPtrSize,
 523    :                                                  block1,
 524  E :                                                  4 * kPtrSize, 4 * kPtrSize));
 525    :  
 526    :    // Trying to remove the fourth entry should fail because it contains a label.
 527  E :    EXPECT_FALSE(block1->RemoveData(3 * kPtrSize, kPtrSize));
 528    :  
 529    :    // Trying to remove the fifth entry should fail because there is a referrer
 530    :    // pointing to it.
 531  E :    EXPECT_FALSE(block1->RemoveData(4 * kPtrSize, kPtrSize));
 532    :  
 533    :    // Trying to remove the sixth entry should fail because it contains a
 534    :    // reference.
 535  E :    EXPECT_FALSE(block1->RemoveData(5 * kPtrSize, kPtrSize));
 536    :  
 537    :    // Finally, we should be able to delete the second entry.
 538  E :    EXPECT_TRUE(block1->RemoveData(kPtrSize, kPtrSize));
 539    :  
 540    :    // Ensure the data_size and block size are as expected.
 541  E :    EXPECT_EQ(5 * kPtrSize, block1->size());
 542  E :    EXPECT_EQ(2 * kPtrSize, block1->data_size());
 543    :  
 544    :    // Ensure the source ranges are as expected.
 545  E :    BlockGraph::Block::SourceRanges expected_src_ranges;
 546    :    expected_src_ranges.Push(
 547    :        BlockGraph::Block::DataRange(0, kPtrSize),
 548  E :        BlockGraph::Block::SourceRange(core::RelativeAddress(0), kPtrSize));
 549    :    expected_src_ranges.Push(
 550    :        BlockGraph::Block::DataRange(kPtrSize, 4 * kPtrSize),
 551    :        BlockGraph::Block::SourceRange(core::RelativeAddress(2 * kPtrSize),
 552  E :                                       4 * kPtrSize));
 553    :    EXPECT_THAT(expected_src_ranges.range_pairs(),
 554  E :                testing::ContainerEq(block1->source_ranges().range_pairs()));
 555    :  
 556    :    // Ensure that the contents of the block's data are as expected.
 557  E :    EXPECT_EQ(0xAAAAAAAAu, data1[0]);
 558  E :    EXPECT_EQ(0xCCCCCCCCu, data1[1]);
 559    :  
 560    :    // Ensure that the labels have been shifted appropriately.
 561  E :    BlockGraph::Block::LabelMap expected_labels;
 562    :    expected_labels.insert(std::make_pair(
 563    :        0 * kPtrSize,
 564  E :        BlockGraph::Label("Pointer1", BlockGraph::DATA_LABEL)));
 565    :    expected_labels.insert(std::make_pair(
 566    :        1 * kPtrSize,
 567  E :        BlockGraph::Label("Pointer3", BlockGraph::DATA_LABEL)));
 568    :    expected_labels.insert(std::make_pair(
 569    :        2 * kPtrSize,
 570  E :        BlockGraph::Label("EndOfPointers", BlockGraph::DATA_LABEL)));
 571  E :    EXPECT_THAT(expected_labels, testing::ContainerEq(block1->labels()));
 572    :  
 573    :    // Ensure that the referrers are as expected.
 574  E :    BlockGraph::Block::ReferrerSet expected_referrers;
 575  E :    expected_referrers.insert(std::make_pair(block2, 0));
 576  E :    expected_referrers.insert(std::make_pair(block3, 0));
 577  E :    expected_referrers.insert(std::make_pair(block4, 0));
 578  E :    EXPECT_THAT(expected_referrers, testing::ContainerEq(block1->referrers()));
 579    :  
 580    :    BlockGraph::Reference expected_ref(BlockGraph::RELATIVE_REF,
 581    :                                       kPtrSize,
 582    :                                       block1,
 583  E :                                       0, 0);
 584  E :    BlockGraph::Reference actual_ref;
 585  E :    EXPECT_TRUE(block2->GetReference(0, &actual_ref));
 586  E :    EXPECT_EQ(expected_ref, actual_ref);
 587    :  
 588    :    expected_ref = BlockGraph::Reference(BlockGraph::RELATIVE_REF,
 589    :                                         kPtrSize,
 590    :                                         block1,
 591  E :                                         kPtrSize, kPtrSize);
 592  E :    EXPECT_TRUE(block3->GetReference(0, &actual_ref));
 593  E :    EXPECT_EQ(expected_ref, actual_ref);
 594    :  
 595    :    expected_ref = BlockGraph::Reference(BlockGraph::RELATIVE_REF,
 596    :                                         kPtrSize,
 597    :                                         block1,
 598  E :                                         3 * kPtrSize, 3 * kPtrSize);
 599  E :    EXPECT_TRUE(block4->GetReference(0, &actual_ref));
 600  E :    EXPECT_EQ(expected_ref, actual_ref);
 601    :  
 602    :    // Ensure that the references have been shifted appropriately.
 603  E :    BlockGraph::Block::ReferenceMap expected_references;
 604  E :    expected_references.insert(std::make_pair(0, outgoing_ref));
 605  E :    expected_references.insert(std::make_pair(kPtrSize, outgoing_ref));
 606  E :    expected_references.insert(std::make_pair(4 * kPtrSize, outgoing_ref));
 607  E :    EXPECT_EQ(expected_references, block1->references());
 608  E :  }
 609    :  
 610  E :  TEST_F(BlockTest, RemoveDataPartlyImplicit) {
 611    :    BlockGraph::Block* block1 = image_.AddBlock(
 612  E :        BlockGraph::CODE_BLOCK, 40, "Block1");
 613  E :    block1->AllocateData(30);
 614    :  
 615    :    // Remove data that spans both the initialized and implicit parts of the
 616    :    // block.
 617  E :    EXPECT_TRUE(block1->RemoveData(25, 10));
 618    :  
 619    :    // We expect both the block and the data size to have shrunk.
 620  E :    EXPECT_EQ(30u, block1->size());
 621  E :    EXPECT_EQ(25u, block1->data_size());
 622  E :  }
 623    :  
 624  E :  TEST_F(BlockTest, RemoveDataImplicit) {
 625    :    BlockGraph::Block* block1 = image_.AddBlock(
 626  E :        BlockGraph::CODE_BLOCK, 40, "Block1");
 627  E :    block1->AllocateData(30);
 628    :  
 629    :    // Do an remove data in the implicitly initialized portion of the block.
 630  E :    EXPECT_TRUE(block1->RemoveData(30, 5));
 631    :  
 632    :    // We expect the block to have shrunk, but the data size should still be the
 633    :    // same.
 634  E :    EXPECT_EQ(35u, block1->size());
 635  E :    EXPECT_EQ(30u, block1->data_size());
 636  E :  }
 637    :  
 638  E :  TEST_F(BlockTest, RemoveDataWithSelfReference) {
 639    :    BlockGraph::Block* block1 = image_.AddBlock(
 640  E :        BlockGraph::CODE_BLOCK, 50, "Block1");
 641    :  
 642  E :    BlockGraph::Reference ref(BlockGraph::ABSOLUTE_REF, kPtrSize, block1, 0, 0);
 643    :    // Insert a self-reference to the block.
 644  E :    block1->SetReference(40, ref);
 645    :  
 646    :    // Remove some data before the reference.
 647  E :    block1->RemoveData(10, 10);
 648    :  
 649  E :    BlockGraph::Reference moved_ref;
 650  E :    ASSERT_TRUE(block1->GetReference(30, &moved_ref));
 651  E :    ASSERT_EQ(ref, moved_ref);
 652    :  
 653  E :    BlockGraph::Block::ReferrerSet expected;
 654  E :    expected.insert(std::make_pair(block1, 30));
 655  E :    ASSERT_EQ(block1->referrers(), expected);
 656  E :  }
 657    :  
 658  E :  TEST_F(BlockTest, InsertOrRemoveDataSameSizeNoAllocate) {
 659    :    BlockGraph::Block* block1 = image_.AddBlock(
 660  E :        BlockGraph::DATA_BLOCK, 40, "Block1");
 661    :  
 662  E :    EXPECT_TRUE(block1->InsertOrRemoveData(0, 20, 20, false));
 663  E :    EXPECT_EQ(40u, block1->size());
 664  E :    EXPECT_EQ(0u, block1->data_size());
 665  E :  }
 666    :  
 667  E :  TEST_F(BlockTest, InsertOrRemoveDataSameSizeAllocate) {
 668    :    BlockGraph::Block* block1 = image_.AddBlock(
 669  E :        BlockGraph::DATA_BLOCK, 40, "Block1");
 670    :  
 671  E :    EXPECT_TRUE(block1->InsertOrRemoveData(0, 20, 20, true));
 672  E :    EXPECT_EQ(40u, block1->size());
 673  E :    EXPECT_EQ(20u, block1->data_size());
 674  E :  }
 675    :  
 676  E :  TEST_F(BlockTest, InsertOrRemoveGrowNoAllocate) {
 677    :    BlockGraph::Block* block1 = image_.AddBlock(
 678  E :        BlockGraph::DATA_BLOCK, 40, "Block1");
 679    :  
 680  E :    EXPECT_TRUE(block1->InsertOrRemoveData(0, 10, 20, false));
 681  E :    EXPECT_EQ(50u, block1->size());
 682  E :    EXPECT_EQ(0u, block1->data_size());
 683  E :  }
 684    :  
 685  E :  TEST_F(BlockTest, InsertOrRemoveGrowAllocate) {
 686    :    BlockGraph::Block* block1 = image_.AddBlock(
 687  E :        BlockGraph::DATA_BLOCK, 40, "Block1");
 688    :  
 689  E :    EXPECT_TRUE(block1->InsertOrRemoveData(0, 10, 20, true));
 690  E :    EXPECT_EQ(50u, block1->size());
 691  E :    EXPECT_EQ(20u, block1->data_size());
 692  E :  }
 693    :  
 694  E :  TEST_F(BlockTest, InsertOrRemoveShrinkNoAllocate) {
 695    :    BlockGraph::Block* block1 = image_.AddBlock(
 696  E :        BlockGraph::DATA_BLOCK, 40, "Block1");
 697  E :    block1->AllocateData(15);
 698    :  
 699  E :    EXPECT_TRUE(block1->InsertOrRemoveData(0, 20, 10, false));
 700  E :    EXPECT_EQ(30u, block1->size());
 701  E :    EXPECT_EQ(10u, block1->data_size());
 702  E :  }
 703    :  
 704  E :  TEST_F(BlockTest, InsertOrRemoveShrinkAllocate) {
 705    :    BlockGraph::Block* block1 = image_.AddBlock(
 706  E :        BlockGraph::DATA_BLOCK, 40, "Block1");
 707    :  
 708  E :    EXPECT_TRUE(block1->InsertOrRemoveData(0, 20, 10, true));
 709  E :    EXPECT_EQ(30u, block1->size());
 710  E :    EXPECT_EQ(10u, block1->data_size());
 711  E :  }
 712    :  
 713  E :  TEST_F(BlockTest, HasExternalReferrers) {
 714    :    // Create block1 that refers to itself. It has no external referrers.
 715    :    BlockGraph::Block* block1 = image_.AddBlock(
 716  E :        BlockGraph::DATA_BLOCK, 40, "Block1");
 717  E :    ASSERT_TRUE(block1 != NULL);
 718    :    EXPECT_TRUE(block1->SetReference(
 719  E :        0, BlockGraph::Reference(BlockGraph::ABSOLUTE_REF, 4, block1, 0, 0)));
 720  E :    EXPECT_FALSE(block1->HasExternalReferrers());
 721    :  
 722    :    // Create a second block that refers to block1.
 723    :    BlockGraph::Block* block2 = image_.AddBlock(
 724  E :        BlockGraph::DATA_BLOCK, 40, "Block2");
 725  E :    ASSERT_TRUE(block2 != NULL);
 726    :    EXPECT_TRUE(block2->SetReference(
 727  E :        0, BlockGraph::Reference(BlockGraph::ABSOLUTE_REF, 4, block1, 0, 0)));
 728    :  
 729    :    // There should now be an external referrer to block1.
 730  E :    EXPECT_TRUE(block1->HasExternalReferrers());
 731  E :  }
 732    :  
 733  E :  TEST_F(BlockTest, RemoveAllReferences) {
 734    :    // Create block1 that refers to itself. It has no external referrers.
 735    :    BlockGraph::Block* block1 = image_.AddBlock(
 736  E :        BlockGraph::DATA_BLOCK, 40, "Block1");
 737  E :    ASSERT_TRUE(block1 != NULL);
 738    :    EXPECT_TRUE(block1->SetReference(
 739  E :        0, BlockGraph::Reference(BlockGraph::ABSOLUTE_REF, 4, block1, 0, 0)));
 740    :  
 741    :    // Create a second block for block1 to refer to.
 742    :    BlockGraph::Block* block2 = image_.AddBlock(
 743  E :        BlockGraph::DATA_BLOCK, 40, "Block2");
 744  E :    ASSERT_TRUE(block2 != NULL);
 745    :    EXPECT_TRUE(block1->SetReference(
 746  E :        4, BlockGraph::Reference(BlockGraph::ABSOLUTE_REF, 4, block2, 0, 0)));
 747    :  
 748    :    // Verify that the references are as expected.
 749  E :    EXPECT_EQ(2U, block1->references().size());
 750  E :    EXPECT_EQ(1U, block1->referrers().size());
 751  E :    EXPECT_EQ(1U, block2->referrers().size());
 752    :  
 753    :    // Remove all references from block1.
 754  E :    EXPECT_TRUE(block1->RemoveAllReferences());
 755    :  
 756    :    // Veify that the references are as expected.
 757  E :    EXPECT_EQ(0U, block1->references().size());
 758  E :    EXPECT_EQ(0U, block1->referrers().size());
 759  E :    EXPECT_EQ(0U, block2->referrers().size());
 760  E :  }
 761    :  
 762  E :  TEST(BlockGraphTest, BlockTypeToString) {
 763  E :    for (int type = 0; type < BlockGraph::BLOCK_TYPE_MAX; ++type) {
 764    :      BlockGraph::BlockType block_type =
 765  E :          static_cast<BlockGraph::BlockType>(type);
 766  E :      EXPECT_TRUE(BlockGraph::BlockTypeToString(block_type) != NULL);
 767  E :    }
 768  E :  }
 769    :  
 770  E :  TEST(BlockGraphTest, LabelAttributesToString) {
 771  E :    BlockGraph::LabelAttributes label_attr = 1;
 772  E :    for (; label_attr != BlockGraph::LABEL_ATTRIBUTES_MAX; label_attr <<= 1) {
 773  E :      std::string s = BlockGraph::LabelAttributesToString(label_attr);
 774  E :      EXPECT_FALSE(s.empty());
 775  E :    }
 776    :  
 777  E :    label_attr = BlockGraph::LABEL_ATTRIBUTES_MAX - 1;
 778  E :    std::string s = BlockGraph::LabelAttributesToString(label_attr);
 779  E :    EXPECT_FALSE(s.empty());
 780  E :  }
 781    :  
 782  E :  TEST(BlockGraphTest, AddSections) {
 783  E :    BlockGraph image;
 784  E :    ASSERT_EQ(0u, image.sections().size());
 785    :  
 786  E :    BlockGraph::Section* section0 = image.AddSection("foo", 0);
 787  E :    ASSERT_TRUE(section0 != NULL);
 788  E :    ASSERT_EQ("foo", section0->name());
 789  E :    ASSERT_EQ(0u, section0->characteristics());
 790  E :    ASSERT_EQ(1u, image.sections().size());
 791    :  
 792  E :    BlockGraph::Section* section1 = image.AddSection("foo", 0);
 793  E :    ASSERT_TRUE(section1 != NULL);
 794  E :    ASSERT_EQ("foo", section1->name());
 795  E :    ASSERT_EQ(0u, section1->characteristics());
 796  E :    ASSERT_EQ(2u, image.sections().size());
 797    :  
 798    :    // This section has the same name and characteristics, but it should not be
 799    :    // the same section as section0.
 800  E :    EXPECT_TRUE(section0 != section1);
 801  E :    EXPECT_NE(section0->id(), section1->id());
 802    :  
 803  E :    BlockGraph::Section* section2 = image.FindOrAddSection("foo", 1);
 804  E :    ASSERT_TRUE(section2 != NULL);
 805  E :    ASSERT_EQ("foo", section2->name());
 806  E :    ASSERT_EQ(1u, section2->characteristics());
 807  E :    ASSERT_EQ(2u, image.sections().size());
 808    :  
 809    :    // This should be the same as section0, the first instance of a section
 810    :    // with name 'foo'.
 811  E :    EXPECT_EQ(section0, section2);
 812    :  
 813  E :    BlockGraph::Section* section3 = image.FindOrAddSection("bar", 1);
 814  E :    ASSERT_TRUE(section3 != NULL);
 815  E :    ASSERT_EQ("bar", section3->name());
 816  E :    ASSERT_EQ(1u, section3->characteristics());
 817  E :    ASSERT_EQ(3u, image.sections().size());
 818    :  
 819    :    // Test out FindSection.
 820  E :    EXPECT_EQ(section0, image.FindSection("foo"));
 821  E :    EXPECT_EQ(section3, image.FindSection("bar"));
 822  E :    EXPECT_TRUE(image.FindSection("baz") == NULL);
 823  E :  }
 824    :  
 825  E :  TEST(BlockGraphTest, RemoveSection) {
 826  E :    BlockGraph image;
 827  E :    ASSERT_EQ(0u, image.sections().size());
 828    :  
 829  E :    BlockGraph::Section* section0 = image.AddSection("foo", 0);
 830  E :    ASSERT_TRUE(section0 != NULL);
 831  E :    ASSERT_EQ(1u, image.sections().size());
 832    :  
 833  E :    BlockGraph::Section* section1 = image.AddSection("bar", 0);
 834  E :    ASSERT_TRUE(section1 != NULL);
 835  E :    ASSERT_EQ(2u, image.sections().size());
 836    :  
 837    :    // We should not be able to delete a non-existent section.
 838  E :    EXPECT_FALSE(image.RemoveSectionById(BlockGraph::kInvalidSectionId));
 839  E :    ASSERT_EQ(2u, image.sections().size());
 840    :  
 841    :    // Deleting normal sections should work just fine.
 842    :  
 843  E :    EXPECT_TRUE(image.RemoveSectionById(section0->id()));
 844  E :    ASSERT_EQ(1u, image.sections().size());
 845    :  
 846  E :    EXPECT_TRUE(image.RemoveSection(section1));
 847  E :    ASSERT_EQ(0u, image.sections().size());
 848  E :  }
 849    :  
 850  E :  TEST(BlockGraphTest, RemoveBlock) {
 851  E :    BlockGraph image;
 852    :  
 853    :    // Add some blocks to the image.
 854  E :    BlockGraph::Block* b1 = image.AddBlock(BlockGraph::CODE_BLOCK, 0x20, "b1");
 855  E :    BlockGraph::Block* b2 = image.AddBlock(BlockGraph::CODE_BLOCK, 0x20, "b2");
 856  E :    BlockGraph::Block* b3 = image.AddBlock(BlockGraph::CODE_BLOCK, 0x20, "b3");
 857  E :    BlockGraph::Block* b4 = image.AddBlock(BlockGraph::CODE_BLOCK, 0x20, "b4");
 858  E :    ASSERT_TRUE(b1 != NULL);
 859  E :    ASSERT_TRUE(b2 != NULL);
 860  E :    ASSERT_TRUE(b3 != NULL);
 861  E :    ASSERT_TRUE(b4 != NULL);
 862  E :    EXPECT_EQ(4u, image.blocks().size());
 863    :  
 864    :    // Add a reference from block 1 to block 2.
 865  E :    BlockGraph::Reference ref12(BlockGraph::PC_RELATIVE_REF, 1, b2, 9, 9);
 866  E :    ASSERT_TRUE(b1->SetReference(0, ref12));
 867  E :    EXPECT_THAT(b1->references(), testing::Contains(std::make_pair(0, ref12)));
 868  E :    EXPECT_THAT(b2->referrers(), testing::Contains(std::make_pair(b1, 0)));
 869  E :    EXPECT_EQ(1u, b1->references().size());
 870  E :    EXPECT_EQ(1u, b2->referrers().size());
 871    :  
 872    :    // Try to delete Block 1. This should fail because it has references.
 873  E :    ASSERT_FALSE(image.RemoveBlock(b1));
 874  E :    EXPECT_EQ(4u, image.blocks().size());
 875    :  
 876    :    // Try to delete Block 2. This should fail because it has referrers.
 877  E :    ASSERT_FALSE(image.RemoveBlockById(b2->id()));
 878  E :    EXPECT_EQ(4u, image.blocks().size());
 879    :  
 880    :    // Try to delete a block that doesn't belong to the block graph. This
 881    :    // should fail.
 882  E :    BlockGraph other_image;
 883    :    BlockGraph::Block* other_block =
 884  E :        other_image.AddBlock(BlockGraph::CODE_BLOCK, 0x20, "other_block");
 885  E :    ASSERT_FALSE(image.RemoveBlock(other_block));
 886  E :    EXPECT_EQ(4u, image.blocks().size());
 887    :  
 888    :    // Try to delete a block with an invalid ID. This should fail.
 889  E :    ASSERT_FALSE(image.RemoveBlockById(15));
 890  E :    EXPECT_EQ(4u, image.blocks().size());
 891    :  
 892    :    // Delete block 3.
 893  E :    ASSERT_TRUE(image.RemoveBlock(b3));
 894  E :    EXPECT_EQ(3u, image.blocks().size());
 895    :  
 896    :    // Delete block 4.
 897  E :    ASSERT_TRUE(image.RemoveBlockById(b4->id()));
 898  E :    EXPECT_EQ(2u, image.blocks().size());
 899  E :  }
 900    :  
 901  E :  TEST(BlockGraphTest, References) {
 902  E :    BlockGraph image;
 903    :  
 904  E :    BlockGraph::Block* b1 = image.AddBlock(BlockGraph::CODE_BLOCK, 0x20, "b1");
 905  E :    BlockGraph::Block* b2 = image.AddBlock(BlockGraph::CODE_BLOCK, 0x20, "b2");
 906  E :    BlockGraph::Block* b3 = image.AddBlock(BlockGraph::CODE_BLOCK, 0x20, "b3");
 907  E :    ASSERT_TRUE(b1 != NULL);
 908  E :    ASSERT_TRUE(b2 != NULL);
 909  E :    ASSERT_TRUE(b3 != NULL);
 910    :  
 911  E :    ASSERT_TRUE(b1->references().empty());
 912  E :    ASSERT_TRUE(b1->referrers().empty());
 913  E :    ASSERT_TRUE(b2->references().empty());
 914  E :    ASSERT_TRUE(b2->referrers().empty());
 915  E :    ASSERT_TRUE(b3->references().empty());
 916  E :    ASSERT_TRUE(b3->referrers().empty());
 917    :  
 918  E :    BlockGraph::Reference dummy;
 919  E :    ASSERT_FALSE(dummy.IsValid());
 920    :  
 921    :    // Add the first reference, and test that we get a backref.
 922  E :    BlockGraph::Reference r_pc(BlockGraph::PC_RELATIVE_REF, 1, b2, 9, 9);
 923  E :    ASSERT_TRUE(r_pc.IsValid());
 924  E :    ASSERT_EQ(BlockGraph::PC_RELATIVE_REF, r_pc.type());
 925  E :    ASSERT_EQ(1, r_pc.size());
 926  E :    ASSERT_EQ(b2, r_pc.referenced());
 927  E :    ASSERT_EQ(9, r_pc.offset());
 928    :  
 929  E :    ASSERT_TRUE(b1->SetReference(0, r_pc));
 930  E :    EXPECT_THAT(b2->referrers(), testing::Contains(std::make_pair(b1, 0)));
 931    :  
 932  E :    ASSERT_TRUE(b1->SetReference(1, r_pc));
 933  E :    EXPECT_THAT(b2->referrers(), testing::Contains(std::make_pair(b1, 1)));
 934    :  
 935  E :    BlockGraph::Reference r_abs(BlockGraph::ABSOLUTE_REF, 4, b2, 13, 13);
 936  E :    ASSERT_FALSE(b1->SetReference(1, r_abs));
 937  E :    BlockGraph::Reference r_rel(BlockGraph::RELATIVE_REF, 4, b2, 17, 17);
 938  E :    ASSERT_TRUE(b1->SetReference(5, r_rel));
 939  E :    BlockGraph::Reference r_file(BlockGraph::FILE_OFFSET_REF, 4, b2, 23, 23);
 940  E :    ASSERT_TRUE(b1->SetReference(9, r_file));
 941    :  
 942    :    // Test that the reference map is as expected.
 943  E :    BlockGraph::Block::ReferenceMap expected;
 944  E :    expected.insert(std::make_pair(0, r_pc));
 945  E :    expected.insert(std::make_pair(1, r_abs));
 946  E :    expected.insert(std::make_pair(5, r_rel));
 947  E :    expected.insert(std::make_pair(9, r_file));
 948  E :    EXPECT_THAT(b1->references(), testing::ContainerEq(expected));
 949    :  
 950    :    // Test reference transfer.
 951    :    // This should fail, as all the references will fall outside b3.
 952    :    // TODO(chrisha): We need to create a logging MessageHandler that we can
 953    :    //     put test expectations on. This test is meant to fail, but we don't
 954    :    //     want to see the error message it would produce! Ideally, this should
 955    :    //     live in 'syzygy/testing' or something of the like, as it could be
 956    :    //     used across many unittests. For now, we simply disable logging for
 957    :    //     this test.
 958  E :    int old_level = logging::GetMinLogLevel();
 959  E :    logging::SetMinLogLevel(logging::LOG_FATAL);
 960  E :    ASSERT_FALSE(b2->TransferReferrers(b3->size(), b3));
 961  E :    logging::SetMinLogLevel(old_level);
 962    :  
 963    :    // Now move the references from b2 to b3
 964  E :    ASSERT_TRUE(b2->TransferReferrers(0, b3));
 965    :    // Test that b2 no longer has referrers.
 966  E :    EXPECT_THAT(b2->referrers(), BlockGraph::Block::ReferrerSet());
 967    :  
 968    :    // Test that the references transferred as expected.
 969  E :    expected.clear();
 970    :    expected.insert(std::make_pair(0,
 971  E :        BlockGraph::Reference(BlockGraph::PC_RELATIVE_REF, 1, b3, 9, 9)));
 972    :    expected.insert(std::make_pair(1,
 973  E :        BlockGraph::Reference(BlockGraph::ABSOLUTE_REF, 4, b3, 13, 13)));
 974    :    expected.insert(std::make_pair(5,
 975  E :        BlockGraph::Reference(BlockGraph::RELATIVE_REF, 4, b3, 17, 17)));
 976    :    expected.insert(std::make_pair(9,
 977  E :        BlockGraph::Reference(BlockGraph::FILE_OFFSET_REF, 4, b3, 23, 23)));
 978  E :    EXPECT_THAT(b1->references(), testing::ContainerEq(expected));
 979    :  
 980    :    // Remove the references.
 981  E :    ASSERT_TRUE(b1->RemoveReference(0));
 982  E :    ASSERT_TRUE(b1->RemoveReference(1));
 983  E :    ASSERT_TRUE(b1->RemoveReference(5));
 984  E :    ASSERT_TRUE(b1->RemoveReference(9));
 985  E :    EXPECT_THAT(b1->references(), BlockGraph::Block::ReferenceMap());
 986    :  
 987  E :    EXPECT_THAT(b2->referrers(), BlockGraph::Block::ReferrerSet());
 988  E :  }
 989    :  
 990  E :  TEST(BlockGraphTest, Labels) {
 991  E :    BlockGraph image;
 992    :  
 993    :    BlockGraph::Block* block =
 994  E :        image.AddBlock(BlockGraph::CODE_BLOCK, 0x20, "labeled");
 995  E :    ASSERT_TRUE(block->labels().empty());
 996  E :    for (int i = 0; i < 0x20; ++i) {
 997  E :      BlockGraph::Label label;
 998  E :      ASSERT_FALSE(block->HasLabel(i));
 999  E :      EXPECT_FALSE(block->GetLabel(i, &label));
1000  E :      EXPECT_FALSE(block->RemoveLabel(i));
1001  E :    }
1002    :  
1003  E :    EXPECT_TRUE(block->SetLabel(13, "foo", BlockGraph::DATA_LABEL));
1004  E :    EXPECT_FALSE(block->SetLabel(13, "foo2", BlockGraph::DATA_LABEL));
1005    :  
1006  E :    EXPECT_TRUE(block->SetLabel(17, "bar", BlockGraph::CODE_LABEL));
1007  E :    EXPECT_FALSE(block->SetLabel(17, "bar2", BlockGraph::CODE_LABEL));
1008    :  
1009  E :    EXPECT_TRUE(block->SetLabel(15, "baz", BlockGraph::CODE_LABEL));
1010  E :    EXPECT_TRUE(block->HasLabel(15));
1011  E :    EXPECT_TRUE(block->RemoveLabel(15));
1012  E :    EXPECT_FALSE(block->HasLabel(15));
1013    :  
1014  E :    for (int i = 0; i < 0x20; ++i) {
1015  E :      BlockGraph::Label label;
1016  E :      if (i == 13 || i == 17) {
1017  E :        ASSERT_TRUE(block->HasLabel(i));
1018  E :        EXPECT_TRUE(block->GetLabel(i, &label));
1019  E :        EXPECT_EQ(std::string(i == 13 ? "foo" : "bar"), label.name());
1020    :        EXPECT_EQ(i == 13 ? BlockGraph::DATA_LABEL :
1021    :                      BlockGraph::CODE_LABEL,
1022  E :                  label.attributes());
1023  E :      } else {
1024  E :        ASSERT_FALSE(block->HasLabel(i));
1025  E :        EXPECT_FALSE(block->GetLabel(i, &label));
1026    :      }
1027  E :    }
1028    :  
1029  E :    BlockGraph::Block::LabelMap expected;
1030    :    expected.insert(std::make_pair(
1031  E :        13, BlockGraph::Label("foo", BlockGraph::DATA_LABEL)));
1032    :    expected.insert(std::make_pair(
1033  E :        17, BlockGraph::Label("bar", BlockGraph::CODE_LABEL)));
1034  E :    EXPECT_THAT(block->labels(), testing::ContainerEq(expected));
1035  E :  }
1036    :  
1037    :  namespace {
1038    :  
1039    :  class BlockGraphSerializationTest : public testing::Test {
1040    :   public:
1041    :    virtual void SetUp() {
1042    :      ASSERT_TRUE(testing::GenerateTestBlockGraph(&image_));
1043    :    }
1044    :  
1045    :   protected:
1046    :    BlockGraph image_;
1047    :  };
1048    :  
1049    :  }  // namespace
1050    :  
1051  E :  TEST(BlockGraphAddressSpaceTest, AddBlock) {
1052  E :    BlockGraph image;
1053  E :    BlockGraph::AddressSpace address_space(&image);
1054    :  
1055    :    // We should be able to insert this block.
1056    :    BlockGraph::Block* block = address_space.AddBlock(BlockGraph::CODE_BLOCK,
1057    :                                                      RelativeAddress(0x1000),
1058    :                                                      0x20,
1059  E :                                                      "code");
1060  E :    ASSERT_TRUE(block != NULL);
1061  E :    EXPECT_EQ(0x1000, block->addr().value());
1062    :  
1063    :    // But inserting anything that intersects with it should fail.
1064    :    EXPECT_EQ(NULL, address_space.AddBlock(BlockGraph::CODE_BLOCK,
1065    :                                           RelativeAddress(0x1000),
1066    :                                           0x20,
1067  E :                                           "code"));
1068    :  
1069    :    // Overlapping from below.
1070    :    EXPECT_EQ(NULL, address_space.AddBlock(BlockGraph::CODE_BLOCK,
1071    :                                           RelativeAddress(0xFF0),
1072    :                                           0x20,
1073  E :                                           "code"));
1074    :    // Enclosing.
1075    :    EXPECT_EQ(NULL, address_space.AddBlock(BlockGraph::CODE_BLOCK,
1076    :                                           RelativeAddress(0xFF0),
1077    :                                           0x30,
1078  E :                                           "code"));
1079    :    // Itersecting to end.
1080    :    EXPECT_EQ(NULL, address_space.AddBlock(BlockGraph::CODE_BLOCK,
1081    :                                           RelativeAddress(0x1010),
1082    :                                           0x10,
1083  E :                                           "code"));
1084    :    // Intersecting, overlapping the back.
1085    :    EXPECT_EQ(NULL, address_space.AddBlock(BlockGraph::CODE_BLOCK,
1086    :                                           RelativeAddress(0x1010),
1087    :                                           0x20,
1088  E :                                           "code"));
1089    :  
1090    :    // We should be able to insert blocks above and below the one above.
1091    :    EXPECT_TRUE(address_space.AddBlock(BlockGraph::CODE_BLOCK,
1092    :                                       RelativeAddress(0xFF0),
1093    :                                       0x10,
1094  E :                                       "code") != NULL);
1095    :    EXPECT_TRUE(address_space.AddBlock(BlockGraph::CODE_BLOCK,
1096    :                                       RelativeAddress(0x1020),
1097    :                                       0x10,
1098  E :                                       "code") != NULL);
1099  E :  }
1100    :  
1101  E :  TEST(BlockGraphAddressSpaceTest, InsertBlock) {
1102  E :    BlockGraph image;
1103  E :    BlockGraph::AddressSpace address_space(&image);
1104    :  
1105    :    BlockGraph::Block* block1 =
1106  E :        image.AddBlock(BlockGraph::CODE_BLOCK, 0x10, "code");
1107    :    BlockGraph::Block* block2 =
1108  E :        image.AddBlock(BlockGraph::CODE_BLOCK, 0x10, "code");
1109    :    BlockGraph::Block* block3 =
1110  E :        image.AddBlock(BlockGraph::CODE_BLOCK, 0x10, "code");
1111    :  
1112  E :    ASSERT_TRUE(address_space.InsertBlock(RelativeAddress(0x1000), block1));
1113  E :    ASSERT_FALSE(address_space.InsertBlock(RelativeAddress(0x1000), block2));
1114  E :    ASSERT_TRUE(address_space.InsertBlock(RelativeAddress(0x1010), block2));
1115  E :    ASSERT_FALSE(address_space.InsertBlock(RelativeAddress(0x1018), block3));
1116  E :    ASSERT_TRUE(address_space.InsertBlock(RelativeAddress(0x1030), block3));
1117    :  
1118  E :    RelativeAddress addr;
1119  E :    EXPECT_TRUE(address_space.GetAddressOf(block1, &addr));
1120  E :    EXPECT_EQ(0x1000, addr.value());
1121  E :    EXPECT_EQ(0x1000, block1->addr().value());
1122    :  
1123  E :    EXPECT_TRUE(address_space.GetAddressOf(block2, &addr));
1124  E :    EXPECT_EQ(0x1010, addr.value());
1125  E :    EXPECT_EQ(0x1010, block2->addr().value());
1126    :  
1127  E :    EXPECT_TRUE(address_space.GetAddressOf(block3, &addr));
1128  E :    EXPECT_EQ(0x1030, addr.value());
1129  E :    EXPECT_EQ(0x1030, block3->addr().value());
1130    :  
1131    :    // Insert a block into a second address space.
1132  E :    BlockGraph::AddressSpace address_space2(&image);
1133  E :    EXPECT_TRUE(address_space2.InsertBlock(RelativeAddress(0x2000), block1));
1134  E :    EXPECT_TRUE(address_space.GetAddressOf(block1, &addr));
1135  E :    EXPECT_EQ(0x1000, addr.value());
1136    :  
1137  E :    EXPECT_TRUE(address_space2.GetAddressOf(block1, &addr));
1138  E :    EXPECT_EQ(0x2000, addr.value());
1139    :  
1140  E :    EXPECT_EQ(0x2000, block1->addr().value());
1141  E :  }
1142    :  
1143  E :  TEST(BlockGraphAddressSpaceTest, GetBlockByAddress) {
1144  E :    BlockGraph image;
1145  E :    BlockGraph::AddressSpace address_space(&image);
1146    :  
1147    :    BlockGraph::Block* block1 = address_space.AddBlock(BlockGraph::CODE_BLOCK,
1148    :                                                       RelativeAddress(0x1000),
1149    :                                                       0x10,
1150  E :                                                       "code");
1151    :    BlockGraph::Block* block2 = address_space.AddBlock(BlockGraph::CODE_BLOCK,
1152    :                                                       RelativeAddress(0x1010),
1153    :                                                       0x10,
1154  E :                                                       "code");
1155    :    BlockGraph::Block* block3 = address_space.AddBlock(BlockGraph::CODE_BLOCK,
1156    :                                                       RelativeAddress(0x1030),
1157    :                                                       0x10,
1158  E :                                                       "code");
1159    :  
1160  E :    EXPECT_EQ(NULL, address_space.GetBlockByAddress(RelativeAddress(0xFFF)));
1161    :  
1162  E :    EXPECT_EQ(block1, address_space.GetBlockByAddress(RelativeAddress(0x1000)));
1163  E :    EXPECT_EQ(block1, address_space.GetBlockByAddress(RelativeAddress(0x100F)));
1164    :  
1165  E :    EXPECT_EQ(block2, address_space.GetBlockByAddress(RelativeAddress(0x1010)));
1166  E :    EXPECT_EQ(block2, address_space.GetBlockByAddress(RelativeAddress(0x101F)));
1167    :  
1168  E :    EXPECT_EQ(NULL, address_space.GetBlockByAddress(RelativeAddress(0x1020)));
1169  E :    EXPECT_EQ(NULL, address_space.GetBlockByAddress(RelativeAddress(0x102F)));
1170    :  
1171  E :    EXPECT_EQ(block3, address_space.GetBlockByAddress(RelativeAddress(0x1030)));
1172  E :    EXPECT_EQ(block3, address_space.GetBlockByAddress(RelativeAddress(0x103F)));
1173    :  
1174  E :    EXPECT_EQ(NULL, address_space.GetBlockByAddress(RelativeAddress(0x1040)));
1175  E :  }
1176    :  
1177  E :  TEST(BlockGraphAddressSpaceTest, GetFirstIntersectingBlock) {
1178  E :    BlockGraph image;
1179  E :    BlockGraph::AddressSpace address_space(&image);
1180    :  
1181    :    BlockGraph::Block* block1 = address_space.AddBlock(BlockGraph::CODE_BLOCK,
1182    :                                                       RelativeAddress(0x1000),
1183    :                                                       0x10,
1184  E :                                                       "code");
1185    :    BlockGraph::Block* block2 = address_space.AddBlock(BlockGraph::CODE_BLOCK,
1186    :                                                       RelativeAddress(0x1010),
1187    :                                                       0x10,
1188  E :                                                       "code");
1189    :    BlockGraph::Block* block3 = address_space.AddBlock(BlockGraph::CODE_BLOCK,
1190    :                                                       RelativeAddress(0x1030),
1191    :                                                       0x10,
1192  E :                                                       "code");
1193    :  
1194    :    EXPECT_EQ(NULL,
1195  E :        address_space.GetFirstIntersectingBlock(RelativeAddress(0xFFF), 0x1));
1196    :    EXPECT_EQ(block1,
1197  E :        address_space.GetFirstIntersectingBlock(RelativeAddress(0xFFF), 0x2));
1198    :    EXPECT_EQ(block1,
1199  E :        address_space.GetFirstIntersectingBlock(RelativeAddress(0x100F), 0x1));
1200    :    EXPECT_EQ(block1,
1201  E :        address_space.GetFirstIntersectingBlock(RelativeAddress(0x100F), 0x2));
1202    :  
1203    :    EXPECT_EQ(block2,
1204  E :        address_space.GetFirstIntersectingBlock(RelativeAddress(0x1010), 0x40));
1205  E :  }
1206    :  
1207  E :  TEST(BlockGraphAddressSpaceTest, GetContainingBlock) {
1208  E :    BlockGraph image;
1209  E :    BlockGraph::AddressSpace address_space(&image);
1210  E :    BlockGraph::Block* found_block = NULL;
1211    :  
1212    :    BlockGraph::Block* block1 = address_space.AddBlock(BlockGraph::CODE_BLOCK,
1213    :                                                       RelativeAddress(0x1000),
1214    :                                                       0x10,
1215  E :                                                       "code");
1216    :    BlockGraph::Block* block2 = address_space.AddBlock(BlockGraph::CODE_BLOCK,
1217    :                                                       RelativeAddress(0x1010),
1218    :                                                       0x10,
1219  E :                                                       "code");
1220    :  
1221    :    // Fully contained in block1
1222    :    EXPECT_EQ(block1,
1223  E :              address_space.GetContainingBlock(RelativeAddress(0x1004), 8));
1224    :  
1225    :    // Fully contained in block2
1226    :    EXPECT_EQ(block2,
1227  E :              address_space.GetContainingBlock(RelativeAddress(0x1014), 8));
1228    :  
1229    :    // Starts before but intersects with block1.
1230  E :    EXPECT_EQ(NULL, address_space.GetContainingBlock(RelativeAddress(0x099E), 8));
1231    :  
1232    :    // Starts in the middle of block1 and overlaps into block2.
1233  E :    EXPECT_EQ(NULL, address_space.GetContainingBlock(RelativeAddress(0x100a), 8));
1234  E :  }
1235    :  
1236  E :  TEST(BlockGraphAddressSpaceTest, GetBlockAddress) {
1237  E :    BlockGraph image;
1238  E :    BlockGraph::AddressSpace address_space(&image);
1239    :  
1240    :    BlockGraph::Block* block1 = address_space.AddBlock(BlockGraph::CODE_BLOCK,
1241    :                                                       RelativeAddress(0x1000),
1242    :                                                       0x10,
1243  E :                                                       "code");
1244    :    BlockGraph::Block* block2 = address_space.AddBlock(BlockGraph::CODE_BLOCK,
1245    :                                                       RelativeAddress(0x1010),
1246    :                                                       0x10,
1247  E :                                                       "code");
1248    :    BlockGraph::Block* block3 =
1249  E :        image.AddBlock(BlockGraph::CODE_BLOCK, 0x10, "code");
1250    :  
1251  E :    RelativeAddress addr;
1252  E :    EXPECT_TRUE(address_space.GetAddressOf(block1, &addr));
1253  E :    EXPECT_EQ(0x1000, addr.value());
1254    :  
1255  E :    EXPECT_TRUE(address_space.GetAddressOf(block2, &addr));
1256  E :    EXPECT_EQ(0x1010, addr.value());
1257    :  
1258  E :    EXPECT_FALSE(address_space.GetAddressOf(block3, &addr));
1259  E :  }
1260    :  
1261  E :  TEST(BlockGraphAddressSpaceTest, MergeIntersectingBlocks) {
1262  E :    BlockGraph image;
1263  E :    BlockGraph::AddressSpace address_space(&image);
1264  E :    RelativeAddress addr1(0x1000);
1265  E :    RelativeAddress addr2(0x1010);
1266  E :    RelativeAddress addr3(0x1030);
1267    :    BlockGraph::Block* block1 = address_space.AddBlock(BlockGraph::CODE_BLOCK,
1268    :                                                       addr1,
1269    :                                                       0x10,
1270  E :                                                       "block1");
1271    :    BlockGraph::Block* block2 = address_space.AddBlock(BlockGraph::CODE_BLOCK,
1272    :                                                       addr2,
1273    :                                                       0x10,
1274  E :                                                       "block2");
1275    :    BlockGraph::Block* block3 = address_space.AddBlock(BlockGraph::CODE_BLOCK,
1276    :                                                       addr3,
1277    :                                                       0x10,
1278  E :                                                       "block3");
1279  E :    ASSERT_TRUE(block2->SetLabel(0, "0x1010", BlockGraph::CODE_LABEL));
1280  E :    ASSERT_TRUE(block2->SetLabel(4, "0x1014", BlockGraph::CODE_LABEL));
1281  E :    ASSERT_TRUE(block3->SetLabel(0, "0x1030", BlockGraph::CODE_LABEL));
1282  E :    ASSERT_TRUE(block3->SetLabel(4, "0x1034", BlockGraph::CODE_LABEL));
1283    :  
1284    :    block1->source_ranges().Push(BlockGraph::Block::DataRange(0, 0x10),
1285  E :                                 BlockGraph::Block::SourceRange(addr1, 0x10));
1286    :    block2->source_ranges().Push(BlockGraph::Block::DataRange(0, 0x10),
1287  E :                                 BlockGraph::Block::SourceRange(addr2, 0x10));
1288    :    block3->source_ranges().Push(BlockGraph::Block::DataRange(0, 0x10),
1289  E :                                 BlockGraph::Block::SourceRange(addr3, 0x10));
1290    :  
1291    :    ASSERT_TRUE(block1->SetReference(0x1,
1292  E :        BlockGraph::Reference(BlockGraph::ABSOLUTE_REF, 4, block2, 0x0, 0x0)));
1293    :    ASSERT_TRUE(block1->SetReference(0x6,
1294  E :        BlockGraph::Reference(BlockGraph::ABSOLUTE_REF, 4, block3, 0x0, 0x0)));
1295    :    ASSERT_TRUE(block2->SetReference(0x1,
1296  E :        BlockGraph::Reference(BlockGraph::PC_RELATIVE_REF, 1, block1, 0x4, 0x4)));
1297    :    ASSERT_TRUE(block2->SetReference(0x6,
1298  E :        BlockGraph::Reference(BlockGraph::PC_RELATIVE_REF, 4, block3, 0x4, 0x4)));
1299    :    ASSERT_TRUE(block3->SetReference(0x1,
1300  E :        BlockGraph::Reference(BlockGraph::PC_RELATIVE_REF, 4, block2, 0x4, 0x4)));
1301    :  
1302    :    BlockGraph::Block* merged = address_space.MergeIntersectingBlocks(
1303  E :        BlockGraph::AddressSpace::Range(RelativeAddress(0x1014), 0x30));
1304    :  
1305  E :    ASSERT_TRUE(merged != NULL);
1306  E :    ASSERT_EQ(RelativeAddress(0x1010), merged->addr());
1307  E :    ASSERT_EQ(0x34, merged->size());
1308    :  
1309    :    // Expect the merged block to have meaningful source ranges.
1310  E :    BlockGraph::Block::SourceRanges::RangePairs expected_source_ranges;
1311    :    expected_source_ranges.push_back(
1312    :        std::make_pair(BlockGraph::Block::DataRange(0, 0x10),
1313  E :                       BlockGraph::Block::SourceRange(addr2, 0x10)));
1314    :    expected_source_ranges.push_back(
1315    :        std::make_pair(BlockGraph::Block::DataRange(0x20, 0x10),
1316  E :                       BlockGraph::Block::SourceRange(addr3, 0x10)));
1317    :    EXPECT_THAT(merged->source_ranges().range_pairs(),
1318  E :                testing::ContainerEq(expected_source_ranges));
1319    :  
1320  E :    BlockGraph::Block::LabelMap expected_labels;
1321    :    expected_labels.insert(std::make_pair(
1322  E :        0x00, BlockGraph::Label("0x1010", BlockGraph::CODE_LABEL)));
1323    :    expected_labels.insert(std::make_pair(
1324  E :        0x04, BlockGraph::Label("0x1014", BlockGraph::CODE_LABEL)));
1325    :    expected_labels.insert(std::make_pair(
1326  E :        0x20, BlockGraph::Label("0x1030", BlockGraph::CODE_LABEL)));
1327    :    expected_labels.insert(std::make_pair(
1328  E :        0x24, BlockGraph::Label("0x1034", BlockGraph::CODE_LABEL)));
1329  E :    EXPECT_THAT(merged->labels(), testing::ContainerEq(expected_labels));
1330    :  
1331  E :    BlockGraph::Block::ReferenceMap expected_refs;
1332    :    expected_refs.insert(std::make_pair(0x1,
1333  E :        BlockGraph::Reference(BlockGraph::PC_RELATIVE_REF, 1, block1, 0x4, 0x4)));
1334    :    expected_refs.insert(std::make_pair(0x6,
1335    :        BlockGraph::Reference(BlockGraph::PC_RELATIVE_REF, 4, merged, 0x24,
1336  E :                              0x24)));
1337    :    expected_refs.insert(std::make_pair(0x21,
1338  E :        BlockGraph::Reference(BlockGraph::PC_RELATIVE_REF, 4, merged, 0x4, 0x4)));
1339  E :    EXPECT_THAT(merged->references(), testing::ContainerEq(expected_refs));
1340    :  
1341  E :    expected_refs.clear();
1342    :    expected_refs.insert(std::make_pair(0x1,
1343  E :        BlockGraph::Reference(BlockGraph::ABSOLUTE_REF, 4, merged, 0x0, 0x0)));
1344    :    expected_refs.insert(std::make_pair(0x6,
1345  E :        BlockGraph::Reference(BlockGraph::ABSOLUTE_REF, 4, merged, 0x20, 0x20)));
1346  E :    EXPECT_THAT(block1->references(), testing::ContainerEq(expected_refs));
1347    :  
1348    :    // We expect that the block graph and the address space have the same size,
1349    :    // as MergeIntersectingBlocks deletes the old blocks from the BlockGraph.
1350  E :    EXPECT_EQ(image.blocks().size(), address_space.address_space_impl().size());
1351  E :  }
1352    :  
1353  E :  TEST(BlockGraphAddressSpaceTest, ContainsBlock) {
1354  E :    BlockGraph image;
1355  E :    BlockGraph::AddressSpace address_space(&image);
1356    :    BlockGraph::Block* block =
1357  E :        image.AddBlock(BlockGraph::CODE_BLOCK, 0x10, "code");
1358    :  
1359  E :    ASSERT_FALSE(address_space.ContainsBlock(block));
1360  E :    EXPECT_TRUE(address_space.InsertBlock(RelativeAddress(0x1000), block));
1361  E :    ASSERT_TRUE(address_space.ContainsBlock(block));
1362  E :  }
1363    :  
1364    :  }  // namespace block_graph

Coverage information generated Tue Jun 25 13:56:24 2013.