Coverage for /Syzygy/relink/relink_app_unittest.cc

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

Coverage information generated Thu Jan 14 17:40:38 2016.