Coverage for /Syzygy/pe/transforms/pe_hot_patching_basic_block_transform.h

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%110.C++source

Line-by-line coverage:

   1    :  // Copyright 2015 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    :  // A basic block subgraph transform that prepares a block for hot patching.
  16    :  //
  17    :  // To make a block hot patchable, we insert five bytes of padding before the
  18    :  // block to accommodate a long jump instruction and make the first instruction
  19    :  // of the block atomically replaceable with a two-byte jump that jumps
  20    :  // to the long jump in the padding. An instruction is atomically replaceable
  21    :  // if it is at least two bytes long and its first two bytes do not cross
  22    :  // a 4-byte boundary. Therefore the alignment of the block will be increased
  23    :  // to at least two and if the block begins with a one-byte instruction, a
  24    :  // two-byte NOP will be prepended and the references referring after the NOP
  25    :  // will refer to the beginning of the block.
  26    :  
  27    :  #ifndef SYZYGY_PE_TRANSFORMS_PE_HOT_PATCHING_BASIC_BLOCK_TRANSFORM_H_
  28    :  #define SYZYGY_PE_TRANSFORMS_PE_HOT_PATCHING_BASIC_BLOCK_TRANSFORM_H_
  29    :  
  30    :  #include <vector>
  31    :  
  32    :  #include "syzygy/block_graph/transforms/iterative_transform.h"
  33    :  
  34    :  namespace pe {
  35    :  namespace transforms {
  36    :  
  37    :  class PEHotPatchingBasicBlockTransform
  38    :      : public block_graph::transforms::NamedBasicBlockSubGraphTransformImpl<
  39    :            PEHotPatchingBasicBlockTransform> {
  40    :   public:
  41    :    typedef block_graph::BlockGraph BlockGraph;
  42    :    typedef block_graph::BasicBlockSubGraph BasicBlockSubGraph;
  43    :    typedef block_graph::TransformPolicyInterface TransformPolicyInterface;
  44    :    typedef BasicBlockSubGraph::BasicCodeBlock BasicCodeBlock;
  45    :  
  46    :    // The transform name.
  47    :    static const char kTransformName[];
  48    :  
  49  E :    PEHotPatchingBasicBlockTransform() {}
  50    :  
  51    :    // BasicBlockSubGraphTransformInterface implementation.
  52    :    // @pre The subgraph must contain a single block that must begin with
  53    :    //     a basic code block.
  54    :    virtual bool TransformBasicBlockSubGraph(
  55    :        const TransformPolicyInterface* policy,
  56    :        BlockGraph* block_graph,
  57    :        BasicBlockSubGraph* bbsg) override;
  58    :  
  59    :   protected:
  60    :    // The length of a long jump instruction. This is the amount of padding that
  61    :    // will be inserted before each block that needs hot patching.
  62    :    static const size_t kLongJumpInstructionLength;
  63    :  
  64    :    // Insert a NOP at the beginning of the code block.
  65    :    // @param code_block The basic code block to insert into.
  66    :    void InsertTwoByteNopAtBlockBeginning(BasicCodeBlock* code_block);
  67    :  
  68    :    // Checks if the first instruction of a basic code block is atomically
  69    :    // replaceable.
  70    :    // @param code_block The basic code block to examine.
  71    :    // @returns true iff the first instruction of the basic code block is
  72    :    //     atomically replaceable.
  73    :    bool IsAtomicallyReplaceableFirstInstruction(BasicCodeBlock* code_block);
  74    :  
  75    :    // Ensures that the first instruction of a block is atomically replaceable.
  76    :    // This function increases the alignment to 2 (if it was lower), checks
  77    :    // the first instruction, and if it is not atomically replaceable
  78    :    // (only one byte long) then prepends a two-byte NOP to the first basic code
  79    :    // block.
  80    :    // @param bbsg The basic block subgraph to change.
  81    :    // @pre The subgraph must contain a single block that must begin with
  82    :    //     a basic code block.
  83    :    void EnsureAtomicallyReplaceableFirstInstruction(BasicBlockSubGraph* bbsg);
  84    :  
  85    :    // Ensures that there is at least kLongJumpInstructionLength padding before
  86    :    // the block represented by the basic block subgraph.
  87    :    // @param block The target block.
  88    :    // @pre The subgraph must contain a single block.
  89    :    void EnsurePaddingForJumpBeforeBlock(BasicBlockSubGraph* bbsg);
  90    :  
  91    :    // Gets the first basic code block of a block in a subgraph according to
  92    :    // the basic block ordering in the block description.
  93    :    // @param bbsg The basic block subgraph to query.
  94    :    // @returns The first code block
  95    :    // @pre The subgraph must contain a single block that must begin with
  96    :    //     a basic code block.
  97    :    BasicCodeBlock* GetFirstBasicCodeBlock(BasicBlockSubGraph* bbsg);
  98    :  
  99    :   private:
 100    :    DISALLOW_COPY_AND_ASSIGN(PEHotPatchingBasicBlockTransform);
 101    :  };
 102    :  
 103    :  }  // namespace transforms
 104    :  }  // namespace pe
 105    :  
 106    :  #endif  // SYZYGY_PE_TRANSFORMS_PE_HOT_PATCHING_BASIC_BLOCK_TRANSFORM_H_

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