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