summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorPavel Labath <pavel@labath.sk>2019-11-05 14:46:54 +0100
committerPavel Labath <pavel@labath.sk>2019-11-15 13:38:00 +0100
commit0908093977b2b80d00baa12f0b2f1424dde096fb (patch)
treefb4b665cad7f163289f1caa963afeb501a880406 /llvm/lib
parentc953e061b410163bc54771f186176a92aac04008 (diff)
downloadbcm5719-llvm-0908093977b2b80d00baa12f0b2f1424dde096fb.tar.gz
bcm5719-llvm-0908093977b2b80d00baa12f0b2f1424dde096fb.zip
DWARFDebugLoc(v4): Add an incremental parsing function
Summary: This adds a visitLocationList function to the DWARF v4 location lists, similar to what already exists for DWARF v5. It follows the approach outlined in previous patches (D69672), where the parsed form is always stored in the DWARF v5 format, which makes it easier for generic code to be built on top of that. v4 location lists are "upgraded" during parsing, and then this upgrade is undone while dumping. Both "inline" and section-based dumping is rewritten to reuse the existing "generic" location list dumper. This means that the output format is consistent for all location lists (the only thing one needs to implement is the function which prints the "raw" form of a location list), and that debug_loc dumping correctly processes base address selection entries, etc. The previous existing debug_loc functionality (e.g., parseOneLocationList) is rewritten on top of the new API, but it is not removed as there is still code which uses them. This will be done in follow-up patches, after I build the API to access the "interpreted" location lists in a generic way (as that is what those users really want). Reviewers: dblaikie, probinson, JDevlieghere, aprantl, SouraVX Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D69847
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFContext.cpp13
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp149
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDie.cpp29
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp10
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp2
5 files changed, 99 insertions, 104 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index 5a1668442fc..3fad575ff40 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -734,13 +734,14 @@ const DWARFDebugLoc *DWARFContext::getDebugLoc() {
if (Loc)
return Loc.get();
- Loc.reset(new DWARFDebugLoc);
// Assume all units have the same address byte size.
- if (getNumCompileUnits()) {
- DWARFDataExtractor LocData(*DObj, DObj->getLocSection(), isLittleEndian(),
- getUnitAtIndex(0)->getAddressByteSize());
- Loc->parse(LocData);
- }
+ auto LocData =
+ getNumCompileUnits()
+ ? DWARFDataExtractor(*DObj, DObj->getLocSection(), isLittleEndian(),
+ getUnitAtIndex(0)->getAddressByteSize())
+ : DWARFDataExtractor("", isLittleEndian(), 0);
+ Loc.reset(new DWARFDebugLoc(std::move(LocData)));
+ Loc->parse();
return Loc.get();
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
index f84de263a78..218bf381567 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
@@ -145,25 +145,6 @@ bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS,
return true;
}
-void DWARFDebugLoc::LocationList::dump(raw_ostream &OS, uint64_t BaseAddress,
- bool IsLittleEndian,
- unsigned AddressSize,
- const MCRegisterInfo *MRI, DWARFUnit *U,
- DIDumpOptions DumpOpts,
- unsigned Indent) const {
- for (const Entry &E : Entries) {
- OS << '\n';
- OS.indent(Indent);
- OS << format("[0x%*.*" PRIx64 ", ", AddressSize * 2, AddressSize * 2,
- BaseAddress + E.Begin);
- OS << format(" 0x%*.*" PRIx64 ")", AddressSize * 2, AddressSize * 2,
- BaseAddress + E.End);
- OS << ": ";
-
- dumpExpression(OS, E.Loc, IsLittleEndian, AddressSize, MRI, U);
- }
-}
-
DWARFDebugLoc::LocationList const *
DWARFDebugLoc::getLocationListAtOffset(uint64_t Offset) const {
auto It = partition_point(
@@ -173,74 +154,84 @@ DWARFDebugLoc::getLocationListAtOffset(uint64_t Offset) const {
return nullptr;
}
-void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI, DIDumpOptions DumpOpts,
- Optional<uint64_t> Offset) const {
- auto DumpLocationList = [&](const LocationList &L) {
- OS << format("0x%8.8" PRIx64 ": ", L.Offset);
- L.dump(OS, 0, IsLittleEndian, AddressSize, MRI, nullptr, DumpOpts, 12);
- OS << "\n";
- };
-
- if (Offset) {
- if (auto *L = getLocationListAtOffset(*Offset))
- DumpLocationList(*L);
- return;
- }
-
- for (const LocationList &L : Locations) {
- DumpLocationList(L);
- if (&L != &Locations.back())
+void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
+ DIDumpOptions DumpOpts,
+ Optional<uint64_t> DumpOffset) const {
+ auto BaseAddr = None;
+ unsigned Indent = 12;
+ if (DumpOffset) {
+ dumpLocationList(&*DumpOffset, OS, BaseAddr, MRI, nullptr, DumpOpts,
+ Indent);
+ } else {
+ uint64_t Offset = 0;
+ StringRef Separator;
+ bool CanContinue = true;
+ while (CanContinue && Data.isValidOffset(Offset)) {
+ OS << Separator;
+ Separator = "\n";
+
+ CanContinue = dumpLocationList(&Offset, OS, BaseAddr, MRI, nullptr,
+ DumpOpts, Indent);
OS << '\n';
+ }
}
}
-Expected<DWARFDebugLoc::LocationList>
-DWARFDebugLoc::parseOneLocationList(const DWARFDataExtractor &Data,
- uint64_t *Offset) {
- LocationList LL;
- LL.Offset = *Offset;
- AddressSize = Data.getAddressSize();
+Error DWARFDebugLoc::visitLocationList(
+ uint64_t *Offset,
+ function_ref<bool(const DWARFLocationEntry &)> Callback) const {
DataExtractor::Cursor C(*Offset);
-
- // 2.6.2 Location Lists
- // A location list entry consists of:
while (true) {
- Entry E;
-
- // 1. A beginning address offset. ...
- E.Begin = Data.getRelocatedAddress(C);
-
- // 2. An ending address offset. ...
- E.End = Data.getRelocatedAddress(C);
+ uint64_t Value0 = Data.getRelocatedAddress(C);
+ uint64_t Value1 = Data.getRelocatedAddress(C);
- if (Error Err = C.takeError())
- return std::move(Err);
+ DWARFLocationEntry E;
// The end of any given location list is marked by an end of list entry,
// which consists of a 0 for the beginning address offset and a 0 for the
- // ending address offset.
- if (E.Begin == 0 && E.End == 0) {
- *Offset = C.tell();
- return LL;
- }
-
- if (E.Begin != (AddressSize == 4 ? -1U : -1ULL)) {
+ // ending address offset. A beginning offset of 0xff...f marks the base
+ // address selection entry.
+ if (Value0 == 0 && Value1 == 0) {
+ E.Kind = dwarf::DW_LLE_end_of_list;
+ } else if (Value0 == (Data.getAddressSize() == 4 ? -1U : -1ULL)) {
+ E.Kind = dwarf::DW_LLE_base_address;
+ E.Value0 = Value1;
+ } else {
+ E.Kind = dwarf::DW_LLE_offset_pair;
+ E.Value0 = Value0;
+ E.Value1 = Value1;
unsigned Bytes = Data.getU16(C);
// A single location description describing the location of the object...
Data.getU8(C, E.Loc, Bytes);
}
- LL.Entries.push_back(std::move(E));
+ if (!C)
+ return C.takeError();
+ if (!Callback(E) || E.Kind == dwarf::DW_LLE_end_of_list)
+ break;
}
+ *Offset = C.tell();
+ return Error::success();
}
-void DWARFDebugLoc::parse(const DWARFDataExtractor &data) {
- IsLittleEndian = data.isLittleEndian();
- AddressSize = data.getAddressSize();
+Expected<DWARFDebugLoc::LocationList>
+DWARFDebugLoc::parseOneLocationList(uint64_t *Offset) {
+ LocationList LL;
+ LL.Offset = *Offset;
+
+ Error E = visitLocationList(Offset, [&](const DWARFLocationEntry &E) {
+ LL.Entries.push_back(E);
+ return true;
+ });
+ if (E)
+ return std::move(E);
+ return std::move(LL);
+}
+void DWARFDebugLoc::parse() {
uint64_t Offset = 0;
- while (Offset < data.getData().size()) {
- if (auto LL = parseOneLocationList(data, &Offset))
+ while (Offset < Data.getData().size()) {
+ if (auto LL = parseOneLocationList(&Offset))
Locations.push_back(std::move(*LL));
else {
logAllUnhandledErrors(LL.takeError(), WithColor::error());
@@ -249,6 +240,30 @@ void DWARFDebugLoc::parse(const DWARFDataExtractor &data) {
}
}
+void DWARFDebugLoc::dumpRawEntry(const DWARFLocationEntry &Entry,
+ raw_ostream &OS, unsigned Indent) const {
+ uint64_t Value0, Value1;
+ switch (Entry.Kind) {
+ case dwarf::DW_LLE_base_address:
+ Value0 = Data.getAddressSize() == 4 ? -1U : -1ULL;
+ Value1 = Entry.Value0;
+ break;
+ case dwarf::DW_LLE_offset_pair:
+ Value0 = Entry.Value0;
+ Value1 = Entry.Value1;
+ break;
+ case dwarf::DW_LLE_end_of_list:
+ Value0 = Value1 = 0;
+ return;
+ default:
+ llvm_unreachable("Not possible in DWARF4!");
+ }
+ OS << '\n';
+ OS.indent(Indent);
+ OS << '(' << format_hex(Value0, 2 + Data.getAddressSize() * 2) << ", "
+ << format_hex(Value1, 2 + Data.getAddressSize() * 2) << ')';
+}
+
Error DWARFDebugLoclists::visitLocationList(
uint64_t *Offset, function_ref<bool(const DWARFLocationEntry &)> F) const {
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index abe63f2716a..49a7f7dc2a5 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -79,7 +79,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)) {
@@ -97,32 +96,8 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue,
uint64_t Offset = *FormValue.getAsSectionOffset();
- if (const DWARFLocationTable *LT = U->getLocationTable()) {
- LT->dumpLocationList(&Offset, OS, U->getBaseAddress(), MRI, U, LLDumpOpts,
- Indent);
- return;
- }
-
- DWARFDebugLoc DebugLoc;
- DWARFDataExtractor Data(Obj, *U->getLocSection(), Ctx.isLittleEndian(),
- Obj.getAddressSize());
-
- FormValue.dump(OS, DumpOpts);
- OS << ": ";
-
- if (Expected<DWARFDebugLoc::LocationList> LL =
- DebugLoc.parseOneLocationList(Data, &Offset)) {
- uint64_t BaseAddr = 0;
- if (Optional<object::SectionedAddress> BA = U->getBaseAddress())
- BaseAddr = BA->Address;
- LL->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(LL.takeError()));
- }
+ U->getLocationTable().dumpLocationList(&Offset, OS, U->getBaseAddress(),
+ MRI, U, LLDumpOpts, Indent);
return;
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index 81c7959f646..7f0ee660cd0 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -175,9 +175,9 @@ DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
const DWARFSection *AOS, const DWARFSection &LS, bool LE,
bool IsDWO, const DWARFUnitVector &UnitVector)
: Context(DC), InfoSection(Section), Header(Header), Abbrev(DA),
- RangeSection(RS), LocSection(LocSection), LineSection(LS),
- StringSection(SS), StringOffsetSection(SOS), AddrOffsetSection(AOS),
- isLittleEndian(LE), IsDWO(IsDWO), UnitVector(UnitVector) {
+ RangeSection(RS), LineSection(LS), StringSection(SS),
+ 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
@@ -195,6 +195,10 @@ DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
Context.getDWARFObj().getLoclistsSection(),
isLittleEndian, getAddressByteSize()),
Header.getVersion());
+ } else {
+ LocTable = std::make_unique<DWARFDebugLoc>(
+ DWARFDataExtractor(Context.getDWARFObj(), *LocSection, isLittleEndian,
+ getAddressByteSize()));
}
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index bf499b6ee09..357cdb299a2 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -1302,7 +1302,7 @@ static bool isVariableIndexable(const DWARFDie &Die, DWARFContext &DCtx) {
if (const DWARFDebugLoc *DebugLoc = DCtx.getDebugLoc()) {
if (const DWARFDebugLoc::LocationList *LocList =
DebugLoc->getLocationListAtOffset(*Offset)) {
- if (any_of(LocList->Entries, [&](const DWARFDebugLoc::Entry &E) {
+ if (any_of(LocList->Entries, [&](const DWARFLocationEntry &E) {
return ContainsInterestingOperators(E.Loc);
}))
return true;
OpenPOWER on IntegriCloud