summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
diff options
context:
space:
mode:
authorPavel Labath <pavel@labath.sk>2019-10-31 15:05:33 +0100
committerPavel Labath <pavel@labath.sk>2019-11-06 16:25:06 +0100
commite1f8c8a16f441aed3aaa6262f932854b74e4f97c (patch)
tree06856f51bebd8074d5d52be7fb084e0785f0bb58 /llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
parentbde32933027a096b6cfe14b0e9385ac1005fc28a (diff)
downloadbcm5719-llvm-e1f8c8a16f441aed3aaa6262f932854b74e4f97c.tar.gz
bcm5719-llvm-e1f8c8a16f441aed3aaa6262f932854b74e4f97c.zip
DWARFDebugLoclists: Move to a incremental parsing model
Summary: This patch stems from the discussion D68270 (including some offline talks). The idea is to provide an "incremental" api for parsing location lists, which will avoid caching or materializing parsed data. An additional goal is to provide a high level location list api, which abstracts the differences between different encoding schemes, and can be used by users which don't care about those (such as LLDB). This patch implements the first part. It implements a call-back based "visitLocationList" api. This function parses a single location list, calling a user-specified callback for each entry. This is going to be the base api, which other location list functions (right now, just the dumping code) are going to be based on. Future patches will do something similar for the v4 location lists, and add a mechanism to translate raw entries into concrete address ranges. Reviewers: dblaikie, probinson, JDevlieghere, aprantl, SouraVX Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D69672
Diffstat (limited to 'llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp')
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp150
1 files changed, 68 insertions, 82 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
index 032feb9088c..e0faaed035d 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
@@ -139,19 +139,19 @@ void DWARFDebugLoc::parse(const DWARFDataExtractor &data) {
}
}
-Expected<DWARFDebugLoclists::LocationList>
-DWARFDebugLoclists::parseOneLocationList(const DWARFDataExtractor &Data,
- uint64_t *Offset, unsigned Version) {
- LocationList LL;
- LL.Offset = *Offset;
- DataExtractor::Cursor C(*Offset);
+Error DWARFDebugLoclists::visitLocationList(
+ const DWARFDataExtractor &Data, uint64_t *Offset, uint16_t Version,
+ llvm::function_ref<bool(const Entry &)> F) {
- // dwarf::DW_LLE_end_of_list_entry is 0 and indicates the end of the list.
- while (auto Kind = Data.getU8(C)) {
+ DataExtractor::Cursor C(*Offset);
+ bool Continue = true;
+ while (Continue) {
Entry E;
- E.Kind = Kind;
- E.Offset = C.tell() - 1;
- switch (Kind) {
+ E.Offset = C.tell();
+ E.Kind = Data.getU8(C);
+ switch (E.Kind) {
+ case dwarf::DW_LLE_end_of_list:
+ break;
case dwarf::DW_LLE_base_addressx:
E.Value0 = Data.getULEB128(C);
break;
@@ -164,10 +164,6 @@ DWARFDebugLoclists::parseOneLocationList(const DWARFDataExtractor &Data,
else
E.Value1 = Data.getULEB128(C);
break;
- case dwarf::DW_LLE_start_length:
- E.Value0 = Data.getRelocatedAddress(C);
- E.Value1 = Data.getULEB128(C);
- break;
case dwarf::DW_LLE_offset_pair:
E.Value0 = Data.getULEB128(C);
E.Value1 = Data.getULEB128(C);
@@ -175,53 +171,62 @@ DWARFDebugLoclists::parseOneLocationList(const DWARFDataExtractor &Data,
case dwarf::DW_LLE_base_address:
E.Value0 = Data.getRelocatedAddress(C);
break;
+ case dwarf::DW_LLE_start_length:
+ E.Value0 = Data.getRelocatedAddress(C);
+ E.Value1 = Data.getULEB128(C);
+ break;
+ case dwarf::DW_LLE_startx_endx:
+ case dwarf::DW_LLE_default_location:
+ case dwarf::DW_LLE_start_end:
default:
cantFail(C.takeError());
return createStringError(errc::illegal_byte_sequence,
- "LLE of kind %x not supported", (int)Kind);
+ "LLE of kind %x not supported", (int)E.Kind);
}
- if (Kind != dwarf::DW_LLE_base_address &&
- Kind != dwarf::DW_LLE_base_addressx) {
+ if (E.Kind != dwarf::DW_LLE_base_address &&
+ E.Kind != dwarf::DW_LLE_base_addressx &&
+ E.Kind != dwarf::DW_LLE_end_of_list) {
unsigned Bytes = Version >= 5 ? Data.getULEB128(C) : 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();
+ Continue = F(E) && E.Kind != dwarf::DW_LLE_end_of_list;
}
- if (Error Err = C.takeError())
- return std::move(Err);
- Entry E;
- E.Kind = dwarf::DW_LLE_end_of_list;
- E.Offset = C.tell() - 1;
- LL.Entries.push_back(E);
*Offset = C.tell();
- return LL;
+ return Error::success();
}
-void DWARFDebugLoclists::parse(const DWARFDataExtractor &data, uint64_t Offset,
- uint64_t EndOffset, uint16_t Version) {
- IsLittleEndian = data.isLittleEndian();
- AddressSize = data.getAddressSize();
-
- while (Offset < EndOffset) {
- if (auto LL = parseOneLocationList(data, &Offset, Version))
- Locations.push_back(std::move(*LL));
- else {
- logAllUnhandledErrors(LL.takeError(), WithColor::error());
- return;
- }
+bool DWARFDebugLoclists::dumpLocationList(const DWARFDataExtractor &Data,
+ uint64_t *Offset, uint16_t Version,
+ raw_ostream &OS, uint64_t BaseAddr,
+ const MCRegisterInfo *MRI,
+ DWARFUnit *U, DIDumpOptions DumpOpts,
+ unsigned Indent) {
+ size_t MaxEncodingStringLength = 0;
+ if (DumpOpts.Verbose) {
+#define HANDLE_DW_LLE(ID, NAME) \
+ MaxEncodingStringLength = std::max(MaxEncodingStringLength, \
+ dwarf::LocListEncodingString(ID).size());
+#include "llvm/BinaryFormat/Dwarf.def"
}
-}
-DWARFDebugLoclists::LocationList const *
-DWARFDebugLoclists::getLocationListAtOffset(uint64_t Offset) const {
- auto It = partition_point(
- Locations, [=](const LocationList &L) { return L.Offset < Offset; });
- if (It != Locations.end() && It->Offset == Offset)
- return &(*It);
- return nullptr;
+ OS << format("0x%8.8" PRIx64 ": ", *Offset);
+ Error E = visitLocationList(Data, Offset, Version, [&](const Entry &E) {
+ E.dump(OS, BaseAddr, Data.isLittleEndian(), Data.getAddressSize(), MRI, U,
+ DumpOpts, Indent, MaxEncodingStringLength);
+ return true;
+ });
+ if (E) {
+ OS << "\n";
+ OS.indent(Indent);
+ OS << "error: " << toString(std::move(E));
+ return false;
+ }
+ return true;
}
void DWARFDebugLoclists::Entry::dump(raw_ostream &OS, uint64_t &BaseAddr,
@@ -297,44 +302,25 @@ void DWARFDebugLoclists::Entry::dump(raw_ostream &OS, uint64_t &BaseAddr,
dumpExpression(OS, Loc, IsLittleEndian, AddressSize, MRI, U);
}
-void DWARFDebugLoclists::LocationList::dump(raw_ostream &OS, uint64_t BaseAddr,
- bool IsLittleEndian,
- unsigned AddressSize,
- const MCRegisterInfo *MRI,
- DWARFUnit *U,
- DIDumpOptions DumpOpts,
- unsigned Indent) const {
- size_t MaxEncodingStringLength = 0;
- if (DumpOpts.Verbose)
- for (const auto &Entry : Entries)
- MaxEncodingStringLength =
- std::max(MaxEncodingStringLength,
- dwarf::LocListEncodingString(Entry.Kind).size());
-
- for (const Entry &E : Entries)
- E.dump(OS, BaseAddr, IsLittleEndian, AddressSize, MRI, U, DumpOpts, Indent,
- MaxEncodingStringLength);
-}
-
-void DWARFDebugLoclists::dump(raw_ostream &OS, uint64_t BaseAddr,
- 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, BaseAddr, IsLittleEndian, AddressSize, MRI, nullptr, DumpOpts,
- /*Indent=*/12);
- OS << "\n";
- };
- if (Offset) {
- if (auto *L = getLocationListAtOffset(*Offset))
- DumpLocationList(*L);
+void DWARFDebugLoclists::dumpRange(const DWARFDataExtractor &Data,
+ uint64_t StartOffset, uint64_t Size,
+ uint16_t Version, raw_ostream &OS,
+ uint64_t BaseAddr, const MCRegisterInfo *MRI,
+ DIDumpOptions DumpOpts) {
+ if (!Data.isValidOffsetForDataOfSize(StartOffset, Size)) {
+ OS << "Invalid dump range\n";
return;
}
-
- for (const LocationList &L : Locations) {
- DumpLocationList(L);
- if (&L != &Locations.back())
- OS << '\n';
+ uint64_t Offset = StartOffset;
+ StringRef Separator;
+ bool CanContinue = true;
+ while (CanContinue && Offset < StartOffset + Size) {
+ OS << Separator;
+ Separator = "\n";
+
+ CanContinue = dumpLocationList(Data, &Offset, Version, OS, BaseAddr, MRI,
+ nullptr, DumpOpts, /*Indent=*/12);
+ OS << '\n';
}
}
OpenPOWER on IntegriCloud