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