1 //===- CodeView.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 // Defines constants and basic types describing CodeView debug information. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_DEBUGINFO_CODEVIEW_CODEVIEW_H 14 #define LLVM_DEBUGINFO_CODEVIEW_CODEVIEW_H 15 16 #include <cinttypes> 17 #include <type_traits> 18 19 #include "llvm/Support/Endian.h" 20 21 namespace llvm { 22 namespace codeview { 23 24 /// Distinguishes individual records in .debug$T or .debug$P section or PDB type 25 /// stream. The documentation and headers talk about this as the "leaf" type. 26 enum class TypeRecordKind : uint16_t { 27 #define TYPE_RECORD(lf_ename, value, name) name = value, 28 #include "CodeViewTypes.def" 29 }; 30 31 /// Duplicate copy of the above enum, but using the official CV names. Useful 32 /// for reference purposes and when dealing with unknown record types. 33 enum TypeLeafKind : uint16_t { 34 #define CV_TYPE(name, val) name = val, 35 #include "CodeViewTypes.def" 36 }; 37 38 /// Distinguishes individual records in the Symbols subsection of a .debug$S 39 /// section. Equivalent to SYM_ENUM_e in cvinfo.h. 40 enum class SymbolRecordKind : uint16_t { 41 #define SYMBOL_RECORD(lf_ename, value, name) name = value, 42 #include "CodeViewSymbols.def" 43 }; 44 45 /// Duplicate copy of the above enum, but using the official CV names. Useful 46 /// for reference purposes and when dealing with unknown record types. 47 enum SymbolKind : uint16_t { 48 #define CV_SYMBOL(name, val) name = val, 49 #include "CodeViewSymbols.def" 50 }; 51 52 #define CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(Class) \ 53 inline Class operator|(Class a, Class b) { \ 54 return static_cast<Class>( \ 55 static_cast<std::underlying_type<Class>::type>(a) | \ 56 static_cast<std::underlying_type<Class>::type>(b)); \ 57 } \ 58 inline Class operator&(Class a, Class b) { \ 59 return static_cast<Class>( \ 60 static_cast<std::underlying_type<Class>::type>(a) & \ 61 static_cast<std::underlying_type<Class>::type>(b)); \ 62 } \ 63 inline Class operator~(Class a) { \ 64 return static_cast<Class>( \ 65 ~static_cast<std::underlying_type<Class>::type>(a)); \ 66 } \ 67 inline Class &operator|=(Class &a, Class b) { \ 68 a = a | b; \ 69 return a; \ 70 } \ 71 inline Class &operator&=(Class &a, Class b) { \ 72 a = a & b; \ 73 return a; \ 74 } 75 76 /// These values correspond to the CV_CPU_TYPE_e enumeration, and are documented 77 /// here: https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx 78 enum class CPUType : uint16_t { 79 Intel8080 = 0x0, 80 Intel8086 = 0x1, 81 Intel80286 = 0x2, 82 Intel80386 = 0x3, 83 Intel80486 = 0x4, 84 Pentium = 0x5, 85 PentiumPro = 0x6, 86 Pentium3 = 0x7, 87 MIPS = 0x10, 88 MIPS16 = 0x11, 89 MIPS32 = 0x12, 90 MIPS64 = 0x13, 91 MIPSI = 0x14, 92 MIPSII = 0x15, 93 MIPSIII = 0x16, 94 MIPSIV = 0x17, 95 MIPSV = 0x18, 96 M68000 = 0x20, 97 M68010 = 0x21, 98 M68020 = 0x22, 99 M68030 = 0x23, 100 M68040 = 0x24, 101 Alpha = 0x30, 102 Alpha21164 = 0x31, 103 Alpha21164A = 0x32, 104 Alpha21264 = 0x33, 105 Alpha21364 = 0x34, 106 PPC601 = 0x40, 107 PPC603 = 0x41, 108 PPC604 = 0x42, 109 PPC620 = 0x43, 110 PPCFP = 0x44, 111 PPCBE = 0x45, 112 SH3 = 0x50, 113 SH3E = 0x51, 114 SH3DSP = 0x52, 115 SH4 = 0x53, 116 SHMedia = 0x54, 117 ARM3 = 0x60, 118 ARM4 = 0x61, 119 ARM4T = 0x62, 120 ARM5 = 0x63, 121 ARM5T = 0x64, 122 ARM6 = 0x65, 123 ARM_XMAC = 0x66, 124 ARM_WMMX = 0x67, 125 ARM7 = 0x68, 126 ARM64 = 0x69, 127 Omni = 0x70, 128 Ia64 = 0x80, 129 Ia64_2 = 0x81, 130 CEE = 0x90, 131 AM33 = 0xa0, 132 M32R = 0xb0, 133 TriCore = 0xc0, 134 X64 = 0xd0, 135 EBC = 0xe0, 136 Thumb = 0xf0, 137 ARMNT = 0xf4, 138 D3D11_Shader = 0x100, 139 }; 140 141 /// These values correspond to the CV_CFL_LANG enumeration, and are documented 142 /// here: https://msdn.microsoft.com/en-us/library/bw3aekw6.aspx 143 enum SourceLanguage : uint8_t { 144 C = 0x00, 145 Cpp = 0x01, 146 Fortran = 0x02, 147 Masm = 0x03, 148 Pascal = 0x04, 149 Basic = 0x05, 150 Cobol = 0x06, 151 Link = 0x07, 152 Cvtres = 0x08, 153 Cvtpgd = 0x09, 154 CSharp = 0x0a, 155 VB = 0x0b, 156 ILAsm = 0x0c, 157 Java = 0x0d, 158 JScript = 0x0e, 159 MSIL = 0x0f, 160 HLSL = 0x10, 161 162 /// The DMD & Swift compilers emit 'D' and 'S', respectively, for the CV 163 /// source language. Microsoft does not have enumerators for them yet. 164 D = 'D', 165 Swift = 'S', 166 }; 167 168 /// These values correspond to the CV_call_e enumeration, and are documented 169 /// at the following locations: 170 /// https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx 171 /// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680207(v=vs.85).aspx 172 /// 173 enum class CallingConvention : uint8_t { 174 NearC = 0x00, // near right to left push, caller pops stack 175 FarC = 0x01, // far right to left push, caller pops stack 176 NearPascal = 0x02, // near left to right push, callee pops stack 177 FarPascal = 0x03, // far left to right push, callee pops stack 178 NearFast = 0x04, // near left to right push with regs, callee pops stack 179 FarFast = 0x05, // far left to right push with regs, callee pops stack 180 NearStdCall = 0x07, // near standard call 181 FarStdCall = 0x08, // far standard call 182 NearSysCall = 0x09, // near sys call 183 FarSysCall = 0x0a, // far sys call 184 ThisCall = 0x0b, // this call (this passed in register) 185 MipsCall = 0x0c, // Mips call 186 Generic = 0x0d, // Generic call sequence 187 AlphaCall = 0x0e, // Alpha call 188 PpcCall = 0x0f, // PPC call 189 SHCall = 0x10, // Hitachi SuperH call 190 ArmCall = 0x11, // ARM call 191 AM33Call = 0x12, // AM33 call 192 TriCall = 0x13, // TriCore Call 193 SH5Call = 0x14, // Hitachi SuperH-5 call 194 M32RCall = 0x15, // M32R Call 195 ClrCall = 0x16, // clr call 196 Inline = 197 0x17, // Marker for routines always inlined and thus lacking a convention 198 NearVector = 0x18 // near left to right push with regs, callee pops stack 199 }; 200 201 enum class ClassOptions : uint16_t { 202 None = 0x0000, 203 Packed = 0x0001, 204 HasConstructorOrDestructor = 0x0002, 205 HasOverloadedOperator = 0x0004, 206 Nested = 0x0008, 207 ContainsNestedClass = 0x0010, 208 HasOverloadedAssignmentOperator = 0x0020, 209 HasConversionOperator = 0x0040, 210 ForwardReference = 0x0080, 211 Scoped = 0x0100, 212 HasUniqueName = 0x0200, 213 Sealed = 0x0400, 214 Intrinsic = 0x2000 215 }; 216 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ClassOptions) 217 218 enum class FrameProcedureOptions : uint32_t { 219 None = 0x00000000, 220 HasAlloca = 0x00000001, 221 HasSetJmp = 0x00000002, 222 HasLongJmp = 0x00000004, 223 HasInlineAssembly = 0x00000008, 224 HasExceptionHandling = 0x00000010, 225 MarkedInline = 0x00000020, 226 HasStructuredExceptionHandling = 0x00000040, 227 Naked = 0x00000080, 228 SecurityChecks = 0x00000100, 229 AsynchronousExceptionHandling = 0x00000200, 230 NoStackOrderingForSecurityChecks = 0x00000400, 231 Inlined = 0x00000800, 232 StrictSecurityChecks = 0x00001000, 233 SafeBuffers = 0x00002000, 234 EncodedLocalBasePointerMask = 0x0000C000, 235 EncodedParamBasePointerMask = 0x00030000, 236 ProfileGuidedOptimization = 0x00040000, 237 ValidProfileCounts = 0x00080000, 238 OptimizedForSpeed = 0x00100000, 239 GuardCfg = 0x00200000, 240 GuardCfw = 0x00400000 241 }; 242 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(FrameProcedureOptions) 243 244 enum class FunctionOptions : uint8_t { 245 None = 0x00, 246 CxxReturnUdt = 0x01, 247 Constructor = 0x02, 248 ConstructorWithVirtualBases = 0x04 249 }; 250 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(FunctionOptions) 251 252 enum class HfaKind : uint8_t { 253 None = 0x00, 254 Float = 0x01, 255 Double = 0x02, 256 Other = 0x03 257 }; 258 259 /// Source-level access specifier. (CV_access_e) 260 enum class MemberAccess : uint8_t { 261 None = 0, 262 Private = 1, 263 Protected = 2, 264 Public = 3 265 }; 266 267 /// Part of member attribute flags. (CV_methodprop_e) 268 enum class MethodKind : uint8_t { 269 Vanilla = 0x00, 270 Virtual = 0x01, 271 Static = 0x02, 272 Friend = 0x03, 273 IntroducingVirtual = 0x04, 274 PureVirtual = 0x05, 275 PureIntroducingVirtual = 0x06 276 }; 277 278 /// Equivalent to CV_fldattr_t bitfield. 279 enum class MethodOptions : uint16_t { 280 None = 0x0000, 281 AccessMask = 0x0003, 282 MethodKindMask = 0x001c, 283 Pseudo = 0x0020, 284 NoInherit = 0x0040, 285 NoConstruct = 0x0080, 286 CompilerGenerated = 0x0100, 287 Sealed = 0x0200 288 }; 289 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(MethodOptions) 290 291 /// Equivalent to CV_LABEL_TYPE_e. 292 enum class LabelType : uint16_t { 293 Near = 0x0, 294 Far = 0x4, 295 }; 296 297 /// Equivalent to CV_modifier_t. 298 /// TODO: Add flag for _Atomic modifier 299 enum class ModifierOptions : uint16_t { 300 None = 0x0000, 301 Const = 0x0001, 302 Volatile = 0x0002, 303 Unaligned = 0x0004 304 }; 305 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ModifierOptions) 306 307 // If the subsection kind has this bit set, then the linker should ignore it. 308 enum : uint32_t { SubsectionIgnoreFlag = 0x80000000 }; 309 310 enum class DebugSubsectionKind : uint32_t { 311 None = 0, 312 Symbols = 0xf1, 313 Lines = 0xf2, 314 StringTable = 0xf3, 315 FileChecksums = 0xf4, 316 FrameData = 0xf5, 317 InlineeLines = 0xf6, 318 CrossScopeImports = 0xf7, 319 CrossScopeExports = 0xf8, 320 321 // These appear to relate to .Net assembly info. 322 ILLines = 0xf9, 323 FuncMDTokenMap = 0xfa, 324 TypeMDTokenMap = 0xfb, 325 MergedAssemblyInput = 0xfc, 326 327 CoffSymbolRVA = 0xfd, 328 }; 329 330 /// Equivalent to CV_ptrtype_e. 331 enum class PointerKind : uint8_t { 332 Near16 = 0x00, // 16 bit pointer 333 Far16 = 0x01, // 16:16 far pointer 334 Huge16 = 0x02, // 16:16 huge pointer 335 BasedOnSegment = 0x03, // based on segment 336 BasedOnValue = 0x04, // based on value of base 337 BasedOnSegmentValue = 0x05, // based on segment value of base 338 BasedOnAddress = 0x06, // based on address of base 339 BasedOnSegmentAddress = 0x07, // based on segment address of base 340 BasedOnType = 0x08, // based on type 341 BasedOnSelf = 0x09, // based on self 342 Near32 = 0x0a, // 32 bit pointer 343 Far32 = 0x0b, // 16:32 pointer 344 Near64 = 0x0c // 64 bit pointer 345 }; 346 347 /// Equivalent to CV_ptrmode_e. 348 enum class PointerMode : uint8_t { 349 Pointer = 0x00, // "normal" pointer 350 LValueReference = 0x01, // "old" reference 351 PointerToDataMember = 0x02, // pointer to data member 352 PointerToMemberFunction = 0x03, // pointer to member function 353 RValueReference = 0x04 // r-value reference 354 }; 355 356 /// Equivalent to misc lfPointerAttr bitfields. 357 enum class PointerOptions : uint32_t { 358 None = 0x00000000, 359 Flat32 = 0x00000100, 360 Volatile = 0x00000200, 361 Const = 0x00000400, 362 Unaligned = 0x00000800, 363 Restrict = 0x00001000, 364 WinRTSmartPointer = 0x00080000, 365 LValueRefThisPointer = 0x00100000, 366 RValueRefThisPointer = 0x00200000 367 }; 368 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(PointerOptions) 369 370 /// Equivalent to CV_pmtype_e. 371 enum class PointerToMemberRepresentation : uint16_t { 372 Unknown = 0x00, // not specified (pre VC8) 373 SingleInheritanceData = 0x01, // member data, single inheritance 374 MultipleInheritanceData = 0x02, // member data, multiple inheritance 375 VirtualInheritanceData = 0x03, // member data, virtual inheritance 376 GeneralData = 0x04, // member data, most general 377 SingleInheritanceFunction = 0x05, // member function, single inheritance 378 MultipleInheritanceFunction = 0x06, // member function, multiple inheritance 379 VirtualInheritanceFunction = 0x07, // member function, virtual inheritance 380 GeneralFunction = 0x08 // member function, most general 381 }; 382 383 enum class VFTableSlotKind : uint8_t { 384 Near16 = 0x00, 385 Far16 = 0x01, 386 This = 0x02, 387 Outer = 0x03, 388 Meta = 0x04, 389 Near = 0x05, 390 Far = 0x06 391 }; 392 393 enum class WindowsRTClassKind : uint8_t { 394 None = 0x00, 395 RefClass = 0x01, 396 ValueClass = 0x02, 397 Interface = 0x03 398 }; 399 400 /// Corresponds to CV_LVARFLAGS bitfield. 401 enum class LocalSymFlags : uint16_t { 402 None = 0, 403 IsParameter = 1 << 0, 404 IsAddressTaken = 1 << 1, 405 IsCompilerGenerated = 1 << 2, 406 IsAggregate = 1 << 3, 407 IsAggregated = 1 << 4, 408 IsAliased = 1 << 5, 409 IsAlias = 1 << 6, 410 IsReturnValue = 1 << 7, 411 IsOptimizedOut = 1 << 8, 412 IsEnregisteredGlobal = 1 << 9, 413 IsEnregisteredStatic = 1 << 10, 414 }; 415 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(LocalSymFlags) 416 417 /// Corresponds to the CV_PUBSYMFLAGS bitfield. 418 enum class PublicSymFlags : uint32_t { 419 None = 0, 420 Code = 1 << 0, 421 Function = 1 << 1, 422 Managed = 1 << 2, 423 MSIL = 1 << 3, 424 }; 425 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(PublicSymFlags) 426 427 /// Corresponds to the CV_PROCFLAGS bitfield. 428 enum class ProcSymFlags : uint8_t { 429 None = 0, 430 HasFP = 1 << 0, 431 HasIRET = 1 << 1, 432 HasFRET = 1 << 2, 433 IsNoReturn = 1 << 3, 434 IsUnreachable = 1 << 4, 435 HasCustomCallingConv = 1 << 5, 436 IsNoInline = 1 << 6, 437 HasOptimizedDebugInfo = 1 << 7, 438 }; 439 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ProcSymFlags) 440 441 /// Corresponds to COMPILESYM2::Flags bitfield. 442 enum class CompileSym2Flags : uint32_t { 443 None = 0, 444 SourceLanguageMask = 0xFF, 445 EC = 1 << 8, 446 NoDbgInfo = 1 << 9, 447 LTCG = 1 << 10, 448 NoDataAlign = 1 << 11, 449 ManagedPresent = 1 << 12, 450 SecurityChecks = 1 << 13, 451 HotPatch = 1 << 14, 452 CVTCIL = 1 << 15, 453 MSILModule = 1 << 16, 454 }; 455 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(CompileSym2Flags) 456 457 /// Corresponds to COMPILESYM3::Flags bitfield. 458 enum class CompileSym3Flags : uint32_t { 459 None = 0, 460 SourceLanguageMask = 0xFF, 461 EC = 1 << 8, 462 NoDbgInfo = 1 << 9, 463 LTCG = 1 << 10, 464 NoDataAlign = 1 << 11, 465 ManagedPresent = 1 << 12, 466 SecurityChecks = 1 << 13, 467 HotPatch = 1 << 14, 468 CVTCIL = 1 << 15, 469 MSILModule = 1 << 16, 470 Sdl = 1 << 17, 471 PGO = 1 << 18, 472 Exp = 1 << 19, 473 }; 474 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(CompileSym3Flags) 475 476 enum class ExportFlags : uint16_t { 477 None = 0, 478 IsConstant = 1 << 0, 479 IsData = 1 << 1, 480 IsPrivate = 1 << 2, 481 HasNoName = 1 << 3, 482 HasExplicitOrdinal = 1 << 4, 483 IsForwarder = 1 << 5 484 }; 485 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ExportFlags) 486 487 // Corresponds to BinaryAnnotationOpcode enum. 488 enum class BinaryAnnotationsOpCode : uint32_t { 489 Invalid, 490 CodeOffset, 491 ChangeCodeOffsetBase, 492 ChangeCodeOffset, 493 ChangeCodeLength, 494 ChangeFile, 495 ChangeLineOffset, 496 ChangeLineEndDelta, 497 ChangeRangeKind, 498 ChangeColumnStart, 499 ChangeColumnEndDelta, 500 ChangeCodeOffsetAndLineOffset, 501 ChangeCodeLengthAndCodeOffset, 502 ChangeColumnEnd, 503 }; 504 505 // Corresponds to CV_cookietype_e enum. 506 enum class FrameCookieKind : uint8_t { 507 Copy, 508 XorStackPointer, 509 XorFramePointer, 510 XorR13, 511 }; 512 513 // Corresponds to CV_HREG_e enum. 514 enum class RegisterId : uint16_t { 515 #define CV_REGISTERS_ALL 516 #define CV_REGISTER(name, value) name = value, 517 #include "CodeViewRegisters.def" 518 #undef CV_REGISTER 519 #undef CV_REGISTERS_ALL 520 }; 521 522 // Register Ids are shared between architectures in CodeView. CPUType is needed 523 // to map register Id to name. 524 struct CPURegister { 525 CPURegister() = delete; 526 CPURegister(CPUType Cpu, codeview::RegisterId Reg) { 527 this->Cpu = Cpu; 528 this->Reg = Reg; 529 } 530 CPUType Cpu; 531 RegisterId Reg; 532 }; 533 534 /// Two-bit value indicating which register is the designated frame pointer 535 /// register. Appears in the S_FRAMEPROC record flags. 536 enum class EncodedFramePtrReg : uint8_t { 537 None = 0, 538 StackPtr = 1, 539 FramePtr = 2, 540 BasePtr = 3, 541 }; 542 543 RegisterId decodeFramePtrReg(EncodedFramePtrReg EncodedReg, CPUType CPU); 544 545 EncodedFramePtrReg encodeFramePtrReg(RegisterId Reg, CPUType CPU); 546 547 /// These values correspond to the THUNK_ORDINAL enumeration. 548 enum class ThunkOrdinal : uint8_t { 549 Standard, 550 ThisAdjustor, 551 Vcall, 552 Pcode, 553 UnknownLoad, 554 TrampIncremental, 555 BranchIsland 556 }; 557 558 enum class TrampolineType : uint16_t { TrampIncremental, BranchIsland }; 559 560 // These values correspond to the CV_SourceChksum_t enumeration. 561 enum class FileChecksumKind : uint8_t { None, MD5, SHA1, SHA256 }; 562 563 enum LineFlags : uint16_t { 564 LF_None = 0, 565 LF_HaveColumns = 1, // CV_LINES_HAVE_COLUMNS 566 }; 567 568 /// Data in the SUBSEC_FRAMEDATA subection. 569 struct FrameData { 570 support::ulittle32_t RvaStart; 571 support::ulittle32_t CodeSize; 572 support::ulittle32_t LocalSize; 573 support::ulittle32_t ParamsSize; 574 support::ulittle32_t MaxStackSize; 575 support::ulittle32_t FrameFunc; 576 support::ulittle16_t PrologSize; 577 support::ulittle16_t SavedRegsSize; 578 support::ulittle32_t Flags; 579 enum : uint32_t { 580 HasSEH = 1 << 0, 581 HasEH = 1 << 1, 582 IsFunctionStart = 1 << 2, 583 }; 584 }; 585 586 // Corresponds to LocalIdAndGlobalIdPair structure. 587 // This structure information allows cross-referencing between PDBs. For 588 // example, when a PDB is being built during compilation it is not yet known 589 // what other modules may end up in the PDB at link time. So certain types of 590 // IDs may clash between the various compile time PDBs. For each affected 591 // module, a subsection would be put into the PDB containing a mapping from its 592 // local IDs to a single ID namespace for all items in the PDB file. 593 struct CrossModuleExport { 594 support::ulittle32_t Local; 595 support::ulittle32_t Global; 596 }; 597 598 struct CrossModuleImport { 599 support::ulittle32_t ModuleNameOffset; 600 support::ulittle32_t Count; // Number of elements 601 // support::ulittle32_t ids[Count]; // id from referenced module 602 }; 603 604 enum class CodeViewContainer { ObjectFile, Pdb }; 605 606 inline uint32_t alignOf(CodeViewContainer Container) { 607 if (Container == CodeViewContainer::ObjectFile) 608 return 1; 609 return 4; 610 } 611 } 612 } 613 614 #endif 615