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