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

Coverage information generated Thu Jul 04 09:34:53 2013.