summaryrefslogtreecommitdiff
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)
downloadllvm-82de10a34c9432029040ced17129079a7d80904e.tar.gz
llvm-82de10a34c9432029040ced17129079a7d80904e.tar.bz2
llvm-82de10a34c9432029040ced17129079a7d80904e.tar.xz
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;