Coverage for /Syzygy/pe/decomposer.h

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

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    :  // Declares the decomposer, which decomposes a PE file into an ImageLayout and
  16    :  // its corresponding BlockGraph.
  17    :  
  18    :  #ifndef SYZYGY_PE_DECOMPOSER_H_
  19    :  #define SYZYGY_PE_DECOMPOSER_H_
  20    :  
  21    :  #include <windows.h>  // NOLINT
  22    :  #include <dia2.h>
  23    :  #include <vector>
  24    :  
  25    :  #include "syzygy/pdb/pdb_file.h"
  26    :  #include "syzygy/pdb/pdb_stream.h"
  27    :  #include "syzygy/pe/dia_browser.h"
  28    :  #include "syzygy/pe/image_layout.h"
  29    :  #include "syzygy/pe/pe_file.h"
  30    :  
  31    :  namespace pe {
  32    :  
  33    :  // Forward declaration of a helper class where we hide our implementation
  34    :  // details.
  35    :  class DecomposerImpl;
  36    :  
  37    :  class Decomposer {
  38    :   public:
  39    :    struct IntermediateReference;
  40    :    typedef std::vector<IntermediateReference> IntermediateReferences;
  41    :  
  42    :    // The separator that is used between the multiple symbol names that can be
  43    :    // associated with a single label.
  44    :    static const char kLabelNameSep[];
  45    :  
  46    :    // Initialize the decomposer for a given image file.
  47    :    // @param image_file the image file to decompose. This must outlive the
  48    :    //     instance of the decomposer.
  49    :    explicit Decomposer(const PEFile& image_file);
  50    :  
  51    :    // Decomposes the image file into a BlockGraph and an ImageLayout, which
  52    :    // have the breakdown of code and data blocks with typed references and
  53    :    // information on where the blocks resided in the original image,
  54    :    // respectively.
  55    :    // @returns true on success, false on failure.
  56    :    bool Decompose(ImageLayout* image_layout);
  57    :  
  58    :    // @name Mutators.
  59    :    // @{
  60    :    // Sets the PDB path to be used. If this is not called it will be inferred
  61    :    // using the information in the module, and searched for using the OS
  62    :    // search functionality.
  63    :    // @param pdb_path the path to the PDB file to be used in decomposing the
  64    :    //     image.
  65  E :    void set_pdb_path(const base::FilePath& pdb_path) { pdb_path_ = pdb_path; }
  66    :    // @}
  67    :  
  68    :    // @name Accessors
  69    :    // @{
  70    :    // Accessor to the PDB path. If Decompose has been called successfully this
  71    :    // will reflect the path of the PDB file that was used to perform the
  72    :    // decomposition.
  73    :    // @returns the PDB path.
  74  E :    const base::FilePath& pdb_path() const { return pdb_path_; }
  75    :    // @}
  76    :  
  77    :   protected:
  78    :    typedef block_graph::BlockGraph BlockGraph;
  79    :    typedef core::RelativeAddress RelativeAddress;
  80    :  
  81    :    // Searches for (if necessary) the PDB file to be used in the decomposition,
  82    :    // and validates that the file exists and matches the module.
  83    :    bool FindAndValidatePdbPath();
  84    :  
  85    :    // @name Used for round-trip decomposition when a serialized block graph is
  86    :    //     in the PDB. Exposed here for unittesting.
  87    :    // @{
  88    :    static bool LoadBlockGraphFromPdbStream(const PEFile& image_file,
  89    :                                            pdb::PdbStream* block_graph_stream,
  90    :                                            ImageLayout* image_layout);
  91    :    static bool LoadBlockGraphFromPdb(const base::FilePath& pdb_path,
  92    :                                      const PEFile& image_file,
  93    :                                      ImageLayout* image_layout,
  94    :                                      bool* stream_exists);
  95    :    // @}
  96    :  
  97    :    // @name Decomposition steps, in order.
  98    :    // @{
  99    :    // Performs the actual decomposition.
 100    :    bool DecomposeImpl();
 101    :    // Parses PE-related blocks and references.
 102    :    bool CreatePEImageBlocksAndReferences(IntermediateReferences* references);
 103    :    // Creates blocks from the COFF group symbols in the linker symbol stream.
 104    :    bool CreateBlocksFromCoffGroups();
 105    :    // Processes the SectionContribution table, creating code/data blocks from it.
 106    :    bool CreateBlocksFromSectionContribs(IDiaSession* session);
 107    :   // Processes the Compiland table and finds cold blocks.
 108    :    bool FindColdBlocksFromCompilands(IDiaSession* session);
 109    :    // Creates gap blocks to flesh out the image. After this has been run all
 110    :    // references should be resolvable.
 111    :    bool CreateGapBlocks();
 112    :    // Finalizes the given vector of intermediate references.
 113    :    bool FinalizeIntermediateReferences(const IntermediateReferences& references);
 114    :    // Creates inter-block references from fixups.
 115    :    bool CreateReferencesFromFixups(IDiaSession* session);
 116    :    // Processes symbols from the PDB, setting block names and labels. This
 117    :    // step is purely optional and only necessary to provide debug information.
 118    :    // This adds names to blocks, adds code labels and their names, and adds
 119    :    // more informative names to data labels.
 120    :    bool ProcessSymbols(IDiaSymbol* root);
 121    :    // @}
 122    :  
 123    :    // @{
 124    :    // @name Callbacks and context structures used by the COFF group parsing
 125    :    //     mechanism.
 126    :    struct VisitLinkerSymbolContext;
 127    :    bool VisitLinkerSymbol(VisitLinkerSymbolContext* context,
 128    :                           uint16 symbol_length,
 129    :                           uint16 symbol_type,
 130    :                           pdb::PdbStream* stream);
 131    :    // @}
 132    :  
 133    :    // @{
 134    :    // @name Callbacks used when parsing DIA symbols. Symbols only need to be
 135    :    //     parsed for debug information and can be completely ignored otherwise.
 136    :    DiaBrowser::BrowserDirective OnPushFunctionOrThunkSymbol(
 137    :        const DiaBrowser& dia_browser,
 138    :        const DiaBrowser::SymTagVector& sym_tags,
 139    :        const DiaBrowser::SymbolPtrVector& symbols);
 140    :    DiaBrowser::BrowserDirective OnPopFunctionOrThunkSymbol(
 141    :        const DiaBrowser& dia_browser,
 142    :        const DiaBrowser::SymTagVector& sym_tags,
 143    :        const DiaBrowser::SymbolPtrVector& symbols);
 144    :    DiaBrowser::BrowserDirective OnFunctionChildSymbol(
 145    :        const DiaBrowser& dia_browser,
 146    :        const DiaBrowser::SymTagVector& sym_tags,
 147    :        const DiaBrowser::SymbolPtrVector& symbols);
 148    :    DiaBrowser::BrowserDirective OnDataSymbol(
 149    :        const DiaBrowser& dia_browser,
 150    :        const DiaBrowser::SymTagVector& sym_tags,
 151    :        const DiaBrowser::SymbolPtrVector& symbols);
 152    :    DiaBrowser::BrowserDirective OnPublicSymbol(
 153    :        const DiaBrowser& dia_browser,
 154    :        const DiaBrowser::SymTagVector& sym_tags,
 155    :        const DiaBrowser::SymbolPtrVector& symbols);
 156    :    DiaBrowser::BrowserDirective OnLabelSymbol(
 157    :        const DiaBrowser& dia_browser,
 158    :        const DiaBrowser::SymTagVector& sym_tags,
 159    :        const DiaBrowser::SymbolPtrVector& symbols);
 160    :    // @}
 161    :  
 162    :    // @name These are called within the scope of OnFunctionChildSymbol, during
 163    :    //     which current_block_ is always set.
 164    :    // @{
 165    :    DiaBrowser::BrowserDirective OnScopeSymbol(enum SymTagEnum type,
 166    :                                               DiaBrowser::SymbolPtr symbol);
 167    :    DiaBrowser::BrowserDirective OnCallSiteSymbol(DiaBrowser::SymbolPtr symbol);
 168    :    // @}
 169    :  
 170    :    // @name Block creation members.
 171    :    // @{
 172    :    // Creates a new block with the given properties, and attaches the
 173    :    // data to it. This assumes that no conflicting block exists.
 174    :    BlockGraph::Block* CreateBlock(BlockGraph::BlockType type,
 175    :                                   RelativeAddress address,
 176    :                                   BlockGraph::Size size,
 177    :                                   const base::StringPiece& name);
 178    :    // Creates a new block with the given properties, or finds an existing PE
 179    :    // parsed block that subsumes it.
 180    :    BlockGraph::Block* CreateBlockOrFindCoveringPeBlock(
 181    :        BlockGraph::BlockType type,
 182    :        RelativeAddress address,
 183    :        BlockGraph::Size size,
 184    :        const base::StringPiece& name);
 185    :    // Creates a gap block of type @p block_type for the given range. For use by
 186    :    // CreateSectionGapBlocks.
 187    :    bool CreateGapBlock(BlockGraph::BlockType block_type,
 188    :                        RelativeAddress address,
 189    :                        BlockGraph::Size size);
 190    :    // Create blocks of type @p block_type for any gaps in the image
 191    :    // section represented by @p header.
 192    :    bool CreateSectionGapBlocks(const IMAGE_SECTION_HEADER* header,
 193    :                                BlockGraph::BlockType block_type);
 194    :    // @}
 195    :  
 196    :    // The PEFile that is being decomposed.
 197    :    const PEFile& image_file_;
 198    :    // The path to corresponding PDB file.
 199    :    base::FilePath pdb_path_;
 200    :  
 201    :    // @name Temporaries that are only valid while inside DecomposeImpl.
 202    :    //     Prevents us from having to pass these around everywhere.
 203    :    // @{
 204    :    // The image layout we're building.
 205    :    ImageLayout* image_layout_;
 206    :    // The image address space we're decomposing to.
 207    :    BlockGraph::AddressSpace* image_;
 208    :    // @}
 209    :  
 210    :    // Data structures holding the relation between functions and their cold
 211    :    // blocks outside of the function address space.
 212    :    // @{
 213    :    typedef std::map<core::RelativeAddress, BlockGraph::Block*> ColdBlocks;
 214    :    typedef std::map<BlockGraph::Block*, ColdBlocks> ColdBlocksMap;
 215    :    typedef std::map<BlockGraph::Block*, BlockGraph::Block*> ColdBlocksParent;
 216    :    ColdBlocksMap cold_blocks_;
 217    :    ColdBlocksParent cold_blocks_parent_;
 218    :    // @}
 219    :  
 220    :    // @name Temporaries that are only valid while in DiaBrowser.
 221    :    // @{
 222    :    BlockGraph::Block* current_block_;
 223    :    RelativeAddress current_address_;
 224    :    size_t current_scope_count_;
 225    :    // @}
 226    :  };
 227    :  
 228    :  }  // namespace pe
 229    :  
 230    :  #endif  // SYZYGY_PE_DECOMPOSER_H_

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