Coverage for /Syzygy/relink/relink_app_unittest.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%2812810.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/relink/relink_app.h"
  16    :  
  17    :  #include "base/stringprintf.h"
  18    :  #include "gmock/gmock.h"
  19    :  #include "gtest/gtest.h"
  20    :  #include "syzygy/block_graph/basic_block_decomposer.h"
  21    :  #include "syzygy/block_graph/typed_block.h"
  22    :  #include "syzygy/block_graph/unittest_util.h"
  23    :  #include "syzygy/common/unittest_util.h"
  24    :  #include "syzygy/core/unittest_util.h"
  25    :  #include "syzygy/pe/decomposer.h"
  26    :  #include "syzygy/pe/pe_utils.h"
  27    :  #include "syzygy/pe/unittest_util.h"
  28    :  #include "syzygy/reorder/reorderer.h"
  29    :  
  30    :  namespace relink {
  31    :  
  32    :  using block_graph::BlockGraph;
  33    :  using common::Application;
  34    :  using core::RelativeAddress;
  35    :  using ::testing::ScopedLogLevelSaver;
  36    :  
  37    :  namespace {
  38    :  
  39    :  class TestRelinkApp : public RelinkApp {
  40    :   public:
  41    :    using RelinkApp::input_image_path_;
  42    :    using RelinkApp::input_pdb_path_;
  43    :    using RelinkApp::output_image_path_;
  44    :    using RelinkApp::output_pdb_path_;
  45    :    using RelinkApp::order_file_path_;
  46    :    using RelinkApp::seed_;
  47    :    using RelinkApp::padding_;
  48    :    using RelinkApp::no_augment_pdb_;
  49    :    using RelinkApp::compress_pdb_;
  50    :    using RelinkApp::no_strip_strings_;
  51    :    using RelinkApp::output_metadata_;
  52    :    using RelinkApp::overwrite_;
  53    :    using RelinkApp::fuzz_;
  54    :  };
  55    :  
  56    :  typedef common::Application<TestRelinkApp> TestApp;
  57    :  
  58    :  class RelinkAppTest : public testing::PELibUnitTest {
  59    :   public:
  60    :    typedef testing::PELibUnitTest Super;
  61    :  
  62    :    RelinkAppTest()
  63    :        : cmd_line_(base::FilePath(L"relink.exe")),
  64    :          test_impl_(test_app_.implementation()),
  65    :          seed_(1234567),
  66    :          padding_(32),
  67    :          no_augment_pdb_(false),
  68    :          compress_pdb_(false),
  69    :          no_strip_strings_(false),
  70    :          output_metadata_(false),
  71  E :          overwrite_(false) {
  72  E :    }
  73    :  
  74  E :    void SetUp() {
  75  E :      Super::SetUp();
  76    :  
  77    :      // Several of the tests generate progress and (deliberate) error messages
  78    :      // that would otherwise clutter the unittest output.
  79  E :      logging::SetMinLogLevel(logging::LOG_FATAL);
  80    :  
  81    :      // Setup the IO streams.
  82  E :      CreateTemporaryDir(&temp_dir_);
  83  E :      stdin_path_ = temp_dir_.Append(L"NUL");
  84  E :      stdout_path_ = temp_dir_.Append(L"stdout.txt");
  85  E :      stderr_path_ = temp_dir_.Append(L"stderr.txt");
  86  E :      InitStreams(stdin_path_, stdout_path_, stderr_path_);
  87    :  
  88    :      // Initialize the (potential) input and output path values.
  89  E :      abs_input_image_path_ = testing::GetExeRelativePath(testing::kTestDllName);
  90  E :      input_image_path_ = testing::GetRelativePath(abs_input_image_path_);
  91  E :      abs_input_pdb_path_ = testing::GetExeRelativePath(testing::kTestDllPdbName);
  92  E :      input_pdb_path_ = testing::GetRelativePath(abs_input_pdb_path_);
  93  E :      output_image_path_ = temp_dir_.Append(input_image_path_.BaseName());
  94  E :      output_pdb_path_ = temp_dir_.Append(input_pdb_path_.BaseName());
  95  E :      order_file_path_ = temp_dir_.Append(L"order.json");
  96    :  
  97    :      // Point the application at the test's command-line and IO streams.
  98  E :      test_app_.set_command_line(&cmd_line_);
  99  E :      test_app_.set_in(in());
 100  E :      test_app_.set_out(out());
 101  E :      test_app_.set_err(err());
 102  E :    }
 103    :  
 104  E :    void GetDllMain(const pe::ImageLayout& layout, BlockGraph::Block** dll_main) {
 105  E :      ASSERT_TRUE(dll_main != NULL);
 106    :      BlockGraph::Block* dos_header_block = layout.blocks.GetBlockByAddress(
 107  E :          RelativeAddress(0));
 108  E :      ASSERT_TRUE(dos_header_block != NULL);
 109    :      BlockGraph::Block* nt_headers_block =
 110  E :          pe::GetNtHeadersBlockFromDosHeaderBlock(dos_header_block);
 111  E :      ASSERT_TRUE(nt_headers_block != NULL);
 112  E :      block_graph::ConstTypedBlock<IMAGE_NT_HEADERS> nt_headers;
 113  E :      ASSERT_TRUE(nt_headers.Init(0, nt_headers_block));
 114  E :      BlockGraph::Reference dll_main_ref;
 115  E :      ASSERT_TRUE(nt_headers_block->GetReference(
 116    :          nt_headers.OffsetOf(nt_headers->OptionalHeader.AddressOfEntryPoint),
 117    :          &dll_main_ref));
 118  E :      ASSERT_EQ(0u, dll_main_ref.offset());
 119  E :      ASSERT_EQ(0u, dll_main_ref.base());
 120  E :      *dll_main = dll_main_ref.referenced();
 121  E :    }
 122    :  
 123    :    // Stashes the current log-level before each test instance and restores it
 124    :    // after each test completes.
 125    :    ScopedLogLevelSaver log_level_saver;
 126    :  
 127    :    // @name The application under test.
 128    :    // @{
 129    :    TestApp test_app_;
 130    :    TestApp::Implementation& test_impl_;
 131    :    base::FilePath temp_dir_;
 132    :    base::FilePath stdin_path_;
 133    :    base::FilePath stdout_path_;
 134    :    base::FilePath stderr_path_;
 135    :    // @}
 136    :  
 137    :    // @name Command-line and parameters.
 138    :    // @{
 139    :    CommandLine cmd_line_;
 140    :    base::FilePath input_image_path_;
 141    :    base::FilePath input_pdb_path_;
 142    :    base::FilePath output_image_path_;
 143    :    base::FilePath output_pdb_path_;
 144    :    base::FilePath order_file_path_;
 145    :    uint32 seed_;
 146    :    size_t padding_;
 147    :    bool no_augment_pdb_;
 148    :    bool compress_pdb_;
 149    :    bool no_strip_strings_;
 150    :    bool output_metadata_;
 151    :    bool overwrite_;
 152    :    // @}
 153    :  
 154    :    // @name Expected final values of input parameters.
 155    :    // @{
 156    :    base::FilePath abs_input_image_path_;
 157    :    base::FilePath abs_input_pdb_path_;
 158    :    // @}
 159    :  };
 160    :  
 161    :  }  // namespace
 162    :  
 163  E :  TEST_F(RelinkAppTest, GetHelp) {
 164  E :    cmd_line_.AppendSwitch("help");
 165  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 166  E :  }
 167    :  
 168  E :  TEST_F(RelinkAppTest, EmptyCommandLineFails) {
 169  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 170  E :  }
 171    :  
 172  E :  TEST_F(RelinkAppTest, ParseWithNeitherInputNorOrderFails) {
 173  E :    cmd_line_.AppendSwitchPath("output-image", output_image_path_);
 174    :  
 175  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 176  E :  }
 177    :  
 178  E :  TEST_F(RelinkAppTest, ParseWithSeedAndOrderFails) {
 179  E :    cmd_line_.AppendSwitchPath("output-image", output_image_path_);
 180  E :    cmd_line_.AppendSwitchASCII("seed", base::StringPrintf("%d", seed_));
 181  E :    cmd_line_.AppendSwitchPath("order_file", order_file_path_);
 182    :  
 183  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 184  E :  }
 185    :  
 186  E :  TEST_F(RelinkAppTest, ParseWithEmptySeedFails) {
 187  E :    cmd_line_.AppendSwitchPath("output-image", output_image_path_);
 188  E :    cmd_line_.AppendSwitch("seed");
 189    :  
 190  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 191  E :  }
 192    :  
 193  E :  TEST_F(RelinkAppTest, ParseWithInvalidSeedFails) {
 194  E :    cmd_line_.AppendSwitchPath("output-image", output_image_path_);
 195  E :    cmd_line_.AppendSwitchASCII("seed", "hello");
 196    :  
 197  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 198  E :  }
 199    :  
 200  E :  TEST_F(RelinkAppTest, ParseWithEmptyPaddingFails) {
 201  E :    cmd_line_.AppendSwitchPath("output-image", output_image_path_);
 202  E :    cmd_line_.AppendSwitch("padding");
 203    :  
 204  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 205  E :  }
 206    :  
 207  E :  TEST_F(RelinkAppTest, ParseWithInvalidPaddingFails) {
 208  E :    cmd_line_.AppendSwitchPath("output-image", output_image_path_);
 209  E :    cmd_line_.AppendSwitchASCII("padding", "hello");
 210    :  
 211  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 212  E :  }
 213    :  
 214  E :  TEST_F(RelinkAppTest, ParseMinimalCommandLineWithInputDll) {
 215  E :    cmd_line_.AppendSwitchPath("input-image", input_image_path_);
 216  E :    cmd_line_.AppendSwitchPath("output-image", output_image_path_);
 217    :  
 218  E :    EXPECT_TRUE(test_impl_.ParseCommandLine(&cmd_line_));
 219  E :    EXPECT_TRUE(test_impl_.SetUp());
 220  E :  }
 221    :  
 222  E :  TEST_F(RelinkAppTest, ParseMinimalCommandLineWithOrderFile) {
 223    :    // The order file doesn't actually exist, so setup should fail to infer the
 224    :    // input dll.
 225  E :    cmd_line_.AppendSwitchPath("order-file", order_file_path_);
 226  E :    cmd_line_.AppendSwitchPath("output-image", output_image_path_);
 227    :  
 228  E :    EXPECT_TRUE(test_impl_.ParseCommandLine(&cmd_line_));
 229    :  
 230  E :    EXPECT_EQ(0, test_impl_.seed_);
 231  E :    EXPECT_EQ(0, test_impl_.padding_);
 232  E :    EXPECT_FALSE(test_impl_.no_augment_pdb_);
 233  E :    EXPECT_FALSE(test_impl_.compress_pdb_);
 234  E :    EXPECT_FALSE(test_impl_.no_strip_strings_);
 235  E :    EXPECT_TRUE(test_impl_.output_metadata_);
 236  E :    EXPECT_FALSE(test_impl_.overwrite_);
 237  E :    EXPECT_FALSE(test_impl_.fuzz_);
 238    :  
 239  E :    EXPECT_FALSE(test_impl_.SetUp());
 240  E :  }
 241    :  
 242  E :  TEST_F(RelinkAppTest, ParseFullCommandLineWithOrderFile) {
 243    :    // Note that we specify the no-metadata flag, so we expect false below
 244    :    // for the output_metadata_ member. Also note that neither seed nor padding
 245    :    // are given, and should default to 0.
 246  E :    cmd_line_.AppendSwitchPath("output-image", output_image_path_);
 247  E :    cmd_line_.AppendSwitchPath("output-pdb", output_pdb_path_);
 248  E :    cmd_line_.AppendSwitchPath("order-file", order_file_path_);
 249  E :    cmd_line_.AppendSwitch("no-augment-pdb");
 250  E :    cmd_line_.AppendSwitch("compress-pdb");
 251  E :    cmd_line_.AppendSwitch("no-strip-strings");
 252  E :    cmd_line_.AppendSwitch("no-metadata");
 253  E :    cmd_line_.AppendSwitch("overwrite");
 254  E :    cmd_line_.AppendSwitch("fuzz");
 255    :  
 256  E :    EXPECT_TRUE(test_impl_.ParseCommandLine(&cmd_line_));
 257  E :    EXPECT_TRUE(test_impl_.input_image_path_.empty());
 258  E :    EXPECT_TRUE(test_impl_.input_pdb_path_.empty());
 259  E :    EXPECT_EQ(output_image_path_, test_impl_.output_image_path_);
 260  E :    EXPECT_EQ(output_pdb_path_, test_impl_.output_pdb_path_);
 261  E :    EXPECT_EQ(order_file_path_, test_impl_.order_file_path_);
 262  E :    EXPECT_EQ(0, test_impl_.seed_);
 263  E :    EXPECT_EQ(0, test_impl_.padding_);
 264  E :    EXPECT_TRUE(test_impl_.no_augment_pdb_);
 265  E :    EXPECT_TRUE(test_impl_.compress_pdb_);
 266  E :    EXPECT_TRUE(test_impl_.no_strip_strings_);
 267  E :    EXPECT_FALSE(test_impl_.output_metadata_);
 268  E :    EXPECT_TRUE(test_impl_.overwrite_);
 269  E :    EXPECT_TRUE(test_impl_.fuzz_);
 270    :  
 271    :    // The order file doesn't actually exist, so setup should fail to infer the
 272    :    // input dll.
 273  E :    EXPECT_FALSE(test_impl_.SetUp());
 274  E :  }
 275    :  
 276  E :  TEST_F(RelinkAppTest, ParseFullCommandLineWithInputSeedAndMetadata) {
 277    :    // Note that we omit the no-metadata flag, so we expect true below for the
 278    :    // output_metadata_ member.
 279  E :    cmd_line_.AppendSwitchPath("input-image", input_image_path_);
 280  E :    cmd_line_.AppendSwitchPath("input-pdb", input_pdb_path_);
 281  E :    cmd_line_.AppendSwitchPath("output-image", output_image_path_);
 282  E :    cmd_line_.AppendSwitchPath("output-pdb", output_pdb_path_);
 283  E :    cmd_line_.AppendSwitchASCII("seed", base::StringPrintf("%d", seed_));
 284  E :    cmd_line_.AppendSwitchASCII("padding", base::StringPrintf("%d", padding_));
 285  E :    cmd_line_.AppendSwitch("no-augment-pdb");
 286  E :    cmd_line_.AppendSwitch("compress-pdb");
 287  E :    cmd_line_.AppendSwitch("no-strip-strings");
 288  E :    cmd_line_.AppendSwitch("overwrite");
 289  E :    cmd_line_.AppendSwitch("fuzz");
 290    :  
 291  E :    EXPECT_TRUE(test_impl_.ParseCommandLine(&cmd_line_));
 292  E :    EXPECT_EQ(abs_input_image_path_, test_impl_.input_image_path_);
 293  E :    EXPECT_EQ(abs_input_pdb_path_, test_impl_.input_pdb_path_);
 294  E :    EXPECT_EQ(output_image_path_, test_impl_.output_image_path_);
 295  E :    EXPECT_EQ(output_pdb_path_, test_impl_.output_pdb_path_);
 296  E :    EXPECT_TRUE(test_impl_.order_file_path_.empty());
 297  E :    EXPECT_EQ(seed_, test_impl_.seed_);
 298  E :    EXPECT_EQ(padding_, test_impl_.padding_);
 299  E :    EXPECT_TRUE(test_impl_.no_augment_pdb_);
 300  E :    EXPECT_TRUE(test_impl_.compress_pdb_);
 301  E :    EXPECT_TRUE(test_impl_.no_strip_strings_);
 302  E :    EXPECT_TRUE(test_impl_.output_metadata_);
 303  E :    EXPECT_TRUE(test_impl_.overwrite_);
 304  E :    EXPECT_TRUE(test_impl_.fuzz_);
 305    :  
 306    :    // SetUp() has nothing else to infer so it should succeed.
 307  E :    EXPECT_TRUE(test_impl_.SetUp());
 308  E :  }
 309    :  
 310  E :  TEST_F(RelinkAppTest, DeprecatedFlagsSucceeds) {
 311  E :    cmd_line_.AppendSwitchPath("input-dll", input_image_path_);
 312  E :    cmd_line_.AppendSwitchPath("output-dll", output_image_path_);
 313  E :    EXPECT_TRUE(test_impl_.ParseCommandLine(&cmd_line_));
 314    :  
 315  E :    EXPECT_EQ(abs_input_image_path_, test_impl_.input_image_path_);
 316  E :    EXPECT_EQ(output_image_path_, test_impl_.output_image_path_);
 317  E :  }
 318    :  
 319  E :  TEST_F(RelinkAppTest, DeprecatedFlagsConflictingInputsFail) {
 320  E :    cmd_line_.AppendSwitchPath("input-dll", input_image_path_);
 321  E :    cmd_line_.AppendSwitchPath("input-image", input_image_path_);
 322  E :    cmd_line_.AppendSwitchPath("output-dll", output_image_path_);
 323  E :    EXPECT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 324  E :  }
 325    :  
 326  E :  TEST_F(RelinkAppTest, DeprecatedFlagsConflictingOutputsFail) {
 327  E :    cmd_line_.AppendSwitchPath("input-dll", input_image_path_);
 328  E :    cmd_line_.AppendSwitchPath("output-dll", output_image_path_);
 329  E :    cmd_line_.AppendSwitchPath("output-image", output_image_path_);
 330  E :    EXPECT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 331  E :  }
 332    :  
 333  E :  TEST_F(RelinkAppTest, RandomRelink) {
 334  E :    cmd_line_.AppendSwitchPath("input-image", input_image_path_);
 335  E :    cmd_line_.AppendSwitchPath("input-pdb", input_pdb_path_);
 336  E :    cmd_line_.AppendSwitchPath("output-image", output_image_path_);
 337  E :    cmd_line_.AppendSwitchPath("output-pdb", output_pdb_path_);
 338  E :    cmd_line_.AppendSwitchASCII("seed", base::StringPrintf("%d", seed_));
 339  E :    cmd_line_.AppendSwitchASCII("padding", base::StringPrintf("%d", padding_));
 340  E :    cmd_line_.AppendSwitch("overwrite");
 341    :  
 342  E :    ASSERT_EQ(0, test_app_.Run());
 343  E :    ASSERT_NO_FATAL_FAILURE(CheckTestDll(output_image_path_));
 344  E :  }
 345    :  
 346  E :  TEST_F(RelinkAppTest, RandomRelinkBasicBlocks) {
 347  E :    cmd_line_.AppendSwitchPath("input-image", input_image_path_);
 348  E :    cmd_line_.AppendSwitchPath("input-pdb", input_pdb_path_);
 349  E :    cmd_line_.AppendSwitchPath("output-image", output_image_path_);
 350  E :    cmd_line_.AppendSwitchPath("output-pdb", output_pdb_path_);
 351  E :    cmd_line_.AppendSwitchASCII("seed", base::StringPrintf("%d", seed_));
 352  E :    cmd_line_.AppendSwitchASCII("padding", base::StringPrintf("%d", padding_));
 353  E :    cmd_line_.AppendSwitch("overwrite");
 354  E :    cmd_line_.AppendSwitch("basic-blocks");
 355  E :    cmd_line_.AppendSwitch("exclude-bb-padding");
 356    :  
 357  E :    ASSERT_EQ(0, test_app_.Run());
 358  E :    ASSERT_NO_FATAL_FAILURE(CheckTestDll(output_image_path_));
 359  E :  }
 360    :  
 361  E :  TEST_F(RelinkAppTest, RandomRelinkBasicBlocksWithFuzzing) {
 362  E :    cmd_line_.AppendSwitchPath("input-image", input_image_path_);
 363  E :    cmd_line_.AppendSwitchPath("input-pdb", input_pdb_path_);
 364  E :    cmd_line_.AppendSwitchPath("output-image", output_image_path_);
 365  E :    cmd_line_.AppendSwitchPath("output-pdb", output_pdb_path_);
 366  E :    cmd_line_.AppendSwitchASCII("seed", base::StringPrintf("%d", seed_));
 367  E :    cmd_line_.AppendSwitchASCII("padding", base::StringPrintf("%d", padding_));
 368  E :    cmd_line_.AppendSwitch("overwrite");
 369  E :    cmd_line_.AppendSwitch("basic-blocks");
 370  E :    cmd_line_.AppendSwitch("exclude-bb-padding");
 371  E :    cmd_line_.AppendSwitch("fuzz");
 372    :  
 373  E :    ASSERT_EQ(0, test_app_.Run());
 374  E :    ASSERT_NO_FATAL_FAILURE(CheckTestDll(output_image_path_));
 375  E :  }
 376    :  
 377  E :  TEST_F(RelinkAppTest, RelinkBlockOrder) {
 378  E :    pe::PEFile pe_file;
 379  E :    ASSERT_TRUE(pe_file.Init(input_image_path_));
 380    :  
 381  E :    BlockGraph bg;
 382  E :    pe::ImageLayout layout(&bg);
 383  E :    pe::Decomposer decomposer(pe_file);
 384  E :    ASSERT_TRUE(decomposer.Decompose(&layout));
 385    :  
 386    :    // Get the DLL main entry point.
 387  E :    BlockGraph::Block* dll_main_block = NULL;
 388  E :    ASSERT_NO_FATAL_FAILURE(GetDllMain(layout, &dll_main_block));
 389    :  
 390    :    // Build a block-level ordering by placing the DLL main entry point at the
 391    :    // beginning of its section.
 392  E :    BlockGraph::Section* text_section = bg.FindSection(".text");
 393  E :    ASSERT_TRUE(text_section != NULL);
 394  E :    reorder::Reorderer::Order order;
 395  E :    order.sections.resize(1);
 396  E :    order.sections[0].id = text_section->id();
 397  E :    order.sections[0].name = text_section->name();
 398  E :    order.sections[0].characteristics = text_section->characteristics();
 399  E :    order.sections[0].blocks.resize(1);
 400  E :    order.sections[0].blocks[0].block = dll_main_block;
 401    :  
 402    :    // Serialize the order file.
 403  E :    ASSERT_TRUE(order.SerializeToJSON(pe_file, order_file_path_, false));
 404    :  
 405    :    // Order the test DLL using the order file we just created.
 406  E :    cmd_line_.AppendSwitchPath("input-image", input_image_path_);
 407  E :    cmd_line_.AppendSwitchPath("input-pdb", input_pdb_path_);
 408  E :    cmd_line_.AppendSwitchPath("output-image", output_image_path_);
 409  E :    cmd_line_.AppendSwitchPath("output-pdb", output_pdb_path_);
 410  E :    cmd_line_.AppendSwitchPath("order-file", order_file_path_);
 411  E :    ASSERT_EQ(0, test_app_.Run());
 412  E :    ASSERT_NO_FATAL_FAILURE(CheckTestDll(output_image_path_));
 413  E :  }
 414    :  
 415  E :  TEST_F(RelinkAppTest, RelinkTestDataBlockOrder) {
 416    :    // Try a block-level reordering using an actual order file generated by our
 417    :    // test_data dependency.
 418    :  
 419    :    base::FilePath test_dll_order_json =
 420  E :        testing::GetExeTestDataRelativePath(L"test_dll_order.json");
 421    :  
 422  E :    cmd_line_.AppendSwitchPath("input-image", input_image_path_);
 423  E :    cmd_line_.AppendSwitchPath("input-pdb", input_pdb_path_);
 424  E :    cmd_line_.AppendSwitchPath("output-image", output_image_path_);
 425  E :    cmd_line_.AppendSwitchPath("output-pdb", output_pdb_path_);
 426  E :    cmd_line_.AppendSwitchPath("order-file", test_dll_order_json);
 427  E :    ASSERT_EQ(0, test_app_.Run());
 428  E :    ASSERT_NO_FATAL_FAILURE(CheckTestDll(output_image_path_));
 429  E :  }
 430    :  
 431  E :  TEST_F(RelinkAppTest, RelinkBasicBlockOrder) {
 432  E :    pe::PEFile pe_file;
 433  E :    ASSERT_TRUE(pe_file.Init(input_image_path_));
 434    :  
 435  E :    BlockGraph bg;
 436  E :    pe::ImageLayout layout(&bg);
 437  E :    pe::Decomposer decomposer(pe_file);
 438  E :    ASSERT_TRUE(decomposer.Decompose(&layout));
 439    :  
 440    :    // Get the DLL main entry point.
 441  E :    BlockGraph::Block* dll_main_block = NULL;
 442  E :    ASSERT_NO_FATAL_FAILURE(GetDllMain(layout, &dll_main_block));
 443    :  
 444    :    // Build a block-level ordering by splitting the DLL main block into two
 445    :    // blocks, each half in a different section.
 446  E :    BlockGraph::Section* text_section = bg.FindSection(".text");
 447  E :    ASSERT_TRUE(text_section != NULL);
 448  E :    reorder::Reorderer::Order order;
 449  E :    order.sections.resize(2);
 450  E :    order.sections[0].id = text_section->id();
 451  E :    order.sections[0].name = text_section->name();
 452  E :    order.sections[0].characteristics = text_section->characteristics();
 453  E :    order.sections[0].blocks.resize(1);
 454  E :    order.sections[0].blocks[0].block = dll_main_block;
 455  E :    order.sections[1].id = reorder::Reorderer::Order::SectionSpec::kNewSectionId;
 456  E :    order.sections[1].name = ".text2";
 457  E :    order.sections[1].characteristics = text_section->characteristics();
 458  E :    order.sections[1].blocks.resize(1);
 459  E :    order.sections[1].blocks[0].block = dll_main_block;
 460    :  
 461    :    // Decompose the block. Iterate over its basic-blocks and take turns placing
 462    :    // them into each of the two above blocks.
 463  E :    block_graph::BasicBlockSubGraph bbsg;
 464  E :    block_graph::BasicBlockDecomposer bb_decomposer(dll_main_block, &bbsg);
 465  E :    ASSERT_TRUE(bb_decomposer.Decompose());
 466  E :    ASSERT_LE(2u, bbsg.basic_blocks().size());
 467    :    block_graph::BasicBlockSubGraph::BBCollection::const_iterator bb_it =
 468  E :        bbsg.basic_blocks().begin();
 469  E :    for (size_t i = 0; bb_it != bbsg.basic_blocks().end(); ++bb_it, i ^= 1) {
 470    :      order.sections[i].blocks[0].basic_block_offsets.push_back(
 471  E :          (*bb_it)->offset());
 472  E :    }
 473    :  
 474    :    // Serialize the order file.
 475  E :    ASSERT_TRUE(order.SerializeToJSON(pe_file, order_file_path_, false));
 476    :  
 477    :    // Order the test DLL using the order file we just created.
 478  E :    cmd_line_.AppendSwitchPath("input-image", input_image_path_);
 479  E :    cmd_line_.AppendSwitchPath("input-pdb", input_pdb_path_);
 480  E :    cmd_line_.AppendSwitchPath("output-image", output_image_path_);
 481  E :    cmd_line_.AppendSwitchPath("output-pdb", output_pdb_path_);
 482  E :    cmd_line_.AppendSwitchPath("order-file", order_file_path_);
 483  E :    ASSERT_EQ(0, test_app_.Run());
 484  E :    ASSERT_NO_FATAL_FAILURE(CheckTestDll(output_image_path_));
 485  E :  }
 486    :  
 487    :  }  // namespace relink

Coverage information generated Thu Jul 04 09:34:53 2013.