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/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 // This is HRFile.
     26 struct PSHashRecord {
     27   support::ulittle32_t Off; // Offset in the symbol record stream
     28   support::ulittle32_t CRef;
     29 };
     30 
     31 // This struct is defined as `SC` in include/dbicommon.h
     32 struct SectionContrib {
     33   support::ulittle16_t ISect;
     34   char Padding[2];
     35   support::little32_t Off;
     36   support::little32_t Size;
     37   support::ulittle32_t Characteristics;
     38   support::ulittle16_t Imod;
     39   char Padding2[2];
     40   support::ulittle32_t DataCrc;
     41   support::ulittle32_t RelocCrc;
     42 };
     43 
     44 // This struct is defined as `SC2` in include/dbicommon.h
     45 struct SectionContrib2 {
     46   // To guarantee SectionContrib2 is standard layout, we cannot use inheritance.
     47   SectionContrib Base;
     48   support::ulittle32_t ISectCoff;
     49 };
     50 
     51 // This corresponds to the `OMFSegMap` structure.
     52 struct SecMapHeader {
     53   support::ulittle16_t SecCount;    // Number of segment descriptors in table
     54   support::ulittle16_t SecCountLog; // Number of logical segment descriptors
     55 };
     56 
     57 // This corresponds to the `OMFSegMapDesc` structure.  The definition is not
     58 // present in the reference implementation, but the layout is derived from
     59 // code that accesses the fields.
     60 struct SecMapEntry {
     61   support::ulittle16_t Flags; // Descriptor flags.  See OMFSegDescFlags
     62   support::ulittle16_t Ovl;   // Logical overlay number.
     63   support::ulittle16_t Group; // Group index into descriptor array.
     64   support::ulittle16_t Frame;
     65   support::ulittle16_t SecName;       // Byte index of the segment or group name
     66                                       // in the sstSegName table, or 0xFFFF.
     67   support::ulittle16_t ClassName;     // Byte index of the class name in the
     68                                       // sstSegName table, or 0xFFFF.
     69   support::ulittle32_t Offset;        // Byte offset of the logical segment
     70                                       // within the specified physical segment.
     71                                       // If group is set in flags, offset is the
     72                                       // offset of the group.
     73   support::ulittle32_t SecByteLength; // Byte count of the segment or group.
     74 };
     75 
     76 /// Some of the values are stored in bitfields.  Since this needs to be portable
     77 /// across compilers and architectures (big / little endian in particular) we
     78 /// can't use the actual structures below, but must instead do the shifting
     79 /// and masking ourselves.  The struct definitions are provided for reference.
     80 struct DbiFlags {
     81   ///  uint16_t IncrementalLinking : 1; // True if linked incrementally
     82   ///  uint16_t IsStripped : 1;         // True if private symbols were
     83   ///  stripped.
     84   ///  uint16_t HasCTypes : 1;          // True if linked with /debug:ctypes.
     85   ///  uint16_t Reserved : 13;
     86   static const uint16_t FlagIncrementalMask = 0x0001;
     87   static const uint16_t FlagStrippedMask = 0x0002;
     88   static const uint16_t FlagHasCTypesMask = 0x0004;
     89 };
     90 
     91 struct DbiBuildNo {
     92   ///  uint16_t MinorVersion : 8;
     93   ///  uint16_t MajorVersion : 7;
     94   ///  uint16_t NewVersionFormat : 1;
     95   static const uint16_t BuildMinorMask = 0x00FF;
     96   static const uint16_t BuildMinorShift = 0;
     97 
     98   static const uint16_t BuildMajorMask = 0x7F00;
     99   static const uint16_t BuildMajorShift = 8;
    100 };
    101 
    102 /// The fixed size header that appears at the beginning of the DBI Stream.
    103 struct DbiStreamHeader {
    104   support::little32_t VersionSignature;
    105   support::ulittle32_t VersionHeader;
    106 
    107   /// How "old" is this DBI Stream. Should match the age of the PDB InfoStream.
    108   support::ulittle32_t Age;
    109 
    110   /// Global symbol stream #
    111   support::ulittle16_t GlobalSymbolStreamIndex;
    112 
    113   /// See DbiBuildNo structure.
    114   support::ulittle16_t BuildNumber;
    115 
    116   /// Public symbols stream #
    117   support::ulittle16_t PublicSymbolStreamIndex;
    118 
    119   /// version of mspdbNNN.dll
    120   support::ulittle16_t PdbDllVersion;
    121 
    122   /// Symbol records stream #
    123   support::ulittle16_t SymRecordStreamIndex;
    124 
    125   /// rbld number of mspdbNNN.dll
    126   support::ulittle16_t PdbDllRbld;
    127 
    128   /// Size of module info stream
    129   support::little32_t ModiSubstreamSize;
    130 
    131   /// Size of sec. contrib stream
    132   support::little32_t SecContrSubstreamSize;
    133 
    134   /// Size of sec. map substream
    135   support::little32_t SectionMapSize;
    136 
    137   /// Size of file info substream
    138   support::little32_t FileInfoSize;
    139 
    140   /// Size of type server map
    141   support::little32_t TypeServerSize;
    142 
    143   /// Index of MFC Type Server
    144   support::ulittle32_t MFCTypeServerIndex;
    145 
    146   /// Size of DbgHeader info
    147   support::little32_t OptionalDbgHdrSize;
    148 
    149   /// Size of EC stream (what is EC?)
    150   support::little32_t ECSubstreamSize;
    151 
    152   /// See DbiFlags enum.
    153   support::ulittle16_t Flags;
    154 
    155   /// See PDB_MachineType enum.
    156   support::ulittle16_t MachineType;
    157 
    158   /// Pad to 64 bytes
    159   support::ulittle32_t Reserved;
    160 };
    161 static_assert(sizeof(DbiStreamHeader) == 64, "Invalid DbiStreamHeader size!");
    162 
    163 struct SectionContribEntry {
    164   support::ulittle16_t Section;
    165   char Padding1[2];
    166   support::little32_t Offset;
    167   support::little32_t Size;
    168   support::ulittle32_t Characteristics;
    169   support::ulittle16_t ModuleIndex;
    170   char Padding2[2];
    171   support::ulittle32_t DataCrc;
    172   support::ulittle32_t RelocCrc;
    173 };
    174 
    175 /// The header preceeding the File Info Substream of the DBI stream.
    176 struct FileInfoSubstreamHeader {
    177   /// Total # of modules, should match number of records in the ModuleInfo
    178   /// substream.
    179   support::ulittle16_t NumModules;
    180 
    181   /// Total # of source files. This value is not accurate because PDB actually
    182   /// supports more than 64k source files, so we ignore it and compute the value
    183   /// from other stream fields.
    184   support::ulittle16_t NumSourceFiles;
    185 
    186   /// Following this header the File Info Substream is laid out as follows:
    187   ///   ulittle16_t ModIndices[NumModules];
    188   ///   ulittle16_t ModFileCounts[NumModules];
    189   ///   ulittle32_t FileNameOffsets[NumSourceFiles];
    190   ///   char Names[][NumSourceFiles];
    191   /// with the caveat that `NumSourceFiles` cannot be trusted, so
    192   /// it is computed by summing the `ModFileCounts` array.
    193 };
    194 
    195 struct ModInfoFlags {
    196   ///  uint16_t fWritten : 1;   // True if DbiModuleDescriptor is dirty
    197   ///  uint16_t fECEnabled : 1; // Is EC symbolic info present?  (What is EC?)
    198   ///  uint16_t unused : 6;     // Reserved
    199   ///  uint16_t iTSM : 8;       // Type Server Index for this module
    200   static const uint16_t HasECFlagMask = 0x2;
    201 
    202   static const uint16_t TypeServerIndexMask = 0xFF00;
    203   static const uint16_t TypeServerIndexShift = 8;
    204 };
    205 
    206 /// The header preceeding each entry in the Module Info substream of the DBI
    207 /// stream.  Corresponds to the type MODI in the reference implementation.
    208 struct ModuleInfoHeader {
    209   /// Currently opened module. This field is a pointer in the reference
    210   /// implementation, but that won't work on 64-bit systems, and anyway it
    211   /// doesn't make sense to read a pointer from a file. For now it is unused,
    212   /// so just ignore it.
    213   support::ulittle32_t Mod;
    214 
    215   /// First section contribution of this module.
    216   SectionContribEntry SC;
    217 
    218   /// See ModInfoFlags definition.
    219   support::ulittle16_t Flags;
    220 
    221   /// Stream Number of module debug info
    222   support::ulittle16_t ModDiStream;
    223 
    224   /// Size of local symbol debug info in above stream
    225   support::ulittle32_t SymBytes;
    226 
    227   /// Size of C11 line number info in above stream
    228   support::ulittle32_t C11Bytes;
    229 
    230   /// Size of C13 line number info in above stream
    231   support::ulittle32_t C13Bytes;
    232 
    233   /// Number of files contributing to this module
    234   support::ulittle16_t NumFiles;
    235 
    236   /// Padding so the next field is 4-byte aligned.
    237   char Padding1[2];
    238 
    239   /// Array of [0..NumFiles) DBI name buffer offsets.  In the reference
    240   /// implementation this field is a pointer.  But since you can't portably
    241   /// serialize a pointer, on 64-bit platforms they copy all the values except
    242   /// this one into the 32-bit version of the struct and use that for
    243   /// serialization.  Regardless, this field is unused, it is only there to
    244   /// store a pointer that can be accessed at runtime.
    245   support::ulittle32_t FileNameOffs;
    246 
    247   /// Name Index for src file name
    248   support::ulittle32_t SrcFileNameNI;
    249 
    250   /// Name Index for path to compiler PDB
    251   support::ulittle32_t PdbFilePathNI;
    252 
    253   /// Following this header are two zero terminated strings.
    254   /// char ModuleName[];
    255   /// char ObjFileName[];
    256 };
    257 
    258 /// Defines a 128-bit unique identifier.  This maps to a GUID on Windows, but
    259 /// is abstracted here for the purposes of non-Windows platforms that don't have
    260 /// the GUID structure defined.
    261 struct PDB_UniqueId {
    262   uint8_t Guid[16];
    263 };
    264 
    265 inline bool operator==(const PDB_UniqueId &LHS, const PDB_UniqueId &RHS) {
    266   return 0 == ::memcmp(LHS.Guid, RHS.Guid, sizeof(LHS.Guid));
    267 }
    268 
    269 // The header preceeding the global TPI stream.
    270 // This corresponds to `HDR` in PDB/dbi/tpi.h.
    271 struct TpiStreamHeader {
    272   struct EmbeddedBuf {
    273     support::little32_t Off;
    274     support::ulittle32_t Length;
    275   };
    276 
    277   support::ulittle32_t Version;
    278   support::ulittle32_t HeaderSize;
    279   support::ulittle32_t TypeIndexBegin;
    280   support::ulittle32_t TypeIndexEnd;
    281   support::ulittle32_t TypeRecordBytes;
    282 
    283   // The following members correspond to `TpiHash` in PDB/dbi/tpi.h.
    284   support::ulittle16_t HashStreamIndex;
    285   support::ulittle16_t HashAuxStreamIndex;
    286   support::ulittle32_t HashKeySize;
    287   support::ulittle32_t NumHashBuckets;
    288 
    289   EmbeddedBuf HashValueBuffer;
    290   EmbeddedBuf IndexOffsetBuffer;
    291   EmbeddedBuf HashAdjBuffer;
    292 };
    293 
    294 const uint32_t MinTpiHashBuckets = 0x1000;
    295 const uint32_t MaxTpiHashBuckets = 0x40000;
    296 
    297 /// The header preceeding the global PDB Stream (Stream 1)
    298 struct InfoStreamHeader {
    299   support::ulittle32_t Version;
    300   support::ulittle32_t Signature;
    301   support::ulittle32_t Age;
    302   PDB_UniqueId Guid;
    303 };
    304 
    305 /// The header preceeding the /names stream.
    306 struct PDBStringTableHeader {
    307   support::ulittle32_t Signature;   // PDBStringTableSignature
    308   support::ulittle32_t HashVersion; // 1 or 2
    309   support::ulittle32_t ByteSize;    // Number of bytes of names buffer.
    310 };
    311 
    312 const uint32_t PDBStringTableSignature = 0xEFFEEFFE;
    313 
    314 } // namespace pdb
    315 } // namespace llvm
    316 
    317 #endif
    318