Coverage for /Syzygy/pdb/pdb_data.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    :  #ifndef SYZYGY_PDB_PDB_DATA_H_
  16    :  #define SYZYGY_PDB_PDB_DATA_H_
  17    :  
  18    :  #include <windows.h>
  19    :  
  20    :  #include <map>
  21    :  #include <string>
  22    :  #include <vector>
  23    :  
  24    :  #include "base/basictypes.h"
  25    :  #include "syzygy/pdb/pdb_constants.h"
  26    :  
  27    :  namespace pdb {
  28    :  
  29    :  // Pdb Info Stream Header, this is at the start of stream #1.
  30    :  struct PdbInfoHeader70 {
  31    :    // Equal to kPdbCurrentVersion for PDBs seen from VS 9.0.
  32    :    uint32 version;
  33    :    // This looks to be the time of the PDB file creation.
  34    :    uint32 timestamp;
  35    :    // Updated every time the PDB file is written.
  36    :    uint32 pdb_age;
  37    :    // This must match the GUID stored off the image's debug directory.
  38    :    GUID signature;
  39    :  };
  40    :  
  41    :  // A structure that we find in the type info hash header, this is not totally
  42    :  // deciphered yet.
  43    :  struct OffsetCb {
  44    :    uint32 offset;
  45    :    uint32 cb;
  46    :  };
  47    :  
  48    :  // Type Info Stream Hash, this is contained in the type info header. This part
  49    :  // hasn't been deciphered yet (the field names are known but we still need to
  50    :  // find out what their content mean).
  51    :  struct TypeInfoHashHeader {
  52    :    uint16 stream_number;
  53    :    uint16 padding;
  54    :    uint32 hash_key;
  55    :    uint32 cb_hash_buckets;
  56    :    OffsetCb offset_cb_hash_vals;
  57    :    OffsetCb offset_cb_type_info_offset;
  58    :    OffsetCb offset_cb_hash_adj;
  59    :  };
  60    :  
  61    :  // Type Info Stream Header, this is at the beginning of stream #2.
  62    :  // See http://moyix.blogspot.ca/2007_10_01_archive.html
  63    :  struct TypeInfoHeader {
  64    :    uint32 version;
  65    :    uint32 len;
  66    :    uint32 type_min;
  67    :    uint32 type_max;
  68    :    uint32 type_info_data_size;
  69    :    TypeInfoHashHeader type_info_hash;
  70    :  };
  71    :  // We coerce a stream of bytes to this structure, so we require it to be
  72    :  // exactly 56 bytes in size.
  73    :  COMPILE_ASSERT(sizeof(TypeInfoHeader) == 56, pdb_type_info_header_wrong_size);
  74    :  
  75    :  // Dbi Info Stream Header, this is at the start of stream #3.
  76    :  // See http://code.google.com/p/pdbparser/wiki/DBI_Format
  77    :  struct DbiHeader {
  78    :    int32 signature;
  79    :    uint32 version;
  80    :    uint32 age;
  81    :    int16 global_symbol_info_stream;
  82    :    uint16 pdb_dll_version;
  83    :    int16 public_symbol_info_stream;
  84    :    uint16 pdb_dll_build_major;
  85    :    int16 symbol_record_stream;
  86    :    uint16 pdb_dll_build_minor;
  87    :    uint32 gp_modi_size;
  88    :    uint32 section_contribution_size;
  89    :    uint32 section_map_size;
  90    :    uint32 file_info_size;
  91    :    uint32 ts_map_size;
  92    :    uint32 mfc_index;
  93    :    uint32 dbg_header_size;
  94    :    uint32 ec_info_size;
  95    :    uint16 flags;
  96    :    uint16 machine;
  97    :    uint32 reserved;
  98    :  };
  99    :  // We coerce a stream of bytes to this structure, so we require it to be
 100    :  // exactly 64 bytes in size.
 101    :  COMPILE_ASSERT(sizeof(DbiHeader) == 64, pdb_dbi_header_wrong_size);
 102    :  
 103    :  // Dbi Debug Header
 104    :  // See http://ccimetadata.codeplex.com/SourceControl/changeset/view/52123#96529
 105    :  // From introspection, it looks like these are stream numbers or -1 if not
 106    :  // defined.
 107    :  struct DbiDbgHeader {
 108    :    int16 fpo;
 109    :    int16 exception;
 110    :    int16 fixup;
 111    :    int16 omap_to_src;
 112    :    int16 omap_from_src;
 113    :    int16 section_header;
 114    :    int16 token_rid_map;
 115    :    int16 x_data;
 116    :    int16 p_data;
 117    :    int16 new_fpo;
 118    :    int16 section_header_origin;
 119    :  };
 120    :  // We coerce a stream of bytes to this structure, so we require it to be
 121    :  // exactly 22 bytes in size.
 122    :  COMPILE_ASSERT(sizeof(DbiDbgHeader) == 22, pdb_dbidbg_header_wrong_size);
 123    :  
 124    :  // Dbi Section Contrib
 125    :  // Represent an element for the section contrib substream of the Dbi stream.
 126    :  struct DbiSectionContrib {
 127    :    int16 section;
 128    :    int16 pad1;
 129    :    int32 offset;
 130    :    int32 size;
 131    :    uint32 flags;
 132    :    int16 module;
 133    :    int16 pad2;
 134    :    uint32 data_crc;
 135    :    uint32 reloc_crc;
 136    :  };
 137    :  // We coerce a stream of bytes to this structure, so we require it to be
 138    :  // exactly 28 bytes in size.
 139    :  COMPILE_ASSERT(sizeof(DbiSectionContrib) == 28,
 140    :                 pdb_dbi_sectioncontrib_wrong_size);
 141    :  
 142    :  // Dbi Module Info
 143    :  // Represent an element for the module info substream of the Dbi stream. This
 144    :  // struct doesn't contain the full module and object name.
 145    :  struct DbiModuleInfoBase {
 146    :    uint32 opened;
 147    :    DbiSectionContrib section;
 148    :    uint16 flags;
 149    :    int16 stream;
 150    :    uint32 symbol_bytes;
 151    :    uint32 old_lines_bytes;
 152    :    uint32 lines_bytes;
 153    :    int16 num_files;
 154    :    uint16 padding;
 155    :    uint32 offsets;
 156    :    uint32 num_source;
 157    :    uint32 num_compiler;
 158    :    // There are two trailing null-terminated 8-bit strings, the first being the
 159    :    // module_name and the second being the object_name. Then this structure is
 160    :    // padded with zeros to have a length that is a multiple of 4.
 161    :  };
 162    :  // We coerce a stream of bytes to this structure, so we require it to be
 163    :  // exactly 64 bytes in size.
 164    :  COMPILE_ASSERT(sizeof(DbiModuleInfoBase) == 64,
 165    :                 pdb_dbi_moduleinfo_wrong_size);
 166    :  
 167    :  // Dbi Section Map
 168    :  // Represent an element for the section map substream of the Dbi stream.
 169    :  struct DbiSectionMapItem {
 170    :    uint8 flags;
 171    :    uint8 section_type;
 172    :    // This field hasn't been deciphered but it is always 0x00000000 or 0xFFFFFFFF
 173    :    // and modifying it doesn't seem to invalidate the PDB.
 174    :    uint16 unknown_data_1[2];
 175    :    uint16 section_number;
 176    :    // Same thing as for unknown_data_1.
 177    :    uint16 unknown_data_2[2];
 178    :    // Value added to the address offset when calculating the RVA.
 179    :    uint32 rva_offset;
 180    :    uint32 section_length;
 181    :  };
 182    :  // We coerce a stream of bytes to this structure, so we require it to be
 183    :  // exactly 20 bytes in size.
 184    :  COMPILE_ASSERT(sizeof(DbiSectionMapItem) == 20,
 185    :                 pdb_dbi_sectionmapitem_wrong_size);
 186    :  
 187    :  // Multi-Stream Format (MSF) Header
 188    :  // See http://code.google.com/p/pdbparser/wiki/MSF_Format
 189    :  struct PdbHeader {
 190    :    uint8 magic_string[kPdbHeaderMagicStringSize];
 191    :    uint32 page_size;
 192    :    uint32 free_page_map;
 193    :    uint32 num_pages;
 194    :    uint32 directory_size;
 195    :    uint32 reserved;
 196    :    uint32 root_pages[kPdbMaxDirPages];
 197    :  };
 198    :  
 199    :  // This is for parsing the FIXUP stream in PDB files generated with the
 200    :  // '/PROFILE' flag. The form of this struct was inferred from looking at
 201    :  // binary dumps of FIXUP streams and correlating them with the disassembly
 202    :  // of the image they refer to. These efforts are documented here:
 203    :  // http://go/syzygy-fixups
 204    :  struct PdbFixup {
 205    :    enum Type {
 206    :      TYPE_ABSOLUTE = 0x6,
 207    :      TYPE_RELATIVE = 0x7,
 208    :      TYPE_OFFSET_32BIT = 0xB,
 209    :      TYPE_OFFSET_8BIT = 0xD,
 210    :      TYPE_PC_RELATIVE = 0x14,
 211    :    };
 212    :  
 213    :    enum Flags {
 214    :      FLAG_IS_DATA = 0x4000,
 215    :      FLAG_REFERS_TO_CODE = 0x8000,
 216    :      FLAG_UNKNOWN = 0x3fff,
 217    :    };
 218    :  
 219    :    // The fixup header.
 220    :    union {
 221    :      uint32 header;
 222    :      struct {
 223    :        Type type:16;
 224    :        unsigned int flags:16;
 225    :      };
 226    :    };
 227    :    // The location of the reference in the image, stored as an RVA. The reference
 228    :    // will always take 4-bytes in the image.
 229    :    uint32 rva_location;
 230    :    // The base to which this reference is tied, stored as an RVA.
 231    :    uint32 rva_base;
 232    :  
 233    :    // This validates that the fixup is of a known type. Any FIXUP that does not
 234    :    // conform to a type that we have already witnessed in sample data will cause
 235    :    // this to return false.
 236    :    bool ValidHeader() const;
 237    :  
 238    :    // Refers to code as opposed to data.
 239  E :    bool refers_to_code() const { return (flags & FLAG_REFERS_TO_CODE) != 0; }
 240    :  
 241    :    // Is stored in data as opposed to being part of an instruction. This is
 242    :    // not always reported properly, as immediate operands to 'jmp'
 243    :    // instructions in thunks (__imp__function_name) set this bit.
 244  E :    bool is_data() const { return (flags & FLAG_IS_DATA) != 0; }
 245    :  
 246    :    // Returns true if the fixup is an offset from some address.
 247    :    bool is_offset() const;
 248    :  
 249    :    // This function returns the size of the reference as encoded at the
 250    :    // address 'rva_location'.
 251    :    size_t size() const;
 252    :  };
 253    :  // We coerce a stream of bytes to this structure, so we require it to be
 254    :  // exactly 12 bytes in size.
 255    :  COMPILE_ASSERT(sizeof(PdbFixup) == 12, pdb_fixup_wrong_size);
 256    :  
 257    :  }  // namespace pdb
 258    :  
 259    :  #endif  // SYZYGY_PDB_PDB_DATA_H_

Coverage information generated Thu Mar 14 11:53:36 2013.