Home | History | Annotate | Download | only in Native
      1 //===- RawTypes.h -----------------------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #ifndef LLVM_DEBUGINFO_PDB_RAW_RAWTYPES_H
     11 #define LLVM_DEBUGINFO_PDB_RAW_RAWTYPES_H
     12 
     13 #include "llvm/DebugInfo/CodeView/GUID.h"
     14 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
     15 #include "llvm/Support/Endian.h"
     16 
     17 namespace llvm {
     18 namespace pdb {
     19 // This struct is defined as "SO" in langapi/include/pdb.h.
     20 struct SectionOffset {
     21   support::ulittle32_t Off;
     22   support::ulittle16_t Isect;
     23   char Padding[2];
     24 };
     25 
     26 /// Header of the hash tables found in the globals and publics sections.
     27 /// Based on GSIHashHdr in
     28 /// https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.h
     29 struct GSIHashHeader {
     30   enum : unsigned {
     31     HdrSignature = ~0U,
     32     HdrVersion = 0xeffe0000 + 19990810,
     33   };
     34   support::ulittle32_t VerSignature;
     35   support::ulittle32_t VerHdr;
     36   support::ulittle32_t HrSize;
     37   support::ulittle32_t NumBuckets;
     38 };
     39 
     40 // This is HRFile.
     41 struct PSHashRecord {
     42   support::ulittle32_t Off; // Offset in the symbol record stream
     43   support::ulittle32_t CRef;
     44 };
     45 
     46 // This struct is defined as `SC` in include/dbicommon.h
     47 struct SectionContrib {
     48   support::ulittle16_t ISect;
     49   char Padding[2];
     50   support::little32_t Off;
     51   support::little32_t Size;
     52   support::ulittle32_t Characteristics;
     53   support::ulittle16_t Imod;
     54   char Padding2[2];
     55   support::ulittle32_t DataCrc;
     56   support::ulittle32_t RelocCrc;
     57 };
     58 
     59 // This struct is defined as `SC2` in include/dbicommon.h
     60 struct SectionContrib2 {
     61   // To guarantee SectionContrib2 is standard layout, we cannot use inheritance.
     62   SectionContrib Base;
     63   support::ulittle32_t ISectCoff;
     64 };
     65 
     66 // This corresponds to the `OMFSegMap` structure.
     67 struct SecMapHeader {
     68   support::ulittle16_t SecCount;    // Number of segment descriptors in table
     69   support::ulittle16_t SecCountLog; // Number of logical segment descriptors
     70 };
     71 
     72 // This corresponds to the `OMFSegMapDesc` structure.  The definition is not
     73 // present in the reference implementation, but the layout is derived from
     74 // code that accesses the fields.
     75 struct SecMapEntry {
     76   support::ulittle16_t Flags; // Descriptor flags.  See OMFSegDescFlags
     77   support::ulittle16_t Ovl;   // Logical overlay number.
     78   support::ulittle16_t Group; // Group index into descriptor array.
     79   support::ulittle16_t Frame;
     80   support::ulittle16_t SecName;       // Byte index of the segment or group name
     81                                       // in the sstSegName table, or 0xFFFF.
     82   support::ulittle16_t ClassName;     // Byte index of the class name in the
     83                                       // sstSegName table, or 0xFFFF.
     84   support::ulittle32_t Offset;        // Byte offset of the logical segment
     85                                       // within the specified physical segment.
     86                                       // If group is set in flags, offset is the
     87                                       // offset of the group.
     88   support::ulittle32_t SecByteLength; // Byte count of the segment or group.
     89 };
     90 
     91 /// Some of the values are stored in bitfields.  Since this needs to be portable
     92 /// across compilers and architectures (big / little endian in particular) we
     93 /// can't use the actual structures below, but must instead do the shifting
     94 /// and masking ourselves.  The struct definitions are provided for reference.
     95 struct DbiFlags {
     96   ///  uint16_t IncrementalLinking : 1; // True if linked incrementally
     97   ///  uint16_t IsStripped : 1;         // True if private symbols were
     98   ///  stripped.
     99   ///  uint16_t HasCTypes : 1;          // True if linked with /debug:ctypes.
    100   ///  uint16_t Reserved : 13;
    101   static const uint16_t FlagIncrementalMask = 0x0001;
    102   static const uint16_t FlagStrippedMask = 0x0002;
    103   static const uint16_t FlagHasCTypesMask = 0x0004;
    104 };
    105 
    106 struct DbiBuildNo {
    107   ///  uint16_t MinorVersion : 8;
    108   ///  uint16_t MajorVersion : 7;
    109   ///  uint16_t NewVersionFormat : 1;
    110   static const uint16_t BuildMinorMask = 0x00FF;
    111   static const uint16_t BuildMinorShift = 0;
    112 
    113   static const uint16_t BuildMajorMask = 0x7F00;
    114   static const uint16_t BuildMajorShift = 8;
    115 
    116   static const uint16_t NewVersionFormatMask = 0x8000;
    117 };
    118 
    119 /// The fixed size header that appears at the beginning of the DBI Stream.
    120 struct DbiStreamHeader {
    121   support::little32_t VersionSignature;
    122   support::ulittle32_t VersionHeader;
    123 
    124   /// How "old" is this DBI Stream. Should match the age of the PDB InfoStream.
    125   support::ulittle32_t Age;
    126 
    127   /// Global symbol stream #
    128   support::ulittle16_t GlobalSymbolStreamIndex;
    129 
    130   /// See DbiBuildNo structure.
    131   support::ulittle16_t BuildNumber;
    132 
    133   /// Public symbols stream #
    134   support::ulittle16_t PublicSymbolStreamIndex;
    135 
    136   /// version of mspdbNNN.dll
    137   support::ulittle16_t PdbDllVersion;
    138 
    139   /// Symbol records stream #
    140   support::ulittle16_t SymRecordStreamIndex;
    141 
    142   /// rbld number of mspdbNNN.dll
    143   support::ulittle16_t PdbDllRbld;
    144 
    145   /// Size of module info stream
    146   support::little32_t ModiSubstreamSize;
    147 
    148   /// Size of sec. contrib stream
    149   support::little32_t SecContrSubstreamSize;
    150 
    151   /// Size of sec. map substream
    152   support::little32_t SectionMapSize;
    153 
    154   /// Size of file info substream
    155   support::little32_t FileInfoSize;
    156 
    157   /// Size of type server map
    158   support::little32_t TypeServerSize;
    159 
    160   /// Index of MFC Type Server
    161   support::ulittle32_t MFCTypeServerIndex;
    162 
    163   /// Size of DbgHeader info
    164   support::little32_t OptionalDbgHdrSize;
    165 
    166   /// Size of EC stream (what is EC?)
    167   support::little32_t ECSubstreamSize;
    168 
    169   /// See DbiFlags enum.
    170   support::ulittle16_t Flags;
    171 
    172   /// See PDB_MachineType enum.
    173   support::ulittle16_t MachineType;
    174 
    175   /// Pad to 64 bytes
    176   support::ulittle32_t Reserved;
    177 };
    178 static_assert(sizeof(DbiStreamHeader) == 64, "Invalid DbiStreamHeader size!");
    179 
    180 /// The header preceeding the File Info Substream of the DBI stream.
    181 struct FileInfoSubstreamHeader {
    182   /// Total # of modules, should match number of records in the ModuleInfo
    183   /// substream.
    184   support::ulittle16_t NumModules;
    185 
    186   /// Total # of source files. This value is not accurate because PDB actually
    187   /// supports more than 64k source files, so we ignore it and compute the value
    188   /// from other stream fields.
    189   support::ulittle16_t NumSourceFiles;
    190 
    191   /// Following this header the File Info Substream is laid out as follows:
    192   ///   ulittle16_t ModIndices[NumModules];
    193   ///   ulittle16_t ModFileCounts[NumModules];
    194   ///   ulittle32_t FileNameOffsets[NumSourceFiles];
    195   ///   char Names[][NumSourceFiles];
    196   /// with the caveat that `NumSourceFiles` cannot be trusted, so
    197   /// it is computed by summing the `ModFileCounts` array.
    198 };
    199 
    200 struct ModInfoFlags {
    201   ///  uint16_t fWritten : 1;   // True if DbiModuleDescriptor is dirty
    202   ///  uint16_t fECEnabled : 1; // Is EC symbolic info present?  (What is EC?)
    203   ///  uint16_t unused : 6;     // Reserved
    204   ///  uint16_t iTSM : 8;       // Type Server Index for this module
    205   static const uint16_t HasECFlagMask = 0x2;
    206 
    207   static const uint16_t TypeServerIndexMask = 0xFF00;
    208   static const uint16_t TypeServerIndexShift = 8;
    209 };
    210 
    211 /// The header preceeding each entry in the Module Info substream of the DBI
    212 /// stream.  Corresponds to the type MODI in the reference implementation.
    213 struct ModuleInfoHeader {
    214   /// Currently opened module. This field is a pointer in the reference
    215   /// implementation, but that won't work on 64-bit systems, and anyway it
    216   /// doesn't make sense to read a pointer from a file. For now it is unused,
    217   /// so just ignore it.
    218   support::ulittle32_t Mod;
    219 
    220   /// First section contribution of this module.
    221   SectionContrib SC;
    222 
    223   /// See ModInfoFlags definition.
    224   support::ulittle16_t Flags;
    225 
    226   /// Stream Number of module debug info
    227   support::ulittle16_t ModDiStream;
    228 
    229   /// Size of local symbol debug info in above stream
    230   support::ulittle32_t SymBytes;
    231 
    232   /// Size of C11 line number info in above stream
    233   support::ulittle32_t C11Bytes;
    234 
    235   /// Size of C13 line number info in above stream
    236   support::ulittle32_t C13Bytes;
    237 
    238   /// Number of files contributing to this module
    239   support::ulittle16_t NumFiles;
    240 
    241   /// Padding so the next field is 4-byte aligned.
    242   char Padding1[2];
    243 
    244   /// Array of [0..NumFiles) DBI name buffer offsets.  In the reference
    245   /// implementation this field is a pointer.  But since you can't portably
    246   /// serialize a pointer, on 64-bit platforms they copy all the values except
    247   /// this one into the 32-bit version of the struct and use that for
    248   /// serialization.  Regardless, this field is unused, it is only there to
    249   /// store a pointer that can be accessed at runtime.
    250   support::ulittle32_t FileNameOffs;
    251 
    252   /// Name Index for src file name
    253   support::ulittle32_t SrcFileNameNI;
    254 
    255   /// Name Index for path to compiler PDB
    256   support::ulittle32_t PdbFilePathNI;
    257 
    258   /// Following this header are two zero terminated strings.
    259   /// char ModuleName[];
    260   /// char ObjFileName[];
    261 };
    262 
    263 // This is PSGSIHDR struct defined in
    264 // https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.h
    265 struct PublicsStreamHeader {
    266   support::ulittle32_t SymHash;
    267   support::ulittle32_t AddrMap;
    268   support::ulittle32_t NumThunks;
    269   support::ulittle32_t SizeOfThunk;
    270   support::ulittle16_t ISectThunkTable;
    271   char Padding[2];
    272   support::ulittle32_t OffThunkTable;
    273   support::ulittle32_t NumSections;
    274 };
    275 
    276 // The header preceeding the global TPI stream.
    277 // This corresponds to `HDR` in PDB/dbi/tpi.h.
    278 struct TpiStreamHeader {
    279   struct EmbeddedBuf {
    280     support::little32_t Off;
    281     support::ulittle32_t Length;
    282   };
    283 
    284   support::ulittle32_t Version;
    285   support::ulittle32_t HeaderSize;
    286   support::ulittle32_t TypeIndexBegin;
    287   support::ulittle32_t TypeIndexEnd;
    288   support::ulittle32_t TypeRecordBytes;
    289 
    290   // The following members correspond to `TpiHash` in PDB/dbi/tpi.h.
    291   support::ulittle16_t HashStreamIndex;
    292   support::ulittle16_t HashAuxStreamIndex;
    293   support::ulittle32_t HashKeySize;
    294   support::ulittle32_t NumHashBuckets;
    295 
    296   EmbeddedBuf HashValueBuffer;
    297   EmbeddedBuf IndexOffsetBuffer;
    298   EmbeddedBuf HashAdjBuffer;
    299 };
    300 
    301 const uint32_t MinTpiHashBuckets = 0x1000;
    302 const uint32_t MaxTpiHashBuckets = 0x40000;
    303 
    304 /// The header preceeding the global PDB Stream (Stream 1)
    305 struct InfoStreamHeader {
    306   support::ulittle32_t Version;
    307   support::ulittle32_t Signature;
    308   support::ulittle32_t Age;
    309   codeview::GUID Guid;
    310 };
    311 
    312 /// The header preceeding the /names stream.
    313 struct PDBStringTableHeader {
    314   support::ulittle32_t Signature;   // PDBStringTableSignature
    315   support::ulittle32_t HashVersion; // 1 or 2
    316   support::ulittle32_t ByteSize;    // Number of bytes of names buffer.
    317 };
    318 
    319 const uint32_t PDBStringTableSignature = 0xEFFEEFFE;
    320 
    321 /// The header preceding the /src/headerblock stream.
    322 struct SrcHeaderBlockHeader {
    323   support::ulittle32_t Version; // PdbRaw_SrcHeaderBlockVer enumeration.
    324   support::ulittle32_t Size;    // Size of entire stream.
    325   uint64_t FileTime;            // Time stamp (Windows FILETIME format).
    326   support::ulittle32_t Age;     // Age
    327   uint8_t Padding[44];          // Pad to 64 bytes.
    328 };
    329 static_assert(sizeof(SrcHeaderBlockHeader) == 64, "Incorrect struct size!");
    330 
    331 /// A single file record entry within the /src/headerblock stream.
    332 struct SrcHeaderBlockEntry {
    333   support::ulittle32_t Size;     // Record Length.
    334   support::ulittle32_t Version;  // PdbRaw_SrcHeaderBlockVer enumeration.
    335   support::ulittle32_t CRC;      // CRC of the original file contents.
    336   support::ulittle32_t FileSize; // Size of original source file.
    337   support::ulittle32_t FileNI;   // String table index of file name.
    338   support::ulittle32_t ObjNI;    // String table index of object name.
    339   support::ulittle32_t VFileNI;  // String table index of virtual file name.
    340   uint8_t Compression;           // PDB_SourceCompression enumeration.
    341   uint8_t IsVirtual;             // Is this a virtual file (injected)?
    342   short Padding;                 // Pad to 4 bytes.
    343   char Reserved[8];
    344 };
    345 
    346 constexpr int I = sizeof(SrcHeaderBlockEntry);
    347 static_assert(sizeof(SrcHeaderBlockEntry) == 40, "Incorrect struct size!");
    348 
    349 } // namespace pdb
    350 } // namespace llvm
    351 
    352 #endif
    353