Coverage for /Syzygy/instrument/transforms/thunk_import_references_transform_unittest.cc

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

Line-by-line coverage:

   1    :  // Copyright 2012 Google Inc.
   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    :  // Unittests for ThunkImportReferencesTransform.
  16    :  
  17    :  #include "syzygy/instrument/transforms/thunk_import_references_transform.h"
  18    :  
  19    :  #include <vector>
  20    :  
  21    :  #include "base/scoped_temp_dir.h"
  22    :  #include "gtest/gtest.h"
  23    :  #include "syzygy/block_graph/typed_block.h"
  24    :  #include "syzygy/core/unittest_util.h"
  25    :  #include "syzygy/pe/decomposer.h"
  26    :  #include "syzygy/pe/transforms/add_imports_transform.h"
  27    :  
  28    :  namespace instrument {
  29    :  namespace transforms {
  30    :  
  31    :  namespace {
  32    :  
  33    :  using block_graph::BlockGraph;
  34    :  using block_graph::TypedBlock;
  35    :  using core::AbsoluteAddress;
  36    :  using pe::transforms::AddImportsTransform;
  37    :  
  38    :  typedef BlockGraph::Block::ReferrerSet ReferrerSet;
  39    :  
  40    :  // Expose protected members for testing.
  41    :  class TestThunkImportReferencesTransform
  42    :      : public ThunkImportReferencesTransform {
  43    :   public:
  44    :    using ThunkImportReferencesTransform::Thunk;
  45    :  
  46  E :    AddImportsTransform& add_imports_transform() {
  47  E :      return ThunkImportReferencesTransform::add_imports_transform();
  48  E :    }
  49    :  };
  50    :  
  51    :  class ThunkImportReferencesTransformTest : public testing::Test {
  52    :   public:
  53  E :    ThunkImportReferencesTransformTest()
  54    :        : input_image_layout_(&block_graph_), dos_header_block_(NULL) {
  55  E :    }
  56    :  
  57  E :    virtual void SetUp() {
  58  E :      tmp_dir_.CreateUniqueTempDir();
  59  E :      ASSERT_TRUE(input_pe_file_.Init(
  60    :          testing::GetOutputRelativePath(L"test_dll.dll")));
  61  E :      ASSERT_NO_FATAL_FAILURE(Decompose());
  62  E :    }
  63    :  
  64  E :    void Decompose() {
  65    :      // Decompose the input image.
  66  E :      pe::Decomposer decomposer(input_pe_file_);
  67    :      decomposer.set_pdb_path(
  68  E :          FilePath(testing::GetOutputRelativePath(L"test_dll.pdb")));
  69  E :      ASSERT_TRUE(decomposer.Decompose(&input_image_layout_))
  70    :          << "Unable to decompose module: "
  71  E :          << input_pe_file_.path().value();
  72    :  
  73    :      // Get the DOS header block.
  74    :      dos_header_block_ =
  75    :          input_image_layout_.blocks.GetBlockByAddress(
  76  E :              BlockGraph::RelativeAddress(0));
  77  E :      ASSERT_TRUE(dos_header_block_ != NULL)
  78  E :          << "Unable to find the DOS header block.";
  79  E :    }
  80    :  
  81    :   protected:
  82    :    pe::PEFile input_pe_file_;
  83    :    pe::ImageLayout input_image_layout_;
  84    :    BlockGraph block_graph_;
  85    :    BlockGraph::Block* dos_header_block_;
  86    :    ScopedTempDir tmp_dir_;
  87    :  };
  88    :  
  89    :  }  // namespace
  90    :  
  91  E :  TEST_F(ThunkImportReferencesTransformTest, TestImports) {
  92    :    // Check that we don't have a thunks section yet.
  93    :    BlockGraph::Section* null_thunks_section =
  94  E :        block_graph_.FindSection(".thunks");
  95  E :    EXPECT_EQ(NULL, null_thunks_section);
  96    :  
  97  E :    TestThunkImportReferencesTransform transform;
  98    :    ASSERT_TRUE(ApplyBlockGraphTransform(
  99  E :        &transform, &block_graph_, dos_header_block_));
 100    :  
 101    :    // Check that we now have a thunks section.
 102  E :    BlockGraph::Section* thunks_section = block_graph_.FindSection(".thunks");
 103  E :    ASSERT_TRUE(thunks_section != NULL);
 104    :  
 105  E :    BlockGraph::SectionId thunks_section_id = thunks_section->id();
 106    :  
 107    :    // The only CODE_BLOCK referrers to the IAT should be in the thunk section.
 108  E :    AddImportsTransform& ait = transform.add_imports_transform();
 109    :    const ReferrerSet& referrers  =
 110  E :        ait.import_address_table_block()->referrers();
 111  E :    ReferrerSet::const_iterator ref_iter(referrers.begin()),
 112  E :                                ref_end(referrers.end());
 113  E :    for (; ref_iter != ref_end; ++ref_iter) {
 114    :      // Use this check to exclude the NT headers and the IDT blocks.
 115  E :      if (ref_iter->first->type() == BlockGraph::CODE_BLOCK)
 116  E :        EXPECT_EQ(thunks_section_id, ref_iter->first->section());
 117  E :    }
 118  E :  }
 119    :  
 120    :  }  // namespace transforms
 121    :  }  // namespace instrument

Coverage information generated Thu Sep 06 11:30:46 2012.