aboutsummaryrefslogtreecommitdiff
path: root/lib/DebugInfo
diff options
context:
space:
mode:
authorEric Christopher <echristo@gmail.com>2013-01-02 23:52:13 +0000
committerEric Christopher <echristo@gmail.com>2013-01-02 23:52:13 +0000
commit82de10a34c9432029040ced17129079a7d80904e (patch)
treeb86879793d221ee32e3ddae9b8f6bf4ff28797fa /lib/DebugInfo
parent278bac3fba5ae8ae620c961621493e6e2ad6f953 (diff)
Extend the dumping infrastructure to deal with additional
sections for debug info. These are some of the dwo sections from the DWARF5 split debug info proposal. Update the fission-cu.ll testcase to show what we should be able to dump more of now. Work in progress: Ultimately the relocations will be gone for the dwo section and the strings will be a different form (as well as the rest of the sections will be included). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@171428 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/DebugInfo')
-rw-r--r--lib/DebugInfo/DWARFCompileUnit.cpp13
-rw-r--r--lib/DebugInfo/DWARFCompileUnit.h21
-rw-r--r--lib/DebugInfo/DWARFContext.cpp77
-rw-r--r--lib/DebugInfo/DWARFContext.h53
-rw-r--r--lib/DebugInfo/DWARFDebugInfoEntry.cpp3
-rw-r--r--lib/DebugInfo/DWARFFormValue.cpp10
6 files changed, 148 insertions, 29 deletions
diff --git a/lib/DebugInfo/DWARFCompileUnit.cpp b/lib/DebugInfo/DWARFCompileUnit.cpp
index bdd65b77e4..5026723417 100644
--- a/lib/DebugInfo/DWARFCompileUnit.cpp
+++ b/lib/DebugInfo/DWARFCompileUnit.cpp
@@ -17,8 +17,7 @@ using namespace llvm;
using namespace dwarf;
DataExtractor DWARFCompileUnit::getDebugInfoExtractor() const {
- return DataExtractor(Context.getInfoSection(),
- Context.isLittleEndian(), getAddressByteSize());
+ return DataExtractor(InfoSection, isLittleEndian, AddrSize);
}
bool DWARFCompileUnit::extract(DataExtractor debug_info, uint32_t *offset_ptr) {
@@ -28,7 +27,6 @@ bool DWARFCompileUnit::extract(DataExtractor debug_info, uint32_t *offset_ptr) {
if (debug_info.isValidOffset(*offset_ptr)) {
uint64_t abbrOffset;
- const DWARFDebugAbbrev *abbr = Context.getDebugAbbrev();
Length = debug_info.getU32(offset_ptr);
Version = debug_info.getU16(offset_ptr);
abbrOffset = debug_info.getU32(offset_ptr);
@@ -36,11 +34,11 @@ bool DWARFCompileUnit::extract(DataExtractor debug_info, uint32_t *offset_ptr) {
bool lengthOK = debug_info.isValidOffset(getNextCompileUnitOffset()-1);
bool versionOK = DWARFContext::isSupportedVersion(Version);
- bool abbrOffsetOK = Context.getAbbrevSection().size() > abbrOffset;
+ bool abbrOffsetOK = AbbrevSection.size() > abbrOffset;
bool addrSizeOK = AddrSize == 4 || AddrSize == 8;
- if (lengthOK && versionOK && addrSizeOK && abbrOffsetOK && abbr != NULL) {
- Abbrevs = abbr->getAbbreviationDeclarationSet(abbrOffset);
+ if (lengthOK && versionOK && addrSizeOK && abbrOffsetOK && Abbrev != NULL) {
+ Abbrevs = Abbrev->getAbbreviationDeclarationSet(abbrOffset);
return true;
}
@@ -79,8 +77,7 @@ bool DWARFCompileUnit::extractRangeList(uint32_t RangeListOffset,
DWARFDebugRangeList &RangeList) const {
// Require that compile unit is extracted.
assert(DieArray.size() > 0);
- DataExtractor RangesData(Context.getRangeSection(),
- Context.isLittleEndian(), AddrSize);
+ DataExtractor RangesData(RangeSection, isLittleEndian, AddrSize);
return RangeList.extract(RangesData, &RangeListOffset);
}
diff --git a/lib/DebugInfo/DWARFCompileUnit.h b/lib/DebugInfo/DWARFCompileUnit.h
index 03e28620d4..ba638dff21 100644
--- a/lib/DebugInfo/DWARFCompileUnit.h
+++ b/lib/DebugInfo/DWARFCompileUnit.h
@@ -17,11 +17,19 @@
namespace llvm {
-class DWARFContext;
+class DWARFDebugAbbrev;
+class StringRef;
class raw_ostream;
+typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t> > RelocAddrMap;
class DWARFCompileUnit {
- DWARFContext &Context;
+ const DWARFDebugAbbrev *Abbrev;
+ StringRef InfoSection;
+ StringRef AbbrevSection;
+ StringRef RangeSection;
+ StringRef StringSection;
+ const RelocAddrMap *RelocMap;
+ bool isLittleEndian;
uint32_t Offset;
uint32_t Length;
@@ -32,11 +40,16 @@ class DWARFCompileUnit {
// The compile unit debug information entry item.
std::vector<DWARFDebugInfoEntryMinimal> DieArray;
public:
- DWARFCompileUnit(DWARFContext &context) : Context(context) {
+
+ DWARFCompileUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef AS,
+ StringRef RS, StringRef SS, const RelocAddrMap *M, bool LE) :
+ Abbrev(DA), InfoSection(IS), AbbrevSection(AS),
+ RangeSection(RS), StringSection(SS), RelocMap(M), isLittleEndian(LE) {
clear();
}
- DWARFContext &getContext() const { return Context; }
+ StringRef getStringSection() const { return StringSection; }
+ const RelocAddrMap *getRelocMap() const { return RelocMap; }
DataExtractor getDebugInfoExtractor() const;
bool extract(DataExtractor debug_info, uint32_t* offset_ptr);
diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp
index 9e67b23116..1270e6ec72 100644
--- a/lib/DebugInfo/DWARFContext.cpp
+++ b/lib/DebugInfo/DWARFContext.cpp
@@ -53,10 +53,10 @@ void DWARFContext::dump(raw_ostream &OS) {
OS << "\n.debug_str contents:\n";
DataExtractor strData(getStringSection(), isLittleEndian(), 0);
offset = 0;
- uint32_t lastOffset = 0;
+ uint32_t strOffset = 0;
while (const char *s = strData.getCStr(&offset)) {
- OS << format("0x%8.8x: \"%s\"\n", lastOffset, s);
- lastOffset = offset;
+ OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
+ strOffset = offset;
}
OS << "\n.debug_ranges contents:\n";
@@ -70,6 +70,22 @@ void DWARFContext::dump(raw_ostream &OS) {
DWARFDebugRangeList rangeList;
while (rangeList.extract(rangesData, &offset))
rangeList.dump(OS);
+
+ OS << "\n.debug_abbrev.dwo contents:\n";
+ getDebugAbbrevDWO()->dump(OS);
+
+ OS << "\n.debug_info.dwo contents:\n";
+ for (unsigned i = 0, e = getNumDWOCompileUnits(); i != e; ++i)
+ getDWOCompileUnitAtIndex(i)->dump(OS);
+
+ OS << "\n.debug_str.dwo contents:\n";
+ DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
+ offset = 0;
+ uint32_t strDWOOffset = 0;
+ while (const char *s = strDWOData.getCStr(&offset)) {
+ OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
+ strDWOOffset = offset;
+ }
}
const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
@@ -83,6 +99,16 @@ const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
return Abbrev.get();
}
+const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
+ if (AbbrevDWO)
+ return AbbrevDWO.get();
+
+ DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0);
+ AbbrevDWO.reset(new DWARFDebugAbbrev());
+ AbbrevDWO->parse(abbrData);
+ return AbbrevDWO.get();
+}
+
const DWARFDebugAranges *DWARFContext::getDebugAranges() {
if (Aranges)
return Aranges.get();
@@ -124,7 +150,10 @@ void DWARFContext::parseCompileUnits() {
const DataExtractor &DIData = DataExtractor(getInfoSection(),
isLittleEndian(), 0);
while (DIData.isValidOffset(offset)) {
- CUs.push_back(DWARFCompileUnit(*this));
+ CUs.push_back(DWARFCompileUnit(getDebugAbbrev(), getInfoSection(),
+ getAbbrevSection(), getRangeSection(),
+ getStringSection(), &infoRelocMap(),
+ isLittleEndian()));
if (!CUs.back().extract(DIData, &offset)) {
CUs.pop_back();
break;
@@ -134,6 +163,26 @@ void DWARFContext::parseCompileUnits() {
}
}
+void DWARFContext::parseDWOCompileUnits() {
+ uint32_t offset = 0;
+ const DataExtractor &DIData = DataExtractor(getInfoDWOSection(),
+ isLittleEndian(), 0);
+ while (DIData.isValidOffset(offset)) {
+ DWOCUs.push_back(DWARFCompileUnit(getDebugAbbrevDWO(), getInfoDWOSection(),
+ getAbbrevDWOSection(),
+ getRangeDWOSection(),
+ getStringDWOSection(),
+ &infoDWORelocMap(),
+ isLittleEndian()));
+ if (!DWOCUs.back().extract(DIData, &offset)) {
+ DWOCUs.pop_back();
+ break;
+ }
+
+ offset = DWOCUs.back().getNextCompileUnitOffset();
+ }
+}
+
namespace {
struct OffsetComparator {
bool operator()(const DWARFCompileUnit &LHS,
@@ -322,14 +371,28 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
ARangeSection = data;
else if (name == "debug_str")
StringSection = data;
- else if (name == "debug_ranges")
+ else if (name == "debug_ranges") {
+ // FIXME: Use the other dwo range section when we emit it.
+ RangeDWOSection = data;
RangeSection = data;
+ }
+ else if (name == "debug_info.dwo")
+ InfoDWOSection = data;
+ else if (name == "debug_abbrev.dwo")
+ AbbrevDWOSection = data;
+ else if (name == "debug_str.dwo")
+ StringDWOSection = data;
// Any more debug info sections go here.
else
continue;
// TODO: For now only handle relocations for the debug_info section.
- if (name != "debug_info")
+ RelocAddrMap *Map;
+ if (name == "debug_info")
+ Map = &InfoRelocMap;
+ else if (name == "debug_info.dwo")
+ Map = &InfoDWORelocMap;
+ else
continue;
if (i->begin_relocations() != i->end_relocations()) {
@@ -372,7 +435,7 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
<< " at " << format("%p", Address)
<< " with width " << format("%d", R.Width)
<< "\n");
- RelocMap[Address] = std::make_pair(R.Width, R.Value);
+ Map->insert(std::make_pair(Address, std::make_pair(R.Width, R.Value)));
}
}
}
diff --git a/lib/DebugInfo/DWARFContext.h b/lib/DebugInfo/DWARFContext.h
index 24613594de..0c3eb30a64 100644
--- a/lib/DebugInfo/DWARFContext.h
+++ b/lib/DebugInfo/DWARFContext.h
@@ -30,12 +30,19 @@ class DWARFContext : public DIContext {
OwningPtr<DWARFDebugAranges> Aranges;
OwningPtr<DWARFDebugLine> Line;
+ SmallVector<DWARFCompileUnit, 1> DWOCUs;
+ OwningPtr<DWARFDebugAbbrev> AbbrevDWO;
+
DWARFContext(DWARFContext &) LLVM_DELETED_FUNCTION;
DWARFContext &operator=(DWARFContext &) LLVM_DELETED_FUNCTION;
/// Read compile units from the debug_info section and store them in CUs.
void parseCompileUnits();
+ /// Read compile units from the debug_info.dwo section and store them in
+ /// DWOCUs.
+ void parseDWOCompileUnits();
+
public:
DWARFContext() {}
virtual void dump(raw_ostream &OS);
@@ -46,6 +53,14 @@ public:
parseCompileUnits();
return CUs.size();
}
+
+ /// Get the number of compile units in the DWO context.
+ unsigned getNumDWOCompileUnits() {
+ if (DWOCUs.empty())
+ parseDWOCompileUnits();
+ return DWOCUs.size();
+ }
+
/// Get the compile unit at the specified index for this compile unit.
DWARFCompileUnit *getCompileUnitAtIndex(unsigned index) {
if (CUs.empty())
@@ -53,9 +68,19 @@ public:
return &CUs[index];
}
+ /// Get the compile unit at the specified index for the DWO compile units.
+ DWARFCompileUnit *getDWOCompileUnitAtIndex(unsigned index) {
+ if (DWOCUs.empty())
+ parseDWOCompileUnits();
+ return &DWOCUs[index];
+ }
+
/// Get a pointer to the parsed DebugAbbrev object.
const DWARFDebugAbbrev *getDebugAbbrev();
+ /// Get a pointer to the parsed dwo abbreviations object.
+ const DWARFDebugAbbrev *getDebugAbbrevDWO();
+
/// Get a pointer to the parsed DebugAranges object.
const DWARFDebugAranges *getDebugAranges();
@@ -69,7 +94,7 @@ public:
DILineInfoSpecifier Specifier = DILineInfoSpecifier());
virtual bool isLittleEndian() const = 0;
- virtual const RelocAddrMap &relocMap() const = 0;
+ virtual const RelocAddrMap &infoRelocMap() const = 0;
virtual StringRef getInfoSection() = 0;
virtual StringRef getAbbrevSection() = 0;
virtual StringRef getARangeSection() = 0;
@@ -77,6 +102,13 @@ public:
virtual StringRef getStringSection() = 0;
virtual StringRef getRangeSection() = 0;
+ // Sections for DWARF5 split dwarf proposal.
+ virtual StringRef getInfoDWOSection() = 0;
+ virtual StringRef getAbbrevDWOSection() = 0;
+ virtual StringRef getStringDWOSection() = 0;
+ virtual StringRef getRangeDWOSection() = 0;
+ virtual const RelocAddrMap &infoDWORelocMap() const = 0;
+
static bool isSupportedVersion(unsigned version) {
return version == 2 || version == 3;
}
@@ -95,23 +127,38 @@ private:
class DWARFContextInMemory : public DWARFContext {
virtual void anchor();
bool IsLittleEndian;
- RelocAddrMap RelocMap;
+ RelocAddrMap InfoRelocMap;
StringRef InfoSection;
StringRef AbbrevSection;
StringRef ARangeSection;
StringRef LineSection;
StringRef StringSection;
StringRef RangeSection;
+
+ // Sections for DWARF5 split dwarf proposal.
+ RelocAddrMap InfoDWORelocMap;
+ StringRef InfoDWOSection;
+ StringRef AbbrevDWOSection;
+ StringRef StringDWOSection;
+ StringRef RangeDWOSection;
+
public:
DWARFContextInMemory(object::ObjectFile *);
virtual bool isLittleEndian() const { return IsLittleEndian; }
- virtual const RelocAddrMap &relocMap() const { return RelocMap; }
+ virtual const RelocAddrMap &infoRelocMap() const { return InfoRelocMap; }
virtual StringRef getInfoSection() { return InfoSection; }
virtual StringRef getAbbrevSection() { return AbbrevSection; }
virtual StringRef getARangeSection() { return ARangeSection; }
virtual StringRef getLineSection() { return LineSection; }
virtual StringRef getStringSection() { return StringSection; }
virtual StringRef getRangeSection() { return RangeSection; }
+
+ // Sections for DWARF5 split dwarf proposal.
+ virtual StringRef getInfoDWOSection() { return InfoDWOSection; }
+ virtual StringRef getAbbrevDWOSection() { return AbbrevDWOSection; }
+ virtual StringRef getStringDWOSection() { return StringDWOSection; }
+ virtual StringRef getRangeDWOSection() { return RangeDWOSection; }
+ virtual const RelocAddrMap &infoDWORelocMap() const { return InfoDWORelocMap; }
};
}
diff --git a/lib/DebugInfo/DWARFDebugInfoEntry.cpp b/lib/DebugInfo/DWARFDebugInfoEntry.cpp
index ab67464453..d3e6e9e845 100644
--- a/lib/DebugInfo/DWARFDebugInfoEntry.cpp
+++ b/lib/DebugInfo/DWARFDebugInfoEntry.cpp
@@ -417,8 +417,7 @@ DWARFDebugInfoEntryMinimal::getAttributeValueAsString(
const {
DWARFFormValue form_value;
if (getAttributeValue(cu, attr, form_value)) {
- DataExtractor stringExtractor(cu->getContext().getStringSection(),
- false, 0);
+ DataExtractor stringExtractor(cu->getStringSection(), false, 0);
return form_value.getAsCString(&stringExtractor);
}
return fail_value;
diff --git a/lib/DebugInfo/DWARFFormValue.cpp b/lib/DebugInfo/DWARFFormValue.cpp
index efc2d96613..1610db27d2 100644
--- a/lib/DebugInfo/DWARFFormValue.cpp
+++ b/lib/DebugInfo/DWARFFormValue.cpp
@@ -105,8 +105,8 @@ DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
case DW_FORM_addr:
case DW_FORM_ref_addr: {
RelocAddrMap::const_iterator AI
- = cu->getContext().relocMap().find(*offset_ptr);
- if (AI != cu->getContext().relocMap().end()) {
+ = cu->getRelocMap()->find(*offset_ptr);
+ if (AI != cu->getRelocMap()->end()) {
const std::pair<uint8_t, int64_t> &R = AI->second;
Value.uval = data.getUnsigned(offset_ptr, cu->getAddressByteSize()) +
R.second;
@@ -153,8 +153,8 @@ DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
break;
case DW_FORM_strp: {
RelocAddrMap::const_iterator AI
- = cu->getContext().relocMap().find(*offset_ptr);
- if (AI != cu->getContext().relocMap().end()) {
+ = cu->getRelocMap()->find(*offset_ptr);
+ if (AI != cu->getRelocMap()->end()) {
const std::pair<uint8_t, int64_t> &R = AI->second;
Value.uval = data.getU32(offset_ptr) + R.second;
} else
@@ -320,7 +320,7 @@ DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data,
void
DWARFFormValue::dump(raw_ostream &OS, const DWARFCompileUnit *cu) const {
- DataExtractor debug_str_data(cu->getContext().getStringSection(), true, 0);
+ DataExtractor debug_str_data(cu->getStringSection(), true, 0);
uint64_t uvalue = getUnsigned();
bool cu_relative_offset = false;