diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/DebugInfo/DWARF')
21 files changed, 449 insertions, 355 deletions
diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp index ddf307de2221..25d2e852a7fe 100644 --- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp +++ b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp @@ -18,8 +18,9 @@ void DWARFAddressRange::dump(raw_ostream &OS, uint32_t AddressSize, const DWARFObject *Obj) const { OS << (DumpOpts.DisplayRawContents ? " " : "["); - OS << format("0x%*.*" PRIx64 ", ", AddressSize * 2, AddressSize * 2, LowPC) - << format("0x%*.*" PRIx64, AddressSize * 2, AddressSize * 2, HighPC); + DWARFFormValue::dumpAddress(OS, AddressSize, LowPC); + OS << ", "; + DWARFFormValue::dumpAddress(OS, AddressSize, HighPC); OS << (DumpOpts.DisplayRawContents ? "" : ")"); if (Obj) diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp index 9bd134105c9b..2b08120ef4dc 100644 --- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp +++ b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp @@ -22,9 +22,10 @@ void DWARFCompileUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) { << ", version = " << format("0x%04x", getVersion()); if (getVersion() >= 5) OS << ", unit_type = " << dwarf::UnitTypeString(getUnitType()); - OS << ", abbr_offset = " - << format("0x%04" PRIx64, getAbbreviations()->getOffset()) - << ", addr_size = " << format("0x%02x", getAddressByteSize()); + OS << ", abbr_offset = " << format("0x%04" PRIx64, getAbbrOffset()); + if (!getAbbreviations()) + OS << " (invalid)"; + OS << ", addr_size = " << format("0x%02x", getAddressByteSize()); if (getVersion() >= 5 && getUnitType() != dwarf::DW_UT_compile) OS << ", DWO_id = " << format("0x%016" PRIx64, *getDWOId()); OS << " (next unit at " << format("0x%08" PRIx64, getNextUnitOffset()) diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp index bf6219497770..749d738af9c1 100644 --- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -255,7 +255,7 @@ static void dumpRnglistsSection( break; Offset = TableOffset + Length; } else { - Rnglists.dump(OS, LookupPooledAddress, DumpOpts); + Rnglists.dump(rnglistData, OS, LookupPooledAddress, DumpOpts); } } } @@ -316,7 +316,7 @@ static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts, return; } - Header.dump(OS, DumpOpts); + Header.dump(Data, OS, DumpOpts); uint64_t EndOffset = Header.length() + Header.getHeaderOffset(); Data.setAddressSize(Header.getAddrSize()); @@ -457,7 +457,7 @@ void DWARFContext::dump( shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame, DObj->getFrameSection().Data)) { if (Expected<const DWARFDebugFrame *> DF = getDebugFrame()) - (*DF)->dump(OS, getRegisterInfo(), *Off); + (*DF)->dump(OS, DumpOpts, getRegisterInfo(), *Off); else RecoverableErrorHandler(DF.takeError()); } @@ -466,7 +466,7 @@ void DWARFContext::dump( shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame, DObj->getEHFrameSection().Data)) { if (Expected<const DWARFDebugFrame *> DF = getEHFrame()) - (*DF)->dump(OS, getRegisterInfo(), *Off); + (*DF)->dump(OS, DumpOpts, getRegisterInfo(), *Off); else RecoverableErrorHandler(DF.takeError()); } @@ -502,7 +502,8 @@ void DWARFContext::dump( 0); DWARFDebugArangeSet set; while (arangesData.isValidOffset(offset)) { - if (Error E = set.extract(arangesData, &offset)) { + if (Error E = + set.extract(arangesData, &offset, DumpOpts.WarningHandler)) { RecoverableErrorHandler(std::move(E)); break; } @@ -525,12 +526,29 @@ void DWARFContext::dump( } }; + auto DumpStrSection = [&](StringRef Section) { + DataExtractor StrData(Section, isLittleEndian(), 0); + uint64_t Offset = 0; + uint64_t StrOffset = 0; + while (StrData.isValidOffset(Offset)) { + Error Err = Error::success(); + const char *CStr = StrData.getCStr(&Offset, &Err); + if (Err) { + DumpOpts.WarningHandler(std::move(Err)); + return; + } + OS << format("0x%8.8" PRIx64 ": \"", StrOffset); + OS.write_escaped(CStr); + OS << "\"\n"; + StrOffset = Offset; + } + }; + if (const auto *Off = shouldDump(Explicit, ".debug_line", DIDT_ID_DebugLine, DObj->getLineSection().Data)) { DWARFDataExtractor LineData(*DObj, DObj->getLineSection(), isLittleEndian(), 0); - DWARFDebugLine::SectionParser Parser(LineData, *this, compile_units(), - type_units()); + DWARFDebugLine::SectionParser Parser(LineData, *this, normal_units()); DumpLineSection(Parser, DumpOpts, *Off); } @@ -539,8 +557,7 @@ void DWARFContext::dump( DObj->getLineDWOSection().Data)) { DWARFDataExtractor LineData(*DObj, DObj->getLineDWOSection(), isLittleEndian(), 0); - DWARFDebugLine::SectionParser Parser(LineData, *this, dwo_compile_units(), - dwo_type_units()); + DWARFDebugLine::SectionParser Parser(LineData, *this, dwo_units()); DumpLineSection(Parser, DumpOpts, *Off); } @@ -555,37 +572,16 @@ void DWARFContext::dump( } if (shouldDump(Explicit, ".debug_str", DIDT_ID_DebugStr, - DObj->getStrSection())) { - DataExtractor strData(DObj->getStrSection(), isLittleEndian(), 0); - uint64_t offset = 0; - uint64_t strOffset = 0; - while (const char *s = strData.getCStr(&offset)) { - OS << format("0x%8.8" PRIx64 ": \"%s\"\n", strOffset, s); - strOffset = offset; - } - } + DObj->getStrSection())) + DumpStrSection(DObj->getStrSection()); + if (shouldDump(ExplicitDWO, ".debug_str.dwo", DIDT_ID_DebugStr, - DObj->getStrDWOSection())) { - DataExtractor strDWOData(DObj->getStrDWOSection(), isLittleEndian(), 0); - uint64_t offset = 0; - uint64_t strDWOOffset = 0; - while (const char *s = strDWOData.getCStr(&offset)) { - OS << format("0x%8.8" PRIx64 ": \"%s\"\n", strDWOOffset, s); - strDWOOffset = offset; - } - } + DObj->getStrDWOSection())) + DumpStrSection(DObj->getStrDWOSection()); + if (shouldDump(Explicit, ".debug_line_str", DIDT_ID_DebugLineStr, - DObj->getLineStrSection())) { - DataExtractor strData(DObj->getLineStrSection(), isLittleEndian(), 0); - uint64_t offset = 0; - uint64_t strOffset = 0; - while (const char *s = strData.getCStr(&offset)) { - OS << format("0x%8.8" PRIx64 ": \"", strOffset); - OS.write_escaped(s); - OS << "\"\n"; - strOffset = offset; - } - } + DObj->getLineStrSection())) + DumpStrSection(DObj->getLineStrSection()); if (shouldDump(Explicit, ".debug_addr", DIDT_ID_DebugAddr, DObj->getAddrSection().Data)) { @@ -1038,7 +1034,9 @@ DWARFContext::DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address) { static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU, uint64_t Address, FunctionNameKind Kind, + DILineInfoSpecifier::FileLineInfoKind FileNameKind, std::string &FunctionName, + std::string &StartFile, uint32_t &StartLine) { // The address may correspond to instruction in some inlined function, // so we have to build the chain of inlined functions and take the @@ -1055,6 +1053,11 @@ static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU, FunctionName = Name; FoundResult = true; } + std::string DeclFile = DIE.getDeclFile(FileNameKind); + if (!DeclFile.empty()) { + StartFile = DeclFile; + FoundResult = true; + } if (auto DeclLineResult = DIE.getDeclLine()) { StartLine = DeclLineResult; FoundResult = true; @@ -1226,8 +1229,9 @@ DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address, if (!CU) return Result; - getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind, - Result.FunctionName, Result.StartLine); + getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind, Spec.FLIKind, + Result.FunctionName, + Result.StartFileName, Result.StartLine); if (Spec.FLIKind != FileLineInfoKind::None) { if (const DWARFLineTable *LineTable = getLineTableForUnit(CU)) { LineTable->getFileLineInfoForAddress( @@ -1246,15 +1250,17 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange( return Lines; uint32_t StartLine = 0; + std::string StartFileName; std::string FunctionName(DILineInfo::BadString); - getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind, - FunctionName, StartLine); + getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind, Spec.FLIKind, + FunctionName, StartFileName, StartLine); // If the Specifier says we don't need FileLineInfo, just // return the top-most function at the starting address. if (Spec.FLIKind == FileLineInfoKind::None) { DILineInfo Result; Result.FunctionName = FunctionName; + Result.StartFileName = StartFileName; Result.StartLine = StartLine; Lines.push_back(std::make_pair(Address.Address, Result)); return Lines; @@ -1278,6 +1284,7 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange( Result.FunctionName = FunctionName; Result.Line = Row.Line; Result.Column = Row.Column; + Result.StartFileName = StartFileName; Result.StartLine = StartLine; Lines.push_back(std::make_pair(Row.Address.Address, Result)); } @@ -1320,6 +1327,7 @@ DWARFContext::getInliningInfoForAddress(object::SectionedAddress Address, Frame.FunctionName = Name; if (auto DeclLineResult = FunctionDIE.getDeclLine()) Frame.StartLine = DeclLineResult; + Frame.StartFileName = FunctionDIE.getDeclFile(Spec.FLIKind); if (Spec.FLIKind != FileLineInfoKind::None) { if (i == 0) { // For the topmost frame, initialize the line table of this @@ -1701,16 +1709,17 @@ public: // FIXME: Use the other dwo range section when we emit it. RangesDWOSection.Data = Data; } - } else if (Name == "debug_info") { + } else if (InfoSectionMap *Sections = + StringSwitch<InfoSectionMap *>(Name) + .Case("debug_info", &InfoSections) + .Case("debug_info.dwo", &InfoDWOSections) + .Case("debug_types", &TypesSections) + .Case("debug_types.dwo", &TypesDWOSections) + .Default(nullptr)) { // Find debug_info and debug_types data by section rather than name as // there are multiple, comdat grouped, of these sections. - InfoSections[Section].Data = Data; - } else if (Name == "debug_info.dwo") { - InfoDWOSections[Section].Data = Data; - } else if (Name == "debug_types") { - TypesSections[Section].Data = Data; - } else if (Name == "debug_types.dwo") { - TypesDWOSections[Section].Data = Data; + DWARFSectionMap &S = (*Sections)[Section]; + S.Data = Data; } if (RelocatedSection == Obj.section_end()) @@ -1771,7 +1780,7 @@ public: // Symbol to [address, section index] cache mapping. std::map<SymbolRef, SymInfo> AddrCache; - bool (*Supports)(uint64_t); + SupportsRelocation Supports; RelocationResolver Resolver; std::tie(Supports, Resolver) = getRelocationResolver(Obj); for (const RelocationRef &Reloc : Section.relocations()) { @@ -1989,6 +1998,6 @@ uint8_t DWARFContext::getCUAddrSize() { // first compile unit. In practice the address size field is repeated across // various DWARF headers (at least in version 5) to make it easier to dump // them independently, not to enable varying the address size. - unit_iterator_range CUs = compile_units(); + auto CUs = compile_units(); return CUs.empty() ? 0 : (*CUs.begin())->getAddressByteSize(); } diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp index 886fe1dff976..da6f6ad903f4 100644 --- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp +++ b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp @@ -53,14 +53,16 @@ uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint64_t *Off, ErrorAsOutParameter ErrAsOut(Err); Optional<RelocAddrEntry> E = Obj->find(*Section, *Off); - uint64_t A = getUnsigned(Off, Size, Err); + uint64_t LocData = getUnsigned(Off, Size, Err); if (!E || (Err && *Err)) - return A; + return LocData; if (SecNdx) *SecNdx = E->SectionIndex; - uint64_t R = E->Resolver(E->Reloc, E->SymbolValue, A); + + uint64_t R = + object::resolveRelocation(E->Resolver, E->Reloc, E->SymbolValue, LocData); if (E->Reloc2) - R = E->Resolver(*E->Reloc2, E->SymbolValue2, R); + R = object::resolveRelocation(E->Resolver, *E->Reloc2, E->SymbolValue2, R); return R; } @@ -104,10 +106,10 @@ DWARFDataExtractor::getEncodedPointer(uint64_t *Offset, uint8_t Encoding, Result = getSigned(Offset, 2); break; case dwarf::DW_EH_PE_sdata4: - Result = getSigned(Offset, 4); + Result = SignExtend64<32>(getRelocatedValue(4, Offset)); break; case dwarf::DW_EH_PE_sdata8: - Result = getSigned(Offset, 8); + Result = getRelocatedValue(8, Offset); break; default: return None; diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp index c3b039b05f30..598e3ecee30e 100644 --- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp +++ b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp @@ -8,6 +8,7 @@ #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h" #include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/DebugInfo/DWARF/DWARFFormValue.h" #include "llvm/Support/Errc.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" @@ -20,9 +21,11 @@ using namespace llvm; void DWARFDebugArangeSet::Descriptor::dump(raw_ostream &OS, uint32_t AddressSize) const { - OS << format("[0x%*.*" PRIx64 ", ", AddressSize * 2, AddressSize * 2, Address) - << format(" 0x%*.*" PRIx64 ")", AddressSize * 2, AddressSize * 2, - getEndAddress()); + OS << '['; + DWARFFormValue::dumpAddress(OS, AddressSize, Address); + OS << ", "; + DWARFFormValue::dumpAddress(OS, AddressSize, getEndAddress()); + OS << ')'; } void DWARFDebugArangeSet::clear() { @@ -32,7 +35,8 @@ void DWARFDebugArangeSet::clear() { } Error DWARFDebugArangeSet::extract(DWARFDataExtractor data, - uint64_t *offset_ptr) { + uint64_t *offset_ptr, + function_ref<void(Error)> WarningHandler) { assert(data.isValidOffset(*offset_ptr)); ArangeDescriptors.clear(); Offset = *offset_ptr; @@ -141,11 +145,11 @@ Error DWARFDebugArangeSet::extract(DWARFDataExtractor data, if (arangeDescriptor.Length == 0 && arangeDescriptor.Address == 0) { if (*offset_ptr == end_offset) return ErrorSuccess(); - return createStringError( + WarningHandler(createStringError( errc::invalid_argument, "address range table at offset 0x%" PRIx64 " has a premature terminator entry at offset 0x%" PRIx64, - Offset, EntryOffset); + Offset, EntryOffset)); } ArangeDescriptors.push_back(arangeDescriptor); diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp index e8ed63075055..e0db469752cd 100644 --- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp +++ b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp @@ -28,7 +28,8 @@ void DWARFDebugAranges::extract( DWARFDebugArangeSet Set; while (DebugArangesData.isValidOffset(Offset)) { - if (Error E = Set.extract(DebugArangesData, &Offset)) { + if (Error E = + Set.extract(DebugArangesData, &Offset, RecoverableErrorHandler)) { RecoverableErrorHandler(std::move(E)); return; } diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp index 0a1b75592290..b74ecac681f3 100644 --- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp +++ b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp @@ -12,6 +12,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataExtractor.h" @@ -29,6 +30,18 @@ using namespace llvm; using namespace dwarf; +static void printRegister(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH, + unsigned RegNum) { + if (MRI) { + if (Optional<unsigned> LLVMRegNum = MRI->getLLVMRegNum(RegNum, IsEH)) { + if (const char *RegName = MRI->getName(*LLVMRegNum)) { + OS << RegName; + return; + } + } + } + OS << "reg" << RegNum; +} // See DWARF standard v3, section 7.23 const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0; @@ -221,9 +234,10 @@ ArrayRef<CFIProgram::OperandType[2]> CFIProgram::getOperandTypes() { } /// Print \p Opcode's operand number \p OperandIdx which has value \p Operand. -void CFIProgram::printOperand(raw_ostream &OS, const MCRegisterInfo *MRI, - bool IsEH, const Instruction &Instr, - unsigned OperandIdx, uint64_t Operand) const { +void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts, + const MCRegisterInfo *MRI, bool IsEH, + const Instruction &Instr, unsigned OperandIdx, + uint64_t Operand) const { assert(OperandIdx < 2); uint8_t Opcode = Instr.Opcode; OperandType Type = getOperandTypes()[Opcode][OperandIdx]; @@ -268,17 +282,19 @@ void CFIProgram::printOperand(raw_ostream &OS, const MCRegisterInfo *MRI, OS << format(" %" PRId64 "*data_alignment_factor" , Operand); break; case OT_Register: - OS << format(" reg%" PRId64, Operand); + OS << ' '; + printRegister(OS, MRI, IsEH, Operand); break; case OT_Expression: assert(Instr.Expression && "missing DWARFExpression object"); OS << " "; - Instr.Expression->print(OS, MRI, nullptr, IsEH); + Instr.Expression->print(OS, DumpOpts, MRI, nullptr, IsEH); break; } } -void CFIProgram::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH, +void CFIProgram::dump(raw_ostream &OS, DIDumpOptions DumpOpts, + const MCRegisterInfo *MRI, bool IsEH, unsigned IndentLevel) const { for (const auto &Instr : Instructions) { uint8_t Opcode = Instr.Opcode; @@ -287,7 +303,7 @@ void CFIProgram::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH, OS.indent(2 * IndentLevel); OS << CallFrameString(Opcode, Arch) << ":"; for (unsigned i = 0; i < Instr.Ops.size(); ++i) - printOperand(OS, MRI, IsEH, Instr, i, Instr.Ops[i]); + printOperand(OS, DumpOpts, MRI, IsEH, Instr, i, Instr.Ops[i]); OS << '\n'; } } @@ -304,7 +320,8 @@ constexpr uint64_t getCIEId(bool IsDWARF64, bool IsEH) { return DW_CIE_ID; } -void CIE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const { +void CIE::dump(raw_ostream &OS, DIDumpOptions DumpOpts, + const MCRegisterInfo *MRI, bool IsEH) const { // A CIE with a zero length is a terminator entry in the .eh_frame section. if (IsEH && Length == 0) { OS << format("%08" PRIx64, Offset) << " ZERO terminator\n"; @@ -336,11 +353,12 @@ void CIE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const { OS << "\n"; } OS << "\n"; - CFIs.dump(OS, MRI, IsEH); + CFIs.dump(OS, DumpOpts, MRI, IsEH); OS << "\n"; } -void FDE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const { +void FDE::dump(raw_ostream &OS, DIDumpOptions DumpOpts, + const MCRegisterInfo *MRI, bool IsEH) const { OS << format("%08" PRIx64, Offset) << format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length) << format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8, CIEPointer) @@ -354,7 +372,7 @@ void FDE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const { OS << " Format: " << FormatString(IsDWARF64) << "\n"; if (LSDAAddress) OS << format(" LSDA Address: %016" PRIx64 "\n", *LSDAAddress); - CFIs.dump(OS, MRI, IsEH); + CFIs.dump(OS, DumpOpts, MRI, IsEH); OS << "\n"; } @@ -521,9 +539,9 @@ Error DWARFDebugFrame::parse(DWARFDataExtractor Data) { "parsing FDE data at 0x%" PRIx64 " failed due to missing CIE", StartOffset); - if (auto Val = Data.getEncodedPointer( - &Offset, Cie->getFDEPointerEncoding(), - EHFrameAddress ? EHFrameAddress + Offset : 0)) { + if (auto Val = + Data.getEncodedPointer(&Offset, Cie->getFDEPointerEncoding(), + EHFrameAddress + Offset)) { InitialLocation = *Val; } if (auto Val = Data.getEncodedPointer( @@ -583,15 +601,16 @@ FrameEntry *DWARFDebugFrame::getEntryAtOffset(uint64_t Offset) const { return nullptr; } -void DWARFDebugFrame::dump(raw_ostream &OS, const MCRegisterInfo *MRI, +void DWARFDebugFrame::dump(raw_ostream &OS, DIDumpOptions DumpOpts, + const MCRegisterInfo *MRI, Optional<uint64_t> Offset) const { if (Offset) { if (auto *Entry = getEntryAtOffset(*Offset)) - Entry->dump(OS, MRI, IsEH); + Entry->dump(OS, DumpOpts, MRI, IsEH); return; } OS << "\n"; for (const auto &Entry : Entries) - Entry->dump(OS, MRI, IsEH); + Entry->dump(OS, DumpOpts, MRI, IsEH); } diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp index 87eab34d58ee..2b7d0c3363a1 100644 --- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp +++ b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp @@ -38,7 +38,8 @@ bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U, uint64_t *OffsetPtr, AbbrevDecl = nullptr; return true; } - AbbrevDecl = U.getAbbreviations()->getAbbreviationDeclaration(AbbrCode); + if (const auto *AbbrevSet = U.getAbbreviations()) + AbbrevDecl = AbbrevSet->getAbbreviationDeclaration(AbbrCode); if (nullptr == AbbrevDecl) { // Restore the original offset. *OffsetPtr = Offset; diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp index 3ca21e97888c..bda41b1f34e9 100644 --- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -79,6 +79,18 @@ bool DWARFDebugLine::Prologue::hasFileAtIndex(uint64_t FileIndex) const { return FileIndex != 0 && FileIndex <= FileNames.size(); } +Optional<uint64_t> DWARFDebugLine::Prologue::getLastValidFileIndex() const { + if (FileNames.empty()) + return None; + uint16_t DwarfVersion = getVersion(); + assert(DwarfVersion != 0 && + "line table prologue has no dwarf version information"); + // In DWARF v5 the file names are 0-indexed. + if (DwarfVersion >= 5) + return FileNames.size() - 1; + return FileNames.size(); +} + const llvm::DWARFDebugLine::FileNameEntry & DWARFDebugLine::Prologue::getFileNameEntry(uint64_t Index) const { uint16_t DwarfVersion = getVersion(); @@ -771,6 +783,18 @@ Error DWARFDebugLine::LineTable::parse( *OS << '\n'; Row::dumpTableHeader(*OS, /*Indent=*/Verbose ? 12 : 0); } + bool TombstonedAddress = false; + auto EmitRow = [&] { + if (!TombstonedAddress) { + if (Verbose) { + *OS << "\n"; + OS->indent(12); + } + if (OS) + State.Row.dump(*OS); + State.appendRowToMatrix(); + } + }; while (*OffsetPtr < EndOffset) { DataExtractor::Cursor Cursor(*OffsetPtr); @@ -822,13 +846,7 @@ Error DWARFDebugLine::LineTable::parse( // No need to test the Cursor is valid here, since it must be to get // into this code path - if it were invalid, the default case would be // followed. - if (Verbose) { - *OS << "\n"; - OS->indent(12); - } - if (OS) - State.Row.dump(*OS); - State.appendRowToMatrix(); + EmitRow(); State.resetRowAndSequence(); break; @@ -870,13 +888,20 @@ Error DWARFDebugLine::LineTable::parse( State.Row.Address.Address = TableData.getRelocatedAddress( Cursor, &State.Row.Address.SectionIndex); + uint64_t Tombstone = + dwarf::computeTombstoneAddress(OpcodeAddressSize); + TombstonedAddress = State.Row.Address.Address == Tombstone; + // Restore the address size if the extractor already had it. if (ExtractorAddressSize != 0) TableData.setAddressSize(ExtractorAddressSize); } - if (Cursor && Verbose) - *OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address.Address); + if (Cursor && Verbose) { + *OS << " ("; + DWARFFormValue::dumpAddress(*OS, OpcodeAddressSize, State.Row.Address.Address); + *OS << ')'; + } } break; @@ -969,13 +994,7 @@ Error DWARFDebugLine::LineTable::parse( case DW_LNS_copy: // Takes no arguments. Append a row to the matrix using the // current values of the state-machine registers. - if (Verbose) { - *OS << "\n"; - OS->indent(12); - } - if (OS) - State.Row.dump(*OS); - State.appendRowToMatrix(); + EmitRow(); break; case DW_LNS_advance_pc: @@ -1140,15 +1159,9 @@ Error DWARFDebugLine::LineTable::parse( ParsingState::AddrAndLineDelta Delta = State.handleSpecialOpcode(Opcode, OpcodeOffset); - if (Verbose) { - *OS << "address += " << Delta.Address << ", line += " << Delta.Line - << "\n"; - OS->indent(12); - } - if (OS) - State.Row.dump(*OS); - - State.appendRowToMatrix(); + if (Verbose) + *OS << "address += " << Delta.Address << ", line += " << Delta.Line; + EmitRow(); *OffsetPtr = Cursor.tell(); } @@ -1406,25 +1419,20 @@ bool DWARFDebugLine::LineTable::getFileLineInfoForAddress( // Therefore, collect up handles on all the Units that point into the // line-table section. static DWARFDebugLine::SectionParser::LineToUnitMap -buildLineToUnitMap(DWARFDebugLine::SectionParser::cu_range CUs, - DWARFDebugLine::SectionParser::tu_range TUs) { +buildLineToUnitMap(DWARFUnitVector::iterator_range Units) { DWARFDebugLine::SectionParser::LineToUnitMap LineToUnit; - for (const auto &CU : CUs) - if (auto CUDIE = CU->getUnitDIE()) + for (const auto &U : Units) + if (auto CUDIE = U->getUnitDIE()) if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list))) - LineToUnit.insert(std::make_pair(*StmtOffset, &*CU)); - for (const auto &TU : TUs) - if (auto TUDIE = TU->getUnitDIE()) - if (auto StmtOffset = toSectionOffset(TUDIE.find(DW_AT_stmt_list))) - LineToUnit.insert(std::make_pair(*StmtOffset, &*TU)); + LineToUnit.insert(std::make_pair(*StmtOffset, &*U)); return LineToUnit; } -DWARFDebugLine::SectionParser::SectionParser(DWARFDataExtractor &Data, - const DWARFContext &C, - cu_range CUs, tu_range TUs) +DWARFDebugLine::SectionParser::SectionParser( + DWARFDataExtractor &Data, const DWARFContext &C, + DWARFUnitVector::iterator_range Units) : DebugLineData(Data), Context(C) { - LineToUnit = buildLineToUnitMap(CUs, TUs); + LineToUnit = buildLineToUnitMap(Units); if (!DebugLineData.isValidOffset(Offset)) Done = true; } diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp index f38126364401..cdffb36741c8 100644 --- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp +++ b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp @@ -106,15 +106,16 @@ DWARFLocationInterpreter::Interpret(const DWARFLocationEntry &E) { } } -static void dumpExpression(raw_ostream &OS, ArrayRef<uint8_t> Data, - bool IsLittleEndian, unsigned AddressSize, - const MCRegisterInfo *MRI, DWARFUnit *U) { +static void dumpExpression(raw_ostream &OS, DIDumpOptions DumpOpts, + ArrayRef<uint8_t> Data, bool IsLittleEndian, + unsigned AddressSize, const MCRegisterInfo *MRI, + DWARFUnit *U) { DWARFDataExtractor Extractor(Data, IsLittleEndian, AddressSize); // Note. We do not pass any format to DWARFExpression, even if the // corresponding unit is known. For now, there is only one operation, // DW_OP_call_ref, which depends on the format; it is rarely used, and // is unexpected in location tables. - DWARFExpression(Extractor, AddressSize).print(OS, MRI, U); + DWARFExpression(Extractor, AddressSize).print(OS, DumpOpts, MRI, U); } bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS, @@ -154,8 +155,8 @@ bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS, E.Kind != dwarf::DW_LLE_base_addressx && E.Kind != dwarf::DW_LLE_end_of_list) { OS << ": "; - dumpExpression(OS, E.Loc, Data.isLittleEndian(), Data.getAddressSize(), - MRI, U); + dumpExpression(OS, DumpOpts, E.Loc, Data.isLittleEndian(), + Data.getAddressSize(), MRI, U); } return true; }); @@ -259,7 +260,6 @@ void DWARFDebugLoc::dumpRawEntry(const DWARFLocationEntry &Entry, Value1 = Entry.Value1; break; case dwarf::DW_LLE_end_of_list: - Value0 = Value1 = 0; return; default: llvm_unreachable("Not possible in DWARF4!"); diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp index f920d69cc43f..80ffd81b3403 100644 --- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp +++ b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp @@ -40,7 +40,7 @@ void DWARFDebugMacro::dump(raw_ostream &OS) const { unsigned IndLevel = 0; for (const auto &Macros : MacroLists) { OS << format("0x%08" PRIx64 ":\n", Macros.Offset); - if (Macros.Header.Version >= 5) + if (Macros.IsDebugMacro) Macros.Header.dumpMacroHeader(OS); for (const Entry &E : Macros.Macros) { // There should not be DW_MACINFO_end_file when IndLevel is Zero. However, @@ -52,8 +52,10 @@ void DWARFDebugMacro::dump(raw_ostream &OS) const { OS << " "; IndLevel += (E.Type == DW_MACINFO_start_file); // Based on which version we are handling choose appropriate macro forms. - if (Macros.Header.Version >= 5) - WithColor(OS, HighlightColor::Macro).get() << MacroString(E.Type); + if (Macros.IsDebugMacro) + WithColor(OS, HighlightColor::Macro).get() + << (Macros.Header.Version < 5 ? GnuMacroString(E.Type) + : MacroString(E.Type)); else WithColor(OS, HighlightColor::Macro).get() << MacinfoString(E.Type); switch (E.Type) { @@ -67,6 +69,9 @@ void DWARFDebugMacro::dump(raw_ostream &OS) const { // DW_MACRO_start_file == DW_MACINFO_start_file // DW_MACRO_end_file == DW_MACINFO_end_file // For readability/uniformity we are using DW_MACRO_*. + // + // The GNU .debug_macro extension's entries have the same encoding + // as DWARF 5's DW_MACRO_* entries, so we only use the latter here. case DW_MACRO_define: case DW_MACRO_undef: case DW_MACRO_define_strp: @@ -97,7 +102,7 @@ void DWARFDebugMacro::dump(raw_ostream &OS) const { } Error DWARFDebugMacro::parseImpl( - Optional<DWARFUnitVector::iterator_range> Units, + Optional<DWARFUnitVector::compile_unit_range> Units, Optional<DataExtractor> StringExtractor, DWARFDataExtractor Data, bool IsMacro) { uint64_t Offset = 0; @@ -118,6 +123,7 @@ Error DWARFDebugMacro::parseImpl( MacroLists.emplace_back(); M = &MacroLists.back(); M->Offset = Offset; + M->IsDebugMacro = IsMacro; if (IsMacro) { auto Err = M->Header.parseMacroHeader(Data, &Offset); if (Err) diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp index 1a1857d8cd79..dc7da5d9348f 100644 --- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp +++ b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp @@ -70,6 +70,9 @@ void DWARFDebugRangeList::dump(raw_ostream &OS) const { DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges( llvm::Optional<object::SectionedAddress> BaseAddr) const { DWARFAddressRangesVector Res; + // debug_addr can't use the max integer tombstone because that's used for the + // base address specifier entry - so use max-1. + uint64_t Tombstone = dwarf::computeTombstoneAddress(AddressSize) - 1; for (const RangeListEntry &RLE : Entries) { if (RLE.isBaseAddressSelectionEntry(AddressSize)) { BaseAddr = {RLE.EndAddress, RLE.SectionIndex}; @@ -78,12 +81,16 @@ DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges( DWARFAddressRange E; E.LowPC = RLE.StartAddress; + if (E.LowPC == Tombstone) + continue; E.HighPC = RLE.EndAddress; E.SectionIndex = RLE.SectionIndex; // Base address of a range list entry is determined by the closest preceding // base address selection entry in the same range list. It defaults to the // base address of the compilation unit if there is no such entry. if (BaseAddr) { + if (BaseAddr->Address == Tombstone) + continue; E.LowPC += BaseAddr->Address; E.HighPC += BaseAddr->Address; if (E.SectionIndex == -1ULL) diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp index 9ae4c5b73ebe..d12acca1962e 100644 --- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp +++ b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp @@ -8,6 +8,7 @@ #include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h" #include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/DebugInfo/DWARF/DWARFFormValue.h" #include "llvm/DebugInfo/DWARF/DWARFUnit.h" #include "llvm/Support/Errc.h" #include "llvm/Support/Error.h" @@ -16,114 +17,87 @@ using namespace llvm; -Error RangeListEntry::extract(DWARFDataExtractor Data, uint64_t End, - uint64_t *OffsetPtr) { +Error RangeListEntry::extract(DWARFDataExtractor Data, uint64_t *OffsetPtr) { Offset = *OffsetPtr; SectionIndex = -1ULL; // The caller should guarantee that we have at least 1 byte available, so // we just assert instead of revalidate. - assert(*OffsetPtr < End && + assert(*OffsetPtr < Data.size() && "not enough space to extract a rangelist encoding"); uint8_t Encoding = Data.getU8(OffsetPtr); + DataExtractor::Cursor C(*OffsetPtr); switch (Encoding) { case dwarf::DW_RLE_end_of_list: Value0 = Value1 = 0; break; // TODO: Support other encodings. case dwarf::DW_RLE_base_addressx: { - uint64_t PreviousOffset = *OffsetPtr - 1; - Value0 = Data.getULEB128(OffsetPtr); - if (End < *OffsetPtr) - return createStringError( - errc::invalid_argument, - "read past end of table when reading " - "DW_RLE_base_addressx encoding at offset 0x%" PRIx64, - PreviousOffset); + Value0 = Data.getULEB128(C); break; } case dwarf::DW_RLE_startx_endx: - return createStringError(errc::not_supported, - "unsupported rnglists encoding DW_RLE_startx_endx at " - "offset 0x%" PRIx64, - *OffsetPtr - 1); + Value0 = Data.getULEB128(C); + Value1 = Data.getULEB128(C); + break; case dwarf::DW_RLE_startx_length: { - uint64_t PreviousOffset = *OffsetPtr - 1; - Value0 = Data.getULEB128(OffsetPtr); - Value1 = Data.getULEB128(OffsetPtr); - if (End < *OffsetPtr) - return createStringError( - errc::invalid_argument, - "read past end of table when reading " - "DW_RLE_startx_length encoding at offset 0x%" PRIx64, - PreviousOffset); + Value0 = Data.getULEB128(C); + Value1 = Data.getULEB128(C); break; } case dwarf::DW_RLE_offset_pair: { - uint64_t PreviousOffset = *OffsetPtr - 1; - Value0 = Data.getULEB128(OffsetPtr); - Value1 = Data.getULEB128(OffsetPtr); - if (End < *OffsetPtr) - return createStringError(errc::invalid_argument, - "read past end of table when reading " - "DW_RLE_offset_pair encoding at offset 0x%" PRIx64, - PreviousOffset); + Value0 = Data.getULEB128(C); + Value1 = Data.getULEB128(C); break; } case dwarf::DW_RLE_base_address: { - if ((End - *OffsetPtr) < Data.getAddressSize()) - return createStringError(errc::invalid_argument, - "insufficient space remaining in table for " - "DW_RLE_base_address encoding at offset 0x%" PRIx64, - *OffsetPtr - 1); - Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex); + Value0 = Data.getRelocatedAddress(C, &SectionIndex); break; } case dwarf::DW_RLE_start_end: { - if ((End - *OffsetPtr) < unsigned(Data.getAddressSize() * 2)) - return createStringError(errc::invalid_argument, - "insufficient space remaining in table for " - "DW_RLE_start_end encoding " - "at offset 0x%" PRIx64, - *OffsetPtr - 1); - Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex); - Value1 = Data.getRelocatedAddress(OffsetPtr); + Value0 = Data.getRelocatedAddress(C, &SectionIndex); + Value1 = Data.getRelocatedAddress(C); break; } case dwarf::DW_RLE_start_length: { - uint64_t PreviousOffset = *OffsetPtr - 1; - Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex); - Value1 = Data.getULEB128(OffsetPtr); - if (End < *OffsetPtr) - return createStringError(errc::invalid_argument, - "read past end of table when reading " - "DW_RLE_start_length encoding at offset 0x%" PRIx64, - PreviousOffset); + Value0 = Data.getRelocatedAddress(C, &SectionIndex); + Value1 = Data.getULEB128(C); break; } default: + consumeError(C.takeError()); return createStringError(errc::not_supported, - "unknown rnglists encoding 0x%" PRIx32 - " at offset 0x%" PRIx64, - uint32_t(Encoding), *OffsetPtr - 1); + "unknown rnglists encoding 0x%" PRIx32 + " at offset 0x%" PRIx64, + uint32_t(Encoding), Offset); + } + + if (!C) { + consumeError(C.takeError()); + return createStringError( + errc::invalid_argument, + "read past end of table when reading %s encoding at offset 0x%" PRIx64, + dwarf::RLEString(Encoding).data(), Offset); } + *OffsetPtr = C.tell(); EntryKind = Encoding; return Error::success(); } DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges( llvm::Optional<object::SectionedAddress> BaseAddr, DWARFUnit &U) const { - return getAbsoluteRanges(BaseAddr, [&](uint32_t Index) { - return U.getAddrOffsetSectionItem(Index); - }); + return getAbsoluteRanges( + BaseAddr, U.getAddressByteSize(), + [&](uint32_t Index) { return U.getAddrOffsetSectionItem(Index); }); } DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges( - Optional<object::SectionedAddress> BaseAddr, + Optional<object::SectionedAddress> BaseAddr, uint8_t AddressByteSize, function_ref<Optional<object::SectionedAddress>(uint32_t)> LookupPooledAddress) const { DWARFAddressRangesVector Res; + uint64_t Tombstone = dwarf::computeTombstoneAddress(AddressByteSize); for (const RangeListEntry &RLE : Entries) { if (RLE.EntryKind == dwarf::DW_RLE_end_of_list) break; @@ -146,8 +120,12 @@ DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges( switch (RLE.EntryKind) { case dwarf::DW_RLE_offset_pair: E.LowPC = RLE.Value0; + if (E.LowPC == Tombstone) + continue; E.HighPC = RLE.Value1; if (BaseAddr) { + if (BaseAddr->Address == Tombstone) + continue; E.LowPC += BaseAddr->Address; E.HighPC += BaseAddr->Address; } @@ -169,11 +147,26 @@ DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges( E.HighPC = E.LowPC + RLE.Value1; break; } + case dwarf::DW_RLE_startx_endx: { + auto Start = LookupPooledAddress(RLE.Value0); + if (!Start) + Start = {0, -1ULL}; + auto End = LookupPooledAddress(RLE.Value1); + if (!End) + End = {0, -1ULL}; + // FIXME: Some error handling if Start.SectionIndex != End.SectionIndex + E.SectionIndex = Start->SectionIndex; + E.LowPC = Start->Address; + E.HighPC = End->Address; + break; + } default: // Unsupported encodings should have been reported during extraction, // so we should not run into any here. llvm_unreachable("Unsupported range list encoding"); } + if (E.LowPC == Tombstone) + continue; Res.push_back(E); } return Res; @@ -206,6 +199,8 @@ void RangeListEntry::dump( OS << ": "; } + uint64_t Tombstone = dwarf::computeTombstoneAddress(AddrSize); + switch (EntryKind) { case dwarf::DW_RLE_end_of_list: OS << (DumpOpts.Verbose ? "" : "<End of list>"); @@ -217,7 +212,7 @@ void RangeListEntry::dump( CurrentBase = Value0; if (!DumpOpts.Verbose) return; - OS << format(" 0x%*.*" PRIx64, AddrSize * 2, AddrSize * 2, Value0); + DWARFFormValue::dumpAddress(OS << ' ', AddrSize, Value0); break; } case dwarf::DW_RLE_base_address: @@ -225,7 +220,7 @@ void RangeListEntry::dump( CurrentBase = Value0; if (!DumpOpts.Verbose) return; - OS << format(" 0x%*.*" PRIx64, AddrSize * 2, AddrSize * 2, Value0); + DWARFFormValue::dumpAddress(OS << ' ', AddrSize, Value0); break; case dwarf::DW_RLE_start_length: PrintRawEntry(OS, *this, AddrSize, DumpOpts); @@ -233,8 +228,11 @@ void RangeListEntry::dump( break; case dwarf::DW_RLE_offset_pair: PrintRawEntry(OS, *this, AddrSize, DumpOpts); - DWARFAddressRange(Value0 + CurrentBase, Value1 + CurrentBase) - .dump(OS, AddrSize, DumpOpts); + if (CurrentBase != Tombstone) + DWARFAddressRange(Value0 + CurrentBase, Value1 + CurrentBase) + .dump(OS, AddrSize, DumpOpts); + else + OS << "dead code"; break; case dwarf::DW_RLE_start_end: DWARFAddressRange(Value0, Value1).dump(OS, AddrSize, DumpOpts); @@ -247,6 +245,17 @@ void RangeListEntry::dump( DWARFAddressRange(Start, Start + Value1).dump(OS, AddrSize, DumpOpts); break; } + case dwarf::DW_RLE_startx_endx: { + PrintRawEntry(OS, *this, AddrSize, DumpOpts); + uint64_t Start = 0; + if (auto SA = LookupPooledAddress(Value0)) + Start = SA->Address; + uint64_t End = 0; + if (auto SA = LookupPooledAddress(Value1)) + End = SA->Address; + DWARFAddressRange(Start, End).dump(OS, AddrSize, DumpOpts); + break; + } default: llvm_unreachable("Unsupported range list encoding"); } diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp index 81a6b5dcd5e7..427f6f4942c3 100644 --- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp +++ b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp @@ -80,7 +80,7 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue, DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()), Ctx.isLittleEndian(), 0); DWARFExpression(Data, U->getAddressByteSize(), U->getFormParams().Format) - .print(OS, MRI, U); + .print(OS, DumpOpts, MRI, U); return; } @@ -113,7 +113,6 @@ static void dumpTypeTagName(raw_ostream &OS, dwarf::Tag T) { } static void dumpArrayType(raw_ostream &OS, const DWARFDie &D) { - Optional<uint64_t> Bound; for (const DWARFDie &C : D.children()) if (C.getTag() == DW_TAG_subrange_type) { Optional<uint64_t> LB; @@ -269,13 +268,23 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die, WithColor(OS, Color) << Name; else if (Attr == DW_AT_decl_line || Attr == DW_AT_call_line) OS << *FormValue.getAsUnsignedConstant(); - else if (Attr == DW_AT_high_pc && !DumpOpts.ShowForm && !DumpOpts.Verbose && - FormValue.getAsUnsignedConstant()) { + else if (Attr == DW_AT_low_pc && + (FormValue.getAsAddress() == + dwarf::computeTombstoneAddress(U->getAddressByteSize()))) { + if (DumpOpts.Verbose) { + FormValue.dump(OS, DumpOpts); + OS << " ("; + } + OS << "dead code"; + if (DumpOpts.Verbose) + OS << ')'; + } else if (Attr == DW_AT_high_pc && !DumpOpts.ShowForm && !DumpOpts.Verbose && + FormValue.getAsUnsignedConstant()) { if (DumpOpts.ShowAddresses) { // Print the actual address rather than the offset. uint64_t LowPC, HighPC, Index; if (Die.getLowAndHighPC(LowPC, HighPC, Index)) - OS << format("0x%016" PRIx64, HighPC); + DWARFFormValue::dumpAddress(OS, U->getAddressByteSize(), HighPC); else FormValue.dump(OS, DumpOpts); } @@ -368,8 +377,7 @@ DWARFDie::findRecursively(ArrayRef<dwarf::Attribute> Attrs) const { Seen.insert(*this); while (!Worklist.empty()) { - DWARFDie Die = Worklist.back(); - Worklist.pop_back(); + DWARFDie Die = Worklist.pop_back_val(); if (!Die.isValid()) continue; @@ -416,6 +424,9 @@ Optional<uint64_t> DWARFDie::getLocBaseAttribute() const { } Optional<uint64_t> DWARFDie::getHighPC(uint64_t LowPC) const { + uint64_t Tombstone = dwarf::computeTombstoneAddress(U->getAddressByteSize()); + if (LowPC == Tombstone) + return None; if (auto FormValue = find(DW_AT_high_pc)) { if (auto Address = FormValue->getAsAddress()) { // High PC is an address. @@ -467,8 +478,7 @@ void DWARFDie::collectChildrenAddressRanges( return; if (isSubprogramDIE()) { if (auto DIERangesOrError = getAddressRanges()) - Ranges.insert(Ranges.end(), DIERangesOrError.get().begin(), - DIERangesOrError.get().end()); + llvm::append_range(Ranges, DIERangesOrError.get()); else llvm::consumeError(DIERangesOrError.takeError()); } @@ -558,6 +568,17 @@ uint64_t DWARFDie::getDeclLine() const { return toUnsigned(findRecursively(DW_AT_decl_line), 0); } +std::string +DWARFDie::getDeclFile(DILineInfoSpecifier::FileLineInfoKind Kind) const { + std::string FileName; + if (auto DeclFile = toUnsigned(findRecursively(DW_AT_decl_file))) { + if (const auto *LT = U->getContext().getLineTableForUnit(U)) { + LT->getFileNameByIndex(*DeclFile, U->getCompilationDir(), Kind, FileName); + } + } + return FileName; +} + void DWARFDie::getCallerFrame(uint32_t &CallFile, uint32_t &CallLine, uint32_t &CallColumn, uint32_t &CallDiscriminator) const { diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp index de5e11e084f4..811716111be5 100644 --- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp +++ b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp @@ -204,11 +204,15 @@ bool DWARFExpression::Operation::extract(DataExtractor Data, } static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS, - uint64_t Operands[2], unsigned Operand) { + DIDumpOptions DumpOpts, uint64_t Operands[2], + unsigned Operand) { assert(Operand < 2 && "operand out of bounds"); auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]); if (Die && Die.getTag() == dwarf::DW_TAG_base_type) { - OS << format(" (0x%08" PRIx64 ")", U->getOffset() + Operands[Operand]); + OS << " ("; + if (DumpOpts.Verbose) + OS << format("0x%08" PRIx64 " -> ", Operands[Operand]); + OS << format("0x%08" PRIx64 ")", U->getOffset() + Operands[Operand]); if (auto Name = Die.find(dwarf::DW_AT_name)) OS << " \"" << Name->getAsCString() << "\""; } else { @@ -217,7 +221,8 @@ static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS, } } -static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, uint8_t Opcode, +static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, + DIDumpOptions DumpOpts, uint8_t Opcode, uint64_t Operands[2], const MCRegisterInfo *MRI, bool isEH) { if (!MRI) @@ -243,7 +248,7 @@ static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, uint8_t Opcode, OS << ' ' << RegName; if (Opcode == DW_OP_regval_type) - prettyPrintBaseTypeRef(U, OS, Operands, 1); + prettyPrintBaseTypeRef(U, OS, DumpOpts, Operands, 1); return true; } } @@ -251,11 +256,10 @@ static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, uint8_t Opcode, return false; } -bool DWARFExpression::Operation::print(raw_ostream &OS, +bool DWARFExpression::Operation::print(raw_ostream &OS, DIDumpOptions DumpOpts, const DWARFExpression *Expr, const MCRegisterInfo *RegInfo, - DWARFUnit *U, - bool isEH) { + DWARFUnit *U, bool isEH) { if (Error) { OS << "<decoding error>"; return false; @@ -269,7 +273,7 @@ bool DWARFExpression::Operation::print(raw_ostream &OS, (Opcode >= DW_OP_reg0 && Opcode <= DW_OP_reg31) || Opcode == DW_OP_bregx || Opcode == DW_OP_regx || Opcode == DW_OP_regval_type) - if (prettyPrintRegisterOp(U, OS, Opcode, Operands, RegInfo, isEH)) + if (prettyPrintRegisterOp(U, OS, DumpOpts, Opcode, Operands, RegInfo, isEH)) return true; for (unsigned Operand = 0; Operand < 2; ++Operand) { @@ -286,7 +290,7 @@ bool DWARFExpression::Operation::print(raw_ostream &OS, if (Opcode == DW_OP_convert && Operands[Operand] == 0) OS << " 0x0"; else - prettyPrintBaseTypeRef(U, OS, Operands, Operand); + prettyPrintBaseTypeRef(U, OS, DumpOpts, Operands, Operand); } else if (Size == Operation::WasmLocationArg) { assert(Operand == 1); switch (Operands[0]) { @@ -311,11 +315,12 @@ bool DWARFExpression::Operation::print(raw_ostream &OS, return true; } -void DWARFExpression::print(raw_ostream &OS, const MCRegisterInfo *RegInfo, - DWARFUnit *U, bool IsEH) const { +void DWARFExpression::print(raw_ostream &OS, DIDumpOptions DumpOpts, + const MCRegisterInfo *RegInfo, DWARFUnit *U, + bool IsEH) const { uint32_t EntryValExprSize = 0; for (auto &Op : *this) { - if (!Op.print(OS, this, RegInfo, U, IsEH)) { + if (!Op.print(OS, DumpOpts, this, RegInfo, U, IsEH)) { uint64_t FailOffset = Op.getEndOffset(); while (FailOffset < Data.getData().size()) OS << format(" %02x", Data.getU8(&FailOffset)); diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp index a7da5acc380b..7a84605211fb 100644 --- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp +++ b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp @@ -358,10 +358,16 @@ bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data, return !errorToBool(std::move(Err)); } +void DWARFFormValue::dumpAddress(raw_ostream &OS, uint8_t AddressSize, + uint64_t Address) { + uint8_t HexDigits = AddressSize * 2; + OS << format("0x%*.*" PRIx64, HexDigits, HexDigits, Address); +} + void DWARFFormValue::dumpSectionedAddress(raw_ostream &OS, DIDumpOptions DumpOpts, object::SectionedAddress SA) const { - OS << format("0x%016" PRIx64, SA.Address); + dumpAddress(OS, U->getAddressByteSize(), SA.Address); dumpAddressSection(U->getContext().getDWARFObj(), OS, DumpOpts, SA.SectionIndex); } diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp index 252b58e5a591..ace7000f07b2 100644 --- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp +++ b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp @@ -71,8 +71,8 @@ void DWARFGdbIndex::dumpSymbolTable(raw_ostream &OS) const { StringRef Name = ConstantPoolStrings.substr( ConstantPoolOffset - StringPoolOffset + E.NameOffset); - auto CuVector = std::find_if( - ConstantPoolVectors.begin(), ConstantPoolVectors.end(), + auto CuVector = llvm::find_if( + ConstantPoolVectors, [&](const std::pair<uint32_t, SmallVector<uint32_t, 0>> &V) { return V.first == E.VecOffset; }); diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp index 2124a49bef60..c876af1e9b51 100644 --- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp +++ b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp @@ -71,12 +71,12 @@ Error DWARFListTableHeader::extract(DWARFDataExtractor Data, ") than there is space for", SectionName.data(), HeaderOffset, HeaderData.OffsetEntryCount); Data.setAddressSize(HeaderData.AddrSize); - for (uint32_t I = 0; I < HeaderData.OffsetEntryCount; ++I) - Offsets.push_back(Data.getRelocatedValue(OffsetByteSize, OffsetPtr)); + *OffsetPtr += HeaderData.OffsetEntryCount * OffsetByteSize; return Error::success(); } -void DWARFListTableHeader::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const { +void DWARFListTableHeader::dump(DataExtractor Data, raw_ostream &OS, + DIDumpOptions DumpOpts) const { if (DumpOpts.Verbose) OS << format("0x%8.8" PRIx64 ": ", HeaderOffset); int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format); @@ -91,7 +91,8 @@ void DWARFListTableHeader::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const { if (HeaderData.OffsetEntryCount > 0) { OS << "offsets: ["; - for (const auto &Off : Offsets) { + for (uint32_t I = 0; I < HeaderData.OffsetEntryCount; ++I) { + auto Off = *getOffsetEntry(Data, I); OS << format("\n0x%0*" PRIx64, OffsetDumpWidth, Off); if (DumpOpts.Verbose) OS << format(" => 0x%08" PRIx64, diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp index c219f34bbc31..a301b65dd444 100644 --- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp +++ b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp @@ -36,9 +36,10 @@ void DWARFTypeUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) { << ", version = " << format("0x%04x", getVersion()); if (getVersion() >= 5) OS << ", unit_type = " << dwarf::UnitTypeString(getUnitType()); - OS << ", abbr_offset = " - << format("0x%04" PRIx64, getAbbreviations()->getOffset()) - << ", addr_size = " << format("0x%02x", getAddressByteSize()) + OS << ", abbr_offset = " << format("0x%04" PRIx64, getAbbrOffset()); + if (!getAbbreviations()) + OS << " (invalid)"; + OS << ", addr_size = " << format("0x%02x", getAddressByteSize()) << ", name = '" << Name << "'" << ", type_signature = " << format("0x%016" PRIx64, getTypeHash()) << ", type_offset = " << format("0x%04" PRIx64, getTypeOffset()) diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp index a6d44f04e468..8493950a29b2 100644 --- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -181,31 +181,6 @@ DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section, StringOffsetSection(SOS), AddrOffsetSection(AOS), isLittleEndian(LE), IsDWO(IsDWO), UnitVector(UnitVector) { clear(); - if (IsDWO) { - // If we are reading a package file, we need to adjust the location list - // data based on the index entries. - StringRef Data = Header.getVersion() >= 5 - ? Context.getDWARFObj().getLoclistsDWOSection().Data - : LocSection->Data; - if (auto *IndexEntry = Header.getIndexEntry()) - if (const auto *C = IndexEntry->getContribution( - Header.getVersion() >= 5 ? DW_SECT_LOCLISTS : DW_SECT_EXT_LOC)) - Data = Data.substr(C->Offset, C->Length); - - DWARFDataExtractor DWARFData(Data, isLittleEndian, getAddressByteSize()); - LocTable = - std::make_unique<DWARFDebugLoclists>(DWARFData, Header.getVersion()); - } else if (Header.getVersion() >= 5) { - LocTable = std::make_unique<DWARFDebugLoclists>( - DWARFDataExtractor(Context.getDWARFObj(), - Context.getDWARFObj().getLoclistsSection(), - isLittleEndian, getAddressByteSize()), - Header.getVersion()); - } else { - LocTable = std::make_unique<DWARFDebugLoc>( - DWARFDataExtractor(Context.getDWARFObj(), *LocSection, isLittleEndian, - getAddressByteSize())); - } } DWARFUnit::~DWARFUnit() = default; @@ -219,13 +194,12 @@ Optional<object::SectionedAddress> DWARFUnit::getAddrOffsetSectionItem(uint32_t Index) const { if (IsDWO) { auto R = Context.info_section_units(); - auto I = R.begin(); // Surprising if a DWO file has more than one skeleton unit in it - this // probably shouldn't be valid, but if a use case is found, here's where to // support it (probably have to linearly search for the matching skeleton CU // here) - if (I != R.end() && std::next(I) == R.end()) - return (*I)->getAddrOffsetSectionItem(Index); + if (hasSingleElement(R)) + return (*R.begin())->getAddrOffsetSectionItem(Index); } if (!AddrOffsetSectionBase) return None; @@ -492,8 +466,8 @@ Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) { // describe address ranges. if (getVersion() >= 5) { // In case of DWP, the base offset from the index has to be added. - uint64_t ContributionBaseOffset = 0; if (IsDWO) { + uint64_t ContributionBaseOffset = 0; if (auto *IndexEntry = Header.getIndexEntry()) if (auto *Contrib = IndexEntry->getContribution(DW_SECT_RNGLISTS)) ContributionBaseOffset = Contrib->Offset; @@ -503,67 +477,36 @@ Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) { DWARFListTableHeader::getHeaderSize(Header.getFormat())); } else setRangesSection(&Context.getDWARFObj().getRnglistsSection(), - toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0)); - if (RangeSection->Data.size()) { - // Parse the range list table header. Individual range lists are - // extracted lazily. - DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection, - isLittleEndian, 0); - auto TableOrError = parseListTableHeader<DWARFDebugRnglistTable>( - RangesDA, RangeSectionBase, Header.getFormat()); - if (!TableOrError) - return createStringError(errc::invalid_argument, - "parsing a range list table: " + - toString(TableOrError.takeError())); - - RngListTable = TableOrError.get(); - - // In a split dwarf unit, there is no DW_AT_rnglists_base attribute. - // Adjust RangeSectionBase to point past the table header. - if (IsDWO && RngListTable) - RangeSectionBase = - ContributionBaseOffset + RngListTable->getHeaderSize(); - } + toSectionOffset(UnitDie.find(DW_AT_rnglists_base), + DWARFListTableHeader::getHeaderSize( + Header.getFormat()))); + } - // In a split dwarf unit, there is no DW_AT_loclists_base attribute. - // Setting LocSectionBase to point past the table header. - if (IsDWO) { - auto &DWOSection = Context.getDWARFObj().getLoclistsDWOSection(); - if (DWOSection.Data.empty()) - return Error::success(); - setLocSection(&DWOSection, - DWARFListTableHeader::getHeaderSize(Header.getFormat())); - } else if (auto X = UnitDie.find(DW_AT_loclists_base)) { - setLocSection(&Context.getDWARFObj().getLoclistsSection(), - toSectionOffset(X, 0)); - } else { - return Error::success(); - } + if (IsDWO) { + // If we are reading a package file, we need to adjust the location list + // data based on the index entries. + StringRef Data = Header.getVersion() >= 5 + ? Context.getDWARFObj().getLoclistsDWOSection().Data + : Context.getDWARFObj().getLocDWOSection().Data; + if (auto *IndexEntry = Header.getIndexEntry()) + if (const auto *C = IndexEntry->getContribution( + Header.getVersion() >= 5 ? DW_SECT_LOCLISTS : DW_SECT_EXT_LOC)) + Data = Data.substr(C->Offset, C->Length); - if (LocSection) { - if (IsDWO) - LoclistTableHeader.emplace(".debug_loclists.dwo", "locations"); - else - LoclistTableHeader.emplace(".debug_loclists", "locations"); - - uint64_t HeaderSize = DWARFListTableHeader::getHeaderSize(Header.getFormat()); - uint64_t Offset = getLocSectionBase(); - DWARFDataExtractor Data(Context.getDWARFObj(), *LocSection, - isLittleEndian, getAddressByteSize()); - if (Offset < HeaderSize) - return createStringError(errc::invalid_argument, - "did not detect a valid" - " list table with base = 0x%" PRIx64 "\n", - Offset); - Offset -= HeaderSize; - if (auto *IndexEntry = Header.getIndexEntry()) - if (const auto *Contrib = IndexEntry->getContribution(DW_SECT_LOCLISTS)) - Offset += Contrib->Offset; - if (Error E = LoclistTableHeader->extract(Data, &Offset)) - return createStringError(errc::invalid_argument, - "parsing a loclist table: " + - toString(std::move(E))); - } + DWARFDataExtractor DWARFData(Data, isLittleEndian, getAddressByteSize()); + LocTable = + std::make_unique<DWARFDebugLoclists>(DWARFData, Header.getVersion()); + LocSectionBase = DWARFListTableHeader::getHeaderSize(Header.getFormat()); + } else if (getVersion() >= 5) { + LocTable = std::make_unique<DWARFDebugLoclists>( + DWARFDataExtractor(Context.getDWARFObj(), + Context.getDWARFObj().getLoclistsSection(), + isLittleEndian, getAddressByteSize()), + getVersion()); + } else { + LocTable = std::make_unique<DWARFDebugLoc>(DWARFDataExtractor( + Context.getDWARFObj(), Context.getDWARFObj().getLocSection(), + isLittleEndian, getAddressByteSize())); } // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for @@ -606,19 +549,8 @@ bool DWARFUnit::parseDWO() { if (AddrOffsetSectionBase) DWO->setAddrOffsetSection(AddrOffsetSection, *AddrOffsetSectionBase); if (getVersion() >= 5) { - DWO->setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(), 0); - DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection, - isLittleEndian, 0); - if (auto TableOrError = parseListTableHeader<DWARFDebugRnglistTable>( - RangesDA, RangeSectionBase, Header.getFormat())) - DWO->RngListTable = TableOrError.get(); - else - Context.getRecoverableErrorHandler()(createStringError( - errc::invalid_argument, "parsing a range list table: %s", - toString(TableOrError.takeError()).c_str())); - - if (DWO->RngListTable) - DWO->RangeSectionBase = DWO->RngListTable->getHeaderSize(); + DWO->setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(), + DWARFListTableHeader::getHeaderSize(getFormat())); } else { auto DWORangesBase = UnitDie.getRangesBaseAttribute(); DWO->setRangesSection(RangeSection, DWORangesBase ? *DWORangesBase : 0); @@ -642,17 +574,13 @@ DWARFUnit::findRnglistFromOffset(uint64_t Offset) { return std::move(E); return RangeList.getAbsoluteRanges(getBaseAddress()); } - if (RngListTable) { - DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection, - isLittleEndian, RngListTable->getAddrSize()); - auto RangeListOrError = RngListTable->findList(RangesData, Offset); - if (RangeListOrError) - return RangeListOrError.get().getAbsoluteRanges(getBaseAddress(), *this); - return RangeListOrError.takeError(); - } - - return createStringError(errc::invalid_argument, - "missing or invalid range list table"); + DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection, + isLittleEndian, Header.getAddressByteSize()); + DWARFDebugRnglistTable RnglistTable; + auto RangeListOrError = RnglistTable.findList(RangesData, Offset); + if (RangeListOrError) + return RangeListOrError.get().getAbsoluteRanges(getBaseAddress(), *this); + return RangeListOrError.takeError(); } Expected<DWARFAddressRangesVector> @@ -660,12 +588,10 @@ DWARFUnit::findRnglistFromIndex(uint32_t Index) { if (auto Offset = getRnglistOffset(Index)) return findRnglistFromOffset(*Offset); - if (RngListTable) - return createStringError(errc::invalid_argument, - "invalid range list table index %d", Index); - return createStringError(errc::invalid_argument, - "missing or invalid range list table"); + "invalid range list table index %d (possibly " + "missing the entire range list table)", + Index); } Expected<DWARFAddressRangesVector> DWARFUnit::collectAddressRanges() { @@ -995,11 +921,35 @@ DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor & DA) { // Prior to DWARF v5, we derive the contribution size from the // index table (in a package file). In a .dwo file it is simply // the length of the string offsets section. - if (!IndexEntry) - return {Optional<StrOffsetsContributionDescriptor>( - {0, StringOffsetSection.Data.size(), 4, Header.getFormat()})}; + StrOffsetsContributionDescriptor Desc; if (C) - return {Optional<StrOffsetsContributionDescriptor>( - {C->Offset, C->Length, 4, Header.getFormat()})}; + Desc = StrOffsetsContributionDescriptor(C->Offset, C->Length, 4, + Header.getFormat()); + else if (!IndexEntry && !StringOffsetSection.Data.empty()) + Desc = StrOffsetsContributionDescriptor(0, StringOffsetSection.Data.size(), + 4, Header.getFormat()); + else + return None; + auto DescOrError = Desc.validateContributionSize(DA); + if (!DescOrError) + return DescOrError.takeError(); + return *DescOrError; +} + +Optional<uint64_t> DWARFUnit::getRnglistOffset(uint32_t Index) { + DataExtractor RangesData(RangeSection->Data, isLittleEndian, + getAddressByteSize()); + DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection, + isLittleEndian, 0); + if (Optional<uint64_t> Off = llvm::DWARFListTableHeader::getOffsetEntry( + RangesData, RangeSectionBase, getFormat(), Index)) + return *Off + RangeSectionBase; + return None; +} + +Optional<uint64_t> DWARFUnit::getLoclistOffset(uint32_t Index) { + if (Optional<uint64_t> Off = llvm::DWARFListTableHeader::getOffsetEntry( + LocTable->getData(), LocSectionBase, getFormat(), Index)) + return *Off + LocSectionBase; return None; } diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp index 3a83317a73a3..ac624ec8b80f 100644 --- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp +++ b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp @@ -172,6 +172,15 @@ unsigned DWARFVerifier::verifyUnitContents(DWARFUnit &Unit) { NumUnitErrors += verifyDebugInfoForm(Die, AttrValue); } + if (Die.hasChildren()) { + if (Die.getFirstChild().isValid() && + Die.getFirstChild().getTag() == DW_TAG_null) { + warn() << dwarf::TagString(Die.getTag()) + << " has DW_CHILDREN_yes but DIE has no children: "; + Die.dump(OS); + } + } + NumUnitErrors += verifyDebugInfoCallSite(Die); } @@ -538,6 +547,39 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die, } break; } + case DW_AT_call_file: + case DW_AT_decl_file: { + if (auto FileIdx = AttrValue.Value.getAsUnsignedConstant()) { + DWARFUnit *U = Die.getDwarfUnit(); + const auto *LT = U->getContext().getLineTableForUnit(U); + if (LT) { + if (!LT->hasFileAtIndex(*FileIdx)) { + bool IsZeroIndexed = LT->Prologue.getVersion() >= 5; + if (Optional<uint64_t> LastFileIdx = LT->getLastValidFileIndex()) { + ReportError("DIE has " + AttributeString(Attr) + + " with an invalid file index " + + llvm::formatv("{0}", *FileIdx) + + " (valid values are [" + (IsZeroIndexed ? "0-" : "1-") + + llvm::formatv("{0}", *LastFileIdx) + "])"); + } else { + ReportError("DIE has " + AttributeString(Attr) + + " with an invalid file index " + + llvm::formatv("{0}", *FileIdx) + + " (the file table in the prologue is empty)"); + } + } + } else { + ReportError("DIE has " + AttributeString(Attr) + + " that references a file with index " + + llvm::formatv("{0}", *FileIdx) + + " and the compile unit has no line table"); + } + } else { + ReportError("DIE has " + AttributeString(Attr) + + " with invalid encoding"); + } + break; + } default: break; } |