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

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
90.4%47520.C++source

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    :  // Implements the BasicBlockEntryHookTransform class.
  16    :  
  17    :  #include "syzygy/instrument/transforms/basic_block_entry_hook_transform.h"
  18    :  
  19    :  #include "base/logging.h"
  20    :  #include "syzygy/pe/block_util.h"
  21    :  #include "syzygy/pe/pe_utils.h"
  22    :  #include "syzygy/pe/transforms/add_imports_transform.h"
  23    :  
  24    :  namespace instrument {
  25    :  namespace transforms {
  26    :  
  27    :  const char BasicBlockEntryHookTransform::kDefaultModuleName[] =
  28    :      "basic_block_entry.dll";
  29    :  
  30    :  const char BasicBlockEntryHookTransform::kDefaultFunctionName[] =
  31    :      "_basic_block_enter";
  32    :  
  33    :  const char BasicBlockEntryHookTransform::kTransformName[] =
  34    :      "BasicBlockEntryHookTransform";
  35    :  
  36    :  BasicBlockEntryHookTransform::BasicBlockEntryHookTransform()
  37  E :      : module_name_(kDefaultModuleName), function_name_(kDefaultFunctionName) {
  38  E :  }
  39    :  
  40    :  BasicBlockEntryHookTransform::BasicBlockEntryHookTransform(
  41    :      const base::StringPiece& module_name,
  42    :      const base::StringPiece& function_name)
  43    :          : module_name_(module_name.begin(), module_name.end()),
  44  E :            function_name_(function_name.begin(), function_name.end()) {
  45  E :    DCHECK(!module_name.empty());
  46  E :    DCHECK(!function_name.empty());
  47  E :  }
  48    :  
  49    :  bool BasicBlockEntryHookTransform::PreBlockGraphIteration(
  50    :      BlockGraph* block_graph,
  51  E :      BlockGraph::Block* header_block) {
  52  E :    pe::transforms::AddImportsTransform::ImportedModule module(module_name_);
  53  E :    size_t function_index = module.AddSymbol(function_name_);
  54    :  
  55  E :    pe::transforms::AddImportsTransform add_imports;
  56  E :    add_imports.AddModule(&module);
  57    :  
  58  E :    if (!ApplyBlockGraphTransform(&add_imports, block_graph, header_block)) {
  59  i :      LOG(ERROR) << "Unable to add import entry for basic-block hook function.";
  60  i :      return false;
  61    :    }
  62    :  
  63  E :    if (!module.GetSymbolReference(function_index, &bb_entry_hook_ref_)) {
  64  i :      LOG(ERROR) << "Unable to get reference to basic-block entry hook import "
  65    :                 << module_name_ << ":" << function_name_ << ".";
  66  i :      return false;
  67    :    }
  68    :  
  69  E :    DCHECK(bb_entry_hook_ref_.IsValid());
  70    :  
  71  E :    return true;
  72  E :  }
  73    :  
  74    :  bool BasicBlockEntryHookTransform::OnBlock(BlockGraph* block_graph,
  75  E :                                             BlockGraph::Block* block) {
  76  E :    DCHECK(block_graph != NULL);
  77  E :    DCHECK(block != NULL);
  78    :  
  79  E :    if (block->type() != BlockGraph::CODE_BLOCK)
  80  E :      return true;
  81    :  
  82  E :    if (!pe::CodeBlockIsBasicBlockDecomposable(block))
  83  E :      return true;
  84    :  
  85  E :    if (!ApplyBasicBlockSubGraphTransform(this, block_graph, block, NULL))
  86  i :      return false;
  87    :  
  88  E :    return true;
  89  E :  }
  90    :  
  91    :  bool BasicBlockEntryHookTransform::TransformBasicBlockSubGraph(
  92  E :      BlockGraph* block_graph , BasicBlockSubGraph* subgraph) {
  93  E :    DCHECK(block_graph != NULL);
  94  E :    DCHECK(subgraph != NULL);
  95  E :    DCHECK(bb_entry_hook_ref_.IsValid());
  96    :  
  97    :    // Insert a call to the basic-block entry hook at the top of each code
  98    :    // basic-block. We use the id_generator_ to assign an ID to each basic-block.
  99    :    BasicBlockSubGraph::BBCollection::iterator it =
 100  E :        subgraph->basic_blocks().begin();
 101  E :    for (; it != subgraph->basic_blocks().end(); ++it) {
 102  E :      BasicBlock& bb = it->second;
 103  E :      if (bb.type() != BasicBlock::BASIC_CODE_BLOCK)
 104  E :        continue;
 105    :  
 106    :      block_graph::BasicBlockAssembler bb_asm(bb.instructions().begin(),
 107  E :                                              &bb.instructions());
 108    :  
 109  E :      bb_asm.push(block_graph::Immediate(bb_addresses_.size(), core::kSize32Bit));
 110    :      bb_asm.call(block_graph::Immediate(bb_entry_hook_ref_.referenced(),
 111  E :                                         bb_entry_hook_ref_.offset()));
 112    :  
 113    :      // Find the source range associated with this basic-block and translate
 114    :      // that to an RVA.
 115    :      // TODO(rogerm): Replace this with a call to request the RVA directly from
 116    :      //     a basic-block, once that call becomes available.
 117    :      const BlockGraph::Block::SourceRanges::RangePair* bb_range_pair =
 118    :          subgraph->original_block()->source_ranges().FindRangePair(
 119  E :              BlockGraph::Block::SourceRanges::SourceRange(bb.offset(), 1));
 120  E :      DCHECK(bb_range_pair != NULL);
 121  E :      const BlockGraph::Block::DataRange& data_range = bb_range_pair->first;
 122  E :      const BlockGraph::Block::SourceRange& src_range = bb_range_pair->second;
 123    :      core::RelativeAddress bb_addr = src_range.start() +
 124  E :          (bb.offset() - data_range.start());
 125    :  
 126    :      // Add the basic-block address to the id-to-address vector.
 127  E :      bb_addresses_.push_back(bb_addr);
 128  E :    }
 129    :  
 130  E :    return true;
 131  E :  }
 132    :  
 133    :  }  // namespace transforms
 134    :  }  // namespace instrument

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