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