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 22 namespace llvm { 23 namespace 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. 27 enum 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. 34 enum 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. 41 enum 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. 48 enum 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 79 enum 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 ARM64 = 0x69, 128 Omni = 0x70, 129 Ia64 = 0x80, 130 Ia64_2 = 0x81, 131 CEE = 0x90, 132 AM33 = 0xa0, 133 M32R = 0xb0, 134 TriCore = 0xc0, 135 X64 = 0xd0, 136 EBC = 0xe0, 137 Thumb = 0xf0, 138 ARMNT = 0xf4, 139 D3D11_Shader = 0x100, 140 }; 141 142 /// These values correspond to the CV_CFL_LANG enumeration, and are documented 143 /// here: https://msdn.microsoft.com/en-us/library/bw3aekw6.aspx 144 enum 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 163 /// The DMD compiler emits 'D' for the CV source language. Microsoft doesn't 164 /// have an enumerator for it yet. 165 D = 'D', 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 ProfileGuidedOptimization = 0x00040000, 235 ValidProfileCounts = 0x00080000, 236 OptimizedForSpeed = 0x00100000, 237 GuardCfg = 0x00200000, 238 GuardCfw = 0x00400000 239 }; 240 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(FrameProcedureOptions) 241 242 enum class FunctionOptions : uint8_t { 243 None = 0x00, 244 CxxReturnUdt = 0x01, 245 Constructor = 0x02, 246 ConstructorWithVirtualBases = 0x04 247 }; 248 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(FunctionOptions) 249 250 enum class HfaKind : uint8_t { 251 None = 0x00, 252 Float = 0x01, 253 Double = 0x02, 254 Other = 0x03 255 }; 256 257 /// Source-level access specifier. (CV_access_e) 258 enum class MemberAccess : uint8_t { 259 None = 0, 260 Private = 1, 261 Protected = 2, 262 Public = 3 263 }; 264 265 /// Part of member attribute flags. (CV_methodprop_e) 266 enum class MethodKind : uint8_t { 267 Vanilla = 0x00, 268 Virtual = 0x01, 269 Static = 0x02, 270 Friend = 0x03, 271 IntroducingVirtual = 0x04, 272 PureVirtual = 0x05, 273 PureIntroducingVirtual = 0x06 274 }; 275 276 /// Equivalent to CV_fldattr_t bitfield. 277 enum class MethodOptions : uint16_t { 278 None = 0x0000, 279 AccessMask = 0x0003, 280 MethodKindMask = 0x001c, 281 Pseudo = 0x0020, 282 NoInherit = 0x0040, 283 NoConstruct = 0x0080, 284 CompilerGenerated = 0x0100, 285 Sealed = 0x0200 286 }; 287 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(MethodOptions) 288 289 /// Equivalent to CV_LABEL_TYPE_e. 290 enum class LabelType : uint16_t { 291 Near = 0x0, 292 Far = 0x4, 293 }; 294 295 /// Equivalent to CV_modifier_t. 296 /// TODO: Add flag for _Atomic modifier 297 enum class ModifierOptions : uint16_t { 298 None = 0x0000, 299 Const = 0x0001, 300 Volatile = 0x0002, 301 Unaligned = 0x0004 302 }; 303 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ModifierOptions) 304 305 enum class DebugSubsectionKind : uint32_t { 306 None = 0, 307 Symbols = 0xf1, 308 Lines = 0xf2, 309 StringTable = 0xf3, 310 FileChecksums = 0xf4, 311 FrameData = 0xf5, 312 InlineeLines = 0xf6, 313 CrossScopeImports = 0xf7, 314 CrossScopeExports = 0xf8, 315 316 // These appear to relate to .Net assembly info. 317 ILLines = 0xf9, 318 FuncMDTokenMap = 0xfa, 319 TypeMDTokenMap = 0xfb, 320 MergedAssemblyInput = 0xfc, 321 322 CoffSymbolRVA = 0xfd, 323 }; 324 325 /// Equivalent to CV_ptrtype_e. 326 enum class PointerKind : uint8_t { 327 Near16 = 0x00, // 16 bit pointer 328 Far16 = 0x01, // 16:16 far pointer 329 Huge16 = 0x02, // 16:16 huge pointer 330 BasedOnSegment = 0x03, // based on segment 331 BasedOnValue = 0x04, // based on value of base 332 BasedOnSegmentValue = 0x05, // based on segment value of base 333 BasedOnAddress = 0x06, // based on address of base 334 BasedOnSegmentAddress = 0x07, // based on segment address of base 335 BasedOnType = 0x08, // based on type 336 BasedOnSelf = 0x09, // based on self 337 Near32 = 0x0a, // 32 bit pointer 338 Far32 = 0x0b, // 16:32 pointer 339 Near64 = 0x0c // 64 bit pointer 340 }; 341 342 /// Equivalent to CV_ptrmode_e. 343 enum class PointerMode : uint8_t { 344 Pointer = 0x00, // "normal" pointer 345 LValueReference = 0x01, // "old" reference 346 PointerToDataMember = 0x02, // pointer to data member 347 PointerToMemberFunction = 0x03, // pointer to member function 348 RValueReference = 0x04 // r-value reference 349 }; 350 351 /// Equivalent to misc lfPointerAttr bitfields. 352 enum class PointerOptions : uint32_t { 353 None = 0x00000000, 354 Flat32 = 0x00000100, 355 Volatile = 0x00000200, 356 Const = 0x00000400, 357 Unaligned = 0x00000800, 358 Restrict = 0x00001000, 359 WinRTSmartPointer = 0x00080000 360 }; 361 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(PointerOptions) 362 363 /// Equivalent to CV_pmtype_e. 364 enum class PointerToMemberRepresentation : uint16_t { 365 Unknown = 0x00, // not specified (pre VC8) 366 SingleInheritanceData = 0x01, // member data, single inheritance 367 MultipleInheritanceData = 0x02, // member data, multiple inheritance 368 VirtualInheritanceData = 0x03, // member data, virtual inheritance 369 GeneralData = 0x04, // member data, most general 370 SingleInheritanceFunction = 0x05, // member function, single inheritance 371 MultipleInheritanceFunction = 0x06, // member function, multiple inheritance 372 VirtualInheritanceFunction = 0x07, // member function, virtual inheritance 373 GeneralFunction = 0x08 // member function, most general 374 }; 375 376 enum class VFTableSlotKind : uint8_t { 377 Near16 = 0x00, 378 Far16 = 0x01, 379 This = 0x02, 380 Outer = 0x03, 381 Meta = 0x04, 382 Near = 0x05, 383 Far = 0x06 384 }; 385 386 enum class WindowsRTClassKind : uint8_t { 387 None = 0x00, 388 RefClass = 0x01, 389 ValueClass = 0x02, 390 Interface = 0x03 391 }; 392 393 /// Corresponds to CV_LVARFLAGS bitfield. 394 enum class LocalSymFlags : uint16_t { 395 None = 0, 396 IsParameter = 1 << 0, 397 IsAddressTaken = 1 << 1, 398 IsCompilerGenerated = 1 << 2, 399 IsAggregate = 1 << 3, 400 IsAggregated = 1 << 4, 401 IsAliased = 1 << 5, 402 IsAlias = 1 << 6, 403 IsReturnValue = 1 << 7, 404 IsOptimizedOut = 1 << 8, 405 IsEnregisteredGlobal = 1 << 9, 406 IsEnregisteredStatic = 1 << 10, 407 }; 408 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(LocalSymFlags) 409 410 /// Corresponds to the CV_PUBSYMFLAGS bitfield. 411 enum class PublicSymFlags : uint32_t { 412 None = 0, 413 Code = 1 << 0, 414 Function = 1 << 1, 415 Managed = 1 << 2, 416 MSIL = 1 << 3, 417 }; 418 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(PublicSymFlags) 419 420 /// Corresponds to the CV_PROCFLAGS bitfield. 421 enum class ProcSymFlags : uint8_t { 422 None = 0, 423 HasFP = 1 << 0, 424 HasIRET = 1 << 1, 425 HasFRET = 1 << 2, 426 IsNoReturn = 1 << 3, 427 IsUnreachable = 1 << 4, 428 HasCustomCallingConv = 1 << 5, 429 IsNoInline = 1 << 6, 430 HasOptimizedDebugInfo = 1 << 7, 431 }; 432 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ProcSymFlags) 433 434 /// Corresponds to COMPILESYM2::Flags bitfield. 435 enum class CompileSym2Flags : uint32_t { 436 None = 0, 437 SourceLanguageMask = 0xFF, 438 EC = 1 << 8, 439 NoDbgInfo = 1 << 9, 440 LTCG = 1 << 10, 441 NoDataAlign = 1 << 11, 442 ManagedPresent = 1 << 12, 443 SecurityChecks = 1 << 13, 444 HotPatch = 1 << 14, 445 CVTCIL = 1 << 15, 446 MSILModule = 1 << 16, 447 }; 448 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(CompileSym2Flags) 449 450 /// Corresponds to COMPILESYM3::Flags bitfield. 451 enum class CompileSym3Flags : uint32_t { 452 None = 0, 453 SourceLanguageMask = 0xFF, 454 EC = 1 << 8, 455 NoDbgInfo = 1 << 9, 456 LTCG = 1 << 10, 457 NoDataAlign = 1 << 11, 458 ManagedPresent = 1 << 12, 459 SecurityChecks = 1 << 13, 460 HotPatch = 1 << 14, 461 CVTCIL = 1 << 15, 462 MSILModule = 1 << 16, 463 Sdl = 1 << 17, 464 PGO = 1 << 18, 465 Exp = 1 << 19, 466 }; 467 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(CompileSym3Flags) 468 469 enum class ExportFlags : uint16_t { 470 None = 0, 471 IsConstant = 1 << 0, 472 IsData = 1 << 1, 473 IsPrivate = 1 << 2, 474 HasNoName = 1 << 3, 475 HasExplicitOrdinal = 1 << 4, 476 IsForwarder = 1 << 5 477 }; 478 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ExportFlags) 479 480 // Corresponds to BinaryAnnotationOpcode enum. 481 enum class BinaryAnnotationsOpCode : uint32_t { 482 Invalid, 483 CodeOffset, 484 ChangeCodeOffsetBase, 485 ChangeCodeOffset, 486 ChangeCodeLength, 487 ChangeFile, 488 ChangeLineOffset, 489 ChangeLineEndDelta, 490 ChangeRangeKind, 491 ChangeColumnStart, 492 ChangeColumnEndDelta, 493 ChangeCodeOffsetAndLineOffset, 494 ChangeCodeLengthAndCodeOffset, 495 ChangeColumnEnd, 496 }; 497 498 // Corresponds to CV_cookietype_e enum. 499 enum class FrameCookieKind : uint8_t { 500 Copy, 501 XorStackPointer, 502 XorFramePointer, 503 XorR13, 504 }; 505 506 // Corresponds to CV_HREG_e enum. 507 enum class RegisterId : uint16_t { 508 #define CV_REGISTER(name, value) name = value, 509 #include "CodeViewRegisters.def" 510 #undef CV_REGISTER 511 }; 512 513 /// These values correspond to the THUNK_ORDINAL enumeration. 514 enum class ThunkOrdinal : uint8_t { 515 Standard, 516 ThisAdjustor, 517 Vcall, 518 Pcode, 519 UnknownLoad, 520 TrampIncremental, 521 BranchIsland 522 }; 523 524 enum class TrampolineType : uint16_t { TrampIncremental, BranchIsland }; 525 526 // These values correspond to the CV_SourceChksum_t enumeration. 527 enum class FileChecksumKind : uint8_t { None, MD5, SHA1, SHA256 }; 528 529 enum LineFlags : uint16_t { 530 LF_None = 0, 531 LF_HaveColumns = 1, // CV_LINES_HAVE_COLUMNS 532 }; 533 534 /// Data in the the SUBSEC_FRAMEDATA subection. 535 struct FrameData { 536 support::ulittle32_t RvaStart; 537 support::ulittle32_t CodeSize; 538 support::ulittle32_t LocalSize; 539 support::ulittle32_t ParamsSize; 540 support::ulittle32_t MaxStackSize; 541 support::ulittle32_t FrameFunc; 542 support::ulittle16_t PrologSize; 543 support::ulittle16_t SavedRegsSize; 544 support::ulittle32_t Flags; 545 enum : uint32_t { 546 HasSEH = 1 << 0, 547 HasEH = 1 << 1, 548 IsFunctionStart = 1 << 2, 549 }; 550 }; 551 552 // Corresponds to LocalIdAndGlobalIdPair structure. 553 // This structure information allows cross-referencing between PDBs. For 554 // example, when a PDB is being built during compilation it is not yet known 555 // what other modules may end up in the PDB at link time. So certain types of 556 // IDs may clash between the various compile time PDBs. For each affected 557 // module, a subsection would be put into the PDB containing a mapping from its 558 // local IDs to a single ID namespace for all items in the PDB file. 559 struct CrossModuleExport { 560 support::ulittle32_t Local; 561 support::ulittle32_t Global; 562 }; 563 564 struct CrossModuleImport { 565 support::ulittle32_t ModuleNameOffset; 566 support::ulittle32_t Count; // Number of elements 567 // support::ulittle32_t ids[Count]; // id from referenced module 568 }; 569 570 enum class CodeViewContainer { ObjectFile, Pdb }; 571 572 inline uint32_t alignOf(CodeViewContainer Container) { 573 if (Container == CodeViewContainer::ObjectFile) 574 return 1; 575 return 4; 576 } 577 } 578 } 579 580 #endif 581