Coverage for /Syzygy/relink/relink_app_unittest.cc

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

Coverage information generated Wed Dec 11 11:34:16 2013.