Update clang to r339409.
Change-Id: I800772d2d838223be1f6b40d490c4591b937fca2
diff --git a/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeView.h b/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeView.h
index 301e4f6..4ce9f68 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeView.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeView.h
@@ -22,8 +22,8 @@
namespace llvm {
namespace codeview {
-/// Distinguishes individual records in .debug$T section or PDB type stream. The
-/// documentation and headers talk about this as the "leaf" type.
+/// Distinguishes individual records in .debug$T or .debug$P section or PDB type
+/// stream. The documentation and headers talk about this as the "leaf" type.
enum class TypeRecordKind : uint16_t {
#define TYPE_RECORD(lf_ename, value, name) name = value,
#include "CodeViewTypes.def"
diff --git a/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def b/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def
index 3f06602..6da8893 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def
@@ -15,254 +15,254 @@
#define CV_REGISTER(name, value)
#endif
-// This currently only contains the "register subset shraed by all processor
+// This currently only contains the "register subset shared by all processor
// types" (ERR etc.) and the x86 registers.
-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(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)
-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(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(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(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(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(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(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(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(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(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(MXCSR, 211)
+CV_REGISTER(CVRegMXCSR, 211)
-CV_REGISTER(EDXEAX, 212)
+CV_REGISTER(CVRegEDXEAX, 212)
-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(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(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(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(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(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(BND0, 396)
-CV_REGISTER(BND1, 397)
-CV_REGISTER(BND2, 398)
+CV_REGISTER(CVRegBND0, 396)
+CV_REGISTER(CVRegBND1, 397)
+CV_REGISTER(CVRegBND2, 398)
-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(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(SIL, 324)
-CV_REGISTER(DIL, 325)
-CV_REGISTER(BPL, 326)
-CV_REGISTER(SPL, 327)
+CV_REGISTER(CVRegSIL, 324)
+CV_REGISTER(CVRegDIL, 325)
+CV_REGISTER(CVRegBPL, 326)
+CV_REGISTER(CVRegSPL, 327)
-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(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(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(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(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(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(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(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(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)
+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)
// cvconst.h defines both CV_REG_YMM0 (252) and CV_AMD64_YMM0 (368). Keep the
// original prefix to distinguish them.
-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(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)
diff --git a/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def b/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def
index 41c5380..b5f1cc0 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def
@@ -143,7 +143,6 @@
CV_SYMBOL(S_MANMANYREG , 0x1121)
CV_SYMBOL(S_MANREGREL , 0x1122)
CV_SYMBOL(S_MANMANYREG2 , 0x1123)
-CV_SYMBOL(S_UNAMESPACE , 0x1124)
CV_SYMBOL(S_DATAREF , 0x1126)
CV_SYMBOL(S_ANNOTATIONREF , 0x1128)
CV_SYMBOL(S_TOKENREF , 0x1129)
@@ -255,6 +254,7 @@
SYMBOL_RECORD(S_LTHREAD32 , 0x1112, ThreadLocalDataSym)
SYMBOL_RECORD_ALIAS(S_GTHREAD32 , 0x1113, GlobalTLS, ThreadLocalDataSym)
+SYMBOL_RECORD(S_UNAMESPACE , 0x1124, UsingNamespaceSym)
#undef CV_SYMBOL
#undef SYMBOL_RECORD
diff --git a/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewTypes.def b/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewTypes.def
index 69ce960..e9a479d 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewTypes.def
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewTypes.def
@@ -87,6 +87,8 @@
TYPE_RECORD(LF_METHODLIST, 0x1206, MethodOverloadList)
+TYPE_RECORD(LF_PRECOMP, 0x1509, Precomp)
+TYPE_RECORD(LF_ENDPRECOMP, 0x0014, EndPrecomp)
// 16 bit type records.
CV_TYPE(LF_MODIFIER_16t, 0x0001)
@@ -106,7 +108,6 @@
CV_TYPE(LF_DIMARRAY_16t, 0x0011)
CV_TYPE(LF_VFTPATH_16t, 0x0012)
CV_TYPE(LF_PRECOMP_16t, 0x0013)
-CV_TYPE(LF_ENDPRECOMP, 0x0014)
CV_TYPE(LF_OEM_16t, 0x0015)
CV_TYPE(LF_TYPESERVER_ST, 0x0016)
@@ -181,7 +182,6 @@
CV_TYPE(LF_ST_MAX, 0x1500)
CV_TYPE(LF_TYPESERVER, 0x1501)
CV_TYPE(LF_DIMARRAY, 0x1508)
-CV_TYPE(LF_PRECOMP, 0x1509)
CV_TYPE(LF_ALIAS, 0x150a)
CV_TYPE(LF_DEFARG, 0x150b)
CV_TYPE(LF_FRIENDFCN, 0x150c)
diff --git a/linux-x64/clang/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h b/linux-x64/clang/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h
index 16d7869..383f7dd 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h
@@ -26,7 +26,7 @@
namespace llvm {
namespace codeview {
-/// \brief Provides amortized O(1) random access to a CodeView type stream.
+/// Provides amortized O(1) random access to a CodeView type stream.
/// Normally to access a type from a type stream, you must know its byte
/// offset into the type stream, because type records are variable-lengthed.
/// However, this is not the way we prefer to access them. For example, given
diff --git a/linux-x64/clang/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/linux-x64/clang/include/llvm/DebugInfo/CodeView/SymbolRecord.h
index cf267f2..9330682 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/SymbolRecord.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/SymbolRecord.h
@@ -942,6 +942,19 @@
uint32_t RecordOffset;
};
+// S_UNAMESPACE
+class UsingNamespaceSym : public SymbolRecord {
+public:
+ explicit UsingNamespaceSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ explicit UsingNamespaceSym(uint32_t RecordOffset)
+ : SymbolRecord(SymbolRecordKind::RegRelativeSym),
+ RecordOffset(RecordOffset) {}
+
+ StringRef Name;
+
+ uint32_t RecordOffset;
+};
+
// S_ANNOTATION
using CVSymbol = CVRecord<SymbolKind>;
diff --git a/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeHashing.h b/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeHashing.h
index 7413375..1f732d2 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeHashing.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeHashing.h
@@ -58,7 +58,10 @@
}
};
-enum class GlobalTypeHashAlg : uint16_t { SHA1 = 0 };
+enum class GlobalTypeHashAlg : uint16_t {
+ SHA1 = 0, // standard 20-byte SHA1 hash
+ SHA1_8 // last 8-bytes of standard SHA1 hash
+};
/// A globally hashed type represents a hash value that is sufficient to
/// uniquely identify a record across multiple type streams or type sequences.
@@ -77,10 +80,10 @@
GloballyHashedType(StringRef H)
: GloballyHashedType(ArrayRef<uint8_t>(H.bytes_begin(), H.bytes_end())) {}
GloballyHashedType(ArrayRef<uint8_t> H) {
- assert(H.size() == 20);
- ::memcpy(Hash.data(), H.data(), 20);
+ assert(H.size() == 8);
+ ::memcpy(Hash.data(), H.data(), 8);
}
- std::array<uint8_t, 20> Hash;
+ std::array<uint8_t, 8> Hash;
/// Given a sequence of bytes representing a record, compute a global hash for
/// this record. Due to the nature of global hashes incorporating the hashes
diff --git a/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeRecord.h b/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeRecord.h
index 55f2822..61ebdf8 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeRecord.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeRecord.h
@@ -896,6 +896,33 @@
TypeIndex ContinuationIndex;
};
+// LF_PRECOMP
+class PrecompRecord : public TypeRecord {
+public:
+ PrecompRecord() = default;
+ explicit PrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
+
+ uint32_t getStartTypeIndex() const { return StartTypeIndex; }
+ uint32_t getTypesCount() const { return TypesCount; }
+ uint32_t getSignature() const { return Signature; }
+ StringRef getPrecompFilePath() const { return PrecompFilePath; }
+
+ uint32_t StartTypeIndex;
+ uint32_t TypesCount;
+ uint32_t Signature;
+ StringRef PrecompFilePath;
+};
+
+// LF_ENDPRECOMP
+class EndPrecompRecord : public TypeRecord {
+public:
+ EndPrecompRecord() = default;
+ explicit EndPrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
+
+ uint32_t getSignature() const { return Signature; }
+
+ uint32_t Signature;
+};
} // end namespace codeview
} // end namespace llvm
diff --git a/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h b/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h
index 59e216a..583740d 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h
@@ -23,7 +23,7 @@
class GlobalTypeTableBuilder;
class MergingTypeTableBuilder;
-/// \brief Merge one set of type records into another. This method assumes
+/// Merge one set of type records into another. This method assumes
/// that all records are type records, and there are no Id records present.
///
/// \param Dest The table to store the re-written type records into.
@@ -40,7 +40,7 @@
SmallVectorImpl<TypeIndex> &SourceToDest,
const CVTypeArray &Types);
-/// \brief Merge one set of id records into another. This method assumes
+/// Merge one set of id records into another. This method assumes
/// that all records are id records, and there are no Type records present.
/// However, since Id records can refer back to Type records, this method
/// assumes that the referenced type records have also been merged into
@@ -65,7 +65,7 @@
SmallVectorImpl<TypeIndex> &SourceToDest,
const CVTypeArray &Ids);
-/// \brief Merge a unified set of type and id records, splitting them into
+/// Merge a unified set of type and id records, splitting them into
/// separate output streams.
///
/// \param DestIds The table to store the re-written id records into.
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DIContext.h b/linux-x64/clang/include/llvm/DebugInfo/DIContext.h
index f89eb34..bbdd5e0 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DIContext.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DIContext.h
@@ -154,6 +154,8 @@
struct DIDumpOptions {
unsigned DumpType = DIDT_All;
unsigned RecurseDepth = -1U;
+ uint16_t Version = 0; // DWARF version to assume when extracting.
+ uint8_t AddrSize = 4; // Address byte size to assume when extracting.
bool ShowAddresses = true;
bool ShowChildren = false;
bool ShowParents = false;
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
index 27f11ca..1d44872 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
@@ -56,12 +56,6 @@
/// in this Accelerator Entry.
virtual Optional<uint64_t> getCUOffset() const = 0;
- /// Returns the Section Offset of the Debug Info Entry associated with this
- /// Accelerator Entry or None if the DIE offset is not recorded in this
- /// Accelerator Entry. The returned offset is relative to the start of the
- /// Section containing the DIE.
- virtual Optional<uint64_t> getDIESectionOffset() const = 0;
-
/// Returns the Tag of the Debug Info Entry associated with this
/// Accelerator Entry or None if the Tag is not recorded in this
/// Accelerator Entry.
@@ -130,7 +124,13 @@
public:
Optional<uint64_t> getCUOffset() const override;
- Optional<uint64_t> getDIESectionOffset() const override;
+
+ /// Returns the Section Offset of the Debug Info Entry associated with this
+ /// Accelerator Entry or None if the DIE offset is not recorded in this
+ /// Accelerator Entry. The returned offset is relative to the start of the
+ /// Section containing the DIE.
+ Optional<uint64_t> getDIESectionOffset() const;
+
Optional<dwarf::Tag> getTag() const override;
/// Returns the value of the Atom in this Accelerator Entry, if the Entry
@@ -239,6 +239,7 @@
public:
class NameIndex;
+ class NameIterator;
class ValueIterator;
/// Dwarf 5 Name Index header.
@@ -283,6 +284,10 @@
Entry(const NameIndex &NameIdx, const Abbrev &Abbr);
+ public:
+ Optional<uint64_t> getCUOffset() const override;
+ Optional<dwarf::Tag> getTag() const override { return tag(); }
+
/// Returns the Index into the Compilation Unit list of the owning Name
/// Index or None if this Accelerator Entry does not have an associated
/// Compilation Unit. It is up to the user to verify that the returned Index
@@ -293,11 +298,6 @@
/// DW_IDX_compile_unit attribute.
Optional<uint64_t> getCUIndex() const;
- public:
- Optional<uint64_t> getCUOffset() const override;
- Optional<uint64_t> getDIESectionOffset() const override;
- Optional<dwarf::Tag> getTag() const override { return tag(); }
-
/// .debug_names-specific getter, which always succeeds (DWARF v5 index
/// entries always have a tag).
dwarf::Tag tag() const { return Abbr->Tag; }
@@ -319,7 +319,6 @@
friend class ValueIterator;
};
-private:
/// Error returned by NameIndex::getEntry to report it has reached the end of
/// the entry list.
class SentinelError : public ErrorInfo<SentinelError> {
@@ -330,6 +329,7 @@
std::error_code convertToErrorCode() const override;
};
+private:
/// DenseMapInfo for struct Abbrev.
struct AbbrevMapInfo {
static Abbrev getEmptyKey();
@@ -351,9 +351,34 @@
public:
/// A single entry in the Name Table (Dwarf 5 sect. 6.1.1.4.6) of the Name
/// Index.
- struct NameTableEntry {
- uint32_t StringOffset; ///< Offset of the name of the described entities.
- uint32_t EntryOffset; ///< Offset of the first Entry in the list.
+ class NameTableEntry {
+ DataExtractor StrData;
+
+ uint32_t Index;
+ uint32_t StringOffset;
+ uint32_t EntryOffset;
+
+ public:
+ NameTableEntry(const DataExtractor &StrData, uint32_t Index,
+ uint32_t StringOffset, uint32_t EntryOffset)
+ : StrData(StrData), Index(Index), StringOffset(StringOffset),
+ EntryOffset(EntryOffset) {}
+
+ /// Return the index of this name in the parent Name Index.
+ uint32_t getIndex() const { return Index; }
+
+ /// Returns the offset of the name of the described entities.
+ uint32_t getStringOffset() const { return StringOffset; }
+
+ /// Return the string referenced by this name table entry or nullptr if the
+ /// string offset is not valid.
+ const char *getString() const {
+ uint32_t Off = StringOffset;
+ return StrData.getCStr(&Off);
+ }
+
+ /// Returns the offset of the first Entry in the list.
+ uint32_t getEntryOffset() const { return EntryOffset; }
};
/// Represents a single accelerator table within the Dwarf 5 .debug_names
@@ -373,14 +398,12 @@
uint32_t EntryOffsetsBase;
uint32_t EntriesBase;
- Expected<Entry> getEntry(uint32_t *Offset) const;
-
void dumpCUs(ScopedPrinter &W) const;
void dumpLocalTUs(ScopedPrinter &W) const;
void dumpForeignTUs(ScopedPrinter &W) const;
void dumpAbbreviations(ScopedPrinter &W) const;
bool dumpEntry(ScopedPrinter &W, uint32_t *Offset) const;
- void dumpName(ScopedPrinter &W, uint32_t Index,
+ void dumpName(ScopedPrinter &W, const NameTableEntry &NTE,
Optional<uint32_t> Hash) const;
void dumpBucket(ScopedPrinter &W, uint32_t Bucket) const;
@@ -429,6 +452,14 @@
return Abbrevs;
}
+ Expected<Entry> getEntry(uint32_t *Offset) const;
+
+ /// Look up all entries in this Name Index matching \c Key.
+ iterator_range<ValueIterator> equal_range(StringRef Key) const;
+
+ NameIterator begin() const { return NameIterator(this, 1); }
+ NameIterator end() const { return NameIterator(this, getNameCount() + 1); }
+
llvm::Error extract();
uint32_t getUnitOffset() const { return Base; }
uint32_t getNextUnitOffset() const { return Base + 4 + Hdr.UnitLength; }
@@ -444,6 +475,10 @@
/// "NameIndices" vector in the Accelerator section.
const NameIndex *CurrentIndex = nullptr;
+ /// Whether this is a local iterator (searches in CurrentIndex only) or not
+ /// (searches all name indices).
+ bool IsLocal;
+
Optional<Entry> CurrentEntry;
unsigned DataOffset = 0; ///< Offset into the section.
std::string Key; ///< The Key we are searching for.
@@ -464,6 +499,10 @@
/// Indexes in the section in sequence.
ValueIterator(const DWARFDebugNames &AccelTable, StringRef Key);
+ /// Create a "begin" iterator for looping over all entries in a specific
+ /// Name Index. Other indices in the section will not be visited.
+ ValueIterator(const NameIndex &NI, StringRef Key);
+
/// End marker.
ValueIterator() = default;
@@ -486,8 +525,55 @@
}
};
+ class NameIterator {
+
+ /// The Name Index we are iterating through.
+ const NameIndex *CurrentIndex;
+
+ /// The current name in the Name Index.
+ uint32_t CurrentName;
+
+ void next() {
+ assert(CurrentName <= CurrentIndex->getNameCount());
+ ++CurrentName;
+ }
+
+ public:
+ using iterator_category = std::input_iterator_tag;
+ using value_type = NameTableEntry;
+ using difference_type = uint32_t;
+ using pointer = NameTableEntry *;
+ using reference = NameTableEntry; // We return entries by value.
+
+ /// Creates an iterator whose initial position is name CurrentName in
+ /// CurrentIndex.
+ NameIterator(const NameIndex *CurrentIndex, uint32_t CurrentName)
+ : CurrentIndex(CurrentIndex), CurrentName(CurrentName) {}
+
+ NameTableEntry operator*() const {
+ return CurrentIndex->getNameTableEntry(CurrentName);
+ }
+ NameIterator &operator++() {
+ next();
+ return *this;
+ }
+ NameIterator operator++(int) {
+ NameIterator I = *this;
+ next();
+ return I;
+ }
+
+ friend bool operator==(const NameIterator &A, const NameIterator &B) {
+ return A.CurrentIndex == B.CurrentIndex && A.CurrentName == B.CurrentName;
+ }
+ friend bool operator!=(const NameIterator &A, const NameIterator &B) {
+ return !(A == B);
+ }
+ };
+
private:
SmallVector<NameIndex, 0> NameIndices;
+ DenseMap<uint32_t, const NameIndex *> CUToNameIndex;
public:
DWARFDebugNames(const DWARFDataExtractor &AccelSection,
@@ -503,6 +589,10 @@
using const_iterator = SmallVector<NameIndex, 0>::const_iterator;
const_iterator begin() const { return NameIndices.begin(); }
const_iterator end() const { return NameIndices.end(); }
+
+ /// Return the Name Index covering the compile unit at CUOffset, or nullptr if
+ /// there is no Name Index covering that unit.
+ const NameIndex *getCUNameIndex(uint32_t CUOffset);
};
} // end namespace llvm
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h
index a18adf8..27d56d7 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h
@@ -18,20 +18,20 @@
class DWARFCompileUnit : public DWARFUnit {
public:
DWARFCompileUnit(DWARFContext &Context, const DWARFSection &Section,
+ const DWARFUnitHeader &Header,
const DWARFDebugAbbrev *DA, const DWARFSection *RS,
StringRef SS, const DWARFSection &SOS,
const DWARFSection *AOS, const DWARFSection &LS, bool LE,
- bool IsDWO, const DWARFUnitSectionBase &UnitSection,
- const DWARFUnitIndex::Entry *Entry)
- : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
- UnitSection, Entry) {}
+ bool IsDWO, const DWARFUnitVector &UnitVector)
+ : DWARFUnit(Context, Section, Header, DA, RS, 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/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFContext.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFContext.h
index e842cf2..fc398bd 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFContext.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFContext.h
@@ -57,8 +57,7 @@
/// 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,8 +74,7 @@
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;
@@ -95,22 +93,17 @@
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();
+ /// 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);
- /// Read type units from the debug_types.dwo section (if necessary)
- /// and store them in DWOTUs.
- void parseDWOTypeUnits();
-
-protected:
std::unique_ptr<const DWARFObject> DObj;
public:
@@ -139,72 +132,102 @@
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 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.
- cu_iterator_range dwo_compile_units() {
- parseDWOCompileUnits();
- return cu_iterator_range(DWOCUs.begin(), DWOCUs.end());
- }
+ 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);
+ /// Return the compile unit that includes an offset (relative to .debug_info).
+ DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset);
+
/// Get a DIE given an exact offset.
DWARFDie getDIEForOffset(uint32_t Offset);
@@ -259,7 +282,14 @@
const AppleAcceleratorTable &getAppleObjC();
/// Get a pointer to a parsed line table corresponding to a compile unit.
- const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *cu);
+ /// Report any parsing issues as warnings on stderr.
+ const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *U);
+
+ /// Get a pointer to a parsed line table corresponding to a compile unit.
+ /// Report any recoverable parsing problems using the callback.
+ Expected<const DWARFDebugLine::LineTable *>
+ getLineTableForUnit(DWARFUnit *U,
+ std::function<void(Error)> RecoverableErrorCallback);
DataExtractor getStringExtractor() const {
return DataExtractor(DObj->getStringSection(), false, 0);
@@ -313,10 +343,11 @@
/// have initialized the relevant target descriptions.
Error loadRegisterInfo(const object::ObjectFile &Obj);
-private:
- /// Return the compile unit that includes an offset (relative to .debug_info).
- DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset);
+ /// Get address size from CUs.
+ /// TODO: refactor compile_units() to make this const.
+ uint8_t getCUAddrSize();
+private:
/// Return the compile unit which contains instruction with provided
/// address.
DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
index 10e146b..1ed0875 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
@@ -51,6 +51,8 @@
/// reflect the absolute address of this pointer.
Optional<uint64_t> getEncodedPointer(uint32_t *Offset, uint8_t Encoding,
uint64_t AbsPosOffset = 0) const;
+
+ size_t size() const { return Section == nullptr ? 0 : Section->Data.size(); }
};
} // end namespace llvm
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h
new file mode 100644
index 0000000..ffbd1b0
--- /dev/null
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h
@@ -0,0 +1,98 @@
+//===- DWARFDebugAddr.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_DWARFDEBUGADDR_H
+#define LLVM_DEBUGINFO_DWARFDEBUGADDR_H
+
+#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 <cstdint>
+#include <map>
+#include <vector>
+
+namespace llvm {
+
+class Error;
+class raw_ostream;
+
+/// A class representing an address table as specified in DWARF v5.
+/// The table consists of a header followed by an array of address values from
+/// .debug_addr section.
+class DWARFDebugAddrTable {
+public:
+ struct Header {
+ /// The total length of the entries for this table, not including the length
+ /// field itself.
+ uint32_t Length = 0;
+ /// The DWARF version number.
+ uint16_t Version = 5;
+ /// The size in bytes of an address on the target architecture. For
+ /// segmented addressing, this is the size of the offset portion of the
+ /// address.
+ uint8_t AddrSize;
+ /// The size in bytes of a segment selector on the target architecture.
+ /// If the target system uses a flat address space, this value is 0.
+ uint8_t SegSize = 0;
+ };
+
+private:
+ dwarf::DwarfFormat Format;
+ uint32_t HeaderOffset;
+ Header HeaderData;
+ uint32_t DataSize = 0;
+ std::vector<uint64_t> Addrs;
+
+public:
+ void clear();
+
+ /// Extract an entire table, including all addresses.
+ Error extract(DWARFDataExtractor Data, uint32_t *OffsetPtr,
+ uint16_t Version, uint8_t AddrSize,
+ std::function<void(Error)> WarnCallback);
+
+ uint32_t getHeaderOffset() const { return HeaderOffset; }
+ uint8_t getAddrSize() const { return HeaderData.AddrSize; }
+ void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {}) const;
+
+ /// Return the address based on a given index.
+ Expected<uint64_t> getAddrEntry(uint32_t Index) const;
+
+ /// Return the size of the table header including the length
+ /// but not including the addresses.
+ uint8_t getHeaderSize() const {
+ switch (Format) {
+ case dwarf::DwarfFormat::DWARF32:
+ return 8; // 4 + 2 + 1 + 1
+ case dwarf::DwarfFormat::DWARF64:
+ return 16; // 12 + 2 + 1 + 1
+ }
+ llvm_unreachable("Invalid DWARF format (expected DWARF32 or DWARF64)");
+ }
+
+ /// Returns the length of this table, including the length field, or 0 if the
+ /// length has not been determined (e.g. because the table has not yet been
+ /// parsed, or there was a problem in parsing).
+ uint32_t getLength() const;
+
+ /// Verify that the given length is valid for this table.
+ bool hasValidLength() const { return getLength() != 0; }
+
+ /// Invalidate Length field to stop further processing.
+ void invalidateLength() { HeaderData.Length = 0; }
+
+ /// Returns the length of the array of addresses.
+ uint32_t getDataSize() const;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_DWARFDEBUGADDR_H
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
index c24364a..8f6ed39 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
@@ -13,9 +13,11 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/DIContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
+#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
#include "llvm/Support/MD5.h"
#include <cstdint>
#include <map>
@@ -103,6 +105,8 @@
uint32_t sizeofPrologueLength() const { return isDWARF64() ? 8 : 4; }
+ bool totalLengthIsValid() const;
+
/// Length of the prologue in bytes.
uint32_t getLength() const {
return PrologueLength + sizeofTotalLength() + sizeof(getVersion()) +
@@ -120,8 +124,8 @@
void clear();
void dump(raw_ostream &OS, DIDumpOptions DumpOptions) const;
- bool parse(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr,
- const DWARFContext &Ctx, const DWARFUnit *U = nullptr);
+ Error parse(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr,
+ const DWARFContext &Ctx, const DWARFUnit *U = nullptr);
};
/// Standard .debug_line state machine structure.
@@ -243,9 +247,10 @@
void clear();
/// Parse prologue and all rows.
- bool parse(DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr,
- const DWARFContext &Ctx, const DWARFUnit *U,
- raw_ostream *OS = nullptr);
+ Error parse(DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr,
+ const DWARFContext &Ctx, const DWARFUnit *U,
+ std::function<void(Error)> RecoverableErrorCallback = warn,
+ raw_ostream *OS = nullptr);
using RowVector = std::vector<Row>;
using RowIter = RowVector::const_iterator;
@@ -259,14 +264,74 @@
private:
uint32_t findRowInSeq(const DWARFDebugLine::Sequence &Seq,
uint64_t Address) const;
- Optional<StringRef> getSourceByIndex(uint64_t FileIndex,
- DILineInfoSpecifier::FileLineInfoKind Kind) const;
+ Optional<StringRef>
+ getSourceByIndex(uint64_t FileIndex,
+ DILineInfoSpecifier::FileLineInfoKind Kind) const;
};
const LineTable *getLineTable(uint32_t Offset) const;
- const LineTable *getOrParseLineTable(DWARFDataExtractor &DebugLineData,
- uint32_t Offset, const DWARFContext &C,
- const DWARFUnit *U);
+ Expected<const LineTable *> getOrParseLineTable(
+ DWARFDataExtractor &DebugLineData, uint32_t Offset,
+ const DWARFContext &Ctx, const DWARFUnit *U,
+ std::function<void(Error)> RecoverableErrorCallback = warn);
+
+ /// Helper to allow for parsing of an entire .debug_line section in sequence.
+ class SectionParser {
+ public:
+ 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,
+ tu_range TUs);
+
+ /// Get the next line table from the section. Report any issues via the
+ /// callbacks.
+ ///
+ /// \param RecoverableErrorCallback - any issues that don't prevent further
+ /// parsing of the table will be reported through this callback.
+ /// \param UnrecoverableErrorCallback - any issues that prevent further
+ /// parsing of the table will be reported through this callback.
+ /// \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);
+
+ /// 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);
+
+ /// Indicates if the parser has parsed as much as possible.
+ ///
+ /// \note Certain problems with the line table structure might mean that
+ /// parsing stops before the end of the section is reached.
+ bool done() const { return Done; }
+
+ /// Get the offset the parser has reached.
+ uint32_t getOffset() const { return Offset; }
+
+ private:
+ DWARFUnit *prepareToParse(uint32_t Offset);
+ void moveToNextTable(uint32_t OldOffset, const Prologue &P);
+
+ LineToUnitMap LineToUnit;
+
+ DWARFDataExtractor &DebugLineData;
+ const DWARFContext &Context;
+ uint32_t Offset = 0;
+ 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 {
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
index a6d319a..9a73745 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
@@ -42,7 +42,8 @@
SmallVector<Entry, 2> Entries;
/// Dump this list on OS.
void dump(raw_ostream &OS, bool IsLittleEndian, unsigned AddressSize,
- const MCRegisterInfo *MRI, unsigned Indent) const;
+ const MCRegisterInfo *MRI, uint64_t BaseAddress,
+ unsigned Indent) const;
};
private:
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h
index 761871d..cae4804 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h
@@ -32,7 +32,7 @@
/// The name of the object as given by the DW_AT_name attribute of the
/// referenced DIE.
- const char *Name;
+ StringRef Name;
};
/// Each table consists of sets of variable length entries. Each set describes
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
index 38b7f22..ce7436d 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
@@ -71,7 +71,7 @@
void clear();
void dump(raw_ostream &OS) const;
- bool extract(const DWARFDataExtractor &data, uint32_t *offset_ptr);
+ Error extract(const DWARFDataExtractor &data, uint32_t *offset_ptr);
const std::vector<RangeListEntry> &getEntries() { return Entries; }
/// getAbsoluteRanges - Returns absolute address ranges defined by this range
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
index 7579def..e2e8ab5 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
@@ -10,10 +10,13 @@
#ifndef LLVM_DEBUGINFO_DWARFDEBUGRNGLISTS_H
#define LLVM_DEBUGINFO_DWARFDEBUGRNGLISTS_H
+#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
+#include "llvm/DebugInfo/DWARF/DWARFListTable.h"
#include <cstdint>
+#include <map>
#include <vector>
namespace llvm {
@@ -21,59 +24,35 @@
class Error;
class raw_ostream;
-class DWARFDebugRnglists {
-private:
- struct Header {
- /// The total length of the entries for this table, not including the length
- /// field itself.
- uint32_t Length = 0;
- /// The DWARF version number.
- uint16_t Version;
- /// The size in bytes of an address on the target architecture. For
- /// segmented addressing, this is the size of the offset portion of the
- /// address.
- uint8_t AddrSize;
- /// The size in bytes of a segment selector on the target architecture.
- /// If the target system uses a flat address space, this value is 0.
- uint8_t SegSize;
- /// The number of offsets that follow the header before the range lists.
- uint32_t OffsetEntryCount;
- };
+/// A class representing a single range list entry.
+struct RangeListEntry : public DWARFListEntryBase {
+ /// The values making up the range list entry. Most represent a range with
+ /// a start and end address or a start address and a length. Others are
+ /// single value base addresses or end-of-list with no values. The unneeded
+ /// values are semantically undefined, but initialized to 0.
+ uint64_t Value0;
+ uint64_t Value1;
+ 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;
+ bool isSentinel() const { return EntryKind == dwarf::DW_RLE_end_of_list; }
+};
+
+/// A class representing a single rangelist.
+class DWARFDebugRnglist : public DWARFListType<RangeListEntry> {
public:
- struct RangeListEntry {
- /// The offset at which the entry is located in the section.
- const uint32_t Offset;
- /// The DWARF encoding (DW_RLE_*).
- const uint8_t EntryKind;
- /// The values making up the range list entry. Most represent a range with
- /// a start and end address or a start address and a length. Others are
- /// single value base addresses or end-of-list with no values. The unneeded
- /// values are semantically undefined, but initialized to 0.
- const uint64_t Value0;
- const uint64_t Value1;
- };
+ /// Build a DWARFAddressRangesVector from a rangelist.
+ DWARFAddressRangesVector
+ getAbsoluteRanges(llvm::Optional<BaseAddress> BaseAddr) const;
+};
- using DWARFRangeList = std::vector<RangeListEntry>;
-
-private:
- uint32_t HeaderOffset;
- Header HeaderData;
- std::vector<uint32_t> Offsets;
- std::vector<DWARFRangeList> Ranges;
- // The length of the longest encoding string we encountered during parsing.
- uint8_t MaxEncodingStringLength = 0;
-
+class DWARFDebugRnglistTable : public DWARFListTableBase<DWARFDebugRnglist> {
public:
- void clear();
- Error extract(DWARFDataExtractor Data, uint32_t *OffsetPtr);
- uint32_t getHeaderOffset() const { return HeaderOffset; }
- void dump(raw_ostream &OS, DIDumpOptions DumpOpts) const;
-
- /// Returns the length of this table, including the length field, or 0 if the
- /// length has not been determined (e.g. because the table has not yet been
- /// parsed, or there was a problem in parsing).
- uint32_t length() const;
+ DWARFDebugRnglistTable()
+ : DWARFListTableBase(/* SectionName = */ ".debug_rnglists",
+ /* HeaderString = */ "ranges:",
+ /* ListTypeString = */ "range") {}
};
} // end namespace llvm
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDie.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDie.h
index 39a3dd3..c77034f 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDie.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDie.h
@@ -46,7 +46,7 @@
public:
DWARFDie() = default;
- DWARFDie(DWARFUnit *Unit, const DWARFDebugInfoEntry * D) : U(Unit), Die(D) {}
+ DWARFDie(DWARFUnit *Unit, const DWARFDebugInfoEntry *D) : U(Unit), Die(D) {}
bool isValid() const { return U && Die; }
explicit operator bool() const { return isValid(); }
@@ -82,9 +82,7 @@
}
/// Returns true for a valid DIE that terminates a sibling chain.
- bool isNULL() const {
- return getAbbreviationDeclarationPtr() == nullptr;
- }
+ bool isNULL() const { return getAbbreviationDeclarationPtr() == nullptr; }
/// Returns true if DIE represents a subprogram (not inlined).
bool isSubprogramDIE() const;
@@ -104,12 +102,24 @@
/// invalid DWARFDie instance if it doesn't.
DWARFDie getSibling() const;
+ /// Get the previous sibling of this DIE object.
+ ///
+ /// \returns a valid DWARFDie instance if this object has a sibling or an
+ /// invalid DWARFDie instance if it doesn't.
+ DWARFDie getPreviousSibling() const;
+
/// Get the first child of this DIE object.
///
/// \returns a valid DWARFDie instance if this object has children or an
/// invalid DWARFDie instance if it doesn't.
DWARFDie getFirstChild() const;
+ /// Get the last child of this DIE object.
+ ///
+ /// \returns a valid null DWARFDie instance if this object has children or an
+ /// invalid DWARFDie instance if it doesn't.
+ DWARFDie getLastChild() const;
+
/// Dump the DIE and all of its attributes to the supplied stream.
///
/// \param OS the stream to use for output.
@@ -117,7 +127,6 @@
void dump(raw_ostream &OS, unsigned indent = 0,
DIDumpOptions DumpOpts = DIDumpOptions()) const;
-
/// Convenience zero-argument overload for debugging.
LLVM_DUMP_METHOD void dump() const;
@@ -207,7 +216,7 @@
///
/// \returns a address range vector that might be empty if no address range
/// information is available.
- DWARFAddressRangesVector getAddressRanges() const;
+ Expected<DWARFAddressRangesVector> getAddressRanges() const;
/// Get all address ranges for any DW_TAG_subprogram DIEs in this DIE or any
/// of its children.
@@ -263,12 +272,16 @@
iterator begin() const;
iterator end() const;
+
+ std::reverse_iterator<iterator> rbegin() const;
+ std::reverse_iterator<iterator> rend() const;
+
iterator_range<iterator> children() const;
};
-class DWARFDie::attribute_iterator :
- public iterator_facade_base<attribute_iterator, std::forward_iterator_tag,
- const DWARFAttribute> {
+class DWARFDie::attribute_iterator
+ : public iterator_facade_base<attribute_iterator, std::forward_iterator_tag,
+ const DWARFAttribute> {
/// The DWARF DIE we are extracting attributes from.
DWARFDie Die;
/// The value vended to clients via the operator*() or operator->().
@@ -276,6 +289,9 @@
/// The attribute index within the abbreviation declaration in Die.
uint32_t Index;
+ friend bool operator==(const attribute_iterator &LHS,
+ const attribute_iterator &RHS);
+
/// Update the attribute index and attempt to read the attribute value. If the
/// attribute is able to be read, update AttrValue and the Index member
/// variable. If the attribute value is not able to be read, an appropriate
@@ -288,14 +304,24 @@
explicit attribute_iterator(DWARFDie D, bool End);
attribute_iterator &operator++();
+ attribute_iterator &operator--();
explicit operator bool() const { return AttrValue.isValid(); }
const DWARFAttribute &operator*() const { return AttrValue; }
- bool operator==(const attribute_iterator &X) const { return Index == X.Index; }
};
+inline bool operator==(const DWARFDie::attribute_iterator &LHS,
+ const DWARFDie::attribute_iterator &RHS) {
+ return LHS.Index == RHS.Index;
+}
+
+inline bool operator!=(const DWARFDie::attribute_iterator &LHS,
+ const DWARFDie::attribute_iterator &RHS) {
+ return !(LHS == RHS);
+}
+
inline bool operator==(const DWARFDie &LHS, const DWARFDie &RHS) {
return LHS.getDebugInfoEntry() == RHS.getDebugInfoEntry() &&
- LHS.getDwarfUnit() == RHS.getDwarfUnit();
+ LHS.getDwarfUnit() == RHS.getDwarfUnit();
}
inline bool operator!=(const DWARFDie &LHS, const DWARFDie &RHS) {
@@ -306,34 +332,43 @@
return LHS.getOffset() < RHS.getOffset();
}
-class DWARFDie::iterator : public iterator_facade_base<iterator,
- std::forward_iterator_tag,
- const DWARFDie> {
+class DWARFDie::iterator
+ : public iterator_facade_base<iterator, std::bidirectional_iterator_tag,
+ const DWARFDie> {
DWARFDie Die;
- void skipNull() {
- if (Die && Die.isNULL())
- Die = DWARFDie();
- }
+
+ friend std::reverse_iterator<llvm::DWARFDie::iterator>;
+ friend bool operator==(const DWARFDie::iterator &LHS,
+ const DWARFDie::iterator &RHS);
+
public:
iterator() = default;
- explicit iterator(DWARFDie D) : Die(D) {
- // If we start out with only a Null DIE then invalidate.
- skipNull();
- }
+ explicit iterator(DWARFDie D) : Die(D) {}
iterator &operator++() {
Die = Die.getSibling();
- // Don't include the NULL die when iterating.
- skipNull();
return *this;
}
- explicit operator bool() const { return Die.isValid(); }
+ iterator &operator--() {
+ Die = Die.getPreviousSibling();
+ return *this;
+ }
+
const DWARFDie &operator*() const { return Die; }
- bool operator==(const iterator &X) const { return Die == X.Die; }
};
+inline bool operator==(const DWARFDie::iterator &LHS,
+ const DWARFDie::iterator &RHS) {
+ return LHS.Die == RHS.Die;
+}
+
+inline bool operator!=(const DWARFDie::iterator &LHS,
+ const DWARFDie::iterator &RHS) {
+ return !(LHS == RHS);
+}
+
// These inline functions must follow the DWARFDie::iterator definition above
// as they use functions from that class.
inline DWARFDie::iterator DWARFDie::begin() const {
@@ -341,7 +376,7 @@
}
inline DWARFDie::iterator DWARFDie::end() const {
- return iterator();
+ return iterator(getLastChild());
}
inline iterator_range<DWARFDie::iterator> DWARFDie::children() const {
@@ -350,4 +385,80 @@
} // end namespace llvm
+namespace std {
+
+template <>
+class reverse_iterator<llvm::DWARFDie::iterator>
+ : public llvm::iterator_facade_base<
+ reverse_iterator<llvm::DWARFDie::iterator>,
+ bidirectional_iterator_tag, const llvm::DWARFDie> {
+
+private:
+ llvm::DWARFDie Die;
+ bool AtEnd;
+
+public:
+ reverse_iterator(llvm::DWARFDie::iterator It)
+ : Die(It.Die), AtEnd(!It.Die.getPreviousSibling()) {
+ if (!AtEnd)
+ Die = Die.getPreviousSibling();
+ }
+
+ reverse_iterator<llvm::DWARFDie::iterator> &operator++() {
+ assert(!AtEnd && "Incrementing rend");
+ llvm::DWARFDie D = Die.getPreviousSibling();
+ if (D)
+ Die = D;
+ else
+ AtEnd = true;
+ return *this;
+ }
+
+ reverse_iterator<llvm::DWARFDie::iterator> &operator--() {
+ if (AtEnd) {
+ AtEnd = false;
+ return *this;
+ }
+ Die = Die.getSibling();
+ assert(!Die.isNULL() && "Decrementing rbegin");
+ return *this;
+ }
+
+ const llvm::DWARFDie &operator*() const {
+ assert(Die.isValid());
+ return Die;
+ }
+
+ // FIXME: We should be able to specify the equals operator as a friend, but
+ // that causes the compiler to think the operator overload is ambiguous
+ // with the friend declaration and the actual definition as candidates.
+ bool equals(const reverse_iterator<llvm::DWARFDie::iterator> &RHS) const {
+ return Die == RHS.Die && AtEnd == RHS.AtEnd;
+ }
+};
+
+} // namespace std
+
+namespace llvm {
+
+inline bool operator==(const std::reverse_iterator<DWARFDie::iterator> &LHS,
+ const std::reverse_iterator<DWARFDie::iterator> &RHS) {
+ return LHS.equals(RHS);
+}
+
+inline bool operator!=(const std::reverse_iterator<DWARFDie::iterator> &LHS,
+ const std::reverse_iterator<DWARFDie::iterator> &RHS) {
+ return !(LHS == RHS);
+}
+
+inline std::reverse_iterator<DWARFDie::iterator> DWARFDie::rbegin() const {
+ return llvm::make_reverse_iterator(end());
+}
+
+inline std::reverse_iterator<DWARFDie::iterator> DWARFDie::rend() const {
+ return llvm::make_reverse_iterator(begin());
+}
+
+} // end namespace llvm
+
#endif // LLVM_DEBUGINFO_DWARFDIE_H
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFListTable.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFListTable.h
new file mode 100644
index 0000000..ab12f3b
--- /dev/null
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFListTable.h
@@ -0,0 +1,278 @@
+//===- DWARFListTable.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_DWARFLISTTABLE_H
+#define LLVM_DEBUGINFO_DWARFLISTTABLE_H
+
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DIContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
+#include <map>
+#include <vector>
+
+namespace llvm {
+
+/// A base class for DWARF list entries, such as range or location list
+/// entries.
+struct DWARFListEntryBase {
+ /// The offset at which the entry is located in the section.
+ uint32_t Offset;
+ /// The DWARF encoding (DW_RLE_* or DW_LLE_*).
+ uint8_t EntryKind;
+ /// The index of the section this entry belongs to.
+ uint64_t SectionIndex;
+};
+
+/// A base class for lists of entries that are extracted from a particular
+/// section, such as range lists or location lists.
+template <typename ListEntryType> class DWARFListType {
+ using EntryType = ListEntryType;
+ using ListEntries = std::vector<EntryType>;
+
+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(); }
+ Error extract(DWARFDataExtractor Data, uint32_t HeaderOffset, uint32_t End,
+ uint32_t *OffsetPtr, StringRef SectionName,
+ StringRef ListStringName);
+};
+
+/// A class representing the header of a list table such as the range list
+/// table in the .debug_rnglists section.
+class DWARFListTableHeader {
+ struct Header {
+ /// The total length of the entries for this table, not including the length
+ /// field itself.
+ uint32_t Length = 0;
+ /// The DWARF version number.
+ uint16_t Version;
+ /// The size in bytes of an address on the target architecture. For
+ /// segmented addressing, this is the size of the offset portion of the
+ /// address.
+ uint8_t AddrSize;
+ /// The size in bytes of a segment selector on the target architecture.
+ /// If the target system uses a flat address space, this value is 0.
+ uint8_t SegSize;
+ /// The number of offsets that follow the header before the range lists.
+ uint32_t OffsetEntryCount;
+ };
+
+ Header HeaderData;
+ /// The offset table, which contains offsets to the individual list entries.
+ /// It is used by forms such as DW_FORM_rnglistx.
+ /// FIXME: Generate the table and use the appropriate forms.
+ std::vector<uint32_t> Offsets;
+ /// The table's format, either DWARF32 or DWARF64.
+ dwarf::DwarfFormat Format;
+ /// The offset at which the header (and hence the table) is located within
+ /// its section.
+ uint32_t HeaderOffset;
+ /// The name of the section the list is located in.
+ StringRef SectionName;
+ /// A characterization of the list for dumping purposes, e.g. "range" or
+ /// "location".
+ StringRef ListTypeString;
+
+public:
+ DWARFListTableHeader(StringRef SectionName, StringRef ListTypeString)
+ : SectionName(SectionName), ListTypeString(ListTypeString) {}
+
+ void clear() {
+ HeaderData = {};
+ Offsets.clear();
+ }
+ uint32_t getHeaderOffset() const { return HeaderOffset; }
+ uint8_t getAddrSize() const { return HeaderData.AddrSize; }
+ uint32_t getLength() const { return HeaderData.Length; }
+ StringRef getSectionName() const { return SectionName; }
+ StringRef getListTypeString() const { return ListTypeString; }
+ dwarf::DwarfFormat getFormat() const { return Format; }
+
+ void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {}) const;
+ Optional<uint32_t> getOffsetEntry(uint32_t Index) const {
+ if (Index < Offsets.size())
+ return Offsets[Index];
+ return None;
+ }
+
+ /// Extract the table header and the array of offsets.
+ Error extract(DWARFDataExtractor Data, uint32_t *OffsetPtr);
+
+ /// Returns the length of the table, including the length field, or 0 if the
+ /// length has not been determined (e.g. because the table has not yet been
+ /// parsed, or there was a problem in parsing).
+ uint32_t length() const;
+};
+
+/// A class representing a table of lists as specified in the DWARF v5
+/// standard for location lists and range lists. The table consists of a header
+/// followed by an array of offsets into a DWARF section, followed by zero or
+/// more list entries. The list entries are kept in a map where the keys are
+/// the lists' section offsets.
+template <typename DWARFListType> class DWARFListTableBase {
+ DWARFListTableHeader Header;
+ /// A mapping between file offsets and lists. It is used to find a particular
+ /// list based on an offset (obtained from DW_AT_ranges, for example).
+ std::map<uint32_t, DWARFListType> ListMap;
+ /// This string is displayed as a heading before the list is dumped
+ /// (e.g. "ranges:").
+ StringRef HeaderString;
+
+protected:
+ DWARFListTableBase(StringRef SectionName, StringRef HeaderString,
+ StringRef ListTypeString)
+ : Header(SectionName, ListTypeString), HeaderString(HeaderString) {}
+
+public:
+ void clear() {
+ Header.clear();
+ ListMap.clear();
+ }
+ /// Extract the table header and the array of offsets.
+ Error extractHeaderAndOffsets(DWARFDataExtractor Data, uint32_t *OffsetPtr) {
+ return Header.extract(Data, OffsetPtr);
+ }
+ /// Extract an entire table, including all list entries.
+ Error extract(DWARFDataExtractor Data, uint32_t *OffsetPtr);
+ /// Look up a list based on a given offset. Extract it and enter it into the
+ /// list map if necessary.
+ Expected<DWARFListType> findList(DWARFDataExtractor Data, uint32_t Offset);
+
+ uint32_t getHeaderOffset() const { return Header.getHeaderOffset(); }
+ uint8_t getAddrSize() const { return Header.getAddrSize(); }
+
+ void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {}) const;
+
+ /// Return the contents of the offset entry designated by a given index.
+ Optional<uint32_t> getOffsetEntry(uint32_t Index) const {
+ return Header.getOffsetEntry(Index);
+ }
+ /// Return the size of the table header including the length but not including
+ /// the offsets. This is dependent on the table format, which is unambiguously
+ /// derived from parsing the table.
+ uint8_t getHeaderSize() const {
+ switch (Header.getFormat()) {
+ case dwarf::DwarfFormat::DWARF32:
+ return 12;
+ case dwarf::DwarfFormat::DWARF64:
+ return 20;
+ }
+ llvm_unreachable("Invalid DWARF format (expected DWARF32 or DWARF64");
+ }
+
+ uint32_t length() { return Header.length(); }
+};
+
+template <typename DWARFListType>
+Error DWARFListTableBase<DWARFListType>::extract(DWARFDataExtractor Data,
+ uint32_t *OffsetPtr) {
+ clear();
+ if (Error E = extractHeaderAndOffsets(Data, OffsetPtr))
+ return E;
+
+ Data.setAddressSize(Header.getAddrSize());
+ uint32_t End = getHeaderOffset() + Header.length();
+ while (*OffsetPtr < End) {
+ DWARFListType CurrentList;
+ uint32_t Off = *OffsetPtr;
+ if (Error E = CurrentList.extract(Data, getHeaderOffset(), End, OffsetPtr,
+ Header.getSectionName(),
+ Header.getListTypeString()))
+ return E;
+ ListMap[Off] = CurrentList;
+ }
+
+ assert(*OffsetPtr == End &&
+ "mismatch between expected length of table and length "
+ "of extracted data");
+ return Error::success();
+}
+
+template <typename ListEntryType>
+Error DWARFListType<ListEntryType>::extract(DWARFDataExtractor Data,
+ uint32_t HeaderOffset, uint32_t End,
+ uint32_t *OffsetPtr,
+ StringRef SectionName,
+ StringRef ListTypeString) {
+ if (*OffsetPtr < HeaderOffset || *OffsetPtr >= End)
+ return createError("invalid %s list offset 0x%" PRIx32,
+ ListTypeString.data(), *OffsetPtr);
+ Entries.clear();
+ while (*OffsetPtr < End) {
+ ListEntryType Entry;
+ if (Error E = Entry.extract(Data, End, OffsetPtr))
+ return E;
+ Entries.push_back(Entry);
+ if (Entry.isSentinel())
+ return Error::success();
+ }
+ return createError("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 {
+ Header.dump(OS, DumpOpts);
+ OS << HeaderString << "\n";
+
+ // Determine the length of the longest encoding string we have in the table,
+ // so we can align the output properly. We only need this in verbose mode.
+ size_t MaxEncodingStringLength = 0;
+ if (DumpOpts.Verbose) {
+ for (const auto &List : ListMap)
+ for (const auto &Entry : List.second.getEntries())
+ MaxEncodingStringLength =
+ std::max(MaxEncodingStringLength,
+ dwarf::RangeListEncodingString(Entry.EntryKind).size());
+ }
+
+ uint64_t CurrentBase = 0;
+ for (const auto &List : ListMap)
+ for (const auto &Entry : List.second.getEntries())
+ Entry.dump(OS, getAddrSize(), MaxEncodingStringLength, CurrentBase,
+ DumpOpts);
+}
+
+template <typename DWARFListType>
+Expected<DWARFListType>
+DWARFListTableBase<DWARFListType>::findList(DWARFDataExtractor Data,
+ uint32_t Offset) {
+ auto Entry = ListMap.find(Offset);
+ if (Entry != ListMap.end())
+ return Entry->second;
+
+ // Extract the list from the section and enter it into the list map.
+ DWARFListType List;
+ uint32_t End = getHeaderOffset() + Header.length();
+ uint32_t StartingOffset = Offset;
+ if (Error E =
+ List.extract(Data, getHeaderOffset(), End, &Offset,
+ Header.getSectionName(), Header.getListTypeString()))
+ return std::move(E);
+ ListMap[StartingOffset] = List;
+ return List;
+}
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_DWARFLISTTABLE_H
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFObject.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFObject.h
index 795eddd..6e8f370 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFObject.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFObject.h
@@ -63,6 +63,7 @@
return Dummy;
}
virtual const DWARFSection &getRangeDWOSection() const { return Dummy; }
+ virtual const DWARFSection &getRnglistsDWOSection() const { return Dummy; }
virtual const DWARFSection &getAddrSection() const { return Dummy; }
virtual const DWARFSection &getAppleNamesSection() const { return Dummy; }
virtual const DWARFSection &getAppleTypesSection() const { return Dummy; }
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
index a659a63..0a5a1aa 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
@@ -24,30 +24,22 @@
class raw_ostream;
class DWARFTypeUnit : public DWARFUnit {
-private:
- uint64_t TypeHash;
- uint32_t TypeOffset;
-
public:
DWARFTypeUnit(DWARFContext &Context, const DWARFSection &Section,
+ const DWARFUnitHeader &Header,
const DWARFDebugAbbrev *DA, const DWARFSection *RS,
StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS,
const DWARFSection &LS, bool LE, bool IsDWO,
- const DWARFUnitSectionBase &UnitSection,
- const DWARFUnitIndex::Entry *Entry)
- : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
- UnitSection, Entry) {}
+ const DWARFUnitVector &UnitVector)
+ : DWARFUnit(Context, Section, Header, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
+ UnitVector) {}
- uint32_t getHeaderSize() const override {
- return DWARFUnit::getHeaderSize() + 12;
- }
+ 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;
-
-protected:
- bool extractImpl(const DWARFDataExtractor &debug_info,
- uint32_t *offset_ptr) override;
+ 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/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index fe3f573..0908504 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -18,6 +18,7 @@
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
@@ -40,124 +41,116 @@
class DWARFDebugAbbrev;
class DWARFUnit;
-/// Base class for all DWARFUnitSection classes. This provides the
-/// functionality common to all unit types.
-class DWARFUnitSectionBase {
+/// Base class describing the header of any kind of "unit." Some information
+/// is specific to certain unit types. We separate this class out so we can
+/// parse the header before deciding what specific kind of unit to construct.
+class DWARFUnitHeader {
+ // Offset within section.
+ uint32_t Offset = 0;
+ // Version, address size, and DWARF format.
+ dwarf::FormParams FormParams;
+ uint32_t Length = 0;
+ uint64_t AbbrOffset = 0;
+
+ // For DWO units only.
+ const DWARFUnitIndex::Entry *IndexEntry = nullptr;
+
+ // For type units only.
+ uint64_t TypeHash = 0;
+ uint32_t TypeOffset = 0;
+
+ // For v5 split or skeleton compile units only.
+ Optional<uint64_t> DWOId;
+
+ // Unit type as parsed, or derived from the section kind.
+ uint8_t UnitType = 0;
+
+ // Size as parsed. uint8_t for compactness.
+ uint8_t Size = 0;
+
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;
+ /// 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);
+ uint32_t getOffset() const { return Offset; }
+ const dwarf::FormParams &getFormParams() const { return FormParams; }
+ uint16_t getVersion() const { return FormParams.Version; }
+ dwarf::DwarfFormat getFormat() const { return FormParams.Format; }
+ uint8_t getAddressByteSize() const { return FormParams.AddrSize; }
+ uint8_t getRefAddrByteSize() const { return FormParams.getRefAddrByteSize(); }
+ uint8_t getDwarfOffsetByteSize() const {
+ return FormParams.getDwarfOffsetByteSize();
+ }
+ uint32_t getLength() const { return Length; }
+ uint64_t getAbbrOffset() const { return AbbrOffset; }
+ Optional<uint64_t> getDWOId() const { return DWOId; }
+ void setDWOId(uint64_t Id) {
+ assert((!DWOId || *DWOId == Id) && "setting DWOId to a different value");
+ DWOId = Id;
+ }
+ const DWARFUnitIndex::Entry *getIndexEntry() const { return IndexEntry; }
+ uint64_t getTypeHash() const { return TypeHash; }
+ uint32_t getTypeOffset() const { return TypeOffset; }
+ uint8_t getUnitType() const { return UnitType; }
+ bool isTypeUnit() const {
+ return UnitType == dwarf::DW_UT_type || UnitType == dwarf::DW_UT_split_type;
+ }
+ uint8_t getSize() const { return Size; }
+ // FIXME: Support DWARF64.
+ uint32_t getNextUnitOffset() const { return Offset + Length + 4; }
};
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 *)>
+ Parser;
+ unsigned NumInfoUnits = 0;
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;
-
- 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() { return size(); }
+ /// Returns number of units from all .debug_info[.dwo] sections.
+ unsigned getNumInfoUnits() { return NumInfoUnits; }
+ /// Returns number of units from all .debug_types[.dwo] sections.
+ unsigned getNumTypesUnits() { 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;
- auto U = llvm::make_unique<UnitType>(
- Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, *this,
- Index ? Index->getFromOffset(Offset) : nullptr);
- if (!U->extract(Data, &Offset))
- return nullptr;
- 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, 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.
@@ -169,6 +162,7 @@
/// Represents a unit's contribution to the string offsets table.
struct StrOffsetsContributionDescriptor {
uint64_t Base = 0;
+ /// The contribution size not including the header.
uint64_t Size = 0;
/// Format and version.
dwarf::FormParams FormParams = {0, 0, dwarf::DwarfFormat::DWARF32};
@@ -194,6 +188,7 @@
/// Section containing this DWARFUnit.
const DWARFSection &InfoSection;
+ DWARFUnitHeader Header;
const DWARFDebugAbbrev *Abbrev;
const DWARFSection *RangeSection;
uint32_t RangeSectionBase;
@@ -204,19 +199,16 @@
uint32_t AddrOffsetSectionBase = 0;
bool isLittleEndian;
bool isDWO;
- const DWARFUnitSectionBase &UnitSection;
+ const DWARFUnitVector &UnitVector;
- // Version, address size, and DWARF format.
- dwarf::FormParams FormParams;
/// Start, length, and DWARF format of the unit's contribution to the string
/// offsets table (DWARF v5).
Optional<StrOffsetsContributionDescriptor> StringOffsetsTableContribution;
- uint32_t Offset;
- uint32_t Length;
+ /// A table of range lists (DWARF v5 and later).
+ Optional<DWARFDebugRnglistTable> RngListTable;
+
mutable const DWARFAbbreviationDeclarationSet *Abbrevs;
- uint64_t AbbrOffset;
- uint8_t UnitType;
llvm::Optional<BaseAddress> BaseAddr;
/// The compile unit debug information entry items.
std::vector<DWARFDebugInfoEntry> DieArray;
@@ -231,8 +223,6 @@
std::shared_ptr<DWARFUnit> DWO;
- const DWARFUnitIndex::Entry *IndexEntry;
-
uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) {
auto First = DieArray.data();
assert(Die >= First && Die < First + DieArray.size());
@@ -240,11 +230,10 @@
}
protected:
- virtual bool extractImpl(const DWARFDataExtractor &debug_info,
- uint32_t *offset_ptr);
+ const DWARFUnitHeader &getHeader() const { return Header; }
- /// Size in bytes of the unit header.
- virtual uint32_t getHeaderSize() const { return getVersion() <= 4 ? 11 : 12; }
+ /// Size in bytes of the parsed unit header.
+ uint32_t getHeaderSize() const { return Header.getSize(); }
/// Find the unit's contribution to the string offsets table and determine its
/// length and form. The given offset is expected to be derived from the unit
@@ -263,16 +252,30 @@
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 DWARFSection &LS, bool LE, bool IsDWO,
- const DWARFUnitSectionBase &UnitSection,
- const DWARFUnitIndex::Entry *IndexEntry = nullptr);
+ const DWARFUnitVector &UnitVector);
virtual ~DWARFUnit();
DWARFContext& getContext() const { return Context; }
-
+ const DWARFSection &getInfoSection() const { return InfoSection; }
+ uint32_t getOffset() const { return Header.getOffset(); }
+ const dwarf::FormParams &getFormParams() const {
+ return Header.getFormParams();
+ }
+ uint16_t getVersion() const { return Header.getVersion(); }
+ uint8_t getAddressByteSize() const { return Header.getAddressByteSize(); }
+ uint8_t getRefAddrByteSize() const { return Header.getRefAddrByteSize(); }
+ uint8_t getDwarfOffsetByteSize() const {
+ return Header.getDwarfOffsetByteSize();
+ }
+ 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; }
const DWARFSection &getStringOffsetSection() const {
@@ -301,30 +304,18 @@
return DataExtractor(StringSection, false, 0);
}
- bool extract(const DWARFDataExtractor &debug_info, uint32_t *offset_ptr);
-
- /// extractRangeList - extracts the range list referenced by this compile
- /// unit from .debug_ranges section. Returns true on success.
- /// Requires that compile unit is already extracted.
- bool extractRangeList(uint32_t RangeListOffset,
- DWARFDebugRangeList &RangeList) const;
+ /// Extract the range list referenced by this compile unit from the
+ /// .debug_ranges section. If the extraction is unsuccessful, an error
+ /// is returned. Successful extraction requires that the compile unit
+ /// has already been extracted.
+ Error extractRangeList(uint32_t RangeListOffset,
+ DWARFDebugRangeList &RangeList) const;
void clear();
- uint32_t getOffset() const { return Offset; }
- uint32_t getNextUnitOffset() const { return Offset + Length + 4; }
- uint32_t getLength() const { return Length; }
const Optional<StrOffsetsContributionDescriptor> &
getStringOffsetsTableContribution() const {
return StringOffsetsTableContribution;
}
- const dwarf::FormParams &getFormParams() const { return FormParams; }
- uint16_t getVersion() const { return FormParams.Version; }
- dwarf::DwarfFormat getFormat() const { return FormParams.Format; }
- uint8_t getAddressByteSize() const { return FormParams.AddrSize; }
- uint8_t getRefAddrByteSize() const { return FormParams.getRefAddrByteSize(); }
- uint8_t getDwarfOffsetByteSize() const {
- return FormParams.getDwarfOffsetByteSize();
- }
uint8_t getDwarfStringOffsetsByteSize() const {
assert(StringOffsetsTableContribution);
@@ -338,8 +329,6 @@
const DWARFAbbreviationDeclarationSet *getAbbreviations() const;
- uint8_t getUnitType() const { return UnitType; }
-
static bool isMatchingUnitTypeAndTag(uint8_t UnitType, dwarf::Tag Tag) {
switch (UnitType) {
case dwarf::DW_UT_compile:
@@ -357,7 +346,7 @@
return false;
}
- /// \brief Return the number of bytes for the header of a unit of
+ /// Return the number of bytes for the header of a unit of
/// UnitType type.
///
/// This function must be called with a valid unit type which in
@@ -377,9 +366,7 @@
llvm_unreachable("Invalid UnitType.");
}
- llvm::Optional<BaseAddress> getBaseAddress() const { return BaseAddr; }
-
- void setBaseAddress(BaseAddress BaseAddr) { this->BaseAddr = BaseAddr; }
+ llvm::Optional<BaseAddress> getBaseAddress();
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) {
extractDIEsIfNeeded(ExtractUnitDIEOnly);
@@ -389,7 +376,29 @@
}
const char *getCompilationDir();
- Optional<uint64_t> getDWOId();
+ Optional<uint64_t> getDWOId() {
+ extractDIEsIfNeeded(/*CUDieOnly*/ true);
+ return getHeader().getDWOId();
+ }
+ void setDWOId(uint64_t NewID) { Header.setDWOId(NewID); }
+
+ /// Return a vector of address ranges resulting from a (possibly encoded)
+ /// range list starting at a given offset in the appropriate ranges section.
+ Expected<DWARFAddressRangesVector> findRnglistFromOffset(uint32_t Offset);
+
+ /// Return a vector of address ranges retrieved from an encoded range
+ /// list whose offset is found via a table lookup given an index (DWARF v5
+ /// and later).
+ Expected<DWARFAddressRangesVector> findRnglistFromIndex(uint32_t Index);
+
+ /// Return a rangelist's offset based on an index. The index designates
+ /// an entry in the rangelist table's offset array and is supplied by
+ /// DW_FORM_rnglistx.
+ Optional<uint32_t> getRnglistOffset(uint32_t Index) {
+ if (RngListTable)
+ return RngListTable->getOffsetEntry(Index);
+ return None;
+ }
void collectAddressRanges(DWARFAddressRangesVector &CURanges);
@@ -404,17 +413,17 @@
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; }
- /// \brief Returns the number of DIEs in the unit. Parses the unit
+ /// Returns the number of DIEs in the unit. Parses the unit
/// if necessary.
unsigned getNumDIEs() {
extractDIEsIfNeeded(false);
return DieArray.size();
}
- /// \brief Return the index of a DIE inside the unit's DIE vector.
+ /// Return the index of a DIE inside the unit's DIE vector.
///
/// It is illegal to call this method with a DIE that hasn't be
/// created by this unit. In other word, it's illegal to call this
@@ -424,7 +433,7 @@
return getDIEIndex(D.getDebugInfoEntry());
}
- /// \brief Return the DIE object at the given index.
+ /// Return the DIE object at the given index.
DWARFDie getDIEAtIndex(unsigned Index) {
assert(Index < DieArray.size());
return DWARFDie(this, &DieArray[Index]);
@@ -432,9 +441,11 @@
DWARFDie getParent(const DWARFDebugInfoEntry *Die);
DWARFDie getSibling(const DWARFDebugInfoEntry *Die);
+ DWARFDie getPreviousSibling(const DWARFDebugInfoEntry *Die);
DWARFDie getFirstChild(const DWARFDebugInfoEntry *Die);
+ DWARFDie getLastChild(const DWARFDebugInfoEntry *Die);
- /// \brief Return the DIE object for a given offset inside the
+ /// Return the DIE object for a given offset inside the
/// unit's DIE vector.
///
/// The unit needs to have its DIEs extracted for this method to work.
@@ -452,7 +463,7 @@
}
uint32_t getLineTableOffset() const {
- if (IndexEntry)
+ if (auto IndexEntry = Header.getIndexEntry())
if (const auto *Contrib = IndexEntry->getOffset(DW_SECT_LINE))
return Contrib->Offset;
return 0;
@@ -463,9 +474,12 @@
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 { return Length + 4 - getHeaderSize(); }
+ size_t getDebugInfoSize() const {
+ return Header.getLength() + 4 - getHeaderSize();
+ }
/// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it
/// hasn't already been done. Returns the number of DIEs parsed at this call.
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFVerifier.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
index afaa299..5463677 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
+++ b/linux-x64/clang/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>
@@ -25,6 +26,7 @@
class DWARFContext;
class DWARFDie;
class DWARFUnit;
+class DWARFCompileUnit;
class DWARFDataExtractor;
class DWARFDebugAbbrev;
class DataExtractor;
@@ -112,20 +114,20 @@
/// \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
@@ -136,7 +138,7 @@
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,12 +148,22 @@
/// - If a unit type is provided, that the unit DIE matches the unit type.
/// - The DIE ranges.
///
- /// \param Unit The DWARF Unit to verifiy.
+ /// \param Unit The DWARF Unit to verify.
/// \param UnitType An optional unit type which will be used to verify the
/// type of the unit DIE.
///
- /// \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, uint8_t UnitType = 0);
+
+ /// 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);
/// Verify that all Die ranges are valid.
///
@@ -171,7 +183,7 @@
/// \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);
@@ -179,14 +191,14 @@
///
/// 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
@@ -198,7 +210,7 @@
/// 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
@@ -240,6 +252,10 @@
unsigned verifyNameIndexAttribute(const DWARFDebugNames::NameIndex &NI,
const DWARFDebugNames::Abbrev &Abbr,
DWARFDebugNames::AttributeEncoding AttrEnc);
+ unsigned verifyNameIndexEntries(const DWARFDebugNames::NameIndex &NI,
+ const DWARFDebugNames::NameTableEntry &NTE);
+ unsigned verifyNameIndexCompleteness(const DWARFDie &Die,
+ const DWARFDebugNames::NameIndex &NI);
/// Verify that the DWARF v5 accelerator table is valid.
///
@@ -251,6 +267,8 @@
/// - The buckets have a valid index, or they are empty.
/// - All names are reachable via the hash table (they have the correct hash,
/// and the hash is in the correct bucket).
+ /// - Information in the index entries is complete (all required entries are
+ /// present) and consistent with the debug_info section DIEs.
///
/// \param AccelSection section containing the acceleration table
/// \param StrData string section
@@ -273,12 +291,12 @@
/// 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/linux-x64/clang/include/llvm/DebugInfo/MSF/MSFBuilder.h b/linux-x64/clang/include/llvm/DebugInfo/MSF/MSFBuilder.h
index 19e5c31..3de98c4 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/MSF/MSFBuilder.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/MSF/MSFBuilder.h
@@ -20,11 +20,13 @@
#include <vector>
namespace llvm {
+class FileBufferByteStream;
+class WritableBinaryStream;
namespace msf {
class MSFBuilder {
public:
- /// \brief Create a new `MSFBuilder`.
+ /// Create a new `MSFBuilder`.
///
/// \param BlockSize The internal block size used by the PDB file. See
/// isValidBlockSize() for a list of valid block sizes.
@@ -109,7 +111,10 @@
/// Finalize the layout and build the headers and structures that describe the
/// MSF layout and can be written directly to the MSF file.
- Expected<MSFLayout> build();
+ Expected<MSFLayout> generateLayout();
+
+ /// Write the MSF layout to the underlying file.
+ Expected<FileBufferByteStream> commit(StringRef Path, MSFLayout &Layout);
BumpPtrAllocator &getAllocator() { return Allocator; }
diff --git a/linux-x64/clang/include/llvm/DebugInfo/MSF/MSFCommon.h b/linux-x64/clang/include/llvm/DebugInfo/MSF/MSFCommon.h
index dd53264..2db2b71 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/MSF/MSFCommon.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/MSF/MSFCommon.h
@@ -69,7 +69,7 @@
std::vector<ArrayRef<support::ulittle32_t>> StreamMap;
};
-/// \brief Describes the layout of a stream in an MSF layout. A "stream" here
+/// Describes the layout of a stream in an MSF layout. A "stream" here
/// is defined as any logical unit of data which may be arranged inside the MSF
/// file as a sequence of (possibly discontiguous) blocks. When we want to read
/// from a particular MSF Stream, we fill out a stream layout structure and the
@@ -81,7 +81,7 @@
std::vector<support::ulittle32_t> Blocks;
};
-/// \brief Determine the layout of the FPM stream, given the MSF layout. An FPM
+/// Determine the layout of the FPM stream, given the MSF layout. An FPM
/// stream spans 1 or more blocks, each at equally spaced intervals throughout
/// the file.
MSFStreamLayout getFpmStreamLayout(const MSFLayout &Msf,
diff --git a/linux-x64/clang/include/llvm/DebugInfo/PDB/DIA/DIAEnumSectionContribs.h b/linux-x64/clang/include/llvm/DebugInfo/PDB/DIA/DIAEnumSectionContribs.h
index 5c37d9b..52c9563 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/PDB/DIA/DIAEnumSectionContribs.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/PDB/DIA/DIAEnumSectionContribs.h
@@ -34,7 +34,7 @@
const DIASession &Session;
CComPtr<IDiaEnumSectionContribs> Enumerator;
};
-}
-}
+} // namespace pdb
+} // namespace llvm
#endif // LLVM_DEBUGINFO_PDB_DIA_DIAENUMSECTIONCONTRIBS_H
diff --git a/linux-x64/clang/include/llvm/DebugInfo/PDB/DIA/DIASectionContrib.h b/linux-x64/clang/include/llvm/DebugInfo/PDB/DIA/DIASectionContrib.h
index 7bc28e3..4688f1f 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/PDB/DIA/DIASectionContrib.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/PDB/DIA/DIASectionContrib.h
@@ -49,7 +49,7 @@
const DIASession &Session;
CComPtr<IDiaSectionContrib> Section;
};
-}
-}
+} // namespace pdb
+} // namespace llvm
#endif // LLVM_DEBUGINFO_PDB_DIA_DIASECTIONCONTRIB_H
diff --git a/linux-x64/clang/include/llvm/DebugInfo/PDB/DIA/DIASession.h b/linux-x64/clang/include/llvm/DebugInfo/PDB/DIA/DIASession.h
index 4f3d728..a636594 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/PDB/DIA/DIASession.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/PDB/DIA/DIASession.h
@@ -41,6 +41,11 @@
std::unique_ptr<PDBSymbol>
findSymbolByAddress(uint64_t Address, PDB_SymType Type) const override;
+ std::unique_ptr<PDBSymbol> findSymbolByRVA(uint32_t RVA,
+ PDB_SymType Type) const override;
+ std::unique_ptr<PDBSymbol>
+ findSymbolBySectOffset(uint32_t Section, uint32_t Offset,
+ PDB_SymType Type) const override;
std::unique_ptr<IPDBEnumLineNumbers>
findLineNumbers(const PDBSymbolCompiland &Compiland,
diff --git a/linux-x64/clang/include/llvm/DebugInfo/PDB/DIA/DIASupport.h b/linux-x64/clang/include/llvm/DebugInfo/PDB/DIA/DIASupport.h
index 3b4a348..92ebc04 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/PDB/DIA/DIASupport.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/PDB/DIA/DIASupport.h
@@ -22,14 +22,6 @@
#define NOMINMAX
#endif
-// llvm/Support/Debug.h unconditionally #defines DEBUG as a macro.
-// DIA headers #define it if it is not already defined, so we have
-// an order of includes problem. The real fix is to make LLVM use
-// something less generic than DEBUG, such as LLVM_DEBUG(), but it's
-// fairly prevalent. So for now, we save the definition state and
-// restore it.
-#pragma push_macro("DEBUG")
-
// atlbase.h has to come before windows.h
#include <atlbase.h>
#include <windows.h>
@@ -39,6 +31,4 @@
#include <dia2.h>
#include <diacreate.h>
-#pragma pop_macro("DEBUG")
-
#endif // LLVM_DEBUGINFO_PDB_DIA_DIASUPPORT_H
diff --git a/linux-x64/clang/include/llvm/DebugInfo/PDB/IPDBSession.h b/linux-x64/clang/include/llvm/DebugInfo/PDB/IPDBSession.h
index 695d62c..88ec517 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/PDB/IPDBSession.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/PDB/IPDBSession.h
@@ -44,6 +44,11 @@
virtual std::unique_ptr<PDBSymbol>
findSymbolByAddress(uint64_t Address, PDB_SymType Type) const = 0;
+ virtual std::unique_ptr<PDBSymbol>
+ findSymbolByRVA(uint32_t RVA, PDB_SymType Type) const = 0;
+ virtual std::unique_ptr<PDBSymbol>
+ findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
+ PDB_SymType Type) const = 0;
virtual std::unique_ptr<IPDBEnumLineNumbers>
findLineNumbers(const PDBSymbolCompiland &Compiland,
diff --git a/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h b/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h
index 8200f51..9eef404 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h
@@ -47,6 +47,8 @@
uint32_t getRecordLength() const;
+ const SectionContrib &getSectionContrib() const;
+
private:
StringRef ModuleName;
StringRef ObjFileName;
diff --git a/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h b/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h
index c918a5d..ce4d079 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h
@@ -49,6 +49,7 @@
void setPdbFilePathNI(uint32_t NI);
void setObjFileName(StringRef Name);
+ void setFirstSectionContrib(const SectionContrib &SC);
void addSymbol(codeview::CVSymbol Symbol);
void
diff --git a/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/DbiStream.h b/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/DbiStream.h
index 760d19a..280615b 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/DbiStream.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/DbiStream.h
@@ -38,9 +38,9 @@
friend class DbiStreamBuilder;
public:
- DbiStream(PDBFile &File, std::unique_ptr<msf::MappedBlockStream> Stream);
+ explicit DbiStream(std::unique_ptr<BinaryStream> Stream);
~DbiStream();
- Error reload();
+ Error reload(PDBFile *Pdb);
PdbRaw_DbiVer getDbiVersion() const;
uint32_t getAge() const;
@@ -89,12 +89,11 @@
private:
Error initializeSectionContributionData();
- Error initializeSectionHeadersData();
+ Error initializeSectionHeadersData(PDBFile *Pdb);
Error initializeSectionMapData();
- Error initializeFpoRecords();
+ Error initializeFpoRecords(PDBFile *Pdb);
- PDBFile &Pdb;
- std::unique_ptr<msf::MappedBlockStream> Stream;
+ std::unique_ptr<BinaryStream> Stream;
PDBStringTable ECNames;
diff --git a/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h b/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h
index daea062..51befcd 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h
@@ -12,6 +12,7 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringSet.h"
+#include "llvm/BinaryFormat/COFF.h"
#include "llvm/Support/Error.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
@@ -46,10 +47,12 @@
void setVersionHeader(PdbRaw_DbiVer V);
void setAge(uint32_t A);
void setBuildNumber(uint16_t B);
+ void setBuildNumber(uint8_t Major, uint8_t Minor);
void setPdbDllVersion(uint16_t V);
void setPdbDllRbld(uint16_t R);
void setFlags(uint16_t F);
void setMachineType(PDB_Machine M);
+ void setMachineType(COFF::MachineTypes M);
void setSectionMap(ArrayRef<SecMapEntry> SecMap);
// Add given bytes as a new stream.
diff --git a/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/InfoStream.h b/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/InfoStream.h
index caeb423..8c52b04 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/InfoStream.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/InfoStream.h
@@ -30,7 +30,7 @@
friend class InfoStreamBuilder;
public:
- InfoStream(std::unique_ptr<msf::MappedBlockStream> Stream);
+ InfoStream(std::unique_ptr<BinaryStream> Stream);
Error reload();
@@ -52,11 +52,11 @@
BinarySubstreamRef getNamedStreamsBuffer() const;
- uint32_t getNamedStreamIndex(llvm::StringRef Name) const;
+ Expected<uint32_t> getNamedStreamIndex(llvm::StringRef Name) const;
StringMap<uint32_t> named_streams() const;
private:
- std::unique_ptr<msf::MappedBlockStream> Stream;
+ std::unique_ptr<BinaryStream> Stream;
const InfoStreamHeader *Header;
diff --git a/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/NativeSession.h b/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/NativeSession.h
index 60a94d9..aff7ef2 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/NativeSession.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/NativeSession.h
@@ -60,6 +60,11 @@
std::unique_ptr<PDBSymbol>
findSymbolByAddress(uint64_t Address, PDB_SymType Type) const override;
+ std::unique_ptr<PDBSymbol> findSymbolByRVA(uint32_t RVA,
+ PDB_SymType Type) const override;
+ std::unique_ptr<PDBSymbol>
+ findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
+ PDB_SymType Type) const override;
std::unique_ptr<IPDBEnumLineNumbers>
findLineNumbers(const PDBSymbolCompiland &Compiland,
diff --git a/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h b/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h
index 58dda71..7f9c4cf 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h
@@ -76,7 +76,7 @@
std::unique_ptr<MemoryBuffer> Content;
};
- Expected<msf::MSFLayout> finalizeMsfLayout();
+ Error finalizeMsfLayout();
Expected<uint32_t> allocateNamedStream(StringRef Name, uint32_t Size);
void commitFpm(WritableBinaryStream &MsfBuffer, const msf::MSFLayout &Layout);
diff --git a/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/RawTypes.h b/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/RawTypes.h
index 5cc8821..19f592d 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/RawTypes.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/RawTypes.h
@@ -112,6 +112,8 @@
static const uint16_t BuildMajorMask = 0x7F00;
static const uint16_t BuildMajorShift = 8;
+
+ static const uint16_t NewVersionFormatMask = 0x8000;
};
/// The fixed size header that appears at the beginning of the DBI Stream.
@@ -175,18 +177,6 @@
};
static_assert(sizeof(DbiStreamHeader) == 64, "Invalid DbiStreamHeader size!");
-struct SectionContribEntry {
- support::ulittle16_t Section;
- char Padding1[2];
- support::little32_t Offset;
- support::little32_t Size;
- support::ulittle32_t Characteristics;
- support::ulittle16_t ModuleIndex;
- char Padding2[2];
- support::ulittle32_t DataCrc;
- support::ulittle32_t RelocCrc;
-};
-
/// The header preceeding the File Info Substream of the DBI stream.
struct FileInfoSubstreamHeader {
/// Total # of modules, should match number of records in the ModuleInfo
@@ -228,7 +218,7 @@
support::ulittle32_t Mod;
/// First section contribution of this module.
- SectionContribEntry SC;
+ SectionContrib SC;
/// See ModInfoFlags definition.
support::ulittle16_t Flags;
diff --git a/linux-x64/clang/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h b/linux-x64/clang/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h
index d6013e2..05d585d 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h
@@ -39,7 +39,9 @@
FORWARD_SYMBOL_METHOD(getAddressSection)
FORWARD_SYMBOL_ID_METHOD(getClassParent)
FORWARD_SYMBOL_METHOD(isCompilerGenerated)
+ FORWARD_SYMBOL_METHOD(isConstructorVirtualBase)
FORWARD_SYMBOL_METHOD(isConstType)
+ FORWARD_SYMBOL_METHOD(isCxxReturnUdt)
FORWARD_SYMBOL_METHOD(hasCustomCallingConvention)
FORWARD_SYMBOL_METHOD(hasFarReturn)
FORWARD_SYMBOL_METHOD(hasAlloca)
diff --git a/linux-x64/clang/include/llvm/DebugInfo/PDB/PDBTypes.h b/linux-x64/clang/include/llvm/DebugInfo/PDB/PDBTypes.h
index bc6233a..da6cb1d 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/PDB/PDBTypes.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/PDB/PDBTypes.h
@@ -111,7 +111,7 @@
/// Specifies the hash algorithm that a source file from a PDB was hashed with.
/// This corresponds to the CV_SourceChksum_t enumeration and are documented
/// here: https://msdn.microsoft.com/en-us/library/e96az21x.aspx
-enum class PDB_Checksum { None = 0, MD5 = 1, SHA1 = 2 };
+enum class PDB_Checksum { None = 0, MD5 = 1, SHA1 = 2, SHA256 = 3 };
/// These values correspond to the CV_CPU_TYPE_e enumeration, and are documented
/// here: https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx
@@ -225,6 +225,7 @@
IlRel,
MetaData,
Constant,
+ RegRelAliasIndir,
Max
};
@@ -234,11 +235,24 @@
/// These values correspond to the StackFrameTypeEnum enumeration, and are
/// documented here: https://msdn.microsoft.com/en-us/library/bc5207xw.aspx.
-enum class PDB_StackFrameType { FPO, KernelTrap, KernelTSS, EBP, FrameData };
+enum class PDB_StackFrameType : uint16_t {
+ FPO,
+ KernelTrap,
+ KernelTSS,
+ EBP,
+ FrameData,
+ Unknown = 0xffff
+};
-/// These values correspond to the StackFrameTypeEnum enumeration, and are
-/// documented here: https://msdn.microsoft.com/en-us/library/bc5207xw.aspx.
-enum class PDB_MemoryType { Code, Data, Stack, HeapCode };
+/// These values correspond to the MemoryTypeEnum enumeration, and are
+/// documented here: https://msdn.microsoft.com/en-us/library/ms165609.aspx.
+enum class PDB_MemoryType : uint16_t {
+ Code,
+ Data,
+ Stack,
+ HeapCode,
+ Any = 0xffff
+};
/// These values correspond to the Basictype enumeration, and are documented
/// here: https://msdn.microsoft.com/en-us/library/4szdtzc3.aspx
@@ -268,7 +282,7 @@
/// These values correspond to the flags that can be combined to control the
/// return of an undecorated name for a C++ decorated name, and are documented
/// here: https://msdn.microsoft.com/en-us/library/kszfk0fs.aspx
-enum PDB_UndnameFlags: uint32_t {
+enum PDB_UndnameFlags : uint32_t {
Undname_Complete = 0x0,
Undname_NoLeadingUnderscores = 0x1,
Undname_NoMsKeywords = 0x2,
diff --git a/linux-x64/clang/include/llvm/DebugInfo/Symbolize/Symbolize.h b/linux-x64/clang/include/llvm/DebugInfo/Symbolize/Symbolize.h
index 6480aef..289148f 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/Symbolize/Symbolize.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/Symbolize/Symbolize.h
@@ -90,11 +90,11 @@
const ObjectFile *Obj,
const std::string &ArchName);
- /// \brief Returns pair of pointers to object and debug object.
+ /// Returns pair of pointers to object and debug object.
Expected<ObjectPair> getOrCreateObjectPair(const std::string &Path,
const std::string &ArchName);
- /// \brief Return a pointer to object file at specified path, for a specified
+ /// Return a pointer to object file at specified path, for a specified
/// architecture (e.g. if path refers to a Mach-O universal binary, only one
/// object file from it will be returned).
Expected<ObjectFile *> getOrCreateObject(const std::string &Path,
@@ -102,14 +102,14 @@
std::map<std::string, std::unique_ptr<SymbolizableModule>> Modules;
- /// \brief Contains cached results of getOrCreateObjectPair().
+ /// Contains cached results of getOrCreateObjectPair().
std::map<std::pair<std::string, std::string>, ObjectPair>
ObjectPairForPathArch;
- /// \brief Contains parsed binary for each path, or parsing error.
+ /// Contains parsed binary for each path, or parsing error.
std::map<std::string, OwningBinary<Binary>> BinaryForPath;
- /// \brief Parsed object file for path/architecture pair, where "path" refers
+ /// Parsed object file for path/architecture pair, where "path" refers
/// to Mach-O universal binary.
std::map<std::pair<std::string, std::string>, std::unique_ptr<ObjectFile>>
ObjectForUBPathAndArch;