diff options
Diffstat (limited to 'llvm/lib/DebugInfo/DWARF/DWARFDie.cpp')
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDie.cpp | 96 |
1 files changed, 50 insertions, 46 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp index cec194e8b6b3..c1dc3b68c6ab 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp @@ -62,16 +62,10 @@ static void dumpRanges(const DWARFObject &Obj, raw_ostream &OS, if (!DumpOpts.ShowAddresses) return; - ArrayRef<SectionName> SectionNames; - if (DumpOpts.Verbose) - SectionNames = Obj.getSectionNames(); - for (const DWARFAddressRange &R : Ranges) { OS << '\n'; OS.indent(Indent); - R.dump(OS, AddressSize); - - DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, R.SectionIndex); + R.dump(OS, AddressSize, DumpOpts, &Obj); } } @@ -79,7 +73,6 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue, DWARFUnit *U, unsigned Indent, DIDumpOptions DumpOpts) { DWARFContext &Ctx = U->getContext(); - const DWARFObject &Obj = Ctx.getDWARFObj(); const MCRegisterInfo *MRI = Ctx.getRegisterInfo(); if (FormValue.isFormClass(DWARFFormValue::FC_Block) || FormValue.isFormClass(DWARFFormValue::FC_Exprloc)) { @@ -91,49 +84,24 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue, return; } - FormValue.dump(OS, DumpOpts); - const auto &DumpLL = [&](auto ExpectedLL) { - if (ExpectedLL) { - uint64_t BaseAddr = 0; - if (Optional<object::SectionedAddress> BA = U->getBaseAddress()) - BaseAddr = BA->Address; - auto LLDumpOpts = DumpOpts; - LLDumpOpts.Verbose = false; - ExpectedLL->dump(OS, BaseAddr, Ctx.isLittleEndian(), Obj.getAddressSize(), - MRI, U, LLDumpOpts, Indent); - } else { - OS << '\n'; - OS.indent(Indent); - OS << formatv("error extracting location list: {0}", - fmt_consume(ExpectedLL.takeError())); - } - }; if (FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) { uint64_t Offset = *FormValue.getAsSectionOffset(); - if (!U->isDWOUnit() && !U->getLocSection()->Data.empty()) { - DWARFDebugLoc DebugLoc; - DWARFDataExtractor Data(Obj, *U->getLocSection(), Ctx.isLittleEndian(), - Obj.getAddressSize()); - DumpLL(DebugLoc.parseOneLocationList(Data, &Offset)); - return; - } - bool UseLocLists = !U->isDWOUnit(); - StringRef LoclistsSectionData = - UseLocLists ? Obj.getLoclistsSection().Data : U->getLocSectionData(); + if (FormValue.getForm() == DW_FORM_loclistx) { + FormValue.dump(OS, DumpOpts); - if (!LoclistsSectionData.empty()) { - DataExtractor Data(LoclistsSectionData, Ctx.isLittleEndian(), - Obj.getAddressSize()); - - // Old-style location list were used in DWARF v4 (.debug_loc.dwo section). - // Modern locations list (.debug_loclists) are used starting from v5. - // Ideally we should take the version from the .debug_loclists section - // header, but using CU's version for simplicity. - DumpLL(DWARFDebugLoclists::parseOneLocationList( - Data, &Offset, UseLocLists ? U->getVersion() : 4)); + if (auto LoclistOffset = U->getLoclistOffset(Offset)) + Offset = *LoclistOffset; + else + return; } + U->getLocationTable().dumpLocationList(&Offset, OS, U->getBaseAddress(), + MRI, Ctx.getDWARFObj(), U, DumpOpts, + Indent); + return; } + + FormValue.dump(OS, DumpOpts); } /// Dump the name encoded in the type tag. @@ -311,7 +279,8 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die, else FormValue.dump(OS, DumpOpts); } - } else if (DWARFAttribute::mayHaveLocationDescription(Attr)) + } else if (Form == dwarf::Form::DW_FORM_exprloc || + DWARFAttribute::mayHaveLocationDescription(Attr)) dumpLocation(OS, FormValue, U, sizeof(BaseIndent) + Indent + 4, DumpOpts); else FormValue.dump(OS, DumpOpts); @@ -441,6 +410,10 @@ Optional<uint64_t> DWARFDie::getRangesBaseAttribute() const { return toSectionOffset(find({DW_AT_rnglists_base, DW_AT_GNU_ranges_base})); } +Optional<uint64_t> DWARFDie::getLocBaseAttribute() const { + return toSectionOffset(find(DW_AT_loclists_base)); +} + Optional<uint64_t> DWARFDie::getHighPC(uint64_t LowPC) const { if (auto FormValue = find(DW_AT_high_pc)) { if (auto Address = FormValue->getAsAddress()) { @@ -516,6 +489,37 @@ bool DWARFDie::addressRangeContainsAddress(const uint64_t Address) const { return false; } +Expected<DWARFLocationExpressionsVector> +DWARFDie::getLocations(dwarf::Attribute Attr) const { + Optional<DWARFFormValue> Location = find(Attr); + if (!Location) + return createStringError(inconvertibleErrorCode(), "No %s", + dwarf::AttributeString(Attr).data()); + + if (Optional<uint64_t> Off = Location->getAsSectionOffset()) { + uint64_t Offset = *Off; + + if (Location->getForm() == DW_FORM_loclistx) { + if (auto LoclistOffset = U->getLoclistOffset(Offset)) + Offset = *LoclistOffset; + else + return createStringError(inconvertibleErrorCode(), + "Loclist table not found"); + } + return U->findLoclistFromOffset(Offset); + } + + if (Optional<ArrayRef<uint8_t>> Expr = Location->getAsBlock()) { + return DWARFLocationExpressionsVector{ + DWARFLocationExpression{None, to_vector<4>(*Expr)}}; + } + + return createStringError( + inconvertibleErrorCode(), "Unsupported %s encoding: %s", + dwarf::AttributeString(Attr).data(), + dwarf::FormEncodingString(Location->getForm()).data()); +} + const char *DWARFDie::getSubroutineName(DINameKind Kind) const { if (!isSubroutineDIE()) return nullptr; |