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

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