diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 |
| commit | d8e91e46262bc44006913e6796843909f1ac7bcd (patch) | |
| tree | 7d0c143d9b38190e0fa0180805389da22cd834c5 /include/llvm/DebugInfo | |
| parent | b7eb8e35e481a74962664b63dfb09483b200209a (diff) | |
Notes
Diffstat (limited to 'include/llvm/DebugInfo')
118 files changed, 2102 insertions, 970 deletions
diff --git a/include/llvm/DebugInfo/CodeView/CVRecord.h b/include/llvm/DebugInfo/CodeView/CVRecord.h index 9dbeb438f4ae..11ca9ff108de 100644 --- a/include/llvm/DebugInfo/CodeView/CVRecord.h +++ b/include/llvm/DebugInfo/CodeView/CVRecord.h @@ -45,13 +45,8 @@ public: return RecordData.drop_front(sizeof(RecordPrefix)); } - Optional<uint32_t> hash() const { return Hash; } - - void setHash(uint32_t Value) { Hash = Value; } - Kind Type; ArrayRef<uint8_t> RecordData; - Optional<uint32_t> Hash; }; template <typename Kind> struct RemappedRecord { diff --git a/include/llvm/DebugInfo/CodeView/CodeView.h b/include/llvm/DebugInfo/CodeView/CodeView.h index 4ce9f68cffd9..8e0d9f608e93 100644 --- a/include/llvm/DebugInfo/CodeView/CodeView.h +++ b/include/llvm/DebugInfo/CodeView/CodeView.h @@ -231,6 +231,8 @@ enum class FrameProcedureOptions : uint32_t { Inlined = 0x00000800, StrictSecurityChecks = 0x00001000, SafeBuffers = 0x00002000, + EncodedLocalBasePointerMask = 0x0000C000, + EncodedParamBasePointerMask = 0x00030000, ProfileGuidedOptimization = 0x00040000, ValidProfileCounts = 0x00080000, OptimizedForSpeed = 0x00100000, @@ -356,7 +358,9 @@ enum class PointerOptions : uint32_t { Const = 0x00000400, Unaligned = 0x00000800, Restrict = 0x00001000, - WinRTSmartPointer = 0x00080000 + WinRTSmartPointer = 0x00080000, + LValueRefThisPointer = 0x00100000, + RValueRefThisPointer = 0x00200000 }; CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(PointerOptions) @@ -510,6 +514,19 @@ enum class RegisterId : uint16_t { #undef CV_REGISTER }; +/// Two-bit value indicating which register is the designated frame pointer +/// register. Appears in the S_FRAMEPROC record flags. +enum class EncodedFramePtrReg : uint8_t { + None = 0, + StackPtr = 1, + FramePtr = 2, + BasePtr = 3, +}; + +RegisterId decodeFramePtrReg(EncodedFramePtrReg EncodedReg, CPUType CPU); + +EncodedFramePtrReg encodeFramePtrReg(RegisterId Reg, CPUType CPU); + /// These values correspond to the THUNK_ORDINAL enumeration. enum class ThunkOrdinal : uint8_t { Standard, diff --git a/include/llvm/DebugInfo/CodeView/CodeViewError.h b/include/llvm/DebugInfo/CodeView/CodeViewError.h index 586a720ce6e4..d4615d02220d 100644 --- a/include/llvm/DebugInfo/CodeView/CodeViewError.h +++ b/include/llvm/DebugInfo/CodeView/CodeViewError.h @@ -24,23 +24,32 @@ enum class cv_error_code { no_records, unknown_member_record, }; +} // namespace codeview +} // namespace llvm + +namespace std { +template <> +struct is_error_code_enum<llvm::codeview::cv_error_code> : std::true_type {}; +} // namespace std + +namespace llvm { +namespace codeview { +const std::error_category &CVErrorCategory(); + +inline std::error_code make_error_code(cv_error_code E) { + return std::error_code(static_cast<int>(E), CVErrorCategory()); +} /// Base class for errors originating when parsing raw PDB files -class CodeViewError : public ErrorInfo<CodeViewError> { +class CodeViewError : public ErrorInfo<CodeViewError, StringError> { public: + using ErrorInfo<CodeViewError, + StringError>::ErrorInfo; // inherit constructors + CodeViewError(const Twine &S) : ErrorInfo(S, cv_error_code::unspecified) {} static char ID; - CodeViewError(cv_error_code C); - CodeViewError(const std::string &Context); - CodeViewError(cv_error_code C, const std::string &Context); +}; - void log(raw_ostream &OS) const override; - const std::string &getErrorMessage() const; - std::error_code convertToErrorCode() const override; +} // namespace codeview +} // namespace llvm -private: - std::string ErrMsg; - cv_error_code Code; -}; -} -} #endif diff --git a/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def b/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def index 6da8893bd61a..fdfcf4d53a23 100644 --- a/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def +++ b/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def @@ -18,251 +18,342 @@ // This currently only contains the "register subset shared by all processor // types" (ERR etc.) and the x86 registers. -CV_REGISTER(CVRegERR, 30000) -CV_REGISTER(CVRegTEB, 30001) -CV_REGISTER(CVRegTIMER, 30002) -CV_REGISTER(CVRegEFAD1, 30003) -CV_REGISTER(CVRegEFAD2, 30004) -CV_REGISTER(CVRegEFAD3, 30005) -CV_REGISTER(CVRegVFRAME, 30006) -CV_REGISTER(CVRegHANDLE, 30007) -CV_REGISTER(CVRegPARAMS, 30008) -CV_REGISTER(CVRegLOCALS, 30009) -CV_REGISTER(CVRegTID, 30010) -CV_REGISTER(CVRegENV, 30011) -CV_REGISTER(CVRegCMDLN, 30012) +// Some system headers define macros that conflict with our enums. Every +// compiler supported by LLVM has the push_macro and pop_macro pragmas, so use +// them to avoid the conflict. +#pragma push_macro("CR0") +#pragma push_macro("CR1") +#pragma push_macro("CR2") +#pragma push_macro("CR3") +#pragma push_macro("CR4") -CV_REGISTER(CVRegNONE, 0) -CV_REGISTER(CVRegAL, 1) -CV_REGISTER(CVRegCL, 2) -CV_REGISTER(CVRegDL, 3) -CV_REGISTER(CVRegBL, 4) -CV_REGISTER(CVRegAH, 5) -CV_REGISTER(CVRegCH, 6) -CV_REGISTER(CVRegDH, 7) -CV_REGISTER(CVRegBH, 8) -CV_REGISTER(CVRegAX, 9) -CV_REGISTER(CVRegCX, 10) -CV_REGISTER(CVRegDX, 11) -CV_REGISTER(CVRegBX, 12) -CV_REGISTER(CVRegSP, 13) -CV_REGISTER(CVRegBP, 14) -CV_REGISTER(CVRegSI, 15) -CV_REGISTER(CVRegDI, 16) -CV_REGISTER(CVRegEAX, 17) -CV_REGISTER(CVRegECX, 18) -CV_REGISTER(CVRegEDX, 19) -CV_REGISTER(CVRegEBX, 20) -CV_REGISTER(CVRegESP, 21) -CV_REGISTER(CVRegEBP, 22) -CV_REGISTER(CVRegESI, 23) -CV_REGISTER(CVRegEDI, 24) -CV_REGISTER(CVRegES, 25) -CV_REGISTER(CVRegCS, 26) -CV_REGISTER(CVRegSS, 27) -CV_REGISTER(CVRegDS, 28) -CV_REGISTER(CVRegFS, 29) -CV_REGISTER(CVRegGS, 30) -CV_REGISTER(CVRegIP, 31) -CV_REGISTER(CVRegFLAGS, 32) -CV_REGISTER(CVRegEIP, 33) -CV_REGISTER(CVRegEFLAGS, 34) -CV_REGISTER(CVRegTEMP, 40) -CV_REGISTER(CVRegTEMPH, 41) -CV_REGISTER(CVRegQUOTE, 42) -CV_REGISTER(CVRegPCDR3, 43) -CV_REGISTER(CVRegPCDR4, 44) -CV_REGISTER(CVRegPCDR5, 45) -CV_REGISTER(CVRegPCDR6, 46) -CV_REGISTER(CVRegPCDR7, 47) -CV_REGISTER(CVRegCR0, 80) -CV_REGISTER(CVRegCR1, 81) -CV_REGISTER(CVRegCR2, 82) -CV_REGISTER(CVRegCR3, 83) -CV_REGISTER(CVRegCR4, 84) -CV_REGISTER(CVRegDR0, 90) -CV_REGISTER(CVRegDR1, 91) -CV_REGISTER(CVRegDR2, 92) -CV_REGISTER(CVRegDR3, 93) -CV_REGISTER(CVRegDR4, 94) -CV_REGISTER(CVRegDR5, 95) -CV_REGISTER(CVRegDR6, 96) -CV_REGISTER(CVRegDR7, 97) -CV_REGISTER(CVRegGDTR, 110) -CV_REGISTER(CVRegGDTL, 111) -CV_REGISTER(CVRegIDTR, 112) -CV_REGISTER(CVRegIDTL, 113) -CV_REGISTER(CVRegLDTR, 114) -CV_REGISTER(CVRegTR, 115) +CV_REGISTER(ERR, 30000) +CV_REGISTER(TEB, 30001) +CV_REGISTER(TIMER, 30002) +CV_REGISTER(EFAD1, 30003) +CV_REGISTER(EFAD2, 30004) +CV_REGISTER(EFAD3, 30005) +CV_REGISTER(VFRAME, 30006) +CV_REGISTER(HANDLE, 30007) +CV_REGISTER(PARAMS, 30008) +CV_REGISTER(LOCALS, 30009) +CV_REGISTER(TID, 30010) +CV_REGISTER(ENV, 30011) +CV_REGISTER(CMDLN, 30012) -CV_REGISTER(CVRegPSEUDO1, 116) -CV_REGISTER(CVRegPSEUDO2, 117) -CV_REGISTER(CVRegPSEUDO3, 118) -CV_REGISTER(CVRegPSEUDO4, 119) -CV_REGISTER(CVRegPSEUDO5, 120) -CV_REGISTER(CVRegPSEUDO6, 121) -CV_REGISTER(CVRegPSEUDO7, 122) -CV_REGISTER(CVRegPSEUDO8, 123) -CV_REGISTER(CVRegPSEUDO9, 124) +CV_REGISTER(NONE, 0) +CV_REGISTER(AL, 1) +CV_REGISTER(CL, 2) +CV_REGISTER(DL, 3) +CV_REGISTER(BL, 4) +CV_REGISTER(AH, 5) +CV_REGISTER(CH, 6) +CV_REGISTER(DH, 7) +CV_REGISTER(BH, 8) +CV_REGISTER(AX, 9) +CV_REGISTER(CX, 10) +CV_REGISTER(DX, 11) +CV_REGISTER(BX, 12) +CV_REGISTER(SP, 13) +CV_REGISTER(BP, 14) +CV_REGISTER(SI, 15) +CV_REGISTER(DI, 16) +CV_REGISTER(EAX, 17) +CV_REGISTER(ECX, 18) +CV_REGISTER(EDX, 19) +CV_REGISTER(EBX, 20) +CV_REGISTER(ESP, 21) +CV_REGISTER(EBP, 22) +CV_REGISTER(ESI, 23) +CV_REGISTER(EDI, 24) +CV_REGISTER(ES, 25) +CV_REGISTER(CS, 26) +CV_REGISTER(SS, 27) +CV_REGISTER(DS, 28) +CV_REGISTER(FS, 29) +CV_REGISTER(GS, 30) +CV_REGISTER(IP, 31) +CV_REGISTER(FLAGS, 32) +CV_REGISTER(EIP, 33) +CV_REGISTER(EFLAGS, 34) +CV_REGISTER(TEMP, 40) +CV_REGISTER(TEMPH, 41) +CV_REGISTER(QUOTE, 42) +CV_REGISTER(PCDR3, 43) +CV_REGISTER(PCDR4, 44) +CV_REGISTER(PCDR5, 45) +CV_REGISTER(PCDR6, 46) +CV_REGISTER(PCDR7, 47) +CV_REGISTER(CR0, 80) +CV_REGISTER(CR1, 81) +CV_REGISTER(CR2, 82) +CV_REGISTER(CR3, 83) +CV_REGISTER(CR4, 84) +CV_REGISTER(DR0, 90) +CV_REGISTER(DR1, 91) +CV_REGISTER(DR2, 92) +CV_REGISTER(DR3, 93) +CV_REGISTER(DR4, 94) +CV_REGISTER(DR5, 95) +CV_REGISTER(DR6, 96) +CV_REGISTER(DR7, 97) +CV_REGISTER(GDTR, 110) +CV_REGISTER(GDTL, 111) +CV_REGISTER(IDTR, 112) +CV_REGISTER(IDTL, 113) +CV_REGISTER(LDTR, 114) +CV_REGISTER(TR, 115) -CV_REGISTER(CVRegST0, 128) -CV_REGISTER(CVRegST1, 129) -CV_REGISTER(CVRegST2, 130) -CV_REGISTER(CVRegST3, 131) -CV_REGISTER(CVRegST4, 132) -CV_REGISTER(CVRegST5, 133) -CV_REGISTER(CVRegST6, 134) -CV_REGISTER(CVRegST7, 135) -CV_REGISTER(CVRegCTRL, 136) -CV_REGISTER(CVRegSTAT, 137) -CV_REGISTER(CVRegTAG, 138) -CV_REGISTER(CVRegFPIP, 139) -CV_REGISTER(CVRegFPCS, 140) -CV_REGISTER(CVRegFPDO, 141) -CV_REGISTER(CVRegFPDS, 142) -CV_REGISTER(CVRegISEM, 143) -CV_REGISTER(CVRegFPEIP, 144) -CV_REGISTER(CVRegFPEDO, 145) +CV_REGISTER(PSEUDO1, 116) +CV_REGISTER(PSEUDO2, 117) +CV_REGISTER(PSEUDO3, 118) +CV_REGISTER(PSEUDO4, 119) +CV_REGISTER(PSEUDO5, 120) +CV_REGISTER(PSEUDO6, 121) +CV_REGISTER(PSEUDO7, 122) +CV_REGISTER(PSEUDO8, 123) +CV_REGISTER(PSEUDO9, 124) -CV_REGISTER(CVRegMM0, 146) -CV_REGISTER(CVRegMM1, 147) -CV_REGISTER(CVRegMM2, 148) -CV_REGISTER(CVRegMM3, 149) -CV_REGISTER(CVRegMM4, 150) -CV_REGISTER(CVRegMM5, 151) -CV_REGISTER(CVRegMM6, 152) -CV_REGISTER(CVRegMM7, 153) +CV_REGISTER(ST0, 128) +CV_REGISTER(ST1, 129) +CV_REGISTER(ST2, 130) +CV_REGISTER(ST3, 131) +CV_REGISTER(ST4, 132) +CV_REGISTER(ST5, 133) +CV_REGISTER(ST6, 134) +CV_REGISTER(ST7, 135) +CV_REGISTER(CTRL, 136) +CV_REGISTER(STAT, 137) +CV_REGISTER(TAG, 138) +CV_REGISTER(FPIP, 139) +CV_REGISTER(FPCS, 140) +CV_REGISTER(FPDO, 141) +CV_REGISTER(FPDS, 142) +CV_REGISTER(ISEM, 143) +CV_REGISTER(FPEIP, 144) +CV_REGISTER(FPEDO, 145) -CV_REGISTER(CVRegXMM0, 154) -CV_REGISTER(CVRegXMM1, 155) -CV_REGISTER(CVRegXMM2, 156) -CV_REGISTER(CVRegXMM3, 157) -CV_REGISTER(CVRegXMM4, 158) -CV_REGISTER(CVRegXMM5, 159) -CV_REGISTER(CVRegXMM6, 160) -CV_REGISTER(CVRegXMM7, 161) +CV_REGISTER(MM0, 146) +CV_REGISTER(MM1, 147) +CV_REGISTER(MM2, 148) +CV_REGISTER(MM3, 149) +CV_REGISTER(MM4, 150) +CV_REGISTER(MM5, 151) +CV_REGISTER(MM6, 152) +CV_REGISTER(MM7, 153) -CV_REGISTER(CVRegMXCSR, 211) +CV_REGISTER(XMM0, 154) +CV_REGISTER(XMM1, 155) +CV_REGISTER(XMM2, 156) +CV_REGISTER(XMM3, 157) +CV_REGISTER(XMM4, 158) +CV_REGISTER(XMM5, 159) +CV_REGISTER(XMM6, 160) +CV_REGISTER(XMM7, 161) -CV_REGISTER(CVRegEDXEAX, 212) +CV_REGISTER(MXCSR, 211) -CV_REGISTER(CVRegEMM0L, 220) -CV_REGISTER(CVRegEMM1L, 221) -CV_REGISTER(CVRegEMM2L, 222) -CV_REGISTER(CVRegEMM3L, 223) -CV_REGISTER(CVRegEMM4L, 224) -CV_REGISTER(CVRegEMM5L, 225) -CV_REGISTER(CVRegEMM6L, 226) -CV_REGISTER(CVRegEMM7L, 227) +CV_REGISTER(EDXEAX, 212) -CV_REGISTER(CVRegEMM0H, 228) -CV_REGISTER(CVRegEMM1H, 229) -CV_REGISTER(CVRegEMM2H, 230) -CV_REGISTER(CVRegEMM3H, 231) -CV_REGISTER(CVRegEMM4H, 232) -CV_REGISTER(CVRegEMM5H, 233) -CV_REGISTER(CVRegEMM6H, 234) -CV_REGISTER(CVRegEMM7H, 235) +CV_REGISTER(EMM0L, 220) +CV_REGISTER(EMM1L, 221) +CV_REGISTER(EMM2L, 222) +CV_REGISTER(EMM3L, 223) +CV_REGISTER(EMM4L, 224) +CV_REGISTER(EMM5L, 225) +CV_REGISTER(EMM6L, 226) +CV_REGISTER(EMM7L, 227) -CV_REGISTER(CVRegMM00, 236) -CV_REGISTER(CVRegMM01, 237) -CV_REGISTER(CVRegMM10, 238) -CV_REGISTER(CVRegMM11, 239) -CV_REGISTER(CVRegMM20, 240) -CV_REGISTER(CVRegMM21, 241) -CV_REGISTER(CVRegMM30, 242) -CV_REGISTER(CVRegMM31, 243) -CV_REGISTER(CVRegMM40, 244) -CV_REGISTER(CVRegMM41, 245) -CV_REGISTER(CVRegMM50, 246) -CV_REGISTER(CVRegMM51, 247) -CV_REGISTER(CVRegMM60, 248) -CV_REGISTER(CVRegMM61, 249) -CV_REGISTER(CVRegMM70, 250) -CV_REGISTER(CVRegMM71, 251) +CV_REGISTER(EMM0H, 228) +CV_REGISTER(EMM1H, 229) +CV_REGISTER(EMM2H, 230) +CV_REGISTER(EMM3H, 231) +CV_REGISTER(EMM4H, 232) +CV_REGISTER(EMM5H, 233) +CV_REGISTER(EMM6H, 234) +CV_REGISTER(EMM7H, 235) -CV_REGISTER(CVRegBND0, 396) -CV_REGISTER(CVRegBND1, 397) -CV_REGISTER(CVRegBND2, 398) +CV_REGISTER(MM00, 236) +CV_REGISTER(MM01, 237) +CV_REGISTER(MM10, 238) +CV_REGISTER(MM11, 239) +CV_REGISTER(MM20, 240) +CV_REGISTER(MM21, 241) +CV_REGISTER(MM30, 242) +CV_REGISTER(MM31, 243) +CV_REGISTER(MM40, 244) +CV_REGISTER(MM41, 245) +CV_REGISTER(MM50, 246) +CV_REGISTER(MM51, 247) +CV_REGISTER(MM60, 248) +CV_REGISTER(MM61, 249) +CV_REGISTER(MM70, 250) +CV_REGISTER(MM71, 251) +CV_REGISTER(BND0, 396) +CV_REGISTER(BND1, 397) +CV_REGISTER(BND2, 398) -CV_REGISTER(CVRegXMM8, 252) -CV_REGISTER(CVRegXMM9, 253) -CV_REGISTER(CVRegXMM10, 254) -CV_REGISTER(CVRegXMM11, 255) -CV_REGISTER(CVRegXMM12, 256) -CV_REGISTER(CVRegXMM13, 257) -CV_REGISTER(CVRegXMM14, 258) -CV_REGISTER(CVRegXMM15, 259) +CV_REGISTER(XMM8, 252) +CV_REGISTER(XMM9, 253) +CV_REGISTER(XMM10, 254) +CV_REGISTER(XMM11, 255) +CV_REGISTER(XMM12, 256) +CV_REGISTER(XMM13, 257) +CV_REGISTER(XMM14, 258) +CV_REGISTER(XMM15, 259) -CV_REGISTER(CVRegSIL, 324) -CV_REGISTER(CVRegDIL, 325) -CV_REGISTER(CVRegBPL, 326) -CV_REGISTER(CVRegSPL, 327) -CV_REGISTER(CVRegRAX, 328) -CV_REGISTER(CVRegRBX, 329) -CV_REGISTER(CVRegRCX, 330) -CV_REGISTER(CVRegRDX, 331) -CV_REGISTER(CVRegRSI, 332) -CV_REGISTER(CVRegRDI, 333) -CV_REGISTER(CVRegRBP, 334) -CV_REGISTER(CVRegRSP, 335) +CV_REGISTER(SIL, 324) +CV_REGISTER(DIL, 325) +CV_REGISTER(BPL, 326) +CV_REGISTER(SPL, 327) -CV_REGISTER(CVRegR8, 336) -CV_REGISTER(CVRegR9, 337) -CV_REGISTER(CVRegR10, 338) -CV_REGISTER(CVRegR11, 339) -CV_REGISTER(CVRegR12, 340) -CV_REGISTER(CVRegR13, 341) -CV_REGISTER(CVRegR14, 342) -CV_REGISTER(CVRegR15, 343) +CV_REGISTER(RAX, 328) +CV_REGISTER(RBX, 329) +CV_REGISTER(RCX, 330) +CV_REGISTER(RDX, 331) +CV_REGISTER(RSI, 332) +CV_REGISTER(RDI, 333) +CV_REGISTER(RBP, 334) +CV_REGISTER(RSP, 335) -CV_REGISTER(CVRegR8B, 344) -CV_REGISTER(CVRegR9B, 345) -CV_REGISTER(CVRegR10B, 346) -CV_REGISTER(CVRegR11B, 347) -CV_REGISTER(CVRegR12B, 348) -CV_REGISTER(CVRegR13B, 349) -CV_REGISTER(CVRegR14B, 350) -CV_REGISTER(CVRegR15B, 351) +CV_REGISTER(R8, 336) +CV_REGISTER(R9, 337) +CV_REGISTER(R10, 338) +CV_REGISTER(R11, 339) +CV_REGISTER(R12, 340) +CV_REGISTER(R13, 341) +CV_REGISTER(R14, 342) +CV_REGISTER(R15, 343) -CV_REGISTER(CVRegR8W, 352) -CV_REGISTER(CVRegR9W, 353) -CV_REGISTER(CVRegR10W, 354) -CV_REGISTER(CVRegR11W, 355) -CV_REGISTER(CVRegR12W, 356) -CV_REGISTER(CVRegR13W, 357) -CV_REGISTER(CVRegR14W, 358) -CV_REGISTER(CVRegR15W, 359) +CV_REGISTER(R8B, 344) +CV_REGISTER(R9B, 345) +CV_REGISTER(R10B, 346) +CV_REGISTER(R11B, 347) +CV_REGISTER(R12B, 348) +CV_REGISTER(R13B, 349) +CV_REGISTER(R14B, 350) +CV_REGISTER(R15B, 351) -CV_REGISTER(CVRegR8D, 360) -CV_REGISTER(CVRegR9D, 361) -CV_REGISTER(CVRegR10D, 362) -CV_REGISTER(CVRegR11D, 363) -CV_REGISTER(CVRegR12D, 364) -CV_REGISTER(CVRegR13D, 365) -CV_REGISTER(CVRegR14D, 366) -CV_REGISTER(CVRegR15D, 367) +CV_REGISTER(R8W, 352) +CV_REGISTER(R9W, 353) +CV_REGISTER(R10W, 354) +CV_REGISTER(R11W, 355) +CV_REGISTER(R12W, 356) +CV_REGISTER(R13W, 357) +CV_REGISTER(R14W, 358) +CV_REGISTER(R15W, 359) + +CV_REGISTER(R8D, 360) +CV_REGISTER(R9D, 361) +CV_REGISTER(R10D, 362) +CV_REGISTER(R11D, 363) +CV_REGISTER(R12D, 364) +CV_REGISTER(R13D, 365) +CV_REGISTER(R14D, 366) +CV_REGISTER(R15D, 367) // cvconst.h defines both CV_REG_YMM0 (252) and CV_AMD64_YMM0 (368). Keep the // original prefix to distinguish them. -CV_REGISTER(CVRegAMD64_YMM0, 368) -CV_REGISTER(CVRegAMD64_YMM1, 369) -CV_REGISTER(CVRegAMD64_YMM2, 370) -CV_REGISTER(CVRegAMD64_YMM3, 371) -CV_REGISTER(CVRegAMD64_YMM4, 372) -CV_REGISTER(CVRegAMD64_YMM5, 373) -CV_REGISTER(CVRegAMD64_YMM6, 374) -CV_REGISTER(CVRegAMD64_YMM7, 375) -CV_REGISTER(CVRegAMD64_YMM8, 376) -CV_REGISTER(CVRegAMD64_YMM9, 377) -CV_REGISTER(CVRegAMD64_YMM10, 378) -CV_REGISTER(CVRegAMD64_YMM11, 379) -CV_REGISTER(CVRegAMD64_YMM12, 380) -CV_REGISTER(CVRegAMD64_YMM13, 381) -CV_REGISTER(CVRegAMD64_YMM14, 382) -CV_REGISTER(CVRegAMD64_YMM15, 383) +CV_REGISTER(AMD64_YMM0, 368) +CV_REGISTER(AMD64_YMM1, 369) +CV_REGISTER(AMD64_YMM2, 370) +CV_REGISTER(AMD64_YMM3, 371) +CV_REGISTER(AMD64_YMM4, 372) +CV_REGISTER(AMD64_YMM5, 373) +CV_REGISTER(AMD64_YMM6, 374) +CV_REGISTER(AMD64_YMM7, 375) +CV_REGISTER(AMD64_YMM8, 376) +CV_REGISTER(AMD64_YMM9, 377) +CV_REGISTER(AMD64_YMM10, 378) +CV_REGISTER(AMD64_YMM11, 379) +CV_REGISTER(AMD64_YMM12, 380) +CV_REGISTER(AMD64_YMM13, 381) +CV_REGISTER(AMD64_YMM14, 382) +CV_REGISTER(AMD64_YMM15, 383) + +CV_REGISTER(AMD64_XMM16, 694) +CV_REGISTER(AMD64_XMM17, 695) +CV_REGISTER(AMD64_XMM18, 696) +CV_REGISTER(AMD64_XMM19, 697) +CV_REGISTER(AMD64_XMM20, 698) +CV_REGISTER(AMD64_XMM21, 699) +CV_REGISTER(AMD64_XMM22, 700) +CV_REGISTER(AMD64_XMM23, 701) +CV_REGISTER(AMD64_XMM24, 702) +CV_REGISTER(AMD64_XMM25, 703) +CV_REGISTER(AMD64_XMM26, 704) +CV_REGISTER(AMD64_XMM27, 705) +CV_REGISTER(AMD64_XMM28, 706) +CV_REGISTER(AMD64_XMM29, 707) +CV_REGISTER(AMD64_XMM30, 708) +CV_REGISTER(AMD64_XMM31, 709) + +CV_REGISTER(AMD64_YMM16, 710) +CV_REGISTER(AMD64_YMM17, 711) +CV_REGISTER(AMD64_YMM18, 712) +CV_REGISTER(AMD64_YMM19, 713) +CV_REGISTER(AMD64_YMM20, 714) +CV_REGISTER(AMD64_YMM21, 715) +CV_REGISTER(AMD64_YMM22, 716) +CV_REGISTER(AMD64_YMM23, 717) +CV_REGISTER(AMD64_YMM24, 718) +CV_REGISTER(AMD64_YMM25, 719) +CV_REGISTER(AMD64_YMM26, 720) +CV_REGISTER(AMD64_YMM27, 721) +CV_REGISTER(AMD64_YMM28, 722) +CV_REGISTER(AMD64_YMM29, 723) +CV_REGISTER(AMD64_YMM30, 724) +CV_REGISTER(AMD64_YMM31, 725) + +CV_REGISTER(AMD64_ZMM0, 726) +CV_REGISTER(AMD64_ZMM1, 727) +CV_REGISTER(AMD64_ZMM2, 728) +CV_REGISTER(AMD64_ZMM3, 729) +CV_REGISTER(AMD64_ZMM4, 730) +CV_REGISTER(AMD64_ZMM5, 731) +CV_REGISTER(AMD64_ZMM6, 732) +CV_REGISTER(AMD64_ZMM7, 733) +CV_REGISTER(AMD64_ZMM8, 734) +CV_REGISTER(AMD64_ZMM9, 735) +CV_REGISTER(AMD64_ZMM10, 736) +CV_REGISTER(AMD64_ZMM11, 737) +CV_REGISTER(AMD64_ZMM12, 738) +CV_REGISTER(AMD64_ZMM13, 739) +CV_REGISTER(AMD64_ZMM14, 740) +CV_REGISTER(AMD64_ZMM15, 741) +CV_REGISTER(AMD64_ZMM16, 742) +CV_REGISTER(AMD64_ZMM17, 743) +CV_REGISTER(AMD64_ZMM18, 744) +CV_REGISTER(AMD64_ZMM19, 745) +CV_REGISTER(AMD64_ZMM20, 746) +CV_REGISTER(AMD64_ZMM21, 747) +CV_REGISTER(AMD64_ZMM22, 748) +CV_REGISTER(AMD64_ZMM23, 749) +CV_REGISTER(AMD64_ZMM24, 750) +CV_REGISTER(AMD64_ZMM25, 751) +CV_REGISTER(AMD64_ZMM26, 752) +CV_REGISTER(AMD64_ZMM27, 753) +CV_REGISTER(AMD64_ZMM28, 754) +CV_REGISTER(AMD64_ZMM29, 755) +CV_REGISTER(AMD64_ZMM30, 756) +CV_REGISTER(AMD64_ZMM31, 757) + +CV_REGISTER(AMD64_K0, 758) +CV_REGISTER(AMD64_K1, 759) +CV_REGISTER(AMD64_K2, 760) +CV_REGISTER(AMD64_K3, 761) +CV_REGISTER(AMD64_K4, 762) +CV_REGISTER(AMD64_K5, 763) +CV_REGISTER(AMD64_K6, 764) +CV_REGISTER(AMD64_K7, 765) + +#pragma pop_macro("CR0") +#pragma pop_macro("CR1") +#pragma pop_macro("CR2") +#pragma pop_macro("CR3") +#pragma pop_macro("CR4") diff --git a/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h b/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h index 1e329c7c3f14..847d93f0e985 100644 --- a/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h +++ b/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h @@ -13,6 +13,7 @@ #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/DebugSubsection.h" #include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" namespace llvm { @@ -26,21 +27,23 @@ public: } Error initialize(BinaryStreamReader Reader); + Error initialize(BinaryStreamRef Stream); FixedStreamArray<FrameData>::Iterator begin() const { return Frames.begin(); } FixedStreamArray<FrameData>::Iterator end() const { return Frames.end(); } - const void *getRelocPtr() const { return RelocPtr; } + const support::ulittle32_t *getRelocPtr() const { return RelocPtr; } private: - const uint32_t *RelocPtr = nullptr; + const support::ulittle32_t *RelocPtr = nullptr; FixedStreamArray<FrameData> Frames; }; class DebugFrameDataSubsection final : public DebugSubsection { public: - DebugFrameDataSubsection() - : DebugSubsection(DebugSubsectionKind::FrameData) {} + DebugFrameDataSubsection(bool IncludeRelocPtr) + : DebugSubsection(DebugSubsectionKind::FrameData), + IncludeRelocPtr(IncludeRelocPtr) {} static bool classof(const DebugSubsection *S) { return S->kind() == DebugSubsectionKind::FrameData; } @@ -52,6 +55,7 @@ public: void setFrames(ArrayRef<FrameData> Frames); private: + bool IncludeRelocPtr = false; std::vector<FrameData> Frames; }; } diff --git a/include/llvm/DebugInfo/CodeView/RecordSerialization.h b/include/llvm/DebugInfo/CodeView/RecordSerialization.h index 58449c2c7565..36237e1a4d9e 100644 --- a/include/llvm/DebugInfo/CodeView/RecordSerialization.h +++ b/include/llvm/DebugInfo/CodeView/RecordSerialization.h @@ -180,26 +180,6 @@ template <typename T> serialize_numeric_impl<T> serialize_numeric(T &Item) { return serialize_numeric_impl<T>(Item); } -// This field is only present in the byte record if the condition is true. The -// condition is evaluated lazily, so it can depend on items that were -// deserialized -// earlier. -#define CV_CONDITIONAL_FIELD(I, C) \ - serialize_conditional(I, [&]() { return !!(C); }) - -// This is an array of N items, where N is evaluated lazily, so it can refer -// to a field deserialized earlier. -#define CV_ARRAY_FIELD_N(I, N) serialize_array(I, [&]() { return N; }) - -// This is an array that exhausts the remainder of the input buffer. -#define CV_ARRAY_FIELD_TAIL(I) serialize_array_tail(I) - -// This is an array that consumes null terminated strings until a double null -// is encountered. -#define CV_STRING_ARRAY_NULL_TERM(I) serialize_null_term_string_array(I) - -#define CV_NUMERIC_FIELD(I) serialize_numeric(I) - template <typename T, typename U> Error consume(BinaryStreamReader &Reader, const serialize_conditional_impl<T, U> &Item) { @@ -242,9 +222,6 @@ Error consume(BinaryStreamReader &Reader, T &&X, U &&Y, Args &&... Rest) { return consume(Reader, Y, std::forward<Args>(Rest)...); } -#define CV_DESERIALIZE(...) \ - if (auto EC = consume(__VA_ARGS__)) \ - return std::move(EC); } } diff --git a/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h b/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h index b5479db97a15..6b5dd2d20d17 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h +++ b/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h @@ -47,7 +47,7 @@ public: return Error::success(); } template <typename T> static Expected<T> deserializeAs(CVSymbol Symbol) { - T Record(Symbol.kind()); + T Record(static_cast<SymbolRecordKind>(Symbol.kind())); if (auto EC = deserializeAs<T>(Symbol, Record)) return std::move(EC); return Record; diff --git a/include/llvm/DebugInfo/CodeView/SymbolDumper.h b/include/llvm/DebugInfo/CodeView/SymbolDumper.h index 293daa851bdd..215da2e2b522 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolDumper.h +++ b/include/llvm/DebugInfo/CodeView/SymbolDumper.h @@ -27,10 +27,10 @@ class CVSymbolDumper { public: CVSymbolDumper(ScopedPrinter &W, TypeCollection &Types, CodeViewContainer Container, - std::unique_ptr<SymbolDumpDelegate> ObjDelegate, + std::unique_ptr<SymbolDumpDelegate> ObjDelegate, CPUType CPU, bool PrintRecordBytes) : W(W), Types(Types), Container(Container), - ObjDelegate(std::move(ObjDelegate)), + ObjDelegate(std::move(ObjDelegate)), CompilationCPUType(CPU), PrintRecordBytes(PrintRecordBytes) {} /// Dumps one type record. Returns false if there was a type parsing error, @@ -43,12 +43,14 @@ public: /// parse error, and true otherwise. Error dump(const CVSymbolArray &Symbols); + CPUType getCompilationCPUType() const { return CompilationCPUType; } + private: ScopedPrinter &W; TypeCollection &Types; CodeViewContainer Container; std::unique_ptr<SymbolDumpDelegate> ObjDelegate; - + CPUType CompilationCPUType; bool PrintRecordBytes; }; } // end namespace codeview diff --git a/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/include/llvm/DebugInfo/CodeView/SymbolRecord.h index 93306824012e..b58825c4a788 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolRecord.h +++ b/include/llvm/DebugInfo/CodeView/SymbolRecord.h @@ -358,6 +358,7 @@ public: // S_PUB32 class PublicSym32 : public SymbolRecord { public: + PublicSym32() : SymbolRecord(SymbolRecordKind::PublicSym32) {} explicit PublicSym32(SymbolRecordKind Kind) : SymbolRecord(Kind) {} explicit PublicSym32(uint32_t RecordOffset) : SymbolRecord(SymbolRecordKind::PublicSym32), @@ -399,6 +400,7 @@ public: uint16_t Module; StringRef Name; + uint16_t modi() const { return Module - 1; } uint32_t RecordOffset; }; @@ -636,6 +638,7 @@ public: // S_OBJNAME class ObjNameSym : public SymbolRecord { public: + explicit ObjNameSym() : SymbolRecord(SymbolRecordKind::ObjNameSym) {} explicit ObjNameSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {} ObjNameSym(uint32_t RecordOffset) : SymbolRecord(SymbolRecordKind::ObjNameSym), RecordOffset(RecordOffset) { @@ -718,6 +721,7 @@ public: // S_COMPILE3 class Compile3Sym : public SymbolRecord { public: + Compile3Sym() : SymbolRecord(SymbolRecordKind::Compile3Sym) {} explicit Compile3Sym(SymbolRecordKind Kind) : SymbolRecord(Kind) {} Compile3Sym(uint32_t RecordOffset) : SymbolRecord(SymbolRecordKind::Compile3Sym), @@ -739,8 +743,17 @@ public: Flags = CompileSym3Flags((uint32_t(Flags) & 0xFFFFFF00) | uint32_t(Lang)); } - uint8_t getLanguage() const { return static_cast<uint32_t>(Flags) & 0xFF; } - uint32_t getFlags() const { return static_cast<uint32_t>(Flags) & ~0xFF; } + SourceLanguage getLanguage() const { + return static_cast<SourceLanguage>(static_cast<uint32_t>(Flags) & 0xFF); + } + CompileSym3Flags getFlags() const { + return static_cast<CompileSym3Flags>(static_cast<uint32_t>(Flags) & ~0xFF); + } + + bool hasOptimizations() const { + return CompileSym3Flags::None != + (getFlags() & (CompileSym3Flags::PGO | CompileSym3Flags::LTCG)); + } uint32_t RecordOffset; }; @@ -761,7 +774,21 @@ public: uint16_t SectionIdOfExceptionHandler; FrameProcedureOptions Flags; + /// Extract the register this frame uses to refer to local variables. + RegisterId getLocalFramePtrReg(CPUType CPU) const { + return decodeFramePtrReg( + EncodedFramePtrReg((uint32_t(Flags) >> 14U) & 0x3U), CPU); + } + + /// Extract the register this frame uses to refer to parameters. + RegisterId getParamFramePtrReg(CPUType CPU) const { + return decodeFramePtrReg( + EncodedFramePtrReg((uint32_t(Flags) >> 16U) & 0x3U), CPU); + } + uint32_t RecordOffset; + +private: }; // S_CALLSITEINFO diff --git a/include/llvm/DebugInfo/CodeView/SymbolRecordHelpers.h b/include/llvm/DebugInfo/CodeView/SymbolRecordHelpers.h new file mode 100644 index 000000000000..3713fe118eaa --- /dev/null +++ b/include/llvm/DebugInfo/CodeView/SymbolRecordHelpers.h @@ -0,0 +1,62 @@ +//===- SymbolRecordHelpers.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORDHELPERS_H +#define LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORDHELPERS_H + +#include "llvm/DebugInfo/CodeView/SymbolRecord.h" + +namespace llvm { +namespace codeview { +/// Return true if this symbol opens a scope. This implies that the symbol has +/// "parent" and "end" fields, which contain the offset of the S_END or +/// S_INLINESITE_END record. +inline bool symbolOpensScope(SymbolKind Kind) { + switch (Kind) { + case SymbolKind::S_GPROC32: + case SymbolKind::S_LPROC32: + case SymbolKind::S_LPROC32_ID: + case SymbolKind::S_GPROC32_ID: + case SymbolKind::S_BLOCK32: + case SymbolKind::S_SEPCODE: + case SymbolKind::S_THUNK32: + case SymbolKind::S_INLINESITE: + case SymbolKind::S_INLINESITE2: + return true; + default: + break; + } + return false; +} + +/// Return true if this ssymbol ends a scope. +inline bool symbolEndsScope(SymbolKind Kind) { + switch (Kind) { + case SymbolKind::S_END: + case SymbolKind::S_PROC_ID_END: + case SymbolKind::S_INLINESITE_END: + return true; + default: + break; + } + return false; +} + +/// Given a symbol P for which symbolOpensScope(P) == true, return the +/// corresponding end offset. +uint32_t getScopeEndOffset(const CVSymbol &Symbol); +uint32_t getScopeParentOffset(const CVSymbol &Symbol); + +CVSymbolArray limitSymbolArrayToScope(const CVSymbolArray &Symbols, + uint32_t ScopeBegin); + +} // namespace codeview +} // namespace llvm + +#endif diff --git a/include/llvm/DebugInfo/CodeView/TypeIndex.h b/include/llvm/DebugInfo/CodeView/TypeIndex.h index c71281de7145..58463a6b13df 100644 --- a/include/llvm/DebugInfo/CodeView/TypeIndex.h +++ b/include/llvm/DebugInfo/CodeView/TypeIndex.h @@ -134,6 +134,8 @@ public: return static_cast<SimpleTypeMode>(Index & SimpleModeMask); } + TypeIndex makeDirect() const { return TypeIndex{getSimpleKind()}; } + static TypeIndex None() { return TypeIndex(SimpleTypeKind::None); } static TypeIndex Void() { return TypeIndex(SimpleTypeKind::Void); } static TypeIndex VoidPointer32() { @@ -143,6 +145,13 @@ public: return TypeIndex(SimpleTypeKind::Void, SimpleTypeMode::NearPointer64); } + static TypeIndex NullptrT() { + // std::nullptr_t uses the pointer mode that doesn't indicate bit-width, + // presumably because std::nullptr_t is intended to be compatible with any + // pointer type. + return TypeIndex(SimpleTypeKind::Void, SimpleTypeMode::NearPointer); + } + static TypeIndex SignedCharacter() { return TypeIndex(SimpleTypeKind::SignedCharacter); } diff --git a/include/llvm/DebugInfo/CodeView/TypeRecord.h b/include/llvm/DebugInfo/CodeView/TypeRecord.h index 61ebdf878ce7..7b4a30ee622d 100644 --- a/include/llvm/DebugInfo/CodeView/TypeRecord.h +++ b/include/llvm/DebugInfo/CodeView/TypeRecord.h @@ -95,6 +95,11 @@ struct MemberAttributes { return MP == MethodKind::IntroducingVirtual || MP == MethodKind::PureIntroducingVirtual; } + + /// Is this method static. + bool isStatic() const { + return getMethodKind() == MethodKind::Static; + } }; // Does not correspond to any tag, this is the tail of an LF_POINTER record @@ -264,14 +269,18 @@ public: // LF_POINTER class PointerRecord : public TypeRecord { public: + // ---------------------------XXXXX static const uint32_t PointerKindShift = 0; static const uint32_t PointerKindMask = 0x1F; + // ------------------------XXX----- static const uint32_t PointerModeShift = 5; static const uint32_t PointerModeMask = 0x07; - static const uint32_t PointerOptionMask = 0xFF; + // ----------XXX------XXXXX-------- + static const uint32_t PointerOptionMask = 0x381f00; + // -------------XXXXXX------------ static const uint32_t PointerSizeShift = 13; static const uint32_t PointerSizeMask = 0xFF; @@ -305,7 +314,7 @@ public: } PointerOptions getOptions() const { - return static_cast<PointerOptions>(Attrs); + return static_cast<PointerOptions>(Attrs & PointerOptionMask); } uint8_t getSize() const { @@ -334,6 +343,14 @@ public: return !!(Attrs & uint32_t(PointerOptions::Restrict)); } + bool isLValueReferenceThisPtr() const { + return !!(Attrs & uint32_t(PointerOptions::LValueRefThisPointer)); + } + + bool isRValueReferenceThisPtr() const { + return !!(Attrs & uint32_t(PointerOptions::RValueRefThisPointer)); + } + TypeIndex ReferentType; uint32_t Attrs; Optional<MemberPointerInfo> MemberInfo; @@ -429,6 +446,14 @@ public: return (Options & ClassOptions::ForwardReference) != ClassOptions::None; } + bool containsNestedClass() const { + return (Options & ClassOptions::ContainsNestedClass) != ClassOptions::None; + } + + bool isScoped() const { + return (Options & ClassOptions::Scoped) != ClassOptions::None; + } + uint16_t getMemberCount() const { return MemberCount; } ClassOptions getOptions() const { return Options; } TypeIndex getFieldList() const { return FieldList; } @@ -655,7 +680,17 @@ public: ArrayRef<TypeIndex> getArgs() const { return ArgIndices; } - SmallVector<TypeIndex, 4> ArgIndices; + /// Indices of known build info arguments. + enum BuildInfoArg { + CurrentDirectory, ///< Absolute CWD path + BuildTool, ///< Absolute compiler path + SourceFile, ///< Path to main source file, relative or absolute + TypeServerPDB, ///< Absolute path of type server PDB (/Fd) + CommandLine, ///< Full canonical command line (maybe -cc1) + MaxArgs + }; + + SmallVector<TypeIndex, MaxArgs> ArgIndices; }; // LF_VFTABLE @@ -923,6 +958,7 @@ public: uint32_t Signature; }; + } // end namespace codeview } // end namespace llvm diff --git a/include/llvm/DebugInfo/CodeView/TypeRecordHelpers.h b/include/llvm/DebugInfo/CodeView/TypeRecordHelpers.h new file mode 100644 index 000000000000..389472ed1aea --- /dev/null +++ b/include/llvm/DebugInfo/CodeView/TypeRecordHelpers.h @@ -0,0 +1,28 @@ +//===- TypeRecordHelpers.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPERECORDHELPERS_H +#define LLVM_DEBUGINFO_CODEVIEW_TYPERECORDHELPERS_H + +#include "llvm/DebugInfo/CodeView/TypeRecord.h" + +namespace llvm { + namespace codeview { + /// Given an arbitrary codeview type, determine if it is an LF_STRUCTURE, + /// LF_CLASS, LF_INTERFACE, LF_UNION, or LF_ENUM with the forward ref class + /// option. + bool isUdtForwardRef(CVType CVT); + + /// Given a CVType which is assumed to be an LF_MODIFIER, return the + /// TypeIndex of the type that the LF_MODIFIER modifies. + TypeIndex getModifiedType(const CVType &CVT); + } +} + +#endif diff --git a/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h b/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h index 583740d2eb4b..0b9f54ec60bf 100644 --- a/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h +++ b/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h @@ -83,18 +83,21 @@ Error mergeIdRecords(MergingTypeTableBuilder &Dest, ArrayRef<TypeIndex> Types, Error mergeTypeAndIdRecords(MergingTypeTableBuilder &DestIds, MergingTypeTableBuilder &DestTypes, SmallVectorImpl<TypeIndex> &SourceToDest, - const CVTypeArray &IdsAndTypes); + const CVTypeArray &IdsAndTypes, + Optional<uint32_t> &PCHSignature); Error mergeTypeAndIdRecords(GlobalTypeTableBuilder &DestIds, GlobalTypeTableBuilder &DestTypes, SmallVectorImpl<TypeIndex> &SourceToDest, const CVTypeArray &IdsAndTypes, - ArrayRef<GloballyHashedType> Hashes); + ArrayRef<GloballyHashedType> Hashes, + Optional<uint32_t> &PCHSignature); Error mergeTypeRecords(GlobalTypeTableBuilder &Dest, SmallVectorImpl<TypeIndex> &SourceToDest, const CVTypeArray &Types, - ArrayRef<GloballyHashedType> Hashes); + ArrayRef<GloballyHashedType> Hashes, + Optional<uint32_t> &PCHSignature); Error mergeIdRecords(GlobalTypeTableBuilder &Dest, ArrayRef<TypeIndex> Types, SmallVectorImpl<TypeIndex> &SourceToDest, diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h index bbdd5e0d9c3f..85e96402a246 100644 --- a/include/llvm/DebugInfo/DIContext.h +++ b/include/llvm/DebugInfo/DIContext.h @@ -81,7 +81,7 @@ class DIInliningInfo { public: DIInliningInfo() = default; - DILineInfo getFrame(unsigned Index) const { + const DILineInfo & getFrame(unsigned Index) const { assert(Index < Frames.size()); return Frames[Index]; } @@ -98,6 +98,11 @@ public: void addFrame(const DILineInfo &Frame) { Frames.push_back(Frame); } + + void resize(unsigned i) { + Frames.resize(i); + } + }; /// Container for description of a global variable. diff --git a/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h b/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h index c219ca75e640..33797419a7b8 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h @@ -18,20 +18,20 @@ namespace llvm { class DWARFCompileUnit : public DWARFUnit { public: DWARFCompileUnit(DWARFContext &Context, const DWARFSection &Section, - const DWARFUnitHeader &Header, - const DWARFDebugAbbrev *DA, const DWARFSection *RS, + const DWARFUnitHeader &Header, const DWARFDebugAbbrev *DA, + const DWARFSection *RS, const DWARFSection *LocSection, StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS, const DWARFSection &LS, bool LE, - bool IsDWO, const DWARFUnitSectionBase &UnitSection) - : DWARFUnit(Context, Section, Header, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, - UnitSection) {} + bool IsDWO, const DWARFUnitVector &UnitVector) + : DWARFUnit(Context, Section, Header, DA, RS, LocSection, SS, SOS, AOS, + LS, LE, IsDWO, UnitVector) {} - // VTable anchor. + /// VTable anchor. ~DWARFCompileUnit() override; - - void dump(raw_ostream &OS, DIDumpOptions DumpOpts); - - static const DWARFSectionKind Section = DW_SECT_INFO; + /// Dump this compile unit to \p OS. + void dump(raw_ostream &OS, DIDumpOptions DumpOpts) override; + /// Enable LLVM-style RTTI. + static bool classof(const DWARFUnit *U) { return !U->isTypeUnit(); } }; } // end namespace llvm diff --git a/include/llvm/DebugInfo/DWARF/DWARFContext.h b/include/llvm/DebugInfo/DWARF/DWARFContext.h index f5419fe02421..dbb6be04544b 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -57,8 +57,7 @@ enum class ErrorPolicy { Halt, Continue }; /// This data structure is the top level entity that deals with dwarf debug /// information parsing. The actual data is supplied through DWARFObj. class DWARFContext : public DIContext { - DWARFUnitSection<DWARFCompileUnit> CUs; - std::deque<DWARFUnitSection<DWARFTypeUnit>> TUs; + DWARFUnitVector NormalUnits; std::unique_ptr<DWARFUnitIndex> CUIndex; std::unique_ptr<DWARFGdbIndex> GdbIndex; std::unique_ptr<DWARFUnitIndex> TUIndex; @@ -75,10 +74,9 @@ class DWARFContext : public DIContext { std::unique_ptr<AppleAcceleratorTable> AppleNamespaces; std::unique_ptr<AppleAcceleratorTable> AppleObjC; - DWARFUnitSection<DWARFCompileUnit> DWOCUs; - std::deque<DWARFUnitSection<DWARFTypeUnit>> DWOTUs; + DWARFUnitVector DWOUnits; std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO; - std::unique_ptr<DWARFDebugLocDWO> LocDWO; + std::unique_ptr<DWARFDebugLoclists> LocDWO; /// The maximum DWARF version of all units. unsigned MaxVersion = 0; @@ -95,22 +93,17 @@ class DWARFContext : public DIContext { std::unique_ptr<MCRegisterInfo> RegInfo; /// Read compile units from the debug_info section (if necessary) - /// and store them in CUs. - void parseCompileUnits(); - - /// Read type units from the debug_types sections (if necessary) - /// and store them in TUs. - void parseTypeUnits(); + /// and type units from the debug_types sections (if necessary) + /// and store them in NormalUnits. + void parseNormalUnits(); /// Read compile units from the debug_info.dwo section (if necessary) - /// and store them in DWOCUs. - void parseDWOCompileUnits(); - - /// Read type units from the debug_types.dwo section (if necessary) - /// and store them in DWOTUs. - void parseDWOTypeUnits(); + /// and type units from the debug_types.dwo section (if necessary) + /// and store them in DWOUnits. + /// If \p Lazy is true, set up to parse but don't actually parse them. + enum { EagerParse = false, LazyParse = true }; + void parseDWOUnits(bool Lazy = false); -protected: std::unique_ptr<const DWARFObject> DObj; public: @@ -139,68 +132,95 @@ public: bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override; - using cu_iterator_range = DWARFUnitSection<DWARFCompileUnit>::iterator_range; - using tu_iterator_range = DWARFUnitSection<DWARFTypeUnit>::iterator_range; - using tu_section_iterator_range = iterator_range<decltype(TUs)::iterator>; + using unit_iterator_range = DWARFUnitVector::iterator_range; - /// Get compile units in this context. - cu_iterator_range compile_units() { - parseCompileUnits(); - return cu_iterator_range(CUs.begin(), CUs.end()); + /// Get units from .debug_info in this context. + unit_iterator_range info_section_units() { + parseNormalUnits(); + return unit_iterator_range(NormalUnits.begin(), + NormalUnits.begin() + + NormalUnits.getNumInfoUnits()); } + /// Get units from .debug_types in this context. + unit_iterator_range types_section_units() { + parseNormalUnits(); + return unit_iterator_range( + NormalUnits.begin() + NormalUnits.getNumInfoUnits(), NormalUnits.end()); + } + + /// Get compile units in this context. + unit_iterator_range compile_units() { return info_section_units(); } + /// Get type units in this context. - tu_section_iterator_range type_unit_sections() { - parseTypeUnits(); - return tu_section_iterator_range(TUs.begin(), TUs.end()); + unit_iterator_range type_units() { return types_section_units(); } + + /// Get all normal compile/type units in this context. + unit_iterator_range normal_units() { + parseNormalUnits(); + return unit_iterator_range(NormalUnits.begin(), NormalUnits.end()); } - /// Get compile units in the DWO context. - cu_iterator_range dwo_compile_units() { - parseDWOCompileUnits(); - return cu_iterator_range(DWOCUs.begin(), DWOCUs.end()); + /// Get units from .debug_info..dwo in the DWO context. + unit_iterator_range dwo_info_section_units() { + parseDWOUnits(); + return unit_iterator_range(DWOUnits.begin(), + DWOUnits.begin() + DWOUnits.getNumInfoUnits()); + } + + /// Get units from .debug_types.dwo in the DWO context. + unit_iterator_range dwo_types_section_units() { + parseDWOUnits(); + return unit_iterator_range(DWOUnits.begin() + DWOUnits.getNumInfoUnits(), + DWOUnits.end()); } + /// Get compile units in the DWO context. + unit_iterator_range dwo_compile_units() { return dwo_info_section_units(); } + /// Get type units in the DWO context. - tu_section_iterator_range dwo_type_unit_sections() { - parseDWOTypeUnits(); - return tu_section_iterator_range(DWOTUs.begin(), DWOTUs.end()); + unit_iterator_range dwo_type_units() { return dwo_types_section_units(); } + + /// Get all units in the DWO context. + unit_iterator_range dwo_units() { + parseDWOUnits(); + return unit_iterator_range(DWOUnits.begin(), DWOUnits.end()); } /// Get the number of compile units in this context. unsigned getNumCompileUnits() { - parseCompileUnits(); - return CUs.size(); + parseNormalUnits(); + return NormalUnits.getNumInfoUnits(); } - /// Get the number of compile units in this context. + /// Get the number of type units in this context. unsigned getNumTypeUnits() { - parseTypeUnits(); - return TUs.size(); + parseNormalUnits(); + return NormalUnits.getNumTypesUnits(); } /// Get the number of compile units in the DWO context. unsigned getNumDWOCompileUnits() { - parseDWOCompileUnits(); - return DWOCUs.size(); + parseDWOUnits(); + return DWOUnits.getNumInfoUnits(); } - /// Get the number of compile units in the DWO context. + /// Get the number of type units in the DWO context. unsigned getNumDWOTypeUnits() { - parseDWOTypeUnits(); - return DWOTUs.size(); + parseDWOUnits(); + return DWOUnits.getNumTypesUnits(); } - /// Get the compile unit at the specified index for this compile unit. - DWARFCompileUnit *getCompileUnitAtIndex(unsigned index) { - parseCompileUnits(); - return CUs[index].get(); + /// Get the unit at the specified index. + DWARFUnit *getUnitAtIndex(unsigned index) { + parseNormalUnits(); + return NormalUnits[index].get(); } - /// Get the compile unit at the specified index for the DWO compile units. - DWARFCompileUnit *getDWOCompileUnitAtIndex(unsigned index) { - parseDWOCompileUnits(); - return DWOCUs[index].get(); + /// Get the unit at the specified index for the DWO units. + DWARFUnit *getDWOUnitAtIndex(unsigned index) { + parseDWOUnits(); + return DWOUnits[index].get(); } DWARFCompileUnit *getDWOCompileUnitForHash(uint64_t Hash); @@ -211,7 +231,17 @@ public: /// Get a DIE given an exact offset. DWARFDie getDIEForOffset(uint32_t Offset); - unsigned getMaxVersion() const { return MaxVersion; } + unsigned getMaxVersion() { + // Ensure info units have been parsed to discover MaxVersion + info_section_units(); + return MaxVersion; + } + + unsigned getMaxDWOVersion() { + // Ensure DWO info units have been parsed to discover MaxVersion + dwo_info_section_units(); + return MaxVersion; + } void setMaxVersionIfGreater(unsigned Version) { if (Version > MaxVersion) @@ -232,7 +262,7 @@ public: const DWARFDebugAbbrev *getDebugAbbrevDWO(); /// Get a pointer to the parsed DebugLoc object. - const DWARFDebugLocDWO *getDebugLocDWO(); + const DWARFDebugLoclists *getDebugLocDWO(); /// Get a pointer to the parsed DebugAranges object. const DWARFDebugAranges *getDebugAranges(); @@ -327,6 +357,13 @@ public: /// TODO: refactor compile_units() to make this const. uint8_t getCUAddrSize(); + /// Dump Error as warning message to stderr. + static void dumpWarning(Error Warning); + + Triple::ArchType getArch() const { + return getDWARFObj().getFile()->getArch(); + } + private: /// Return the compile unit which contains instruction with provided /// address. diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h b/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h index ff1c7fb38389..7dc07d774aba 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h @@ -13,6 +13,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/iterator.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/Triple.h" #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" #include "llvm/DebugInfo/DWARF/DWARFExpression.h" #include "llvm/Support/Error.h" @@ -59,9 +60,11 @@ public: unsigned size() const { return (unsigned)Instructions.size(); } bool empty() const { return Instructions.empty(); } - CFIProgram(uint64_t CodeAlignmentFactor, int64_t DataAlignmentFactor) + CFIProgram(uint64_t CodeAlignmentFactor, int64_t DataAlignmentFactor, + Triple::ArchType Arch) : CodeAlignmentFactor(CodeAlignmentFactor), - DataAlignmentFactor(DataAlignmentFactor) {} + DataAlignmentFactor(DataAlignmentFactor), + Arch(Arch) {} /// Parse and store a sequence of CFI instructions from Data, /// starting at *Offset and ending at EndOffset. *Offset is updated @@ -76,6 +79,7 @@ private: std::vector<Instruction> Instructions; const uint64_t CodeAlignmentFactor; const int64_t DataAlignmentFactor; + Triple::ArchType Arch; /// Convenience method to add a new instruction with the given opcode. void addInstruction(uint8_t Opcode) { @@ -130,8 +134,9 @@ public: enum FrameKind { FK_CIE, FK_FDE }; FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length, uint64_t CodeAlign, - int64_t DataAlign) - : Kind(K), Offset(Offset), Length(Length), CFIs(CodeAlign, DataAlign) {} + int64_t DataAlign, Triple::ArchType Arch) + : Kind(K), Offset(Offset), Length(Length), + CFIs(CodeAlign, DataAlign, Arch) {} virtual ~FrameEntry() {} @@ -168,9 +173,9 @@ public: int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister, SmallString<8> AugmentationData, uint32_t FDEPointerEncoding, uint32_t LSDAPointerEncoding, Optional<uint64_t> Personality, - Optional<uint32_t> PersonalityEnc) + Optional<uint32_t> PersonalityEnc, Triple::ArchType Arch) : FrameEntry(FK_CIE, Offset, Length, CodeAlignmentFactor, - DataAlignmentFactor), + DataAlignmentFactor, Arch), Version(Version), Augmentation(std::move(Augmentation)), AddressSize(AddressSize), SegmentDescriptorSize(SegmentDescriptorSize), CodeAlignmentFactor(CodeAlignmentFactor), @@ -224,10 +229,11 @@ public: // is obtained lazily once it's actually required. FDE(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset, uint64_t InitialLocation, uint64_t AddressRange, CIE *Cie, - Optional<uint64_t> LSDAAddress) + Optional<uint64_t> LSDAAddress, Triple::ArchType Arch) : FrameEntry(FK_FDE, Offset, Length, Cie ? Cie->getCodeAlignmentFactor() : 0, - Cie ? Cie->getDataAlignmentFactor() : 0), + Cie ? Cie->getDataAlignmentFactor() : 0, + Arch), LinkedCIEOffset(LinkedCIEOffset), InitialLocation(InitialLocation), AddressRange(AddressRange), LinkedCIE(Cie), LSDAAddress(LSDAAddress) {} @@ -256,6 +262,7 @@ private: /// A parsed .debug_frame or .eh_frame section class DWARFDebugFrame { + const Triple::ArchType Arch; // True if this is parsing an eh_frame section. const bool IsEH; // Not zero for sane pointer values coming out of eh_frame @@ -272,7 +279,8 @@ public: // it is a .debug_frame section. EHFrameAddress should be different // than zero for correct parsing of .eh_frame addresses when they // use a PC-relative encoding. - DWARFDebugFrame(bool IsEH = false, uint64_t EHFrameAddress = 0); + DWARFDebugFrame(Triple::ArchType Arch, + bool IsEH = false, uint64_t EHFrameAddress = 0); ~DWARFDebugFrame(); /// Dump the section data into the given stream. diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h index 5b2af34bbcf5..d50af5a057f1 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h @@ -247,10 +247,11 @@ public: void clear(); /// Parse prologue and all rows. - Error parse(DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr, - const DWARFContext &Ctx, const DWARFUnit *U, - std::function<void(Error)> RecoverableErrorCallback = warn, - raw_ostream *OS = nullptr); + Error parse( + DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr, + const DWARFContext &Ctx, const DWARFUnit *U, + std::function<void(Error)> RecoverableErrorCallback, + raw_ostream *OS = nullptr); using RowVector = std::vector<Row>; using RowIter = RowVector::const_iterator; @@ -273,14 +274,13 @@ public: Expected<const LineTable *> getOrParseLineTable( DWARFDataExtractor &DebugLineData, uint32_t Offset, const DWARFContext &Ctx, const DWARFUnit *U, - std::function<void(Error)> RecoverableErrorCallback = warn); + std::function<void(Error)> RecoverableErrorCallback); /// Helper to allow for parsing of an entire .debug_line section in sequence. class SectionParser { public: - using cu_range = DWARFUnitSection<DWARFCompileUnit>::iterator_range; - using tu_range = - iterator_range<std::deque<DWARFUnitSection<DWARFTypeUnit>>::iterator>; + using cu_range = DWARFUnitVector::iterator_range; + using tu_range = DWARFUnitVector::iterator_range; using LineToUnitMap = std::map<uint64_t, DWARFUnit *>; SectionParser(DWARFDataExtractor &Data, const DWARFContext &C, cu_range CUs, @@ -296,16 +296,17 @@ public: /// \param OS - if not null, the parser will print information about the /// table as it parses it. LineTable - parseNext(function_ref<void(Error)> RecoverableErrorCallback = warn, - function_ref<void(Error)> UnrecoverableErrorCallback = warn, - raw_ostream *OS = nullptr); + parseNext( + function_ref<void(Error)> RecoverableErrorCallback, + function_ref<void(Error)> UnrecoverableErrorCallback, + raw_ostream *OS = nullptr); /// Skip the current line table and go to the following line table (if /// present) immediately. /// /// \param ErrorCallback - report any prologue parsing issues via this /// callback. - void skip(function_ref<void(Error)> ErrorCallback = warn); + void skip(function_ref<void(Error)> ErrorCallback); /// Indicates if the parser has parsed as much as possible. /// @@ -328,12 +329,6 @@ public: bool Done = false; }; - /// Helper function for DWARFDebugLine parse functions, to report issues - /// identified during parsing. - /// - /// \param Err The Error to report. - static void warn(Error Err); - private: struct ParsingState { ParsingState(struct LineTable *LT); diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h index 9a73745fb6b4..da2098e15402 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h @@ -73,19 +73,21 @@ public: uint32_t *Offset); }; -class DWARFDebugLocDWO { +class DWARFDebugLoclists { public: struct Entry { - uint64_t Start; - uint32_t Length; + uint8_t Kind; + uint64_t Value0; + uint64_t Value1; SmallVector<char, 4> Loc; }; struct LocationList { unsigned Offset; SmallVector<Entry, 2> Entries; - void dump(raw_ostream &OS, bool IsLittleEndian, unsigned AddressSize, - const MCRegisterInfo *RegInfo, unsigned Indent) const; + void dump(raw_ostream &OS, uint64_t BaseAddr, bool IsLittleEndian, + unsigned AddressSize, const MCRegisterInfo *RegInfo, + unsigned Indent) const; }; private: @@ -98,15 +100,15 @@ private: bool IsLittleEndian; public: - void parse(DataExtractor data); - void dump(raw_ostream &OS, const MCRegisterInfo *RegInfo, + void parse(DataExtractor data, unsigned Version); + void dump(raw_ostream &OS, uint64_t BaseAddr, const MCRegisterInfo *RegInfo, Optional<uint64_t> Offset) const; /// Return the location list at the given offset or nullptr. LocationList const *getLocationListAtOffset(uint64_t Offset) const; - static Optional<LocationList> parseOneLocationList(DataExtractor Data, - uint32_t *Offset); + static Optional<LocationList> + parseOneLocationList(DataExtractor Data, unsigned *Offset, unsigned Version); }; } // end namespace llvm diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h b/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h index cae4804e61d3..9e1656eb1615 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h @@ -13,6 +13,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/DebugInfo/DWARF/DWARFObject.h" #include <cstdint> #include <vector> @@ -67,7 +68,8 @@ private: bool GnuStyle; public: - DWARFDebugPubTable(StringRef Data, bool LittleEndian, bool GnuStyle); + DWARFDebugPubTable(const DWARFObject &Obj, const DWARFSection &Sec, + bool LittleEndian, bool GnuStyle); void dump(raw_ostream &OS) const; diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h b/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h index ce7436d9faa3..bc26edf00647 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h @@ -18,7 +18,6 @@ namespace llvm { -struct BaseAddress; class raw_ostream; class DWARFDebugRangeList { @@ -78,7 +77,7 @@ public: /// list. Has to be passed base address of the compile unit referencing this /// range list. DWARFAddressRangesVector - getAbsoluteRanges(llvm::Optional<BaseAddress> BaseAddr) const; + getAbsoluteRanges(llvm::Optional<SectionedAddress> BaseAddr) const; }; } // end namespace llvm diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h b/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h index e2e8ab5ed219..5cc8d789e598 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h @@ -10,6 +10,7 @@ #ifndef LLVM_DEBUGINFO_DWARFDEBUGRNGLISTS_H #define LLVM_DEBUGINFO_DWARFDEBUGRNGLISTS_H +#include "llvm/ADT/Optional.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/DebugInfo/DIContext.h" #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" @@ -23,6 +24,7 @@ namespace llvm { class Error; class raw_ostream; +class DWARFUnit; /// A class representing a single range list entry. struct RangeListEntry : public DWARFListEntryBase { @@ -35,7 +37,9 @@ struct RangeListEntry : public DWARFListEntryBase { Error extract(DWARFDataExtractor Data, uint32_t End, uint32_t *OffsetPtr); void dump(raw_ostream &OS, uint8_t AddrSize, uint8_t MaxEncodingStringLength, - uint64_t &CurrentBase, DIDumpOptions DumpOpts) const; + uint64_t &CurrentBase, DIDumpOptions DumpOpts, + llvm::function_ref<Optional<SectionedAddress>(uint32_t)> + LookupPooledAddress) const; bool isSentinel() const { return EntryKind == dwarf::DW_RLE_end_of_list; } }; @@ -44,7 +48,8 @@ class DWARFDebugRnglist : public DWARFListType<RangeListEntry> { public: /// Build a DWARFAddressRangesVector from a rangelist. DWARFAddressRangesVector - getAbsoluteRanges(llvm::Optional<BaseAddress> BaseAddr) const; + getAbsoluteRanges(llvm::Optional<SectionedAddress> BaseAddr, + DWARFUnit &U) const; }; class DWARFDebugRnglistTable : public DWARFListTableBase<DWARFDebugRnglist> { diff --git a/include/llvm/DebugInfo/DWARF/DWARFDie.h b/include/llvm/DebugInfo/DWARF/DWARFDie.h index c77034f6348f..56d46cd739a2 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDie.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDie.h @@ -180,6 +180,7 @@ public: /// \returns a valid DWARFDie instance if the attribute exists, or an invalid /// DWARFDie object if it doesn't. DWARFDie getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const; + DWARFDie getAttributeValueAsReferencedDie(const DWARFFormValue &V) const; /// Extract the range base attribute from this DIE as absolute section offset. /// @@ -404,6 +405,10 @@ public: Die = Die.getPreviousSibling(); } + llvm::DWARFDie::iterator base() const { + return llvm::DWARFDie::iterator(AtEnd ? Die : Die.getSibling()); + } + reverse_iterator<llvm::DWARFDie::iterator> &operator++() { assert(!AtEnd && "Incrementing rend"); llvm::DWARFDie D = Die.getPreviousSibling(); diff --git a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h index 1b5f71c946f9..727e853c09fb 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h +++ b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h @@ -61,7 +61,6 @@ public: dwarf::Form getForm() const { return Form; } uint64_t getRawUValue() const { return Value.uval; } - uint64_t getSectionIndex() const { return Value.SectionIndex; } void setForm(dwarf::Form F) { Form = F; } void setUValue(uint64_t V) { Value.uval = V; } void setSValue(int64_t V) { Value.sval = V; } @@ -75,6 +74,10 @@ public: bool isFormClass(FormClass FC) const; const DWARFUnit *getUnit() const { return U; } void dump(raw_ostream &OS, DIDumpOptions DumpOpts = DIDumpOptions()) const; + void dumpSectionedAddress(raw_ostream &OS, DIDumpOptions DumpOpts, + SectionedAddress SA) const; + static void dumpAddressSection(const DWARFObject &Obj, raw_ostream &OS, + DIDumpOptions DumpOpts, uint64_t SectionIndex); /// Extracts a value in \p Data at offset \p *OffsetPtr. The information /// in \p FormParams is needed to interpret some forms. The optional @@ -101,6 +104,7 @@ public: Optional<int64_t> getAsSignedConstant() const; Optional<const char *> getAsCString() const; Optional<uint64_t> getAsAddress() const; + Optional<SectionedAddress> getAsSectionedAddress() const; Optional<uint64_t> getAsSectionOffset() const; Optional<ArrayRef<uint8_t>> getAsBlock() const; Optional<uint64_t> getAsCStringOffset() const; @@ -238,6 +242,13 @@ inline Optional<uint64_t> toAddress(const Optional<DWARFFormValue> &V) { return None; } +inline Optional<SectionedAddress> +toSectionedAddress(const Optional<DWARFFormValue> &V) { + if (V) + return V->getAsSectionedAddress(); + return None; +} + /// Take an optional DWARFFormValue and extract a address. /// /// \param V and optional DWARFFormValue to attempt to extract the value from. diff --git a/include/llvm/DebugInfo/DWARF/DWARFGdbIndex.h b/include/llvm/DebugInfo/DWARF/DWARFGdbIndex.h index 8d1ac5c83c23..073e02903c39 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFGdbIndex.h +++ b/include/llvm/DebugInfo/DWARF/DWARFGdbIndex.h @@ -24,6 +24,7 @@ class DWARFGdbIndex { uint32_t Version; uint32_t CuListOffset; + uint32_t TuListOffset; uint32_t AddressAreaOffset; uint32_t SymbolTableOffset; uint32_t ConstantPoolOffset; @@ -34,6 +35,13 @@ class DWARFGdbIndex { }; SmallVector<CompUnitEntry, 0> CuList; + struct TypeUnitEntry { + uint64_t Offset; + uint64_t TypeOffset; + uint64_t TypeSignature; + }; + SmallVector<TypeUnitEntry, 0> TuList; + struct AddressEntry { uint64_t LowAddress; /// The low address. uint64_t HighAddress; /// The high address. @@ -55,6 +63,7 @@ class DWARFGdbIndex { uint32_t StringPoolOffset; void dumpCUList(raw_ostream &OS) const; + void dumpTUList(raw_ostream &OS) const; void dumpAddressArea(raw_ostream &OS) const; void dumpSymbolTable(raw_ostream &OS) const; void dumpConstantPool(raw_ostream &OS) const; diff --git a/include/llvm/DebugInfo/DWARF/DWARFListTable.h b/include/llvm/DebugInfo/DWARF/DWARFListTable.h index ab12f3bc08b0..9b987314f209 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFListTable.h +++ b/include/llvm/DebugInfo/DWARF/DWARFListTable.h @@ -13,6 +13,7 @@ #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/DebugInfo/DIContext.h" #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" +#include "llvm/Support/Errc.h" #include "llvm/Support/Error.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" @@ -43,10 +44,6 @@ protected: ListEntries Entries; public: - // FIXME: We need to consolidate the various verions of "createError" - // that are used in the DWARF consumer. Until then, this is a workaround. - Error createError(const char *, const char *, uint32_t); - const ListEntries &getEntries() const { return Entries; } bool empty() const { return Entries.empty(); } void clear() { Entries.clear(); } @@ -102,6 +99,7 @@ public: uint32_t getHeaderOffset() const { return HeaderOffset; } uint8_t getAddrSize() const { return HeaderData.AddrSize; } uint32_t getLength() const { return HeaderData.Length; } + uint16_t getVersion() const { return HeaderData.Version; } StringRef getSectionName() const { return SectionName; } StringRef getListTypeString() const { return ListTypeString; } dwarf::DwarfFormat getFormat() const { return Format; } @@ -159,7 +157,10 @@ public: uint32_t getHeaderOffset() const { return Header.getHeaderOffset(); } uint8_t getAddrSize() const { return Header.getAddrSize(); } - void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {}) const; + void dump(raw_ostream &OS, + llvm::function_ref<Optional<SectionedAddress>(uint32_t)> + LookupPooledAddress, + DIDumpOptions DumpOpts = {}) const; /// Return the contents of the offset entry designated by a given index. Optional<uint32_t> getOffsetEntry(uint32_t Index) const { @@ -213,7 +214,8 @@ Error DWARFListType<ListEntryType>::extract(DWARFDataExtractor Data, StringRef SectionName, StringRef ListTypeString) { if (*OffsetPtr < HeaderOffset || *OffsetPtr >= End) - return createError("invalid %s list offset 0x%" PRIx32, + return createStringError(errc::invalid_argument, + "invalid %s list offset 0x%" PRIx32, ListTypeString.data(), *OffsetPtr); Entries.clear(); while (*OffsetPtr < End) { @@ -224,14 +226,18 @@ Error DWARFListType<ListEntryType>::extract(DWARFDataExtractor Data, if (Entry.isSentinel()) return Error::success(); } - return createError("no end of list marker detected at end of %s table " + return createStringError(errc::illegal_byte_sequence, + "no end of list marker detected at end of %s table " "starting at offset 0x%" PRIx32, SectionName.data(), HeaderOffset); } template <typename DWARFListType> -void DWARFListTableBase<DWARFListType>::dump(raw_ostream &OS, - DIDumpOptions DumpOpts) const { +void DWARFListTableBase<DWARFListType>::dump( + raw_ostream &OS, + llvm::function_ref<Optional<SectionedAddress>(uint32_t)> + LookupPooledAddress, + DIDumpOptions DumpOpts) const { Header.dump(OS, DumpOpts); OS << HeaderString << "\n"; @@ -250,7 +256,7 @@ void DWARFListTableBase<DWARFListType>::dump(raw_ostream &OS, for (const auto &List : ListMap) for (const auto &Entry : List.second.getEntries()) Entry.dump(OS, getAddrSize(), MaxEncodingStringLength, CurrentBase, - DumpOpts); + DumpOpts, LookupPooledAddress); } template <typename DWARFListType> diff --git a/include/llvm/DebugInfo/DWARF/DWARFObject.h b/include/llvm/DebugInfo/DWARF/DWARFObject.h index 6e8f370f4aea..d611b5d075c8 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFObject.h +++ b/include/llvm/DebugInfo/DWARF/DWARFObject.h @@ -33,11 +33,13 @@ public: virtual ArrayRef<SectionName> getSectionNames() const { return {}; } virtual bool isLittleEndian() const = 0; virtual uint8_t getAddressSize() const { llvm_unreachable("unimplemented"); } - virtual const DWARFSection &getInfoSection() const { return Dummy; } + virtual void + forEachInfoSections(function_ref<void(const DWARFSection &)> F) const {} virtual void forEachTypesSections(function_ref<void(const DWARFSection &)> F) const {} virtual StringRef getAbbrevSection() const { return ""; } virtual const DWARFSection &getLocSection() const { return Dummy; } + virtual const DWARFSection &getLoclistsSection() const { return Dummy; } virtual StringRef getARangeSection() const { return ""; } virtual StringRef getDebugFrameSection() const { return ""; } virtual StringRef getEHFrameSection() const { return ""; } @@ -47,12 +49,13 @@ public: virtual const DWARFSection &getRangeSection() const { return Dummy; } virtual const DWARFSection &getRnglistsSection() const { return Dummy; } virtual StringRef getMacinfoSection() const { return ""; } - virtual StringRef getPubNamesSection() const { return ""; } - virtual StringRef getPubTypesSection() const { return ""; } - virtual StringRef getGnuPubNamesSection() const { return ""; } - virtual StringRef getGnuPubTypesSection() const { return ""; } + virtual const DWARFSection &getPubNamesSection() const { return Dummy; } + virtual const DWARFSection &getPubTypesSection() const { return Dummy; } + virtual const DWARFSection &getGnuPubNamesSection() const { return Dummy; } + virtual const DWARFSection &getGnuPubTypesSection() const { return Dummy; } virtual const DWARFSection &getStringOffsetSection() const { return Dummy; } - virtual const DWARFSection &getInfoDWOSection() const { return Dummy; } + virtual void + forEachInfoDWOSections(function_ref<void(const DWARFSection &)> F) const {} virtual void forEachTypesDWOSections(function_ref<void(const DWARFSection &)> F) const {} virtual StringRef getAbbrevDWOSection() const { return ""; } diff --git a/include/llvm/DebugInfo/DWARF/DWARFSection.h b/include/llvm/DebugInfo/DWARF/DWARFSection.h index 77045f0794ae..7f8235965297 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFSection.h +++ b/include/llvm/DebugInfo/DWARF/DWARFSection.h @@ -23,6 +23,11 @@ struct SectionName { bool IsNameUnique; }; +struct SectionedAddress { + uint64_t Address; + uint64_t SectionIndex; +}; + } // end namespace llvm #endif // LLVM_DEBUGINFO_DWARF_DWARFSECTION_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h b/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h index cb5a78ee3dbf..8ca5ba13fc23 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h @@ -26,19 +26,20 @@ class raw_ostream; class DWARFTypeUnit : public DWARFUnit { public: DWARFTypeUnit(DWARFContext &Context, const DWARFSection &Section, - const DWARFUnitHeader &Header, - const DWARFDebugAbbrev *DA, const DWARFSection *RS, + const DWARFUnitHeader &Header, const DWARFDebugAbbrev *DA, + const DWARFSection *RS, const DWARFSection *LocSection, StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS, const DWARFSection &LS, bool LE, bool IsDWO, - const DWARFUnitSectionBase &UnitSection) - : DWARFUnit(Context, Section, Header, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, - UnitSection) {} + const DWARFUnitVector &UnitVector) + : DWARFUnit(Context, Section, Header, DA, RS, LocSection, SS, SOS, AOS, + LS, LE, IsDWO, UnitVector) {} uint64_t getTypeHash() const { return getHeader().getTypeHash(); } uint32_t getTypeOffset() const { return getHeader().getTypeOffset(); } - void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {}); - static const DWARFSectionKind Section = DW_SECT_TYPES; + void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override; + // Enable LLVM-style RTTI. + static bool classof(const DWARFUnit *U) { return U->isTypeUnit(); } }; } // end namespace llvm diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h index 988a7958184c..79c3ce1106d5 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -72,7 +72,8 @@ public: /// Parse a unit header from \p debug_info starting at \p offset_ptr. bool extract(DWARFContext &Context, const DWARFDataExtractor &debug_info, uint32_t *offset_ptr, DWARFSectionKind Kind = DW_SECT_INFO, - const DWARFUnitIndex *Index = nullptr); + const DWARFUnitIndex *Index = nullptr, + const DWARFUnitIndex::Entry *Entry = nullptr); uint32_t getOffset() const { return Offset; } const dwarf::FormParams &getFormParams() const { return FormParams; } uint16_t getVersion() const { return FormParams.Version; } @@ -101,133 +102,66 @@ public: uint32_t getNextUnitOffset() const { return Offset + Length + 4; } }; -/// Base class for all DWARFUnitSection classes. This provides the -/// functionality common to all unit types. -class DWARFUnitSectionBase { -public: - /// Returns the Unit that contains the given section offset in the - /// same section this Unit originated from. - virtual DWARFUnit *getUnitForOffset(uint32_t Offset) const = 0; - virtual DWARFUnit *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) = 0; - - void parse(DWARFContext &C, const DWARFSection &Section); - void parseDWO(DWARFContext &C, const DWARFSection &DWOSection, - bool Lazy = false); - -protected: - ~DWARFUnitSectionBase() = default; - - virtual void parseImpl(DWARFContext &Context, const DWARFObject &Obj, - const DWARFSection &Section, - const DWARFDebugAbbrev *DA, const DWARFSection *RS, - StringRef SS, const DWARFSection &SOS, - const DWARFSection *AOS, const DWARFSection &LS, - bool isLittleEndian, bool isDWO, bool Lazy) = 0; -}; - const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context, DWARFSectionKind Kind); -/// Concrete instance of DWARFUnitSection, specialized for one Unit type. -template<typename UnitType> -class DWARFUnitSection final : public SmallVector<std::unique_ptr<UnitType>, 1>, - public DWARFUnitSectionBase { - bool Parsed = false; - std::function<std::unique_ptr<UnitType>(uint32_t)> Parser; +/// Describe a collection of units. Intended to hold all units either from +/// .debug_info and .debug_types, or from .debug_info.dwo and .debug_types.dwo. +class DWARFUnitVector final : public SmallVector<std::unique_ptr<DWARFUnit>, 1> { + std::function<std::unique_ptr<DWARFUnit>(uint32_t, DWARFSectionKind, + const DWARFSection *, + const DWARFUnitIndex::Entry *)> + Parser; + int NumInfoUnits = -1; public: - using UnitVector = SmallVectorImpl<std::unique_ptr<UnitType>>; + using UnitVector = SmallVectorImpl<std::unique_ptr<DWARFUnit>>; using iterator = typename UnitVector::iterator; using iterator_range = llvm::iterator_range<typename UnitVector::iterator>; - UnitType *getUnitForOffset(uint32_t Offset) const override { - auto *CU = std::upper_bound( - this->begin(), this->end(), Offset, - [](uint32_t LHS, const std::unique_ptr<UnitType> &RHS) { - return LHS < RHS->getNextUnitOffset(); - }); - if (CU != this->end() && (*CU)->getOffset() <= Offset) - return CU->get(); - return nullptr; - } - UnitType *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) override { - const auto *CUOff = E.getOffset(DW_SECT_INFO); - if (!CUOff) - return nullptr; + DWARFUnit *getUnitForOffset(uint32_t Offset) const; + DWARFUnit *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E); - auto Offset = CUOff->Offset; + /// Read units from a .debug_info or .debug_types section. Calls made + /// before finishedInfoUnits() are assumed to be for .debug_info sections, + /// calls after finishedInfoUnits() are for .debug_types sections. Caller + /// must not mix calls to addUnitsForSection and addUnitsForDWOSection. + void addUnitsForSection(DWARFContext &C, const DWARFSection &Section, + DWARFSectionKind SectionKind); + /// Read units from a .debug_info.dwo or .debug_types.dwo section. Calls + /// made before finishedInfoUnits() are assumed to be for .debug_info.dwo + /// sections, calls after finishedInfoUnits() are for .debug_types.dwo + /// sections. Caller must not mix calls to addUnitsForSection and + /// addUnitsForDWOSection. + void addUnitsForDWOSection(DWARFContext &C, const DWARFSection &DWOSection, + DWARFSectionKind SectionKind, bool Lazy = false); - auto *CU = std::upper_bound( - this->begin(), this->end(), CUOff->Offset, - [](uint32_t LHS, const std::unique_ptr<UnitType> &RHS) { - return LHS < RHS->getNextUnitOffset(); - }); - if (CU != this->end() && (*CU)->getOffset() <= Offset) - return CU->get(); - - if (!Parser) - return nullptr; + /// Add an existing DWARFUnit to this UnitVector. This is used by the DWARF + /// verifier to process unit separately. + DWARFUnit *addUnit(std::unique_ptr<DWARFUnit> Unit); - auto U = Parser(Offset); - if (!U) - U = nullptr; - - auto *NewCU = U.get(); - this->insert(CU, std::move(U)); - return NewCU; + /// Returns number of all units held by this instance. + unsigned getNumUnits() const { return size(); } + /// Returns number of units from all .debug_info[.dwo] sections. + unsigned getNumInfoUnits() const { + return NumInfoUnits == -1 ? size() : NumInfoUnits; } + /// Returns number of units from all .debug_types[.dwo] sections. + unsigned getNumTypesUnits() const { return size() - NumInfoUnits; } + /// Indicate that parsing .debug_info[.dwo] is done, and remaining units + /// will be from .debug_types[.dwo]. + void finishedInfoUnits() { NumInfoUnits = size(); } private: - void parseImpl(DWARFContext &Context, const DWARFObject &Obj, - const DWARFSection &Section, const DWARFDebugAbbrev *DA, - const DWARFSection *RS, StringRef SS, const DWARFSection &SOS, - const DWARFSection *AOS, const DWARFSection &LS, bool LE, - bool IsDWO, bool Lazy) override { - if (Parsed) - return; - DWARFDataExtractor Data(Obj, Section, LE, 0); - if (!Parser) { - const DWARFUnitIndex *Index = nullptr; - if (IsDWO) - Index = &getDWARFUnitIndex(Context, UnitType::Section); - Parser = [=, &Context, &Section, &SOS, - &LS](uint32_t Offset) -> std::unique_ptr<UnitType> { - if (!Data.isValidOffset(Offset)) - return nullptr; - DWARFUnitHeader Header; - if (!Header.extract(Context, Data, &Offset, UnitType::Section, Index)) - return nullptr; - auto U = llvm::make_unique<UnitType>( - Context, Section, Header, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, - *this); - return U; - }; - } - if (Lazy) - return; - auto I = this->begin(); - uint32_t Offset = 0; - while (Data.isValidOffset(Offset)) { - if (I != this->end() && (*I)->getOffset() == Offset) { - ++I; - continue; - } - auto U = Parser(Offset); - if (!U) - break; - Offset = U->getNextUnitOffset(); - I = std::next(this->insert(I, std::move(U))); - } - Parsed = true; - } + void addUnitsImpl(DWARFContext &Context, const DWARFObject &Obj, + const DWARFSection &Section, const DWARFDebugAbbrev *DA, + const DWARFSection *RS, const DWARFSection *LocSection, + StringRef SS, const DWARFSection &SOS, + const DWARFSection *AOS, const DWARFSection &LS, bool LE, + bool IsDWO, bool Lazy, DWARFSectionKind SectionKind); }; /// Represents base address of the CU. -struct BaseAddress { - uint64_t Address; - uint64_t SectionIndex; -}; - /// Represents a unit's contribution to the string offsets table. struct StrOffsetsContributionDescriptor { uint64_t Base = 0; @@ -261,14 +195,20 @@ class DWARFUnit { const DWARFDebugAbbrev *Abbrev; const DWARFSection *RangeSection; uint32_t RangeSectionBase; + /// We either keep track of the location list section or its data, depending + /// on whether we are handling a split DWARF section or not. + union { + const DWARFSection *LocSection; + StringRef LocSectionData; + }; const DWARFSection &LineSection; StringRef StringSection; const DWARFSection &StringOffsetSection; const DWARFSection *AddrOffsetSection; uint32_t AddrOffsetSectionBase = 0; bool isLittleEndian; - bool isDWO; - const DWARFUnitSectionBase &UnitSection; + bool IsDWO; + const DWARFUnitVector &UnitVector; /// Start, length, and DWARF format of the unit's contribution to the string /// offsets table (DWARF v5). @@ -278,7 +218,7 @@ class DWARFUnit { Optional<DWARFDebugRnglistTable> RngListTable; mutable const DWARFAbbreviationDeclarationSet *Abbrevs; - llvm::Optional<BaseAddress> BaseAddr; + llvm::Optional<SectionedAddress> BaseAddr; /// The compile unit debug information entry items. std::vector<DWARFDebugInfoEntry> DieArray; @@ -308,28 +248,30 @@ protected: /// length and form. The given offset is expected to be derived from the unit /// DIE's DW_AT_str_offsets_base attribute. Optional<StrOffsetsContributionDescriptor> - determineStringOffsetsTableContribution(DWARFDataExtractor &DA, - uint64_t Offset); + determineStringOffsetsTableContribution(DWARFDataExtractor &DA); /// Find the unit's contribution to the string offsets table and determine its /// length and form. The given offset is expected to be 0 in a dwo file or, /// in a dwp file, the start of the unit's contribution to the string offsets /// table section (as determined by the index table). Optional<StrOffsetsContributionDescriptor> - determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA, - uint64_t Offset); + determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA); public: DWARFUnit(DWARFContext &Context, const DWARFSection &Section, - const DWARFUnitHeader &Header, - const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS, - const DWARFSection &SOS, const DWARFSection *AOS, + const DWARFUnitHeader &Header, const DWARFDebugAbbrev *DA, + const DWARFSection *RS, const DWARFSection *LocSection, + StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS, const DWARFSection &LS, bool LE, bool IsDWO, - const DWARFUnitSectionBase &UnitSection); + const DWARFUnitVector &UnitVector); virtual ~DWARFUnit(); + bool isDWOUnit() const { return IsDWO; } DWARFContext& getContext() const { return Context; } + const DWARFSection &getInfoSection() const { return InfoSection; } + const DWARFSection *getLocSection() const { return LocSection; } + StringRef getLocSectionData() const { return LocSectionData; } uint32_t getOffset() const { return Header.getOffset(); } const dwarf::FormParams &getFormParams() const { return Header.getFormParams(); @@ -342,6 +284,7 @@ public: } uint32_t getLength() const { return Header.getLength(); } uint8_t getUnitType() const { return Header.getUnitType(); } + bool isTypeUnit() const { return Header.isTypeUnit(); } uint32_t getNextUnitOffset() const { return Header.getNextUnitOffset(); } const DWARFSection &getLineSection() const { return LineSection; } StringRef getStringSection() const { return StringSection; } @@ -362,8 +305,8 @@ public: RangeSectionBase = Base; } - bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const; - bool getStringOffsetSectionItem(uint32_t Index, uint64_t &Result) const; + Optional<SectionedAddress> getAddrOffsetSectionItem(uint32_t Index) const; + Optional<uint64_t> getStringOffsetSectionItem(uint32_t Index) const; DWARFDataExtractor getDebugInfoExtractor() const; @@ -433,7 +376,7 @@ public: llvm_unreachable("Invalid UnitType."); } - llvm::Optional<BaseAddress> getBaseAddress(); + llvm::Optional<SectionedAddress> getBaseAddress(); DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) { extractDIEsIfNeeded(ExtractUnitDIEOnly); @@ -467,7 +410,7 @@ public: return None; } - void collectAddressRanges(DWARFAddressRangesVector &CURanges); + Expected<DWARFAddressRangesVector> collectAddressRanges(); /// Returns subprogram DIE with address range encompassing the provided /// address. The pointer is alive as long as parsed compile unit DIEs are not @@ -480,8 +423,8 @@ public: void getInlinedChainForAddress(uint64_t Address, SmallVectorImpl<DWARFDie> &InlinedChain); - /// getUnitSection - Return the DWARFUnitSection containing this unit. - const DWARFUnitSectionBase &getUnitSection() const { return UnitSection; } + /// Return the DWARFUnitVector containing this unit. + const DWARFUnitVector &getUnitVector() const { return UnitVector; } /// Returns the number of DIEs in the unit. Parses the unit /// if necessary. @@ -541,6 +484,7 @@ public: return die_iterator_range(DieArray.begin(), DieArray.end()); } + virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0; private: /// Size in bytes of the .debug_info data associated with this compile unit. size_t getDebugInfoSize() const { diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h b/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h index 49ed4bb222f3..16be5f9401c0 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h +++ b/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h @@ -74,6 +74,7 @@ private: int InfoColumn = -1; std::unique_ptr<DWARFSectionKind[]> ColumnKinds; std::unique_ptr<Entry[]> Rows; + mutable std::vector<Entry *> OffsetLookup; static StringRef getColumnHeader(DWARFSectionKind DS); diff --git a/include/llvm/DebugInfo/DWARF/DWARFVerifier.h b/include/llvm/DebugInfo/DWARF/DWARFVerifier.h index a829510a219d..e47fbea5646e 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFVerifier.h +++ b/include/llvm/DebugInfo/DWARF/DWARFVerifier.h @@ -14,6 +14,7 @@ #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h" #include "llvm/DebugInfo/DWARF/DWARFAddressRange.h" #include "llvm/DebugInfo/DWARF/DWARFDie.h" +#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" #include <cstdint> #include <map> @@ -96,10 +97,14 @@ private: /// lies between to valid DIEs. std::map<uint64_t, std::set<uint32_t>> ReferenceToDIEOffsets; uint32_t NumDebugLineErrors = 0; + // Used to relax some checks that do not currently work portably + bool IsObjectFile; + bool IsMachOObject; raw_ostream &error() const; raw_ostream &warn() const; raw_ostream ¬e() const; + raw_ostream &dump(const DWARFDie &Die, unsigned indent = 0) const; /// Verifies the abbreviations section. /// @@ -113,20 +118,20 @@ private: /// \returns The number of errors that occurred during verification. unsigned verifyAbbrevSection(const DWARFDebugAbbrev *Abbrev); - /// Verifies the header of a unit in the .debug_info section. + /// Verifies the header of a unit in a .debug_info or .debug_types section. /// /// This function currently checks for: /// - Unit is in 32-bit DWARF format. The function can be modified to /// support 64-bit format. /// - The DWARF version is valid /// - The unit type is valid (if unit is in version >=5) - /// - The unit doesn't extend beyond .debug_info section + /// - The unit doesn't extend beyond the containing section /// - The address size is valid /// - The offset in the .debug_abbrev section is valid /// - /// \param DebugInfoData The .debug_info section data + /// \param DebugInfoData The section data /// \param Offset A reference to the offset start of the unit. The offset will - /// be updated to point to the next unit in .debug_info + /// be updated to point to the next unit in the section /// \param UnitIndex The index of the unit to be verified /// \param UnitType A reference to the type of the unit /// \param isUnitDWARF64 A reference to a flag that shows whether the unit is @@ -137,7 +142,7 @@ private: uint32_t *Offset, unsigned UnitIndex, uint8_t &UnitType, bool &isUnitDWARF64); - /// Verifies the header of a unit in the .debug_info section. + /// Verifies the header of a unit in a .debug_info or .debug_types section. /// /// This function currently verifies: /// - The debug info attributes. @@ -146,13 +151,29 @@ private: /// - That the root DIE is a unit DIE. /// - If a unit type is provided, that the unit DIE matches the unit type. /// - The DIE ranges. + /// - That call site entries are only nested within subprograms with a + /// DW_AT_call attribute. /// - /// \param Unit The DWARF Unit to verifiy. - /// \param UnitType An optional unit type which will be used to verify the - /// type of the unit DIE. + /// \param Unit The DWARF Unit to verify. /// - /// \returns true if the content is verified successfully, false otherwise. - bool verifyUnitContents(DWARFUnit &Unit, uint8_t UnitType = 0); + /// \returns The number of errors that occurred during verification. + unsigned verifyUnitContents(DWARFUnit &Unit); + + /// Verifies the unit headers and contents in a .debug_info or .debug_types + /// section. + /// + /// \param S The DWARF Section to verify. + /// \param SectionKind The object-file section kind that S comes from. + /// + /// \returns The number of errors that occurred during verification. + unsigned verifyUnitSection(const DWARFSection &S, + DWARFSectionKind SectionKind); + + /// Verifies that a call site entry is nested within a subprogram with a + /// DW_AT_call attribute. + /// + /// \returns Number of errors that occurred during verification. + unsigned verifyDebugInfoCallSite(const DWARFDie &Die); /// Verify that all Die ranges are valid. /// @@ -172,7 +193,7 @@ private: /// \param AttrValue The DWARF attribute value to check /// /// \returns NumErrors The number of errors occurred during verification of - /// attributes' values in a .debug_info section unit + /// attributes' values in a unit unsigned verifyDebugInfoAttribute(const DWARFDie &Die, DWARFAttribute &AttrValue); @@ -180,14 +201,14 @@ private: /// /// This function currently checks for: /// - All DW_FORM_ref values that are CU relative have valid CU offsets - /// - All DW_FORM_ref_addr values have valid .debug_info offsets + /// - All DW_FORM_ref_addr values have valid section offsets /// - All DW_FORM_strp values have valid .debug_str offsets /// /// \param Die The DWARF DIE that owns the attribute value /// \param AttrValue The DWARF attribute value to check /// /// \returns NumErrors The number of errors occurred during verification of - /// attributes' forms in a .debug_info section unit + /// attributes' forms in a unit unsigned verifyDebugInfoForm(const DWARFDie &Die, DWARFAttribute &AttrValue); /// Verifies the all valid references that were found when iterating through @@ -199,7 +220,7 @@ private: /// CU relative and absolute references. /// /// \returns NumErrors The number of errors occurred during verification of - /// references for the .debug_info section + /// references for the .debug_info and .debug_types sections unsigned verifyDebugInfoReferences(); /// Verify the DW_AT_stmt_list encoding and value and ensure that no @@ -268,8 +289,8 @@ private: public: DWARFVerifier(raw_ostream &S, DWARFContext &D, - DIDumpOptions DumpOpts = DIDumpOptions::getForSingleDIE()) - : OS(S), DCtx(D), DumpOpts(std::move(DumpOpts)) {} + DIDumpOptions DumpOpts = DIDumpOptions::getForSingleDIE()); + /// Verify the information in any of the following sections, if available: /// .debug_abbrev, debug_abbrev.dwo /// @@ -280,12 +301,12 @@ public: /// false otherwise. bool handleDebugAbbrev(); - /// Verify the information in the .debug_info section. + /// Verify the information in the .debug_info and .debug_types sections. /// - /// Any errors are reported to the stream that was this object was + /// Any errors are reported to the stream that this object was /// constructed with. /// - /// \returns true if the .debug_info verifies successfully, false otherwise. + /// \returns true if all sections verify successfully, false otherwise. bool handleDebugInfo(); /// Verify the information in the .debug_line section. diff --git a/include/llvm/DebugInfo/MSF/MSFError.h b/include/llvm/DebugInfo/MSF/MSFError.h index e66aeca3cd45..5c043a7837b3 100644 --- a/include/llvm/DebugInfo/MSF/MSFError.h +++ b/include/llvm/DebugInfo/MSF/MSFError.h @@ -24,22 +24,28 @@ enum class msf_error_code { invalid_format, block_in_use }; +} // namespace msf +} // namespace llvm + +namespace std { +template <> +struct is_error_code_enum<llvm::msf::msf_error_code> : std::true_type {}; +} // namespace std + +namespace llvm { +namespace msf { +const std::error_category &MSFErrCategory(); + +inline std::error_code make_error_code(msf_error_code E) { + return std::error_code(static_cast<int>(E), MSFErrCategory()); +} /// Base class for errors originating when parsing raw PDB files -class MSFError : public ErrorInfo<MSFError> { +class MSFError : public ErrorInfo<MSFError, StringError> { public: + using ErrorInfo<MSFError, StringError>::ErrorInfo; // inherit constructors + MSFError(const Twine &S) : ErrorInfo(S, msf_error_code::unspecified) {} static char ID; - MSFError(msf_error_code C); - MSFError(const std::string &Context); - MSFError(msf_error_code C, const std::string &Context); - - void log(raw_ostream &OS) const override; - const std::string &getErrorMessage() const; - std::error_code convertToErrorCode() const override; - -private: - std::string ErrMsg; - msf_error_code Code; }; } // namespace msf } // namespace llvm diff --git a/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h b/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h index 9713dce362d2..ac7f19637ab1 100644 --- a/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h +++ b/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h @@ -43,11 +43,6 @@ public: void reset() override { Enumerator->reset(); } - ConcreteSymbolEnumerator<ChildType> *clone() const override { - std::unique_ptr<IPDBEnumSymbols> WrappedClone(Enumerator->clone()); - return new ConcreteSymbolEnumerator<ChildType>(std::move(WrappedClone)); - } - private: std::unique_ptr<IPDBEnumSymbols> Enumerator; diff --git a/include/llvm/DebugInfo/PDB/DIA/DIADataStream.h b/include/llvm/DebugInfo/PDB/DIA/DIADataStream.h index 930bea6060b2..881d7329ab66 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIADataStream.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIADataStream.h @@ -24,7 +24,6 @@ public: llvm::Optional<RecordType> getItemAtIndex(uint32_t Index) const override; bool getNext(RecordType &Record) override; void reset() override; - DIADataStream *clone() const override; private: CComPtr<IDiaEnumDebugStreamData> StreamData; diff --git a/include/llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h b/include/llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h index ffae6645e94b..1f129052d034 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h @@ -27,7 +27,6 @@ public: ChildTypePtr getChildAtIndex(uint32_t Index) const override; ChildTypePtr getNext() override; void reset() override; - DIAEnumDebugStreams *clone() const override; private: CComPtr<IDiaEnumDebugStreams> Enumerator; diff --git a/include/llvm/DebugInfo/PDB/DIA/DIAEnumFrameData.h b/include/llvm/DebugInfo/PDB/DIA/DIAEnumFrameData.h new file mode 100644 index 000000000000..f3b02f07e648 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/DIA/DIAEnumFrameData.h @@ -0,0 +1,36 @@ +//==- DIAEnumFrameData.h --------------------------------------- -*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_PDB_DIA_DIAENUMFRAMEDATA_H +#define LLVM_DEBUGINFO_PDB_DIA_DIAENUMFRAMEDATA_H + +#include "DIASupport.h" +#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" +#include "llvm/DebugInfo/PDB/IPDBFrameData.h" + +namespace llvm { +namespace pdb { + +class DIAEnumFrameData : public IPDBEnumChildren<IPDBFrameData> { +public: + explicit DIAEnumFrameData(CComPtr<IDiaEnumFrameData> DiaEnumerator); + + uint32_t getChildCount() const override; + ChildTypePtr getChildAtIndex(uint32_t Index) const override; + ChildTypePtr getNext() override; + void reset() override; + +private: + CComPtr<IDiaEnumFrameData> Enumerator; +}; + +} // namespace pdb +} // namespace llvm + +#endif diff --git a/include/llvm/DebugInfo/PDB/DIA/DIAEnumInjectedSources.h b/include/llvm/DebugInfo/PDB/DIA/DIAEnumInjectedSources.h index 39490a4b2209..4669a8d31196 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIAEnumInjectedSources.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIAEnumInjectedSources.h @@ -16,22 +16,18 @@ namespace llvm { namespace pdb { -class DIASession; class DIAEnumInjectedSources : public IPDBEnumChildren<IPDBInjectedSource> { public: explicit DIAEnumInjectedSources( - const DIASession &PDBSession, CComPtr<IDiaEnumInjectedSources> DiaEnumerator); uint32_t getChildCount() const override; ChildTypePtr getChildAtIndex(uint32_t Index) const override; ChildTypePtr getNext() override; void reset() override; - DIAEnumInjectedSources *clone() const override; private: - const DIASession &Session; CComPtr<IDiaEnumInjectedSources> Enumerator; }; } // namespace pdb diff --git a/include/llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h b/include/llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h index 08f0de124ede..f1cb6268a26d 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h @@ -26,7 +26,6 @@ public: ChildTypePtr getChildAtIndex(uint32_t Index) const override; ChildTypePtr getNext() override; void reset() override; - DIAEnumLineNumbers *clone() const override; private: CComPtr<IDiaEnumLineNumbers> Enumerator; diff --git a/include/llvm/DebugInfo/PDB/DIA/DIAEnumSectionContribs.h b/include/llvm/DebugInfo/PDB/DIA/DIAEnumSectionContribs.h index 52c9563b5d5f..ac2ae317d263 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIAEnumSectionContribs.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIAEnumSectionContribs.h @@ -28,7 +28,6 @@ public: ChildTypePtr getChildAtIndex(uint32_t Index) const override; ChildTypePtr getNext() override; void reset() override; - DIAEnumSectionContribs *clone() const override; private: const DIASession &Session; diff --git a/include/llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h b/include/llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h index e69d18f5ba37..dac3df06a178 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h @@ -27,7 +27,6 @@ public: ChildTypePtr getChildAtIndex(uint32_t Index) const override; ChildTypePtr getNext() override; void reset() override; - DIAEnumSourceFiles *clone() const override; private: const DIASession &Session; diff --git a/include/llvm/DebugInfo/PDB/DIA/DIAEnumSymbols.h b/include/llvm/DebugInfo/PDB/DIA/DIAEnumSymbols.h index f779cd1f4be3..9689859ae0f8 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIAEnumSymbols.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIAEnumSymbols.h @@ -27,7 +27,6 @@ public: std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override; std::unique_ptr<PDBSymbol> getNext() override; void reset() override; - DIAEnumSymbols *clone() const override; private: const DIASession &Session; diff --git a/include/llvm/DebugInfo/PDB/DIA/DIAEnumTables.h b/include/llvm/DebugInfo/PDB/DIA/DIAEnumTables.h index 926fcfe69648..f4f856ebb6fd 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIAEnumTables.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIAEnumTables.h @@ -26,7 +26,6 @@ public: std::unique_ptr<IPDBTable> getChildAtIndex(uint32_t Index) const override; std::unique_ptr<IPDBTable> getNext() override; void reset() override; - DIAEnumTables *clone() const override; private: CComPtr<IDiaEnumTables> Enumerator; diff --git a/include/llvm/DebugInfo/PDB/DIA/DIAError.h b/include/llvm/DebugInfo/PDB/DIA/DIAError.h index 35a39a0df5ca..2b33a65a0a14 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIAError.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIAError.h @@ -23,23 +23,29 @@ enum class dia_error_code { already_loaded, debug_info_mismatch, }; +} // namespace pdb +} // namespace llvm + +namespace std { +template <> +struct is_error_code_enum<llvm::pdb::dia_error_code> : std::true_type {}; +} // namespace std + +namespace llvm { +namespace pdb { +const std::error_category &DIAErrCategory(); + +inline std::error_code make_error_code(dia_error_code E) { + return std::error_code(static_cast<int>(E), DIAErrCategory()); +} /// Base class for errors originating in DIA SDK, e.g. COM calls -class DIAError : public ErrorInfo<DIAError> { +class DIAError : public ErrorInfo<DIAError, StringError> { public: + using ErrorInfo<DIAError, StringError>::ErrorInfo; + DIAError(const Twine &S) : ErrorInfo(S, dia_error_code::unspecified) {} static char ID; - DIAError(dia_error_code C); - DIAError(StringRef Context); - DIAError(dia_error_code C, StringRef Context); - - void log(raw_ostream &OS) const override; - StringRef getErrorMessage() const; - std::error_code convertToErrorCode() const override; - -private: - std::string ErrMsg; - dia_error_code Code; }; -} -} +} // namespace pdb +} // namespace llvm #endif diff --git a/include/llvm/DebugInfo/PDB/DIA/DIAFrameData.h b/include/llvm/DebugInfo/PDB/DIA/DIAFrameData.h new file mode 100644 index 000000000000..0ce6cfc93030 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/DIA/DIAFrameData.h @@ -0,0 +1,39 @@ +//===- DIAFrameData.h - DIA Impl. of IPDBFrameData ---------------- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_PDB_DIA_DIAFRAMEDATA_H +#define LLVM_DEBUGINFO_PDB_DIA_DIAFRAMEDATA_H + +#include "DIASupport.h" +#include "llvm/DebugInfo/PDB/IPDBFrameData.h" + +namespace llvm { +namespace pdb { + +class DIASession; + +class DIAFrameData : public IPDBFrameData { +public: + explicit DIAFrameData(CComPtr<IDiaFrameData> DiaFrameData); + + uint32_t getAddressOffset() const override; + uint32_t getAddressSection() const override; + uint32_t getLengthBlock() const override; + std::string getProgram() const override; + uint32_t getRelativeVirtualAddress() const override; + uint64_t getVirtualAddress() const override; + +private: + CComPtr<IDiaFrameData> FrameData; +}; + +} // namespace pdb +} // namespace llvm + +#endif diff --git a/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h b/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h index dfb35647055a..5d4f855c63ca 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h @@ -20,7 +20,8 @@ class DIARawSymbol : public IPDBRawSymbol { public: DIARawSymbol(const DIASession &PDBSession, CComPtr<IDiaSymbol> DiaSymbol); - void dump(raw_ostream &OS, int Indent) const override; + void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields, + PdbSymbolIdField RecurseIdFields) const override; CComPtr<IDiaSymbol> getDiaSymbol() const { return Symbol; } @@ -63,25 +64,25 @@ public: uint32_t getAddressOffset() const override; uint32_t getAddressSection() const override; uint32_t getAge() const override; - uint32_t getArrayIndexTypeId() const override; + SymIndexId getArrayIndexTypeId() const override; uint32_t getBaseDataOffset() const override; uint32_t getBaseDataSlot() const override; - uint32_t getBaseSymbolId() const override; + SymIndexId getBaseSymbolId() const override; PDB_BuiltinType getBuiltinType() const override; uint32_t getBitPosition() const override; PDB_CallingConv getCallingConvention() const override; - uint32_t getClassParentId() const override; + SymIndexId getClassParentId() const override; std::string getCompilerName() const override; uint32_t getCount() const override; uint32_t getCountLiveRanges() const override; PDB_Lang getLanguage() const override; - uint32_t getLexicalParentId() const override; + SymIndexId getLexicalParentId() const override; std::string getLibraryName() const override; uint32_t getLiveRangeStartAddressOffset() const override; uint32_t getLiveRangeStartAddressSection() const override; uint32_t getLiveRangeStartRelativeVirtualAddress() const override; codeview::RegisterId getLocalBasePointerRegisterId() const override; - uint32_t getLowerBoundId() const override; + SymIndexId getLowerBoundId() const override; uint32_t getMemorySpaceKind() const override; std::string getName() const override; uint32_t getNumberOfAcceleratorPointerTags() const override; @@ -91,7 +92,7 @@ public: uint32_t getNumberOfRows() const override; std::string getObjectFileName() const override; uint32_t getOemId() const override; - uint32_t getOemSymbolId() const override; + SymIndexId getOemSymbolId() const override; uint32_t getOffsetInUdt() const override; PDB_Cpu getPlatform() const override; uint32_t getRank() const override; @@ -105,9 +106,9 @@ public: std::string getSourceFileName() const override; std::unique_ptr<IPDBLineNumber> getSrcLineOnTypeDefn() const override; uint32_t getStride() const override; - uint32_t getSubTypeId() const override; + SymIndexId getSubTypeId() const override; std::string getSymbolsFileName() const override; - uint32_t getSymIndexId() const override; + SymIndexId getSymIndexId() const override; uint32_t getTargetOffset() const override; uint32_t getTargetRelativeVirtualAddress() const override; uint64_t getTargetVirtualAddress() const override; @@ -115,16 +116,16 @@ public: uint32_t getTextureSlot() const override; uint32_t getTimeStamp() const override; uint32_t getToken() const override; - uint32_t getTypeId() const override; + SymIndexId getTypeId() const override; uint32_t getUavSlot() const override; std::string getUndecoratedName() const override; std::string getUndecoratedNameEx(PDB_UndnameFlags Flags) const override; - uint32_t getUnmodifiedTypeId() const override; - uint32_t getUpperBoundId() const override; + SymIndexId getUnmodifiedTypeId() const override; + SymIndexId getUpperBoundId() const override; Variant getValue() const override; uint32_t getVirtualBaseDispIndex() const override; uint32_t getVirtualBaseOffset() const override; - uint32_t getVirtualTableShapeId() const override; + SymIndexId getVirtualTableShapeId() const override; std::unique_ptr<PDBSymbolTypeBuiltin> getVirtualBaseTableType() const override; PDB_DataKind getDataKind() const override; diff --git a/include/llvm/DebugInfo/PDB/DIA/DIASession.h b/include/llvm/DebugInfo/PDB/DIA/DIASession.h index a63659439389..592e061a8d83 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIASession.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIASession.h @@ -32,7 +32,7 @@ public: uint64_t getLoadAddress() const override; bool setLoadAddress(uint64_t Address) override; std::unique_ptr<PDBSymbolExe> getGlobalScope() override; - std::unique_ptr<PDBSymbol> getSymbolById(uint32_t SymbolId) const override; + std::unique_ptr<PDBSymbol> getSymbolById(SymIndexId SymbolId) const override; bool addressForVA(uint64_t VA, uint32_t &Section, uint32_t &Offset) const override; @@ -85,6 +85,7 @@ public: std::unique_ptr<IPDBEnumSectionContribs> getSectionContribs() const override; + std::unique_ptr<IPDBEnumFrameData> getFrameData() const override; private: CComPtr<IDiaSession> Session; }; diff --git a/include/llvm/DebugInfo/PDB/GenericError.h b/include/llvm/DebugInfo/PDB/GenericError.h index 03205a986f1a..997f13f5f30e 100644 --- a/include/llvm/DebugInfo/PDB/GenericError.h +++ b/include/llvm/DebugInfo/PDB/GenericError.h @@ -16,29 +16,37 @@ namespace llvm { namespace pdb { -enum class generic_error_code { - invalid_path = 1, +enum class pdb_error_code { + invalid_utf8_path = 1, dia_sdk_not_present, - type_server_not_found, + dia_failed_loading, + signature_out_of_date, + external_cmdline_ref, unspecified, }; +} // namespace pdb +} // namespace llvm + +namespace std { +template <> +struct is_error_code_enum<llvm::pdb::pdb_error_code> : std::true_type {}; +} // namespace std + +namespace llvm { +namespace pdb { +const std::error_category &PDBErrCategory(); + +inline std::error_code make_error_code(pdb_error_code E) { + return std::error_code(static_cast<int>(E), PDBErrCategory()); +} /// Base class for errors originating when parsing raw PDB files -class GenericError : public ErrorInfo<GenericError> { +class PDBError : public ErrorInfo<PDBError, StringError> { public: + using ErrorInfo<PDBError, StringError>::ErrorInfo; // inherit constructors + PDBError(const Twine &S) : ErrorInfo(S, pdb_error_code::unspecified) {} static char ID; - GenericError(generic_error_code C); - GenericError(StringRef Context); - GenericError(generic_error_code C, StringRef Context); - - void log(raw_ostream &OS) const override; - StringRef getErrorMessage() const; - std::error_code convertToErrorCode() const override; - -private: - std::string ErrMsg; - generic_error_code Code; }; -} -} +} // namespace pdb +} // namespace llvm #endif diff --git a/include/llvm/DebugInfo/PDB/IPDBDataStream.h b/include/llvm/DebugInfo/PDB/IPDBDataStream.h index 67b5a06d7c59..0d7a286a11a6 100644 --- a/include/llvm/DebugInfo/PDB/IPDBDataStream.h +++ b/include/llvm/DebugInfo/PDB/IPDBDataStream.h @@ -32,7 +32,6 @@ public: virtual Optional<RecordType> getItemAtIndex(uint32_t Index) const = 0; virtual bool getNext(RecordType &Record) = 0; virtual void reset() = 0; - virtual IPDBDataStream *clone() const = 0; }; } // end namespace pdb diff --git a/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h b/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h index b6b7d95f6282..7017f2600e9b 100644 --- a/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h +++ b/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h @@ -10,6 +10,7 @@ #ifndef LLVM_DEBUGINFO_PDB_IPDBENUMCHILDREN_H #define LLVM_DEBUGINFO_PDB_IPDBENUMCHILDREN_H +#include <cassert> #include <cstdint> #include <memory> @@ -27,7 +28,19 @@ public: virtual ChildTypePtr getChildAtIndex(uint32_t Index) const = 0; virtual ChildTypePtr getNext() = 0; virtual void reset() = 0; - virtual MyType *clone() const = 0; +}; + +template <typename ChildType> +class NullEnumerator : public IPDBEnumChildren<ChildType> { + virtual uint32_t getChildCount() const override { return 0; } + virtual std::unique_ptr<ChildType> + getChildAtIndex(uint32_t Index) const override { + return nullptr; + } + virtual std::unique_ptr<ChildType> getNext() override { + return nullptr; + } + virtual void reset() override {} }; } // end namespace pdb diff --git a/include/llvm/DebugInfo/PDB/IPDBFrameData.h b/include/llvm/DebugInfo/PDB/IPDBFrameData.h new file mode 100644 index 000000000000..74679215b880 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/IPDBFrameData.h @@ -0,0 +1,36 @@ +//===- IPDBFrameData.h - base interface for frame data ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_PDB_IPDBFRAMEDATA_H +#define LLVM_DEBUGINFO_PDB_IPDBFRAMEDATA_H + +#include <cstdint> +#include <string> + +namespace llvm { +namespace pdb { + +/// IPDBFrameData defines an interface used to represent a frame data of some +/// code block. +class IPDBFrameData { +public: + virtual ~IPDBFrameData(); + + virtual uint32_t getAddressOffset() const = 0; + virtual uint32_t getAddressSection() const = 0; + virtual uint32_t getLengthBlock() const = 0; + virtual std::string getProgram() const = 0; + virtual uint32_t getRelativeVirtualAddress() const = 0; + virtual uint64_t getVirtualAddress() const = 0; +}; + +} // namespace pdb +} // namespace llvm + +#endif diff --git a/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h b/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h index bcb2eaa35630..7c818d7cadeb 100644 --- a/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h +++ b/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h @@ -11,6 +11,7 @@ #define LLVM_DEBUGINFO_PDB_IPDBRAWSYMBOL_H #include "PDBTypes.h" +#include "llvm/ADT/BitmaskEnum.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/CodeView/CodeView.h" @@ -21,9 +22,26 @@ class raw_ostream; namespace pdb { +class IPDBSession; class PDBSymbolTypeVTable; class PDBSymbolTypeVTableShape; +enum class PdbSymbolIdField : uint32_t { + None = 0, + SymIndexId = 1 << 0, + LexicalParent = 1 << 1, + ClassParent = 1 << 2, + Type = 1 << 3, + UnmodifiedType = 1 << 4, + All = 0xFFFFFFFF, + LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ All) +}; + +void dumpSymbolIdField(raw_ostream &OS, StringRef Name, SymIndexId Value, + int Indent, const IPDBSession &Session, + PdbSymbolIdField FieldId, PdbSymbolIdField ShowFlags, + PdbSymbolIdField RecurseFlags); + /// IPDBRawSymbol defines an interface used to represent an arbitrary symbol. /// It exposes a monolithic interface consisting of accessors for the union of /// all properties that are valid for any symbol type. This interface is then @@ -33,7 +51,8 @@ class IPDBRawSymbol { public: virtual ~IPDBRawSymbol(); - virtual void dump(raw_ostream &OS, int Indent) const = 0; + virtual void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields, + PdbSymbolIdField RecurseIdFields) const = 0; virtual std::unique_ptr<IPDBEnumSymbols> findChildren(PDB_SymType Type) const = 0; @@ -74,26 +93,26 @@ public: virtual uint32_t getAddressOffset() const = 0; virtual uint32_t getAddressSection() const = 0; virtual uint32_t getAge() const = 0; - virtual uint32_t getArrayIndexTypeId() const = 0; + virtual SymIndexId getArrayIndexTypeId() const = 0; virtual uint32_t getBaseDataOffset() const = 0; virtual uint32_t getBaseDataSlot() const = 0; - virtual uint32_t getBaseSymbolId() const = 0; + virtual SymIndexId getBaseSymbolId() const = 0; virtual PDB_BuiltinType getBuiltinType() const = 0; virtual uint32_t getBitPosition() const = 0; virtual PDB_CallingConv getCallingConvention() const = 0; - virtual uint32_t getClassParentId() const = 0; + virtual SymIndexId getClassParentId() const = 0; virtual std::string getCompilerName() const = 0; virtual uint32_t getCount() const = 0; virtual uint32_t getCountLiveRanges() const = 0; virtual void getFrontEndVersion(VersionInfo &Version) const = 0; virtual PDB_Lang getLanguage() const = 0; - virtual uint32_t getLexicalParentId() const = 0; + virtual SymIndexId getLexicalParentId() const = 0; virtual std::string getLibraryName() const = 0; virtual uint32_t getLiveRangeStartAddressOffset() const = 0; virtual uint32_t getLiveRangeStartAddressSection() const = 0; virtual uint32_t getLiveRangeStartRelativeVirtualAddress() const = 0; virtual codeview::RegisterId getLocalBasePointerRegisterId() const = 0; - virtual uint32_t getLowerBoundId() const = 0; + virtual SymIndexId getLowerBoundId() const = 0; virtual uint32_t getMemorySpaceKind() const = 0; virtual std::string getName() const = 0; virtual uint32_t getNumberOfAcceleratorPointerTags() const = 0; @@ -103,7 +122,7 @@ public: virtual uint32_t getNumberOfRows() const = 0; virtual std::string getObjectFileName() const = 0; virtual uint32_t getOemId() const = 0; - virtual uint32_t getOemSymbolId() const = 0; + virtual SymIndexId getOemSymbolId() const = 0; virtual uint32_t getOffsetInUdt() const = 0; virtual PDB_Cpu getPlatform() const = 0; virtual uint32_t getRank() const = 0; @@ -118,9 +137,9 @@ public: virtual std::unique_ptr<IPDBLineNumber> getSrcLineOnTypeDefn() const = 0; virtual uint32_t getStride() const = 0; - virtual uint32_t getSubTypeId() const = 0; + virtual SymIndexId getSubTypeId() const = 0; virtual std::string getSymbolsFileName() const = 0; - virtual uint32_t getSymIndexId() const = 0; + virtual SymIndexId getSymIndexId() const = 0; virtual uint32_t getTargetOffset() const = 0; virtual uint32_t getTargetRelativeVirtualAddress() const = 0; virtual uint64_t getTargetVirtualAddress() const = 0; @@ -128,18 +147,18 @@ public: virtual uint32_t getTextureSlot() const = 0; virtual uint32_t getTimeStamp() const = 0; virtual uint32_t getToken() const = 0; - virtual uint32_t getTypeId() const = 0; + virtual SymIndexId getTypeId() const = 0; virtual uint32_t getUavSlot() const = 0; virtual std::string getUndecoratedName() const = 0; virtual std::string getUndecoratedNameEx(PDB_UndnameFlags Flags) const = 0; - virtual uint32_t getUnmodifiedTypeId() const = 0; - virtual uint32_t getUpperBoundId() const = 0; + virtual SymIndexId getUnmodifiedTypeId() const = 0; + virtual SymIndexId getUpperBoundId() const = 0; virtual Variant getValue() const = 0; virtual uint32_t getVirtualBaseDispIndex() const = 0; virtual uint32_t getVirtualBaseOffset() const = 0; virtual std::unique_ptr<PDBSymbolTypeBuiltin> getVirtualBaseTableType() const = 0; - virtual uint32_t getVirtualTableShapeId() const = 0; + virtual SymIndexId getVirtualTableShapeId() const = 0; virtual PDB_DataKind getDataKind() const = 0; virtual PDB_SymType getSymTag() const = 0; virtual codeview::GUID getGuid() const = 0; @@ -237,6 +256,8 @@ public: virtual std::string getUnused() const = 0; }; +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); + } // namespace pdb } // namespace llvm diff --git a/include/llvm/DebugInfo/PDB/IPDBSession.h b/include/llvm/DebugInfo/PDB/IPDBSession.h index 88ec517bc4a5..88fd02c0a345 100644 --- a/include/llvm/DebugInfo/PDB/IPDBSession.h +++ b/include/llvm/DebugInfo/PDB/IPDBSession.h @@ -30,7 +30,8 @@ public: virtual uint64_t getLoadAddress() const = 0; virtual bool setLoadAddress(uint64_t Address) = 0; virtual std::unique_ptr<PDBSymbolExe> getGlobalScope() = 0; - virtual std::unique_ptr<PDBSymbol> getSymbolById(uint32_t SymbolId) const = 0; + virtual std::unique_ptr<PDBSymbol> + getSymbolById(SymIndexId SymbolId) const = 0; virtual bool addressForVA(uint64_t VA, uint32_t &Section, uint32_t &Offset) const = 0; @@ -38,7 +39,7 @@ public: uint32_t &Offset) const = 0; template <typename T> - std::unique_ptr<T> getConcreteSymbolById(uint32_t SymbolId) const { + std::unique_ptr<T> getConcreteSymbolById(SymIndexId SymbolId) const { return unique_dyn_cast_or_null<T>(getSymbolById(SymbolId)); } @@ -90,6 +91,9 @@ public: virtual std::unique_ptr<IPDBEnumSectionContribs> getSectionContribs() const = 0; + + virtual std::unique_ptr<IPDBEnumFrameData> + getFrameData() const = 0; }; } // namespace pdb } // namespace llvm diff --git a/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h b/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h index ce4d07917755..ac7f741afefa 100644 --- a/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h @@ -51,6 +51,7 @@ public: void setObjFileName(StringRef Name); void setFirstSectionContrib(const SectionContrib &SC); void addSymbol(codeview::CVSymbol Symbol); + void addSymbolsInBulk(ArrayRef<uint8_t> BulkSymbols); void addDebugSubsection(std::shared_ptr<codeview::DebugSubsection> Subsection); @@ -91,7 +92,7 @@ private: std::string ModuleName; std::string ObjFileName; std::vector<std::string> SourceFiles; - std::vector<codeview::CVSymbol> Symbols; + std::vector<ArrayRef<uint8_t>> Symbols; std::vector<std::unique_ptr<codeview::DebugSubsectionRecordBuilder>> C13Builders; diff --git a/include/llvm/DebugInfo/PDB/Native/DbiStream.h b/include/llvm/DebugInfo/PDB/Native/DbiStream.h index 280615bdb507..a3ca607efbef 100644 --- a/include/llvm/DebugInfo/PDB/Native/DbiStream.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiStream.h @@ -78,7 +78,7 @@ public: const DbiModuleList &modules() const; - FixedStreamArray<object::coff_section> getSectionHeaders(); + FixedStreamArray<object::coff_section> getSectionHeaders() const; FixedStreamArray<object::FpoData> getFpoRecords(); diff --git a/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h b/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h index 51befcdac775..b538de576677 100644 --- a/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h @@ -15,6 +15,7 @@ #include "llvm/BinaryFormat/COFF.h" #include "llvm/Support/Error.h" +#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" #include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h" #include "llvm/DebugInfo/PDB/Native/RawConstants.h" @@ -24,11 +25,15 @@ #include "llvm/Support/Endian.h" namespace llvm { +namespace codeview { +struct FrameData; +} namespace msf { class MSFBuilder; } namespace object { struct coff_section; +struct FpoData; } namespace pdb { class DbiStream; @@ -65,6 +70,8 @@ public: void setGlobalsStreamIndex(uint32_t Index); void setPublicsStreamIndex(uint32_t Index); void setSymbolRecordStreamIndex(uint32_t Index); + void addNewFpoData(const codeview::FrameData &FD); + void addOldFpoData(const object::FpoData &Fpo); Expected<DbiModuleDescriptorBuilder &> addModuleInfo(StringRef ModuleName); Error addModuleSourceFile(DbiModuleDescriptorBuilder &Module, StringRef File); @@ -84,7 +91,8 @@ public: private: struct DebugStream { - ArrayRef<uint8_t> Data; + std::function<Error(BinaryStreamWriter &)> WriteFn; + uint32_t Size = 0; uint16_t StreamNumber = kInvalidStreamIndex; }; @@ -117,6 +125,9 @@ private: std::vector<std::unique_ptr<DbiModuleDescriptorBuilder>> ModiList; + Optional<codeview::DebugFrameDataSubsection> NewFpoData; + std::vector<object::FpoData> OldFpoData; + StringMap<uint32_t> SourceFileNames; PDBStringTableBuilder ECNamesBuilder; diff --git a/include/llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h b/include/llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h index 1a4f89d607df..4c39ca762b5b 100644 --- a/include/llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h @@ -61,7 +61,6 @@ public: void addGlobalSymbol(const codeview::ProcRefSym &Sym); void addGlobalSymbol(const codeview::DataSym &Sym); void addGlobalSymbol(const codeview::ConstantSym &Sym); - void addGlobalSymbol(const codeview::UDTSym &Sym); void addGlobalSymbol(const codeview::CVSymbol &Sym); private: diff --git a/include/llvm/DebugInfo/PDB/Native/GlobalsStream.h b/include/llvm/DebugInfo/PDB/Native/GlobalsStream.h index fdc58dc60f7e..7f84564ee988 100644 --- a/include/llvm/DebugInfo/PDB/Native/GlobalsStream.h +++ b/include/llvm/DebugInfo/PDB/Native/GlobalsStream.h @@ -10,18 +10,20 @@ #ifndef LLVM_DEBUGINFO_PDB_RAW_GLOBALS_STREAM_H #define LLVM_DEBUGINFO_PDB_RAW_GLOBALS_STREAM_H +#include "llvm/ADT/iterator.h" +#include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" #include "llvm/DebugInfo/PDB/Native/RawConstants.h" #include "llvm/DebugInfo/PDB/Native/RawTypes.h" #include "llvm/DebugInfo/PDB/PDBTypes.h" #include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/Error.h" -#include "llvm/ADT/iterator.h" namespace llvm { namespace pdb { class DbiStream; class PDBFile; +class SymbolStream; /// Iterator over hash records producing symbol record offsets. Abstracts away /// the fact that symbol record offsets on disk are off-by-one. @@ -30,8 +32,6 @@ class GSIHashIterator GSIHashIterator, FixedStreamArrayIterator<PSHashRecord>, std::random_access_iterator_tag, const uint32_t> { public: - GSIHashIterator() = default; - template <typename T> GSIHashIterator(T &&v) : GSIHashIterator::iterator_adaptor_base(std::forward<T &&>(v)) {} @@ -52,8 +52,9 @@ class GSIHashTable { public: const GSIHashHeader *HashHdr; FixedStreamArray<PSHashRecord> HashRecords; - ArrayRef<uint8_t> HashBitmap; + FixedStreamArray<support::ulittle32_t> HashBitmap; FixedStreamArray<support::ulittle32_t> HashBuckets; + std::array<int32_t, IPHR_HASH + 1> BucketMap; Error read(BinaryStreamReader &Reader); @@ -74,6 +75,9 @@ public: const GSIHashTable &getGlobalsTable() const { return GlobalsTable; } Error reload(); + std::vector<std::pair<uint32_t, codeview::CVSymbol>> + findRecordsByName(StringRef Name, const SymbolStream &Symbols) const; + private: GSIHashTable GlobalsTable; std::unique_ptr<msf::MappedBlockStream> Stream; diff --git a/include/llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h b/include/llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h index 419e8ada06f7..101127a355f5 100644 --- a/include/llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h @@ -35,11 +35,18 @@ public: InfoStreamBuilder &operator=(const InfoStreamBuilder &) = delete; void setVersion(PdbRaw_ImplVer V); + void addFeature(PdbRaw_FeatureSig Sig); + + // If this is true, the PDB contents are hashed and this hash is used as + // PDB GUID and as Signature. The age is always 1. + void setHashPDBContentsToGUID(bool B); + + // These only have an effect if hashPDBContentsToGUID() is false. void setSignature(uint32_t S); void setAge(uint32_t A); void setGuid(codeview::GUID G); - void addFeature(PdbRaw_FeatureSig Sig); + bool hashPDBContentsToGUID() const { return HashPDBContentsToGUID; } uint32_t getAge() const { return Age; } codeview::GUID getGuid() const { return Guid; } Optional<uint32_t> getSignature() const { return Signature; } @@ -60,6 +67,8 @@ private: Optional<uint32_t> Signature; codeview::GUID Guid; + bool HashPDBContentsToGUID = false; + NamedStreamMap &NamedStreams; }; } diff --git a/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h b/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h index 6602264d1b74..8d590df288f3 100644 --- a/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h +++ b/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h @@ -15,6 +15,7 @@ #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" +#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" #include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/Error.h" #include <cstdint> @@ -43,13 +44,17 @@ public: symbols(bool *HadError) const; const codeview::CVSymbolArray &getSymbolArray() const { return SymbolArray; } + const codeview::CVSymbolArray + getSymbolArrayForScope(uint32_t ScopeBegin) const; BinarySubstreamRef getSymbolsSubstream() const; BinarySubstreamRef getC11LinesSubstream() const; BinarySubstreamRef getC13LinesSubstream() const; BinarySubstreamRef getGlobalRefsSubstream() const; - ModuleDebugStreamRef &operator=(ModuleDebugStreamRef &&Other) = default; + ModuleDebugStreamRef &operator=(ModuleDebugStreamRef &&Other) = delete; + + codeview::CVSymbol readSymbolAtOffset(uint32_t Offset) const; iterator_range<DebugSubsectionIterator> subsections() const; codeview::DebugSubsectionArray getSubsectionsArray() const { @@ -64,7 +69,7 @@ public: findChecksumsSubsection() const; private: - const DbiModuleDescriptor &Mod; + DbiModuleDescriptor Mod; uint32_t Signature; diff --git a/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h b/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h index bd5c09e5ff76..3cd465503044 100644 --- a/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h +++ b/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h @@ -21,11 +21,12 @@ public: NativeCompilandSymbol(NativeSession &Session, SymIndexId SymbolId, DbiModuleDescriptor MI); - std::unique_ptr<NativeRawSymbol> clone() const override; + void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields, + PdbSymbolIdField RecurseIdFields) const override; PDB_SymType getSymTag() const override; bool isEditAndContinueEnabled() const override; - uint32_t getLexicalParentId() const override; + SymIndexId getLexicalParentId() const override; std::string getLibraryName() const override; std::string getName() const override; diff --git a/include/llvm/DebugInfo/PDB/Native/NativeEnumGlobals.h b/include/llvm/DebugInfo/PDB/Native/NativeEnumGlobals.h new file mode 100644 index 000000000000..4442a1ec41fb --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/NativeEnumGlobals.h @@ -0,0 +1,43 @@ +//==- NativeEnumGlobals.h - Native Global Enumerator impl --------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMGLOBALS_H +#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMGLOBALS_H + +#include "llvm/DebugInfo/CodeView/SymbolRecord.h" +#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" +#include "llvm/DebugInfo/PDB/PDBSymbol.h" + +#include <vector> + +namespace llvm { +namespace pdb { + +class NativeSession; + +class NativeEnumGlobals : public IPDBEnumChildren<PDBSymbol> { +public: + NativeEnumGlobals(NativeSession &Session, + std::vector<codeview::SymbolKind> Kinds); + + uint32_t getChildCount() const override; + std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override; + std::unique_ptr<PDBSymbol> getNext() override; + void reset() override; + +private: + std::vector<uint32_t> MatchOffsets; + uint32_t Index; + NativeSession &Session; +}; + +} // namespace pdb +} // namespace llvm + +#endif diff --git a/include/llvm/DebugInfo/PDB/Native/NativeEnumModules.h b/include/llvm/DebugInfo/PDB/Native/NativeEnumModules.h index 6aa1460dbb4e..c268641a1008 100644 --- a/include/llvm/DebugInfo/PDB/Native/NativeEnumModules.h +++ b/include/llvm/DebugInfo/PDB/Native/NativeEnumModules.h @@ -11,28 +11,23 @@ #define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMMODULES_H #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" -#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" #include "llvm/DebugInfo/PDB/PDBSymbol.h" namespace llvm { namespace pdb { -class DbiModuleList; class NativeSession; class NativeEnumModules : public IPDBEnumChildren<PDBSymbol> { public: - NativeEnumModules(NativeSession &Session, const DbiModuleList &Modules, - uint32_t Index = 0); + NativeEnumModules(NativeSession &Session, uint32_t Index = 0); uint32_t getChildCount() const override; std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override; std::unique_ptr<PDBSymbol> getNext() override; void reset() override; - NativeEnumModules *clone() const override; private: NativeSession &Session; - const DbiModuleList &Modules; uint32_t Index; }; } diff --git a/include/llvm/DebugInfo/PDB/Native/NativeEnumSymbol.h b/include/llvm/DebugInfo/PDB/Native/NativeEnumSymbol.h deleted file mode 100644 index 41b7b78b8d80..000000000000 --- a/include/llvm/DebugInfo/PDB/Native/NativeEnumSymbol.h +++ /dev/null @@ -1,60 +0,0 @@ -//===- NativeEnumSymbol.h - info about enum type ----------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMSYMBOL_H -#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMSYMBOL_H - -#include "llvm/DebugInfo/CodeView/CodeView.h" -#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" -#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" -#include "llvm/DebugInfo/PDB/Native/NativeSession.h" - -namespace llvm { -namespace pdb { - -class NativeEnumSymbol : public NativeRawSymbol, - public codeview::TypeVisitorCallbacks { -public: - NativeEnumSymbol(NativeSession &Session, SymIndexId Id, - const codeview::CVType &CV); - ~NativeEnumSymbol() override; - - std::unique_ptr<NativeRawSymbol> clone() const override; - - std::unique_ptr<IPDBEnumSymbols> - findChildren(PDB_SymType Type) const override; - - Error visitKnownRecord(codeview::CVType &CVR, - codeview::EnumRecord &Record) override; - Error visitKnownMember(codeview::CVMemberRecord &CVM, - codeview::EnumeratorRecord &Record) override; - - PDB_SymType getSymTag() const override; - uint32_t getClassParentId() const override; - uint32_t getUnmodifiedTypeId() const override; - bool hasConstructor() const override; - bool hasAssignmentOperator() const override; - bool hasCastOperator() const override; - uint64_t getLength() const override; - std::string getName() const override; - bool isNested() const override; - bool hasOverloadedOperator() const override; - bool isPacked() const override; - bool isScoped() const override; - uint32_t getTypeId() const override; - -protected: - codeview::CVType CV; - codeview::EnumRecord Record; -}; - -} // namespace pdb -} // namespace llvm - -#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMSYMBOL_H diff --git a/include/llvm/DebugInfo/PDB/Native/NativeEnumTypes.h b/include/llvm/DebugInfo/PDB/Native/NativeEnumTypes.h index e0a5c8d9ad81..f8ac1655dc61 100644 --- a/include/llvm/DebugInfo/PDB/Native/NativeEnumTypes.h +++ b/include/llvm/DebugInfo/PDB/Native/NativeEnumTypes.h @@ -26,23 +26,20 @@ class NativeEnumTypes : public IPDBEnumChildren<PDBSymbol> { public: NativeEnumTypes(NativeSession &Session, codeview::LazyRandomTypeCollection &TypeCollection, - codeview::TypeLeafKind Kind); + std::vector<codeview::TypeLeafKind> Kinds); + + NativeEnumTypes(NativeSession &Session, + std::vector<codeview::TypeIndex> Indices); uint32_t getChildCount() const override; std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override; std::unique_ptr<PDBSymbol> getNext() override; void reset() override; - NativeEnumTypes *clone() const override; private: - NativeEnumTypes(NativeSession &Session, - const std::vector<codeview::TypeIndex> &Matches, - codeview::TypeLeafKind Kind); - std::vector<codeview::TypeIndex> Matches; uint32_t Index; NativeSession &Session; - codeview::TypeLeafKind Kind; }; } // namespace pdb diff --git a/include/llvm/DebugInfo/PDB/Native/NativeExeSymbol.h b/include/llvm/DebugInfo/PDB/Native/NativeExeSymbol.h index 587c7ff2b092..f4030da1d026 100644 --- a/include/llvm/DebugInfo/PDB/Native/NativeExeSymbol.h +++ b/include/llvm/DebugInfo/PDB/Native/NativeExeSymbol.h @@ -16,11 +16,14 @@ namespace llvm { namespace pdb { +class DbiStream; + class NativeExeSymbol : public NativeRawSymbol { -public: - NativeExeSymbol(NativeSession &Session, SymIndexId SymbolId); + // EXE symbol is the authority on the various symbol types. + DbiStream *Dbi = nullptr; - std::unique_ptr<NativeRawSymbol> clone() const override; +public: + NativeExeSymbol(NativeSession &Session, SymIndexId Id); std::unique_ptr<IPDBEnumSymbols> findChildren(PDB_SymType Type) const override; @@ -30,9 +33,6 @@ public: codeview::GUID getGuid() const override; bool hasCTypes() const override; bool hasPrivateSymbols() const override; - -private: - PDBFile &File; }; } // namespace pdb diff --git a/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h b/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h index 5b70ecfa2056..6505a7d39573 100644 --- a/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h +++ b/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h @@ -19,15 +19,16 @@ namespace pdb { class NativeSession; -typedef uint32_t SymIndexId; - class NativeRawSymbol : public IPDBRawSymbol { -public: - NativeRawSymbol(NativeSession &PDBSession, SymIndexId SymbolId); + friend class SymbolCache; + virtual void initialize() {} - virtual std::unique_ptr<NativeRawSymbol> clone() const = 0; +public: + NativeRawSymbol(NativeSession &PDBSession, PDB_SymType Tag, + SymIndexId SymbolId); - void dump(raw_ostream &OS, int Indent) const override; + void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields, + PdbSymbolIdField RecurseIdFields) const override; std::unique_ptr<IPDBEnumSymbols> findChildren(PDB_SymType Type) const override; @@ -68,25 +69,25 @@ public: uint32_t getAddressOffset() const override; uint32_t getAddressSection() const override; uint32_t getAge() const override; - uint32_t getArrayIndexTypeId() const override; + SymIndexId getArrayIndexTypeId() const override; uint32_t getBaseDataOffset() const override; uint32_t getBaseDataSlot() const override; - uint32_t getBaseSymbolId() const override; + SymIndexId getBaseSymbolId() const override; PDB_BuiltinType getBuiltinType() const override; uint32_t getBitPosition() const override; PDB_CallingConv getCallingConvention() const override; - uint32_t getClassParentId() const override; + SymIndexId getClassParentId() const override; std::string getCompilerName() const override; uint32_t getCount() const override; uint32_t getCountLiveRanges() const override; PDB_Lang getLanguage() const override; - uint32_t getLexicalParentId() const override; + SymIndexId getLexicalParentId() const override; std::string getLibraryName() const override; uint32_t getLiveRangeStartAddressOffset() const override; uint32_t getLiveRangeStartAddressSection() const override; uint32_t getLiveRangeStartRelativeVirtualAddress() const override; codeview::RegisterId getLocalBasePointerRegisterId() const override; - uint32_t getLowerBoundId() const override; + SymIndexId getLowerBoundId() const override; uint32_t getMemorySpaceKind() const override; std::string getName() const override; uint32_t getNumberOfAcceleratorPointerTags() const override; @@ -96,7 +97,7 @@ public: uint32_t getNumberOfRows() const override; std::string getObjectFileName() const override; uint32_t getOemId() const override; - uint32_t getOemSymbolId() const override; + SymIndexId getOemSymbolId() const override; uint32_t getOffsetInUdt() const override; PDB_Cpu getPlatform() const override; uint32_t getRank() const override; @@ -110,9 +111,9 @@ public: std::string getSourceFileName() const override; std::unique_ptr<IPDBLineNumber> getSrcLineOnTypeDefn() const override; uint32_t getStride() const override; - uint32_t getSubTypeId() const override; + SymIndexId getSubTypeId() const override; std::string getSymbolsFileName() const override; - uint32_t getSymIndexId() const override; + SymIndexId getSymIndexId() const override; uint32_t getTargetOffset() const override; uint32_t getTargetRelativeVirtualAddress() const override; uint64_t getTargetVirtualAddress() const override; @@ -120,16 +121,16 @@ public: uint32_t getTextureSlot() const override; uint32_t getTimeStamp() const override; uint32_t getToken() const override; - uint32_t getTypeId() const override; + SymIndexId getTypeId() const override; uint32_t getUavSlot() const override; std::string getUndecoratedName() const override; std::string getUndecoratedNameEx(PDB_UndnameFlags Flags) const override; - uint32_t getUnmodifiedTypeId() const override; - uint32_t getUpperBoundId() const override; + SymIndexId getUnmodifiedTypeId() const override; + SymIndexId getUpperBoundId() const override; Variant getValue() const override; uint32_t getVirtualBaseDispIndex() const override; uint32_t getVirtualBaseOffset() const override; - uint32_t getVirtualTableShapeId() const override; + SymIndexId getVirtualTableShapeId() const override; std::unique_ptr<PDBSymbolTypeBuiltin> getVirtualBaseTableType() const override; PDB_DataKind getDataKind() const override; @@ -230,6 +231,7 @@ public: protected: NativeSession &Session; + PDB_SymType Tag; SymIndexId SymbolId; }; diff --git a/include/llvm/DebugInfo/PDB/Native/NativeSession.h b/include/llvm/DebugInfo/PDB/Native/NativeSession.h index aff7ef2f8f21..4878e47d3121 100644 --- a/include/llvm/DebugInfo/PDB/Native/NativeSession.h +++ b/include/llvm/DebugInfo/PDB/Native/NativeSession.h @@ -15,9 +15,8 @@ #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/PDB/IPDBRawSymbol.h" #include "llvm/DebugInfo/PDB/IPDBSession.h" -#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" -#include "llvm/DebugInfo/PDB/Native/NativeBuiltinSymbol.h" #include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" +#include "llvm/DebugInfo/PDB/Native/SymbolCache.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Error.h" @@ -25,6 +24,7 @@ namespace llvm { class MemoryBuffer; namespace pdb { class PDBFile; +class NativeExeSymbol; class NativeSession : public IPDBSession { public: @@ -37,21 +37,10 @@ public: static Error createFromExe(StringRef Path, std::unique_ptr<IPDBSession> &Session); - std::unique_ptr<PDBSymbolCompiland> - createCompilandSymbol(DbiModuleDescriptor MI); - - std::unique_ptr<PDBSymbolTypeEnum> - createEnumSymbol(codeview::TypeIndex Index); - - std::unique_ptr<IPDBEnumSymbols> - createTypeEnumerator(codeview::TypeLeafKind Kind); - - SymIndexId findSymbolByTypeIndex(codeview::TypeIndex TI); - uint64_t getLoadAddress() const override; bool setLoadAddress(uint64_t Address) override; std::unique_ptr<PDBSymbolExe> getGlobalScope() override; - std::unique_ptr<PDBSymbol> getSymbolById(uint32_t SymbolId) const override; + std::unique_ptr<PDBSymbol> getSymbolById(SymIndexId SymbolId) const override; bool addressForVA(uint64_t VA, uint32_t &Section, uint32_t &Offset) const override; @@ -104,14 +93,23 @@ public: std::unique_ptr<IPDBEnumSectionContribs> getSectionContribs() const override; + std::unique_ptr<IPDBEnumFrameData> getFrameData() const override; + PDBFile &getPDBFile() { return *Pdb; } const PDBFile &getPDBFile() const { return *Pdb; } + NativeExeSymbol &getNativeGlobalScope() const; + SymbolCache &getSymbolCache() { return Cache; } + const SymbolCache &getSymbolCache() const { return Cache; } + private: + void initializeExeSymbol(); + std::unique_ptr<PDBFile> Pdb; std::unique_ptr<BumpPtrAllocator> Allocator; - std::vector<std::unique_ptr<NativeRawSymbol>> SymbolCache; - DenseMap<codeview::TypeIndex, SymIndexId> TypeIndexToSymbolId; + + SymbolCache Cache; + SymIndexId ExeSymbol = 0; }; } // namespace pdb } // namespace llvm diff --git a/include/llvm/DebugInfo/PDB/Native/NativeSymbolEnumerator.h b/include/llvm/DebugInfo/PDB/Native/NativeSymbolEnumerator.h new file mode 100644 index 000000000000..acc5eb8ff2c2 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/NativeSymbolEnumerator.h @@ -0,0 +1,51 @@ +//===- NativeSymbolEnumerator.h - info about enumerator values --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVESYMBOLENUMERATOR_H +#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVESYMBOLENUMERATOR_H + +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" +#include "llvm/DebugInfo/PDB/Native/NativeSession.h" + +namespace llvm { +namespace pdb { +class NativeTypeEnum; + +class NativeSymbolEnumerator : public NativeRawSymbol { +public: + NativeSymbolEnumerator(NativeSession &Session, SymIndexId Id, + const NativeTypeEnum &Parent, + codeview::EnumeratorRecord Record); + + ~NativeSymbolEnumerator() override; + + void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields, + PdbSymbolIdField RecurseIdFields) const override; + + SymIndexId getClassParentId() const override; + SymIndexId getLexicalParentId() const override; + std::string getName() const override; + SymIndexId getTypeId() const override; + PDB_DataKind getDataKind() const override; + PDB_LocType getLocationType() const override; + bool isConstType() const override; + bool isVolatileType() const override; + bool isUnalignedType() const override; + Variant getValue() const override; + +protected: + const NativeTypeEnum &Parent; + codeview::EnumeratorRecord Record; +}; + +} // namespace pdb +} // namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEENUM_H diff --git a/include/llvm/DebugInfo/PDB/Native/NativeTypeArray.h b/include/llvm/DebugInfo/PDB/Native/NativeTypeArray.h new file mode 100644 index 000000000000..10e68e6df450 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/NativeTypeArray.h @@ -0,0 +1,50 @@ +//===- NativeTypeArray.h ------------------------------------------ C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEARRAY_H +#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEARRAY_H + +#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" + +#include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/PDB/PDBTypes.h" + +namespace llvm { +namespace pdb { + +class NativeSession; + +class NativeTypeArray : public NativeRawSymbol { +public: + NativeTypeArray(NativeSession &Session, SymIndexId Id, codeview::TypeIndex TI, + codeview::ArrayRecord Record); + ~NativeTypeArray() override; + + void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields, + PdbSymbolIdField RecurseIdFields) const override; + + SymIndexId getArrayIndexTypeId() const override; + + bool isConstType() const override; + bool isUnalignedType() const override; + bool isVolatileType() const override; + + uint32_t getCount() const override; + SymIndexId getTypeId() const override; + uint64_t getLength() const override; + +protected: + codeview::ArrayRecord Record; + codeview::TypeIndex Index; +}; + +} // namespace pdb +} // namespace llvm + +#endif diff --git a/include/llvm/DebugInfo/PDB/Native/NativeBuiltinSymbol.h b/include/llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h index 4f532c6e3829..725dfb89222f 100644 --- a/include/llvm/DebugInfo/PDB/Native/NativeBuiltinSymbol.h +++ b/include/llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h @@ -1,4 +1,4 @@ -//===- NativeBuiltinSymbol.h -------------------------------------- C++ -*-===// +//===- NativeTypeBuiltin.h ---------------------------------------- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVEBUILTINSYMBOL_H -#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEBUILTINSYMBOL_H +#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEBUILTIN_H +#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEBUILTIN_H #include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" @@ -19,15 +19,15 @@ namespace pdb { class NativeSession; -class NativeBuiltinSymbol : public NativeRawSymbol { +class NativeTypeBuiltin : public NativeRawSymbol { public: - NativeBuiltinSymbol(NativeSession &PDBSession, SymIndexId Id, - PDB_BuiltinType T, uint64_t L); - ~NativeBuiltinSymbol() override; + NativeTypeBuiltin(NativeSession &PDBSession, SymIndexId Id, + codeview::ModifierOptions Mods, PDB_BuiltinType T, + uint64_t L); + ~NativeTypeBuiltin() override; - virtual std::unique_ptr<NativeRawSymbol> clone() const override; - - void dump(raw_ostream &OS, int Indent) const override; + void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields, + PdbSymbolIdField RecurseIdFields) const override; PDB_SymType getSymTag() const override; @@ -39,6 +39,7 @@ public: protected: NativeSession &Session; + codeview::ModifierOptions Mods; PDB_BuiltinType Type; uint64_t Length; }; diff --git a/include/llvm/DebugInfo/PDB/Native/NativeTypeEnum.h b/include/llvm/DebugInfo/PDB/Native/NativeTypeEnum.h new file mode 100644 index 000000000000..a5cbefc18111 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/NativeTypeEnum.h @@ -0,0 +1,75 @@ +//===- NativeTypeEnum.h - info about enum type ------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEENUM_H +#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEENUM_H + +#include "llvm/ADT/Optional.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" +#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" +#include "llvm/DebugInfo/PDB/Native/NativeSession.h" + +namespace llvm { +namespace pdb { + +class NativeTypeBuiltin; + +class NativeTypeEnum : public NativeRawSymbol { +public: + NativeTypeEnum(NativeSession &Session, SymIndexId Id, codeview::TypeIndex TI, + codeview::EnumRecord Record); + + NativeTypeEnum(NativeSession &Session, SymIndexId Id, + NativeTypeEnum &UnmodifiedType, + codeview::ModifierRecord Modifier); + ~NativeTypeEnum() override; + + void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields, + PdbSymbolIdField RecurseIdFields) const override; + + std::unique_ptr<IPDBEnumSymbols> + findChildren(PDB_SymType Type) const override; + + PDB_BuiltinType getBuiltinType() const override; + PDB_SymType getSymTag() const override; + SymIndexId getUnmodifiedTypeId() const override; + bool hasConstructor() const override; + bool hasAssignmentOperator() const override; + bool hasCastOperator() const override; + uint64_t getLength() const override; + std::string getName() const override; + bool isConstType() const override; + bool isVolatileType() const override; + bool isUnalignedType() const override; + bool isNested() const override; + bool hasOverloadedOperator() const override; + bool hasNestedTypes() const override; + bool isIntrinsic() const override; + bool isPacked() const override; + bool isScoped() const override; + SymIndexId getTypeId() const override; + bool isRefUdt() const override; + bool isValueUdt() const override; + bool isInterfaceUdt() const override; + + const NativeTypeBuiltin &getUnderlyingBuiltinType() const; + const codeview::EnumRecord &getEnumRecord() const { return *Record; } + +protected: + codeview::TypeIndex Index; + Optional<codeview::EnumRecord> Record; + NativeTypeEnum *UnmodifiedType = nullptr; + Optional<codeview::ModifierRecord> Modifiers; +}; + +} // namespace pdb +} // namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEENUM_H diff --git a/include/llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h b/include/llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h new file mode 100644 index 000000000000..1b1b87f6581f --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h @@ -0,0 +1,74 @@ +//===- NativeTypeFunctionSig.h - info about function signature ---*- C++-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEFUNCTIONSIG_H +#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEFUNCTIONSIG_H + +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" +#include "llvm/DebugInfo/PDB/Native/NativeSession.h" + +namespace llvm { +namespace pdb { + +class NativeTypeUDT; + +class NativeTypeFunctionSig : public NativeRawSymbol { +protected: + void initialize() override; + +public: + NativeTypeFunctionSig(NativeSession &Session, SymIndexId Id, + codeview::TypeIndex TI, codeview::ProcedureRecord Proc); + + NativeTypeFunctionSig(NativeSession &Session, SymIndexId Id, + codeview::TypeIndex TI, + codeview::MemberFunctionRecord MemberFunc); + + ~NativeTypeFunctionSig() override; + + void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields, + PdbSymbolIdField RecurseIdFields) const override; + + std::unique_ptr<IPDBEnumSymbols> + findChildren(PDB_SymType Type) const override; + + SymIndexId getClassParentId() const override; + PDB_CallingConv getCallingConvention() const override; + uint32_t getCount() const override; + SymIndexId getTypeId() const override; + int32_t getThisAdjust() const override; + bool hasConstructor() const override; + bool isConstType() const override; + bool isConstructorVirtualBase() const override; + bool isCxxReturnUdt() const override; + bool isUnalignedType() const override; + bool isVolatileType() const override; + +private: + void initializeArgList(codeview::TypeIndex ArgListTI); + + union { + codeview::MemberFunctionRecord MemberFunc; + codeview::ProcedureRecord Proc; + }; + + SymIndexId ClassParentId = 0; + codeview::TypeIndex Index; + codeview::ArgListRecord ArgList; + bool IsMemberFunction = false; +}; + +} // namespace pdb +} // namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEPOINTER_H
\ No newline at end of file diff --git a/include/llvm/DebugInfo/PDB/Native/NativeTypePointer.h b/include/llvm/DebugInfo/PDB/Native/NativeTypePointer.h new file mode 100644 index 000000000000..bcb7431fecf1 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/NativeTypePointer.h @@ -0,0 +1,61 @@ +//===- NativeTypePointer.h - info about pointer type -------------*- C++-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEPOINTER_H +#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEPOINTER_H + +#include "llvm/ADT/Optional.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" +#include "llvm/DebugInfo/PDB/Native/NativeSession.h" + +namespace llvm { +namespace pdb { + +class NativeTypePointer : public NativeRawSymbol { +public: + // Create a pointer record for a simple type. + NativeTypePointer(NativeSession &Session, SymIndexId Id, + codeview::TypeIndex TI); + + // Create a pointer record for a non-simple type. + NativeTypePointer(NativeSession &Session, SymIndexId Id, + codeview::TypeIndex TI, codeview::PointerRecord PR); + ~NativeTypePointer() override; + + void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields, + PdbSymbolIdField RecurseIdFields) const override; + + SymIndexId getClassParentId() const override; + bool isConstType() const override; + uint64_t getLength() const override; + bool isReference() const override; + bool isRValueReference() const override; + bool isPointerToDataMember() const override; + bool isPointerToMemberFunction() const override; + SymIndexId getTypeId() const override; + bool isRestrictedType() const override; + bool isVolatileType() const override; + bool isUnalignedType() const override; + + bool isSingleInheritance() const override; + bool isMultipleInheritance() const override; + bool isVirtualInheritance() const override; + +protected: + bool isMemberPointer() const; + codeview::TypeIndex TI; + Optional<codeview::PointerRecord> Record; +}; + +} // namespace pdb +} // namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEPOINTER_H
\ No newline at end of file diff --git a/include/llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h b/include/llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h new file mode 100644 index 000000000000..06eb6fcf3764 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h @@ -0,0 +1,42 @@ +//===- NativeTypeTypedef.h - info about typedef ------------------*- C++-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPETYPEDEF_H +#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPETYPEDEF_H + +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/SymbolRecord.h" +#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" +#include "llvm/DebugInfo/PDB/Native/NativeSession.h" + +namespace llvm { +namespace pdb { + +class NativeTypeTypedef : public NativeRawSymbol { +public: + // Create a pointer record for a non-simple type. + NativeTypeTypedef(NativeSession &Session, SymIndexId Id, + codeview::UDTSym Typedef); + + ~NativeTypeTypedef() override; + + void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields, + PdbSymbolIdField RecurseIdFields) const override; + + std::string getName() const override; + SymIndexId getTypeId() const override; + +protected: + codeview::UDTSym Record; +}; + +} // namespace pdb +} // namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEPOINTER_H
\ No newline at end of file diff --git a/include/llvm/DebugInfo/PDB/Native/NativeTypeUDT.h b/include/llvm/DebugInfo/PDB/Native/NativeTypeUDT.h new file mode 100644 index 000000000000..84821d8731be --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/NativeTypeUDT.h @@ -0,0 +1,74 @@ +//===- NativeTypeUDT.h - info about class/struct type ------------*- C++-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEUDT_H +#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEUDT_H + +#include "llvm/ADT/Optional.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" +#include "llvm/DebugInfo/PDB/Native/NativeSession.h" + +namespace llvm { +namespace pdb { + +class NativeTypeUDT : public NativeRawSymbol { +public: + NativeTypeUDT(NativeSession &Session, SymIndexId Id, codeview::TypeIndex TI, + codeview::ClassRecord Class); + + NativeTypeUDT(NativeSession &Session, SymIndexId Id, codeview::TypeIndex TI, + codeview::UnionRecord Union); + + NativeTypeUDT(NativeSession &Session, SymIndexId Id, + NativeTypeUDT &UnmodifiedType, + codeview::ModifierRecord Modifier); + + ~NativeTypeUDT() override; + + void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields, + PdbSymbolIdField RecurseIdFields) const override; + + std::string getName() const override; + SymIndexId getLexicalParentId() const override; + SymIndexId getUnmodifiedTypeId() const override; + SymIndexId getVirtualTableShapeId() const override; + uint64_t getLength() const override; + PDB_UdtType getUdtKind() const override; + bool hasConstructor() const override; + bool isConstType() const override; + bool hasAssignmentOperator() const override; + bool hasCastOperator() const override; + bool hasNestedTypes() const override; + bool hasOverloadedOperator() const override; + bool isInterfaceUdt() const override; + bool isIntrinsic() const override; + bool isNested() const override; + bool isPacked() const override; + bool isRefUdt() const override; + bool isScoped() const override; + bool isValueUdt() const override; + bool isUnalignedType() const override; + bool isVolatileType() const override; + +protected: + codeview::TypeIndex Index; + + Optional<codeview::ClassRecord> Class; + Optional<codeview::UnionRecord> Union; + NativeTypeUDT *UnmodifiedType = nullptr; + codeview::TagRecord *Tag = nullptr; + Optional<codeview::ModifierRecord> Modifiers; +}; + +} // namespace pdb +} // namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEUDT_H
\ No newline at end of file diff --git a/include/llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h b/include/llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h new file mode 100644 index 000000000000..a996f34ef859 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h @@ -0,0 +1,46 @@ +//===- NativeTypeVTShape.h - info about virtual table shape ------*- C++-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEVTSHAPE_H +#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEVTSHAPE_H + +#include "llvm/ADT/Optional.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" +#include "llvm/DebugInfo/PDB/Native/NativeSession.h" + +namespace llvm { +namespace pdb { + +class NativeTypeVTShape : public NativeRawSymbol { +public: + // Create a pointer record for a non-simple type. + NativeTypeVTShape(NativeSession &Session, SymIndexId Id, + codeview::TypeIndex TI, codeview::VFTableShapeRecord SR); + + ~NativeTypeVTShape() override; + + void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields, + PdbSymbolIdField RecurseIdFields) const override; + + bool isConstType() const override; + bool isVolatileType() const override; + bool isUnalignedType() const override; + uint32_t getCount() const override; + +protected: + codeview::TypeIndex TI; + codeview::VFTableShapeRecord Record; +}; + +} // namespace pdb +} // namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEVTSHAPE_H
\ No newline at end of file diff --git a/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h b/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h index 7f9c4cf9fa83..37458749a8d8 100644 --- a/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h @@ -53,7 +53,9 @@ public: PDBStringTableBuilder &getStringTableBuilder(); GSIStreamBuilder &getGsiBuilder(); - Error commit(StringRef Filename); + // If HashPDBContentsToGUID is true on the InfoStreamBuilder, Guid is filled + // with the computed PDB GUID on return. + Error commit(StringRef Filename, codeview::GUID *Guid); Expected<uint32_t> getNamedStreamIndex(StringRef Name) const; Error addNamedStream(StringRef Name, StringRef Data); diff --git a/include/llvm/DebugInfo/PDB/Native/RawError.h b/include/llvm/DebugInfo/PDB/Native/RawError.h index 3624a7682e38..97d11b4f20d1 100644 --- a/include/llvm/DebugInfo/PDB/Native/RawError.h +++ b/include/llvm/DebugInfo/PDB/Native/RawError.h @@ -31,23 +31,29 @@ enum class raw_error_code { stream_too_long, invalid_tpi_hash, }; +} // namespace pdb +} // namespace llvm + +namespace std { +template <> +struct is_error_code_enum<llvm::pdb::raw_error_code> : std::true_type {}; +} // namespace std + +namespace llvm { +namespace pdb { +const std::error_category &RawErrCategory(); + +inline std::error_code make_error_code(raw_error_code E) { + return std::error_code(static_cast<int>(E), RawErrCategory()); +} /// Base class for errors originating when parsing raw PDB files -class RawError : public ErrorInfo<RawError> { +class RawError : public ErrorInfo<RawError, StringError> { public: + using ErrorInfo<RawError, StringError>::ErrorInfo; // inherit constructors + RawError(const Twine &S) : ErrorInfo(S, raw_error_code::unspecified) {} static char ID; - RawError(raw_error_code C); - RawError(const std::string &Context); - RawError(raw_error_code C, const std::string &Context); - - void log(raw_ostream &OS) const override; - const std::string &getErrorMessage() const; - std::error_code convertToErrorCode() const override; - -private: - std::string ErrMsg; - raw_error_code Code; }; -} -} +} // namespace pdb +} // namespace llvm #endif diff --git a/include/llvm/DebugInfo/PDB/Native/RawTypes.h b/include/llvm/DebugInfo/PDB/Native/RawTypes.h index 19f592d562e4..8f6d6611c032 100644 --- a/include/llvm/DebugInfo/PDB/Native/RawTypes.h +++ b/include/llvm/DebugInfo/PDB/Native/RawTypes.h @@ -343,7 +343,6 @@ struct SrcHeaderBlockEntry { char Reserved[8]; }; -constexpr int I = sizeof(SrcHeaderBlockEntry); static_assert(sizeof(SrcHeaderBlockEntry) == 40, "Incorrect struct size!"); } // namespace pdb diff --git a/include/llvm/DebugInfo/PDB/Native/SymbolCache.h b/include/llvm/DebugInfo/PDB/Native/SymbolCache.h new file mode 100644 index 000000000000..08e1d41e6ee9 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/SymbolCache.h @@ -0,0 +1,148 @@ +//==- SymbolCache.h - Cache of native symbols and ids ------------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_PDB_NATIVE_SYMBOLCACHE_H +#define LLVM_DEBUGINFO_PDB_NATIVE_SYMBOLCACHE_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" +#include "llvm/Support/Allocator.h" + +#include <memory> +#include <vector> + +namespace llvm { +namespace pdb { +class DbiStream; +class PDBFile; + +class SymbolCache { + NativeSession &Session; + DbiStream *Dbi = nullptr; + + /// Cache of all stable symbols, indexed by SymIndexId. Just because a + /// symbol has been parsed does not imply that it will be stable and have + /// an Id. Id allocation is an implementation, with the only guarantee + /// being that once an Id is allocated, the symbol can be assumed to be + /// cached. + std::vector<std::unique_ptr<NativeRawSymbol>> Cache; + + /// For type records from the TPI stream which have been paresd and cached, + /// stores a mapping to SymIndexId of the cached symbol. + DenseMap<codeview::TypeIndex, SymIndexId> TypeIndexToSymbolId; + + /// For field list members which have been parsed and cached, stores a mapping + /// from (IndexOfClass, MemberIndex) to the corresponding SymIndexId of the + /// cached symbol. + DenseMap<std::pair<codeview::TypeIndex, uint32_t>, SymIndexId> + FieldListMembersToSymbolId; + + /// List of SymIndexIds for each compiland, indexed by compiland index as they + /// appear in the PDB file. + std::vector<SymIndexId> Compilands; + + /// Map from global symbol offset to SymIndexId. + DenseMap<uint32_t, SymIndexId> GlobalOffsetToSymbolId; + + SymIndexId createSymbolPlaceholder() { + SymIndexId Id = Cache.size(); + Cache.push_back(nullptr); + return Id; + } + + template <typename ConcreteSymbolT, typename CVRecordT, typename... Args> + SymIndexId createSymbolForType(codeview::TypeIndex TI, codeview::CVType CVT, + Args &&... ConstructorArgs) { + CVRecordT Record; + if (auto EC = + codeview::TypeDeserializer::deserializeAs<CVRecordT>(CVT, Record)) { + consumeError(std::move(EC)); + return 0; + } + + return createSymbol<ConcreteSymbolT>( + TI, std::move(Record), std::forward<Args>(ConstructorArgs)...); + } + + SymIndexId createSymbolForModifiedType(codeview::TypeIndex ModifierTI, + codeview::CVType CVT); + + SymIndexId createSimpleType(codeview::TypeIndex TI, + codeview::ModifierOptions Mods); + +public: + SymbolCache(NativeSession &Session, DbiStream *Dbi); + + template <typename ConcreteSymbolT, typename... Args> + SymIndexId createSymbol(Args &&... ConstructorArgs) { + SymIndexId Id = Cache.size(); + + // Initial construction must not access the cache, since it must be done + // atomically. + auto Result = llvm::make_unique<ConcreteSymbolT>( + Session, Id, std::forward<Args>(ConstructorArgs)...); + Result->SymbolId = Id; + + NativeRawSymbol *NRS = static_cast<NativeRawSymbol *>(Result.get()); + Cache.push_back(std::move(Result)); + + // After the item is in the cache, we can do further initialization which + // is then allowed to access the cache. + NRS->initialize(); + return Id; + } + + std::unique_ptr<IPDBEnumSymbols> + createTypeEnumerator(codeview::TypeLeafKind Kind); + + std::unique_ptr<IPDBEnumSymbols> + createTypeEnumerator(std::vector<codeview::TypeLeafKind> Kinds); + + std::unique_ptr<IPDBEnumSymbols> + createGlobalsEnumerator(codeview::SymbolKind Kind); + + SymIndexId findSymbolByTypeIndex(codeview::TypeIndex TI); + + template <typename ConcreteSymbolT, typename... Args> + SymIndexId getOrCreateFieldListMember(codeview::TypeIndex FieldListTI, + uint32_t Index, + Args &&... ConstructorArgs) { + SymIndexId SymId = Cache.size(); + std::pair<codeview::TypeIndex, uint32_t> Key{FieldListTI, Index}; + auto Result = FieldListMembersToSymbolId.try_emplace(Key, SymId); + if (Result.second) + SymId = + createSymbol<ConcreteSymbolT>(std::forward<Args>(ConstructorArgs)...); + else + SymId = Result.first->second; + return SymId; + } + + SymIndexId getOrCreateGlobalSymbolByOffset(uint32_t Offset); + + std::unique_ptr<PDBSymbolCompiland> getOrCreateCompiland(uint32_t Index); + uint32_t getNumCompilands() const; + + std::unique_ptr<PDBSymbol> getSymbolById(SymIndexId SymbolId) const; + + NativeRawSymbol &getNativeSymbolById(SymIndexId SymbolId) const; + + template <typename ConcreteT> + ConcreteT &getNativeSymbolById(SymIndexId SymbolId) const { + return static_cast<ConcreteT &>(getNativeSymbolById(SymbolId)); + } +}; + +} // namespace pdb +} // namespace llvm + +#endif diff --git a/include/llvm/DebugInfo/PDB/Native/TpiHashing.h b/include/llvm/DebugInfo/PDB/Native/TpiHashing.h index c1edec7a26fe..c2996ccf1825 100644 --- a/include/llvm/DebugInfo/PDB/Native/TpiHashing.h +++ b/include/llvm/DebugInfo/PDB/Native/TpiHashing.h @@ -18,6 +18,54 @@ namespace pdb { Expected<uint32_t> hashTypeRecord(const llvm::codeview::CVType &Type); +struct TagRecordHash { + explicit TagRecordHash(codeview::ClassRecord CR, uint32_t Full, + uint32_t Forward) + : FullRecordHash(Full), ForwardDeclHash(Forward), Class(std::move(CR)) { + State = 0; + } + + explicit TagRecordHash(codeview::EnumRecord ER, uint32_t Full, + uint32_t Forward) + : FullRecordHash(Full), ForwardDeclHash(Forward), Enum(std::move(ER)) { + State = 1; + } + + explicit TagRecordHash(codeview::UnionRecord UR, uint32_t Full, + uint32_t Forward) + : FullRecordHash(Full), ForwardDeclHash(Forward), Union(std::move(UR)) { + State = 2; + } + + uint32_t FullRecordHash; + uint32_t ForwardDeclHash; + + codeview::TagRecord &getRecord() { + switch (State) { + case 0: + return Class; + case 1: + return Enum; + case 2: + return Union; + } + llvm_unreachable("unreachable!"); + } + +private: + union { + codeview::ClassRecord Class; + codeview::EnumRecord Enum; + codeview::UnionRecord Union; + }; + + uint8_t State = 0; +}; + +/// Given a CVType referring to a class, structure, union, or enum, compute +/// the hash of its forward decl and full decl. +Expected<TagRecordHash> hashTagRecord(const codeview::CVType &Type); + } // end namespace pdb } // end namespace llvm diff --git a/include/llvm/DebugInfo/PDB/Native/TpiStream.h b/include/llvm/DebugInfo/PDB/Native/TpiStream.h index b77939929ecf..b76576a7a263 100644 --- a/include/llvm/DebugInfo/PDB/Native/TpiStream.h +++ b/include/llvm/DebugInfo/PDB/Native/TpiStream.h @@ -58,10 +58,21 @@ public: codeview::LazyRandomTypeCollection &typeCollection() { return *Types; } + Expected<codeview::TypeIndex> + findFullDeclForForwardRef(codeview::TypeIndex ForwardRefTI) const; + + std::vector<codeview::TypeIndex> findRecordsByName(StringRef Name) const; + + codeview::CVType getType(codeview::TypeIndex Index); + BinarySubstreamRef getTypeRecordsSubstream() const; Error commit(); + void buildHashMap(); + + bool supportsTypeLookup() const; + private: PDBFile &Pdb; std::unique_ptr<msf::MappedBlockStream> Stream; @@ -77,6 +88,8 @@ private: FixedStreamArray<codeview::TypeIndexOffset> TypeIndexOffsets; HashTable<support::ulittle32_t> HashAdjusters; + std::vector<std::vector<codeview::TypeIndex>> HashMap; + const TpiStreamHeader *Header; }; } diff --git a/include/llvm/DebugInfo/PDB/PDBExtras.h b/include/llvm/DebugInfo/PDB/PDBExtras.h index 3c9a19801f89..aaec71aa8c90 100644 --- a/include/llvm/DebugInfo/PDB/PDBExtras.h +++ b/include/llvm/DebugInfo/PDB/PDBExtras.h @@ -12,6 +12,8 @@ #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/PDB/PDBTypes.h" +#include "llvm/Support/raw_ostream.h" + #include <unordered_map> namespace llvm { @@ -24,6 +26,7 @@ using TagStats = std::unordered_map<PDB_SymType, int>; raw_ostream &operator<<(raw_ostream &OS, const PDB_VariantType &Value); raw_ostream &operator<<(raw_ostream &OS, const PDB_CallingConv &Conv); +raw_ostream &operator<<(raw_ostream &OS, const PDB_BuiltinType &Type); raw_ostream &operator<<(raw_ostream &OS, const PDB_DataKind &Data); raw_ostream &operator<<(raw_ostream &OS, const codeview::RegisterId &Reg); raw_ostream &operator<<(raw_ostream &OS, const PDB_LocType &Loc); @@ -41,6 +44,15 @@ raw_ostream &operator<<(raw_ostream &OS, const Variant &Value); raw_ostream &operator<<(raw_ostream &OS, const VersionInfo &Version); raw_ostream &operator<<(raw_ostream &OS, const TagStats &Stats); + +template <typename T> +void dumpSymbolField(raw_ostream &OS, StringRef Name, T Value, int Indent) { + OS << "\n"; + OS.indent(Indent); + OS << Name << ": " << Value; +} + + } // end namespace pdb } // end namespace llvm diff --git a/include/llvm/DebugInfo/PDB/PDBSymbol.h b/include/llvm/DebugInfo/PDB/PDBSymbol.h index 04373463212b..3a74f7c3aace 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbol.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbol.h @@ -49,9 +49,22 @@ class IPDBRawSymbol; class IPDBSession; #define DECLARE_PDB_SYMBOL_CONCRETE_TYPE(TagValue) \ +private: \ + using PDBSymbol::PDBSymbol; \ + friend class PDBSymbol; \ + \ +public: \ static const PDB_SymType Tag = TagValue; \ static bool classof(const PDBSymbol *S) { return S->getSymTag() == Tag; } +#define DECLARE_PDB_SYMBOL_CUSTOM_TYPE(Condition) \ +private: \ + using PDBSymbol::PDBSymbol; \ + friend class PDBSymbol; \ + \ +public: \ + static bool classof(const PDBSymbol *S) { return Condition; } + /// PDBSymbol defines the base of the inheritance hierarchy for concrete symbol /// types (e.g. functions, executables, vtables, etc). All concrete symbol /// types inherit from PDBSymbol and expose the exact set of methods that are @@ -59,14 +72,33 @@ class IPDBSession; /// reference "Lexical and Class Hierarchy of Symbol Types": /// https://msdn.microsoft.com/en-us/library/370hs6k4.aspx class PDBSymbol { + static std::unique_ptr<PDBSymbol> createSymbol(const IPDBSession &PDBSession, + PDB_SymType Tag); + protected: - PDBSymbol(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> Symbol); - PDBSymbol(PDBSymbol &Symbol); + explicit PDBSymbol(const IPDBSession &PDBSession); + PDBSymbol(PDBSymbol &&Other); public: static std::unique_ptr<PDBSymbol> - create(const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol); + create(const IPDBSession &PDBSession, + std::unique_ptr<IPDBRawSymbol> RawSymbol); + static std::unique_ptr<PDBSymbol> create(const IPDBSession &PDBSession, + IPDBRawSymbol &RawSymbol); + + template <typename ConcreteT> + static std::unique_ptr<ConcreteT> + createAs(const IPDBSession &PDBSession, + std::unique_ptr<IPDBRawSymbol> RawSymbol) { + std::unique_ptr<PDBSymbol> S = create(PDBSession, std::move(RawSymbol)); + return unique_dyn_cast_or_null<ConcreteT>(std::move(S)); + } + template <typename ConcreteT> + static std::unique_ptr<ConcreteT> createAs(const IPDBSession &PDBSession, + IPDBRawSymbol &RawSymbol) { + std::unique_ptr<PDBSymbol> S = create(PDBSession, RawSymbol); + return unique_dyn_cast_or_null<ConcreteT>(std::move(S)); + } virtual ~PDBSymbol(); @@ -80,7 +112,8 @@ public: /// normally goes on the right side of the symbol. virtual void dumpRight(PDBSymDumper &Dumper) const {} - void defaultDump(raw_ostream &OS, int Indent) const; + void defaultDump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowFlags, + PdbSymbolIdField RecurseFlags) const; void dumpProperties() const; void dumpChildStats() const; @@ -94,8 +127,6 @@ public: return Enumerator->getNext(); } - std::unique_ptr<PDBSymbol> clone() const; - template <typename T> std::unique_ptr<ConcreteSymbolEnumerator<T>> findAllChildren() const { auto BaseIter = RawSymbol->findChildren(T::Tag); @@ -131,7 +162,8 @@ protected: } const IPDBSession &Session; - std::unique_ptr<IPDBRawSymbol> RawSymbol; + std::unique_ptr<IPDBRawSymbol> OwnedRawSymbol; + IPDBRawSymbol *RawSymbol = nullptr; }; } // namespace llvm diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolAnnotation.h b/include/llvm/DebugInfo/PDB/PDBSymbolAnnotation.h index 3169146e5b12..ef00df15cb0a 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolAnnotation.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolAnnotation.h @@ -18,12 +18,9 @@ class raw_ostream; namespace pdb { class PDBSymbolAnnotation : public PDBSymbol { -public: - PDBSymbolAnnotation(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> Symbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Annotation) +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getAddressOffset) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h b/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h index d81da1eaa023..2cf9c72a8886 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h @@ -19,12 +19,8 @@ class raw_ostream; namespace pdb { class PDBSymbolBlock : public PDBSymbol { -public: - PDBSymbolBlock(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> Symbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Block) - +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getAddressOffset) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h b/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h index 9549089c7eb4..04dbd962ebd4 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h @@ -20,12 +20,8 @@ class raw_ostream; namespace pdb { class PDBSymbolCompiland : public PDBSymbol { -public: - PDBSymbolCompiland(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> CompilandSymbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Compiland) - +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(isEditAndContinueEnabled) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h b/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h index dba50c42cf81..3d651a464d94 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h @@ -19,12 +19,8 @@ class raw_ostream; namespace pdb { class PDBSymbolCompilandDetails : public PDBSymbol { -public: - PDBSymbolCompilandDetails(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> Symbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::CompilandDetails) - +public: void dump(PDBSymDumper &Dumper) const override; void getFrontEndVersion(VersionInfo &Version) const { diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h b/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h index 7868f0459086..ffc408314d9a 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h @@ -18,12 +18,8 @@ namespace llvm { class raw_ostream; namespace pdb { class PDBSymbolCompilandEnv : public PDBSymbol { -public: - PDBSymbolCompilandEnv(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> Symbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::CompilandEnv) - +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_ID_METHOD(getLexicalParent) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolCustom.h b/include/llvm/DebugInfo/PDB/PDBSymbolCustom.h index 54f089404262..c29e4c31d3f3 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolCustom.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolCustom.h @@ -23,12 +23,8 @@ namespace pdb { /// fit anywhere else in the lexical hierarchy. /// https://msdn.microsoft.com/en-us/library/d88sf09h.aspx class PDBSymbolCustom : public PDBSymbol { -public: - PDBSymbolCustom(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> CustomSymbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Custom) - +public: void dump(PDBSymDumper &Dumper) const override; void getDataBytes(llvm::SmallVector<uint8_t, 32> &bytes); diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolData.h b/include/llvm/DebugInfo/PDB/PDBSymbolData.h index 76b14bf17784..217e1e976e6b 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolData.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolData.h @@ -21,12 +21,8 @@ class raw_ostream; namespace pdb { class PDBSymbolData : public PDBSymbol { -public: - PDBSymbolData(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> DataSymbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Data) - +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getAccess) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolExe.h b/include/llvm/DebugInfo/PDB/PDBSymbolExe.h index 2c2d74665040..366d0cf4777f 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolExe.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolExe.h @@ -20,12 +20,8 @@ class raw_ostream; namespace pdb { class PDBSymbolExe : public PDBSymbol { -public: - PDBSymbolExe(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> ExeSymbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Exe) - +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getAge) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h b/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h index 05d585d25763..129e557c7f25 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h @@ -22,18 +22,14 @@ class raw_ostream; namespace pdb { class PDBSymbolFunc : public PDBSymbol { + DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Function) public: - PDBSymbolFunc(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> FuncSymbol); - void dump(PDBSymDumper &Dumper) const override; bool isDestructor() const; std::unique_ptr<IPDBEnumChildren<PDBSymbolData>> getArguments() const; - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Function) - FORWARD_SYMBOL_METHOD(getAccess) FORWARD_SYMBOL_METHOD(getAddressOffset) FORWARD_SYMBOL_METHOD(getAddressSection) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h b/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h index 3341bd9b30fd..18db8a50fd1b 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h @@ -20,12 +20,8 @@ class raw_ostream; namespace pdb { class PDBSymbolFuncDebugEnd : public PDBSymbol { -public: - PDBSymbolFuncDebugEnd(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> FuncDebugEndSymbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::FuncDebugEnd) - +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getAddressOffset) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h b/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h index 6729838597c8..83d82f0cbcc5 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h @@ -19,12 +19,8 @@ class raw_ostream; namespace pdb { class PDBSymbolFuncDebugStart : public PDBSymbol { -public: - PDBSymbolFuncDebugStart(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> FuncDebugStartSymbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::FuncDebugStart) - +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getAddressOffset) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h b/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h index c2b1c28c929e..8b2617fcd757 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h @@ -19,12 +19,8 @@ class raw_ostream; namespace pdb { class PDBSymbolLabel : public PDBSymbol { -public: - PDBSymbolLabel(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> LabelSymbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Label) - +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getAddressOffset) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h b/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h index c9e6ee67c575..9def3edb469a 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h @@ -19,12 +19,8 @@ class raw_ostream; namespace pdb { class PDBSymbolPublicSymbol : public PDBSymbol { -public: - PDBSymbolPublicSymbol(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> PublicSymbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::PublicSymbol) - +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getAddressOffset) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h b/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h index 614fad86caa8..7bb0555362db 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h @@ -19,12 +19,8 @@ class raw_ostream; namespace pdb { class PDBSymbolThunk : public PDBSymbol { -public: - PDBSymbolThunk(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> ThunkSymbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Thunk) - +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getAccess) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h index 39b7d3b300ea..488f668bdc10 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h @@ -19,12 +19,8 @@ class raw_ostream; namespace pdb { class PDBSymbolTypeArray : public PDBSymbol { -public: - PDBSymbolTypeArray(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> ArrayTypeSymbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::ArrayType) - +public: void dump(PDBSymDumper &Dumper) const override; void dumpRight(PDBSymDumper &Dumper) const override; diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h index d607a3d81170..550deedd7504 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h @@ -22,12 +22,8 @@ class raw_ostream; namespace pdb { class PDBSymbolTypeBaseClass : public PDBSymbol { -public: - PDBSymbolTypeBaseClass(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> Symbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::BaseClass) - +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getAccess) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h index 5b1863c42a04..e07e88802b8f 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h @@ -19,12 +19,8 @@ class raw_ostream; namespace pdb { class PDBSymbolTypeBuiltin : public PDBSymbol { -public: - PDBSymbolTypeBuiltin(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> Symbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::BuiltinType) - +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getBuiltinType) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h index 199b3f8b304e..0d8979c9c5c5 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h @@ -19,12 +19,8 @@ class raw_ostream; namespace pdb { class PDBSymbolTypeCustom : public PDBSymbol { -public: - PDBSymbolTypeCustom(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> Symbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::CustomType) - +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getOemId) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h index e635eb5bbf6f..58292a63501f 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h @@ -19,12 +19,8 @@ class raw_ostream; namespace pdb { class PDBSymbolTypeDimension : public PDBSymbol { -public: - PDBSymbolTypeDimension(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> Symbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Dimension) - +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getLowerBoundId) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h index ddbe7e58f183..f463047bb5b5 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h @@ -21,12 +21,8 @@ class raw_ostream; namespace pdb { class PDBSymbolTypeEnum : public PDBSymbol { -public: - PDBSymbolTypeEnum(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> EnumTypeSymbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Enum) - +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getBuiltinType) @@ -38,6 +34,7 @@ public: FORWARD_SYMBOL_METHOD(hasNestedTypes) FORWARD_SYMBOL_METHOD(getLength) FORWARD_SYMBOL_ID_METHOD(getLexicalParent) + FORWARD_SYMBOL_ID_METHOD(getUnmodifiedType) FORWARD_SYMBOL_METHOD(getName) FORWARD_SYMBOL_METHOD(getSrcLineOnTypeDefn) FORWARD_SYMBOL_METHOD(isNested) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h index 24c13128111f..5b940b0737af 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h @@ -19,12 +19,8 @@ class raw_ostream; namespace pdb { class PDBSymbolTypeFriend : public PDBSymbol { -public: - PDBSymbolTypeFriend(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> Symbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Friend) - +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_ID_METHOD(getClassParent) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h index 3855999c473f..074cb418fc82 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h @@ -19,12 +19,8 @@ class raw_ostream; namespace pdb { class PDBSymbolTypeFunctionArg : public PDBSymbol { -public: - PDBSymbolTypeFunctionArg(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> Symbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::FunctionArg) - +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_ID_METHOD(getClassParent) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h index abd4cf5effa2..dfdf436197c3 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h @@ -19,12 +19,8 @@ class raw_ostream; namespace pdb { class PDBSymbolTypeFunctionSig : public PDBSymbol { -public: - PDBSymbolTypeFunctionSig(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> Symbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::FunctionSig) - +public: std::unique_ptr<IPDBEnumSymbols> getArguments() const; void dump(PDBSymDumper &Dumper) const override; diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h index 31cf5363dde1..d716abd640c6 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h @@ -19,12 +19,8 @@ class raw_ostream; namespace pdb { class PDBSymbolTypeManaged : public PDBSymbol { -public: - PDBSymbolTypeManaged(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> Symbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::ManagedType) - +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getName) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h index 7612ebac31dd..300d6722fc4d 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h @@ -19,16 +19,13 @@ class raw_ostream; namespace pdb { class PDBSymbolTypePointer : public PDBSymbol { -public: - PDBSymbolTypePointer(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> Symbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::PointerType) - +public: void dump(PDBSymDumper &Dumper) const override; void dumpRight(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(isConstType) + FORWARD_SYMBOL_ID_METHOD(getClassParent) FORWARD_SYMBOL_METHOD(getLength) FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(isReference) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h index 16c1d1b88c6d..d6e2a36486d5 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h @@ -19,12 +19,8 @@ class raw_ostream; namespace pdb { class PDBSymbolTypeTypedef : public PDBSymbol { -public: - PDBSymbolTypeTypedef(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> Symbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Typedef) - +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getBuiltinType) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h index e259b6dca3d5..937dd6c87221 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h @@ -23,17 +23,8 @@ class raw_ostream; namespace pdb { class PDBSymbolTypeUDT : public PDBSymbol { -public: - PDBSymbolTypeUDT(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> UDTSymbol); - - std::unique_ptr<PDBSymbolTypeUDT> clone() const { - return getSession().getConcreteSymbolById<PDBSymbolTypeUDT>( - getSymIndexId()); - } - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::UDT) - +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_ID_METHOD(getClassParent) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h index e270c2b7eb95..6efce4bbd686 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h @@ -19,12 +19,8 @@ class raw_ostream; namespace pdb { class PDBSymbolTypeVTable : public PDBSymbol { -public: - PDBSymbolTypeVTable(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> VtblSymbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::VTable) - +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_ID_METHOD(getClassParent) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h index 8acaabea5bb8..8949052b0c0f 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h @@ -19,12 +19,8 @@ class raw_ostream; namespace pdb { class PDBSymbolTypeVTableShape : public PDBSymbol { -public: - PDBSymbolTypeVTableShape(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> VtblShapeSymbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::VTableShape) - +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(isConstType) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolUnknown.h b/include/llvm/DebugInfo/PDB/PDBSymbolUnknown.h index de43e47badbd..e935ac6ce0dc 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolUnknown.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolUnknown.h @@ -18,16 +18,11 @@ class raw_ostream; namespace pdb { class PDBSymbolUnknown : public PDBSymbol { -public: - PDBSymbolUnknown(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> UnknownSymbol); + DECLARE_PDB_SYMBOL_CUSTOM_TYPE(S->getSymTag() == PDB_SymType::None || + S->getSymTag() >= PDB_SymType::Max) +public: void dump(PDBSymDumper &Dumper) const override; - - static bool classof(const PDBSymbol *S) { - return (S->getSymTag() == PDB_SymType::None || - S->getSymTag() >= PDB_SymType::Max); - } }; } // namespace llvm diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h b/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h index 70fbd5b84c34..4e8c99fc8d89 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h @@ -19,12 +19,9 @@ class raw_ostream; namespace pdb { class PDBSymbolUsingNamespace : public PDBSymbol { -public: - PDBSymbolUsingNamespace(const IPDBSession &PDBSession, - std::unique_ptr<IPDBRawSymbol> Symbol); - DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::UsingNamespace) +public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_ID_METHOD(getLexicalParent) diff --git a/include/llvm/DebugInfo/PDB/PDBTypes.h b/include/llvm/DebugInfo/PDB/PDBTypes.h index da6cb1d26771..917f3ed73910 100644 --- a/include/llvm/DebugInfo/PDB/PDBTypes.h +++ b/include/llvm/DebugInfo/PDB/PDBTypes.h @@ -12,6 +12,7 @@ #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" +#include "llvm/DebugInfo/PDB/IPDBFrameData.h" #include "llvm/DebugInfo/PDB/Native/RawTypes.h" #include <cctype> #include <cstddef> @@ -22,6 +23,8 @@ namespace llvm { namespace pdb { +typedef uint32_t SymIndexId; + class IPDBDataStream; class IPDBInjectedSource; class IPDBLineNumber; @@ -69,6 +72,7 @@ using IPDBEnumLineNumbers = IPDBEnumChildren<IPDBLineNumber>; using IPDBEnumTables = IPDBEnumChildren<IPDBTable>; using IPDBEnumInjectedSources = IPDBEnumChildren<IPDBInjectedSource>; using IPDBEnumSectionContribs = IPDBEnumChildren<IPDBSectionContrib>; +using IPDBEnumFrameData = IPDBEnumChildren<IPDBFrameData>; /// Specifies which PDB reader implementation is to be used. Only a value /// of PDB_ReaderType::DIA is currently supported, but Native is in the works. @@ -208,6 +212,18 @@ enum class PDB_SymType { CustomType, ManagedType, Dimension, + CallSite, + InlineSite, + BaseInterface, + VectorType, + MatrixType, + HLSLType, + Caller, + Callee, + Export, + HeapAllocationSite, + CoffGroup, + Inlinee, Max }; @@ -334,6 +350,36 @@ enum PDB_VariantType { struct Variant { Variant() = default; + explicit Variant(bool V) : Type(PDB_VariantType::Bool) { Value.Bool = V; } + explicit Variant(int8_t V) : Type(PDB_VariantType::Int8) { Value.Int8 = V; } + explicit Variant(int16_t V) : Type(PDB_VariantType::Int16) { + Value.Int16 = V; + } + explicit Variant(int32_t V) : Type(PDB_VariantType::Int32) { + Value.Int32 = V; + } + explicit Variant(int64_t V) : Type(PDB_VariantType::Int64) { + Value.Int64 = V; + } + explicit Variant(float V) : Type(PDB_VariantType::Single) { + Value.Single = V; + } + explicit Variant(double V) : Type(PDB_VariantType::Double) { + Value.Double = V; + } + explicit Variant(uint8_t V) : Type(PDB_VariantType::UInt8) { + Value.UInt8 = V; + } + explicit Variant(uint16_t V) : Type(PDB_VariantType::UInt16) { + Value.UInt16 = V; + } + explicit Variant(uint32_t V) : Type(PDB_VariantType::UInt32) { + Value.UInt32 = V; + } + explicit Variant(uint64_t V) : Type(PDB_VariantType::UInt64) { + Value.UInt64 = V; + } + Variant(const Variant &Other) { *this = Other; } |
