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