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