summaryrefslogtreecommitdiff
path: root/lib/DebugInfo
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2014-03-25 01:44:02 +0000
committerDavid Blaikie <dblaikie@gmail.com>2014-03-25 01:44:02 +0000
commitb13d54f5880b2dafadd89182ee9adaff11fa9cf3 (patch)
tree13bb06196737d105a47493ce7045cf68ff6bfc95 /lib/DebugInfo
parent6cfebbd64d6a4dc80706d8f8eba066d3fb8b1749 (diff)
downloadllvm-b13d54f5880b2dafadd89182ee9adaff11fa9cf3.tar.gz
llvm-b13d54f5880b2dafadd89182ee9adaff11fa9cf3.tar.bz2
llvm-b13d54f5880b2dafadd89182ee9adaff11fa9cf3.tar.xz
DebugInfo: Support debug_loc under fission
Implement debug_loc.dwo, as well as llvm-dwarfdump support for dumping this section. Outlined in the DWARF5 spec and http://gcc.gnu.org/wiki/DebugFission the debug_loc.dwo section has more variation than the standard debug_loc, allowing 3 different forms of entry (plus the end of list entry). GCC seems to, and Clang certainly, only use one form, so I've just implemented dumping support for that for now. It wasn't immediately obvious that there was a good refactoring to share the implementation of dumping support between debug_loc and debug_loc.dwo, so they're separate for now - ideas welcome or I may come back to it at some point. As per a comment in the code, we could choose different forms that may reduce the number of debug_addr entries we emit, but that will require further study. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204697 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/DebugInfo')
-rw-r--r--lib/DebugInfo/DWARFContext.cpp16
-rw-r--r--lib/DebugInfo/DWARFContext.h7
-rw-r--r--lib/DebugInfo/DWARFDebugLoc.cpp52
-rw-r--r--lib/DebugInfo/DWARFDebugLoc.h21
4 files changed, 96 insertions, 0 deletions
diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp
index 0afe6ef6e1..60c5f6ab56 100644
--- a/lib/DebugInfo/DWARFContext.cpp
+++ b/lib/DebugInfo/DWARFContext.cpp
@@ -96,6 +96,11 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
getDebugLoc()->dump(OS);
}
+ if (DumpType == DIDT_All || DumpType == DIDT_LocDwo) {
+ OS << "\n.debug_loc.dwo contents:\n";
+ getDebugLocDWO()->dump(OS);
+ }
+
if (DumpType == DIDT_All || DumpType == DIDT_Frames) {
OS << "\n.debug_frame contents:\n";
getDebugFrame()->dump(OS);
@@ -237,6 +242,16 @@ const DWARFDebugLoc *DWARFContext::getDebugLoc() {
return Loc.get();
}
+const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() {
+ if (LocDWO)
+ return LocDWO.get();
+
+ DataExtractor LocData(getLocDWOSection().Data, isLittleEndian(), 0);
+ LocDWO.reset(new DWARFDebugLocDWO());
+ LocDWO->parse(LocData);
+ return LocDWO.get();
+}
+
const DWARFDebugAranges *DWARFContext::getDebugAranges() {
if (Aranges)
return Aranges.get();
@@ -648,6 +663,7 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj)
.Case("debug_gnu_pubtypes", &GnuPubTypesSection)
.Case("debug_info.dwo", &InfoDWOSection.Data)
.Case("debug_abbrev.dwo", &AbbrevDWOSection)
+ .Case("debug_loc.dwo", &LocDWOSection.Data)
.Case("debug_line.dwo", &LineDWOSection.Data)
.Case("debug_str.dwo", &StringDWOSection)
.Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
diff --git a/lib/DebugInfo/DWARFContext.h b/lib/DebugInfo/DWARFContext.h
index a3bae79273..ad6841ae9e 100644
--- a/lib/DebugInfo/DWARFContext.h
+++ b/lib/DebugInfo/DWARFContext.h
@@ -42,6 +42,7 @@ class DWARFContext : public DIContext {
CUVector DWOCUs;
TUVector DWOTUs;
std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
+ std::unique_ptr<DWARFDebugLocDWO> LocDWO;
DWARFContext(DWARFContext &) LLVM_DELETED_FUNCTION;
DWARFContext &operator=(DWARFContext &) LLVM_DELETED_FUNCTION;
@@ -148,6 +149,9 @@ public:
/// Get a pointer to the parsed dwo abbreviations object.
const DWARFDebugAbbrev *getDebugAbbrevDWO();
+ /// Get a pointer to the parsed DebugLoc object.
+ const DWARFDebugLocDWO *getDebugLocDWO();
+
/// Get a pointer to the parsed DebugAranges object.
const DWARFDebugAranges *getDebugAranges();
@@ -173,6 +177,7 @@ public:
virtual const TypeSectionMap &getTypesSections() = 0;
virtual StringRef getAbbrevSection() = 0;
virtual const Section &getLocSection() = 0;
+ virtual const Section &getLocDWOSection() = 0;
virtual StringRef getARangeSection() = 0;
virtual StringRef getDebugFrameSection() = 0;
virtual const Section &getLineSection() = 0;
@@ -216,6 +221,7 @@ class DWARFContextInMemory : public DWARFContext {
TypeSectionMap TypesSections;
StringRef AbbrevSection;
Section LocSection;
+ Section LocDWOSection;
StringRef ARangeSection;
StringRef DebugFrameSection;
Section LineSection;
@@ -246,6 +252,7 @@ public:
const TypeSectionMap &getTypesSections() override { return TypesSections; }
StringRef getAbbrevSection() override { return AbbrevSection; }
const Section &getLocSection() override { return LocSection; }
+ const Section &getLocDWOSection() override { return LocDWOSection; }
StringRef getARangeSection() override { return ARangeSection; }
StringRef getDebugFrameSection() override { return DebugFrameSection; }
const Section &getLineSection() override { return LineSection; }
diff --git a/lib/DebugInfo/DWARFDebugLoc.cpp b/lib/DebugInfo/DWARFDebugLoc.cpp
index 5f0ff0240d..e4aa5dcce2 100644
--- a/lib/DebugInfo/DWARFDebugLoc.cpp
+++ b/lib/DebugInfo/DWARFDebugLoc.cpp
@@ -11,6 +11,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Dwarf.h"
using namespace llvm;
@@ -74,3 +75,54 @@ void DWARFDebugLoc::parse(DataExtractor data, unsigned AddressSize) {
if (data.isValidOffset(Offset))
llvm::errs() << "error: failed to consume entire .debug_loc section\n";
}
+
+void DWARFDebugLocDWO::parse(DataExtractor data) {
+ uint32_t Offset = 0;
+ while (data.isValidOffset(Offset)) {
+ Locations.resize(Locations.size() + 1);
+ LocationList &Loc = Locations.back();
+ Loc.Offset = Offset;
+ dwarf::LocationListEntry Kind;
+ while ((Kind = static_cast<dwarf::LocationListEntry>(
+ data.getU8(&Offset))) != dwarf::DW_LLE_end_of_list_entry) {
+
+ if (Kind != dwarf::DW_LLE_start_length_entry) {
+ llvm::errs() << "error: dumping support for LLE of kind " << (int)Kind
+ << " not implemented\n";
+ return;
+ }
+
+ Entry E;
+
+ E.Start = data.getULEB128(&Offset);
+ E.Length = data.getU32(&Offset);
+
+ unsigned Bytes = data.getU16(&Offset);
+ // A single location description describing the location of the object...
+ StringRef str = data.getData().substr(Offset, Bytes);
+ Offset += Bytes;
+ E.Loc.resize(str.size());
+ std::copy(str.begin(), str.end(), E.Loc.begin());
+
+ Loc.Entries.push_back(std::move(E));
+ }
+ }
+}
+
+void DWARFDebugLocDWO::dump(raw_ostream &OS) const {
+ for (const LocationList &L : Locations) {
+ OS << format("0x%8.8x: ", L.Offset);
+ const unsigned Indent = 12;
+ for (const Entry &E : L.Entries) {
+ if (&E != L.Entries.begin())
+ OS.indent(Indent);
+ OS << "Beginning address index: " << E.Start << '\n';
+ OS.indent(Indent) << " Length: " << E.Length << '\n';
+ OS.indent(Indent) << " Location description: ";
+ for (unsigned char Loc : E.Loc)
+ OS << format("%2.2x ", Loc);
+ OS << "\n\n";
+ }
+ }
+}
+
diff --git a/lib/DebugInfo/DWARFDebugLoc.h b/lib/DebugInfo/DWARFDebugLoc.h
index d31aaaa127..663acbb42f 100644
--- a/lib/DebugInfo/DWARFDebugLoc.h
+++ b/lib/DebugInfo/DWARFDebugLoc.h
@@ -55,6 +55,27 @@ public:
/// specified address size to interpret the address ranges.
void parse(DataExtractor data, unsigned AddressSize);
};
+
+class DWARFDebugLocDWO {
+ struct Entry {
+ uint64_t Start;
+ uint32_t Length;
+ SmallVector<unsigned char, 4> Loc;
+ };
+
+ struct LocationList {
+ unsigned Offset;
+ SmallVector<Entry, 2> Entries;
+ };
+
+ typedef SmallVector<LocationList, 4> LocationLists;
+
+ LocationLists Locations;
+
+public:
+ void parse(DataExtractor data);
+ void dump(raw_ostream &OS) const;
+};
}
#endif