summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/DebugInfo/DWARFFormValue.h10
-rw-r--r--lib/DebugInfo/DWARFCompileUnit.cpp145
-rw-r--r--lib/DebugInfo/DWARFCompileUnit.h53
-rw-r--r--lib/DebugInfo/DWARFDebugAranges.cpp2
-rw-r--r--lib/DebugInfo/DWARFDebugInfoEntry.cpp63
-rw-r--r--lib/DebugInfo/DWARFDebugInfoEntry.h7
-rw-r--r--lib/DebugInfo/DWARFFormValue.cpp61
7 files changed, 250 insertions, 91 deletions
diff --git a/include/llvm/DebugInfo/DWARFFormValue.h b/include/llvm/DebugInfo/DWARFFormValue.h
index eaaccfb4f3..ad6f71d664 100644
--- a/include/llvm/DebugInfo/DWARFFormValue.h
+++ b/include/llvm/DebugInfo/DWARFFormValue.h
@@ -20,7 +20,7 @@ class raw_ostream;
class DWARFFormValue {
public:
struct ValueType {
- ValueType() : data(NULL) {
+ ValueType() : data(NULL), IsDWOIndex(false) {
uval = 0;
}
@@ -30,6 +30,7 @@ public:
const char* cstr;
};
const uint8_t* data;
+ bool IsDWOIndex;
};
enum {
@@ -63,11 +64,8 @@ public:
bool resolveCompileUnitReferences(const DWARFCompileUnit* cu);
uint64_t getUnsigned() const { return Value.uval; }
int64_t getSigned() const { return Value.sval; }
- const char *getAsCString(const DataExtractor *debug_str_data_ptr) const;
- const char *getIndirectCString(const DataExtractor *,
- const DataExtractor *) const;
- uint64_t getIndirectAddress(const DataExtractor *,
- const DWARFCompileUnit *) const;
+ const char *getAsCString(const DWARFCompileUnit *CU) const;
+ uint64_t getAsAddress(const DWARFCompileUnit *CU) const;
bool skipValue(DataExtractor debug_info_data, uint32_t *offset_ptr,
const DWARFCompileUnit *cu) const;
static bool skipValue(uint16_t form, DataExtractor debug_info_data,
diff --git a/lib/DebugInfo/DWARFCompileUnit.cpp b/lib/DebugInfo/DWARFCompileUnit.cpp
index 93b1622e80..4b6aa272f7 100644
--- a/lib/DebugInfo/DWARFCompileUnit.cpp
+++ b/lib/DebugInfo/DWARFCompileUnit.cpp
@@ -12,12 +12,31 @@
#include "llvm/DebugInfo/DWARFFormValue.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace dwarf;
-DataExtractor DWARFCompileUnit::getDebugInfoExtractor() const {
- return DataExtractor(InfoSection, isLittleEndian, AddrSize);
+bool DWARFCompileUnit::getAddrOffsetSectionItem(uint32_t Index,
+ uint64_t &Result) const {
+ uint32_t Offset = AddrOffsetSectionBase + Index * AddrSize;
+ if (AddrOffsetSection.size() < Offset + AddrSize)
+ return false;
+ DataExtractor DA(AddrOffsetSection, isLittleEndian, AddrSize);
+ Result = DA.getAddress(&Offset);
+ return true;
+}
+
+bool DWARFCompileUnit::getStringOffsetSectionItem(uint32_t Index,
+ uint32_t &Result) const {
+ // FIXME: string offset section entries are 8-byte for DWARF64.
+ const uint32_t ItemSize = 4;
+ uint32_t Offset = Index * ItemSize;
+ if (StringOffsetSection.size() < Offset + ItemSize)
+ return false;
+ DataExtractor DA(StringOffsetSection, isLittleEndian, 0);
+ Result = DA.getU32(&Offset);
+ return true;
}
bool DWARFCompileUnit::extract(DataExtractor debug_info, uint32_t *offset_ptr) {
@@ -78,7 +97,8 @@ bool DWARFCompileUnit::extractRangeList(uint32_t RangeListOffset,
// Require that compile unit is extracted.
assert(DieArray.size() > 0);
DataExtractor RangesData(RangeSection, isLittleEndian, AddrSize);
- return RangeList.extract(RangesData, &RangeListOffset);
+ uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
+ return RangeList.extract(RangesData, &ActualRangeListOffset);
}
void DWARFCompileUnit::clear() {
@@ -88,7 +108,10 @@ void DWARFCompileUnit::clear() {
Abbrevs = 0;
AddrSize = 0;
BaseAddr = 0;
+ RangeSectionBase = 0;
+ AddrOffsetSectionBase = 0;
clearDIEs(false);
+ DWO.reset();
}
void DWARFCompileUnit::dump(raw_ostream &OS) {
@@ -112,6 +135,15 @@ const char *DWARFCompileUnit::getCompilationDir() {
return DieArray[0].getAttributeValueAsString(this, DW_AT_comp_dir, 0);
}
+uint64_t DWARFCompileUnit::getDWOId() {
+ extractDIEsIfNeeded(true);
+ const uint64_t FailValue = -1ULL;
+ if (DieArray.empty())
+ return FailValue;
+ return DieArray[0]
+ .getAttributeValueAsUnsigned(this, DW_AT_GNU_dwo_id, FailValue);
+}
+
void DWARFCompileUnit::setDIERelations() {
if (DieArray.empty())
return;
@@ -207,21 +239,72 @@ size_t DWARFCompileUnit::extractDIEsIfNeeded(bool CUDieOnly) {
DieArray.size() > 1)
return 0; // Already parsed.
- extractDIEsToVector(DieArray.empty(), !CUDieOnly, DieArray);
+ bool HasCUDie = DieArray.size() > 0;
+ extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
- // Set the base address of current compile unit.
- if (!DieArray.empty()) {
+ if (DieArray.empty())
+ return 0;
+
+ // If CU DIE was just parsed, copy several attribute values from it.
+ if (!HasCUDie) {
uint64_t BaseAddr =
DieArray[0].getAttributeValueAsUnsigned(this, DW_AT_low_pc, -1U);
if (BaseAddr == -1U)
BaseAddr = DieArray[0].getAttributeValueAsUnsigned(this, DW_AT_entry_pc, 0);
setBaseAddress(BaseAddr);
+ AddrOffsetSectionBase =
+ DieArray[0].getAttributeValueAsReference(this, DW_AT_GNU_addr_base, 0);
+ RangeSectionBase =
+ DieArray[0].getAttributeValueAsReference(this, DW_AT_GNU_ranges_base, 0);
}
setDIERelations();
return DieArray.size();
}
+DWARFCompileUnit::DWOHolder::DWOHolder(object::ObjectFile *DWOFile)
+ : DWOFile(DWOFile),
+ DWOContext(cast<DWARFContext>(DIContext::getDWARFContext(DWOFile))),
+ DWOCU(0) {
+ if (DWOContext->getNumDWOCompileUnits() > 0)
+ DWOCU = DWOContext->getDWOCompileUnitAtIndex(0);
+}
+
+bool DWARFCompileUnit::parseDWO() {
+ if (DWO.get() != 0)
+ return false;
+ extractDIEsIfNeeded(true);
+ if (DieArray.empty())
+ return false;
+ const char *DWOFileName =
+ DieArray[0].getAttributeValueAsString(this, DW_AT_GNU_dwo_name, 0);
+ if (DWOFileName == 0)
+ return false;
+ const char *CompilationDir =
+ DieArray[0].getAttributeValueAsString(this, DW_AT_comp_dir, 0);
+ SmallString<16> AbsolutePath;
+ if (sys::path::is_relative(DWOFileName) && CompilationDir != 0) {
+ sys::path::append(AbsolutePath, CompilationDir);
+ }
+ sys::path::append(AbsolutePath, DWOFileName);
+ object::ObjectFile *DWOFile =
+ object::ObjectFile::createObjectFile(AbsolutePath);
+ if (!DWOFile)
+ return false;
+ // Reset DWOHolder.
+ DWO.reset(new DWOHolder(DWOFile));
+ DWARFCompileUnit *DWOCU = DWO->getCU();
+ // Verify that compile unit in .dwo file is valid.
+ if (DWOCU == 0 || DWOCU->getDWOId() != getDWOId()) {
+ DWO.reset();
+ return false;
+ }
+ // Share .debug_addr and .debug_ranges section with compile unit in .dwo
+ DWOCU->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase);
+ DWOCU->setRangesSection(RangeSection, RangeSectionBase);
+ return true;
+}
+
void DWARFCompileUnit::clearDIEs(bool KeepCUDie) {
if (DieArray.size() > (unsigned)KeepCUDie) {
// std::vectors never get any smaller when resized to a smaller size,
@@ -241,7 +324,8 @@ void DWARFCompileUnit::clearDIEs(bool KeepCUDie) {
void
DWARFCompileUnit::buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
- bool clear_dies_if_already_not_parsed){
+ bool clear_dies_if_already_not_parsed,
+ uint32_t CUOffsetInAranges) {
// This function is usually called if there in no .debug_aranges section
// in order to produce a compile unit level set of address ranges that
// is accurate. If the DIEs weren't parsed, then we don't want all dies for
@@ -250,7 +334,17 @@ DWARFCompileUnit::buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
// down.
const bool clear_dies = extractDIEsIfNeeded(false) > 1 &&
clear_dies_if_already_not_parsed;
- DieArray[0].buildAddressRangeTable(this, debug_aranges);
+ DieArray[0].buildAddressRangeTable(this, debug_aranges, CUOffsetInAranges);
+ bool DWOCreated = parseDWO();
+ if (DWO.get()) {
+ // If there is a .dwo file for this compile unit, then skeleton CU DIE
+ // doesn't have children, and we should instead build address range table
+ // from DIEs in the .debug_info.dwo section of .dwo file.
+ DWO->getCU()->buildAddressRangeTable(
+ debug_aranges, clear_dies_if_already_not_parsed, CUOffsetInAranges);
+ }
+ if (DWOCreated && clear_dies_if_already_not_parsed)
+ DWO.reset();
// Keep memory down by clearing DIEs if this generate function
// caused them to be parsed.
@@ -258,21 +352,38 @@ DWARFCompileUnit::buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
clearDIEs(true);
}
+const DWARFDebugInfoEntryMinimal *
+DWARFCompileUnit::getSubprogramForAddress(uint64_t Address) {
+ extractDIEsIfNeeded(false);
+ for (size_t i = 0, n = DieArray.size(); i != n; i++)
+ if (DieArray[i].isSubprogramDIE() &&
+ DieArray[i].addressRangeContainsAddress(this, Address)) {
+ return &DieArray[i];
+ }
+ return 0;
+}
+
DWARFDebugInfoEntryInlinedChain
DWARFCompileUnit::getInlinedChainForAddress(uint64_t Address) {
// First, find a subprogram that contains the given address (the root
// of inlined chain).
- extractDIEsIfNeeded(false);
- const DWARFDebugInfoEntryMinimal *SubprogramDIE = 0;
- for (size_t i = 0, n = DieArray.size(); i != n; i++) {
- if (DieArray[i].isSubprogramDIE() &&
- DieArray[i].addressRangeContainsAddress(this, Address)) {
- SubprogramDIE = &DieArray[i];
- break;
+ const DWARFCompileUnit *ChainCU = 0;
+ const DWARFDebugInfoEntryMinimal *SubprogramDIE =
+ getSubprogramForAddress(Address);
+ if (SubprogramDIE) {
+ ChainCU = this;
+ } else {
+ // Try to look for subprogram DIEs in the DWO file.
+ parseDWO();
+ if (DWO.get()) {
+ SubprogramDIE = DWO->getCU()->getSubprogramForAddress(Address);
+ if (SubprogramDIE)
+ ChainCU = DWO->getCU();
}
}
+
// Get inlined chain rooted at this subprogram DIE.
if (!SubprogramDIE)
return DWARFDebugInfoEntryInlinedChain();
- return SubprogramDIE->getInlinedChainForAddress(this, Address);
-}
+ return SubprogramDIE->getInlinedChainForAddress(ChainCU, Address);
+ }
diff --git a/lib/DebugInfo/DWARFCompileUnit.h b/lib/DebugInfo/DWARFCompileUnit.h
index 97f847962e..09167d128f 100644
--- a/lib/DebugInfo/DWARFCompileUnit.h
+++ b/lib/DebugInfo/DWARFCompileUnit.h
@@ -10,6 +10,7 @@
#ifndef LLVM_DEBUGINFO_DWARFCOMPILEUNIT_H
#define LLVM_DEBUGINFO_DWARFCOMPILEUNIT_H
+#include "llvm/ADT/OwningPtr.h"
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugInfoEntry.h"
#include "DWARFDebugRangeList.h"
@@ -18,6 +19,10 @@
namespace llvm {
+namespace object {
+class ObjectFile;
+}
+
class DWARFDebugAbbrev;
class StringRef;
class raw_ostream;
@@ -30,9 +35,11 @@ class DWARFCompileUnit {
StringRef InfoSection;
StringRef AbbrevSection;
StringRef RangeSection;
+ uint32_t RangeSectionBase;
StringRef StringSection;
StringRef StringOffsetSection;
StringRef AddrOffsetSection;
+ uint32_t AddrOffsetSectionBase;
const RelocAddrMap *RelocMap;
bool isLittleEndian;
@@ -44,6 +51,17 @@ class DWARFCompileUnit {
uint64_t BaseAddr;
// The compile unit debug information entry items.
std::vector<DWARFDebugInfoEntryMinimal> DieArray;
+
+ class DWOHolder {
+ OwningPtr<object::ObjectFile> DWOFile;
+ OwningPtr<DWARFContext> DWOContext;
+ DWARFCompileUnit *DWOCU;
+ public:
+ DWOHolder(object::ObjectFile *DWOFile);
+ DWARFCompileUnit *getCU() const { return DWOCU; }
+ };
+ OwningPtr<DWOHolder> DWO;
+
public:
DWARFCompileUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef AS,
@@ -57,9 +75,27 @@ public:
StringRef getStringSection() const { return StringSection; }
StringRef getStringOffsetSection() const { return StringOffsetSection; }
- StringRef getAddrOffsetSection() const { return AddrOffsetSection; }
+ void setAddrOffsetSection(StringRef AOS, uint32_t Base) {
+ AddrOffsetSection = AOS;
+ AddrOffsetSectionBase = Base;
+ }
+ void setRangesSection(StringRef RS, uint32_t Base) {
+ RangeSection = RS;
+ RangeSectionBase = Base;
+ }
+
+ bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
+ // FIXME: Result should be uint64_t in DWARF64.
+ bool getStringOffsetSectionItem(uint32_t Index, uint32_t &Result) const;
+
+ DataExtractor getDebugInfoExtractor() const {
+ return DataExtractor(InfoSection, isLittleEndian, AddrSize);
+ }
+ DataExtractor getStringExtractor() const {
+ return DataExtractor(StringSection, false, 0);
+ }
+
const RelocAddrMap *getRelocMap() const { return RelocMap; }
- DataExtractor getDebugInfoExtractor() const;
bool extract(DataExtractor debug_info, uint32_t* offset_ptr);
uint32_t extract(uint32_t offset, DataExtractor debug_info_data,
@@ -105,6 +141,7 @@ public:
}
const char *getCompilationDir();
+ uint64_t getDWOId();
/// setDIERelations - We read in all of the DIE entries into our flat list
/// of DIE entries and now we need to go back through all of them and set the
@@ -112,7 +149,8 @@ public:
void setDIERelations();
void buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
- bool clear_dies_if_already_not_parsed);
+ bool clear_dies_if_already_not_parsed,
+ uint32_t CUOffsetInAranges);
/// getInlinedChainForAddress - fetches inlined chain for a given address.
/// Returns empty chain if there is no subprogram containing address. The
@@ -125,6 +163,15 @@ private:
std::vector<DWARFDebugInfoEntryMinimal> &DIEs) const;
/// clearDIEs - Clear parsed DIEs to keep memory usage low.
void clearDIEs(bool KeepCUDie);
+
+ /// parseDWO - Parses .dwo file for current compile unit. Returns true if
+ /// it was actually constructed.
+ bool parseDWO();
+
+ /// getSubprogramForAddress - Returns subprogram DIE with address range
+ /// encompassing the provided address. The pointer is alive as long as parsed
+ /// compile unit DIEs are not cleared.
+ const DWARFDebugInfoEntryMinimal *getSubprogramForAddress(uint64_t Address);
};
}
diff --git a/lib/DebugInfo/DWARFDebugAranges.cpp b/lib/DebugInfo/DWARFDebugAranges.cpp
index f79862d606..56de5ea28d 100644
--- a/lib/DebugInfo/DWARFDebugAranges.cpp
+++ b/lib/DebugInfo/DWARFDebugAranges.cpp
@@ -95,7 +95,7 @@ bool DWARFDebugAranges::generate(DWARFContext *ctx) {
if (DWARFCompileUnit *cu = ctx->getCompileUnitAtIndex(cu_idx)) {
uint32_t CUOffset = cu->getOffset();
if (ParsedCUOffsets.insert(CUOffset).second)
- cu->buildAddressRangeTable(this, true);
+ cu->buildAddressRangeTable(this, true, CUOffset);
}
}
}
diff --git a/lib/DebugInfo/DWARFDebugInfoEntry.cpp b/lib/DebugInfo/DWARFDebugInfoEntry.cpp
index 9abf8dd262..775e68fa23 100644
--- a/lib/DebugInfo/DWARFDebugInfoEntry.cpp
+++ b/lib/DebugInfo/DWARFDebugInfoEntry.cpp
@@ -222,29 +222,30 @@ DWARFDebugInfoEntryMinimal::getAttributeValue(const DWARFCompileUnit *cu,
return 0;
}
-const char*
-DWARFDebugInfoEntryMinimal::getAttributeValueAsString(
- const DWARFCompileUnit* cu,
- const uint16_t attr,
- const char* fail_value)
- const {
- DWARFFormValue form_value;
- if (getAttributeValue(cu, attr, form_value)) {
- DataExtractor stringExtractor(cu->getStringSection(), false, 0);
- return form_value.getAsCString(&stringExtractor);
- }
- return fail_value;
+const char *DWARFDebugInfoEntryMinimal::getAttributeValueAsString(
+ const DWARFCompileUnit *CU, const uint16_t Attr,
+ const char *FailValue) const {
+ DWARFFormValue FormValue;
+ if (getAttributeValue(CU, Attr, FormValue))
+ return FormValue.getAsCString(CU);
+ return FailValue;
}
-uint64_t
-DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsigned(
- const DWARFCompileUnit* cu,
- const uint16_t attr,
- uint64_t fail_value) const {
- DWARFFormValue form_value;
- if (getAttributeValue(cu, attr, form_value))
- return form_value.getUnsigned();
- return fail_value;
+uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsAddress(
+ const DWARFCompileUnit *CU, const uint16_t Attr, uint64_t FailValue) const {
+ DWARFFormValue FormValue;
+ if (getAttributeValue(CU, Attr, FormValue))
+ return FormValue.getAsAddress(CU);
+ return FailValue;
+}
+
+uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsigned(
+ const DWARFCompileUnit *CU, const uint16_t Attr, uint64_t FailValue) const {
+ DWARFFormValue FormValue;
+ if (getAttributeValue(CU, Attr, FormValue)) {
+ return FormValue.getUnsigned();
+ }
+ return FailValue;
}
int64_t
@@ -274,29 +275,29 @@ bool DWARFDebugInfoEntryMinimal::getLowAndHighPC(const DWARFCompileUnit *CU,
uint64_t &LowPC,
uint64_t &HighPC) const {
HighPC = -1ULL;
- LowPC = getAttributeValueAsUnsigned(CU, DW_AT_low_pc, -1ULL);
+ LowPC = getAttributeValueAsAddress(CU, DW_AT_low_pc, -1ULL);
if (LowPC != -1ULL)
- HighPC = getAttributeValueAsUnsigned(CU, DW_AT_high_pc, -1ULL);
+ HighPC = getAttributeValueAsAddress(CU, DW_AT_high_pc, -1ULL);
return (HighPC != -1ULL);
}
void
DWARFDebugInfoEntryMinimal::buildAddressRangeTable(const DWARFCompileUnit *CU,
- DWARFDebugAranges *DebugAranges)
+ DWARFDebugAranges *DebugAranges,
+ uint32_t CUOffsetInAranges)
const {
if (AbbrevDecl) {
if (isSubprogramDIE()) {
uint64_t LowPC, HighPC;
- if (getLowAndHighPC(CU, LowPC, HighPC)) {
- DebugAranges->appendRange(CU->getOffset(), LowPC, HighPC);
- }
+ if (getLowAndHighPC(CU, LowPC, HighPC))
+ DebugAranges->appendRange(CUOffsetInAranges, LowPC, HighPC);
// FIXME: try to append ranges from .debug_ranges section.
}
- const DWARFDebugInfoEntryMinimal *child = getFirstChild();
- while (child) {
- child->buildAddressRangeTable(CU, DebugAranges);
- child = child->getSibling();
+ const DWARFDebugInfoEntryMinimal *Child = getFirstChild();
+ while (Child) {
+ Child->buildAddressRangeTable(CU, DebugAranges, CUOffsetInAranges);
+ Child = Child->getSibling();
}
}
}
diff --git a/lib/DebugInfo/DWARFDebugInfoEntry.h b/lib/DebugInfo/DWARFDebugInfoEntry.h
index a69911f561..2feea36b91 100644
--- a/lib/DebugInfo/DWARFDebugInfoEntry.h
+++ b/lib/DebugInfo/DWARFDebugInfoEntry.h
@@ -128,6 +128,10 @@ public:
const uint16_t attr,
const char *fail_value) const;
+ uint64_t getAttributeValueAsAddress(const DWARFCompileUnit *CU,
+ const uint16_t Attr,
+ uint64_t FailValue) const;
+
uint64_t getAttributeValueAsUnsigned(const DWARFCompileUnit *cu,
const uint16_t attr,
uint64_t fail_value) const;
@@ -146,7 +150,8 @@ public:
uint64_t &LowPC, uint64_t &HighPC) const;
void buildAddressRangeTable(const DWARFCompileUnit *CU,
- DWARFDebugAranges *DebugAranges) const;
+ DWARFDebugAranges *DebugAranges,
+ uint32_t CUOffsetInAranges) const;
bool addressRangeContainsAddress(const DWARFCompileUnit *CU,
const uint64_t Address) const;
diff --git a/lib/DebugInfo/DWARFFormValue.cpp b/lib/DebugInfo/DWARFFormValue.cpp
index 1a1cf2452c..48e0d20908 100644
--- a/lib/DebugInfo/DWARFFormValue.cpp
+++ b/lib/DebugInfo/DWARFFormValue.cpp
@@ -183,10 +183,9 @@ DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
Value.uval = data.getU64(offset_ptr);
break;
case DW_FORM_GNU_addr_index:
- Value.uval = data.getULEB128(offset_ptr);
- break;
case DW_FORM_GNU_str_index:
Value.uval = data.getULEB128(offset_ptr);
+ Value.IsDWOIndex = true;
break;
default:
return false;
@@ -322,12 +321,11 @@ DWARFFormValue::dump(raw_ostream &OS, const DWARFCompileUnit *cu) const {
switch (Form) {
case DW_FORM_addr: OS << format("0x%016" PRIx64, uvalue); break;
case DW_FORM_GNU_addr_index: {
- StringRef AddrOffsetSec = cu->getAddrOffsetSection();
OS << format(" indexed (%8.8x) address = ", (uint32_t)uvalue);
- if (AddrOffsetSec.size() != 0) {
- DataExtractor DA(AddrOffsetSec, true, cu->getAddressByteSize());
- OS << format("0x%016" PRIx64, getIndirectAddress(&DA, cu));
- } else
+ uint64_t Address;
+ if (cu->getAddrOffsetSectionItem(uvalue, Address))
+ OS << format("0x%016" PRIx64, Address);
+ else
OS << "<no .debug_addr section>";
break;
}
@@ -376,7 +374,7 @@ DWARFFormValue::dump(raw_ostream &OS, const DWARFCompileUnit *cu) const {
case DW_FORM_udata: OS << getUnsigned(); break;
case DW_FORM_strp: {
OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue);
- const char* dbg_str = getAsCString(&debug_str_data);
+ const char* dbg_str = getAsCString(cu);
if (dbg_str) {
OS << '"';
OS.write_escaped(dbg_str);
@@ -386,8 +384,7 @@ DWARFFormValue::dump(raw_ostream &OS, const DWARFCompileUnit *cu) const {
}
case DW_FORM_GNU_str_index: {
OS << format(" indexed (%8.8x) string = ", (uint32_t)uvalue);
- const char *dbg_str = getIndirectCString(&debug_str_data,
- &debug_str_offset_data);
+ const char *dbg_str = getAsCString(cu);
if (dbg_str) {
OS << '"';
OS.write_escaped(dbg_str);
@@ -440,33 +437,33 @@ DWARFFormValue::dump(raw_ostream &OS, const DWARFCompileUnit *cu) const {
}
const char*
-DWARFFormValue::getAsCString(const DataExtractor *debug_str_data_ptr) const {
- if (isInlinedCStr()) {
+DWARFFormValue::getAsCString(const DWARFCompileUnit *CU) const {
+ if (isInlinedCStr())
return Value.cstr;
- } else if (debug_str_data_ptr) {
- uint32_t offset = Value.uval;
- return debug_str_data_ptr->getCStr(&offset);
+ if (!CU)
+ return NULL;
+ uint32_t Offset = Value.uval;
+ if (Value.IsDWOIndex) {
+ uint32_t StrOffset;
+ if (!CU->getStringOffsetSectionItem(Offset, StrOffset))
+ return NULL;
+ Offset = StrOffset;
}
- return NULL;
-}
-
-const char*
-DWARFFormValue::getIndirectCString(const DataExtractor *DS,
- const DataExtractor *DSO) const {
- if (!DS || !DSO) return NULL;
-
- uint32_t offset = Value.uval * 4;
- uint32_t soffset = DSO->getU32(&offset);
- return DS->getCStr(&soffset);
+ return CU->getStringExtractor().getCStr(&Offset);
}
uint64_t
-DWARFFormValue::getIndirectAddress(const DataExtractor *DA,
- const DWARFCompileUnit *cu) const {
- if (!DA) return 0;
-
- uint32_t offset = Value.uval * cu->getAddressByteSize();
- return DA->getAddress(&offset);
+DWARFFormValue::getAsAddress(const DWARFCompileUnit *CU) const {
+ if (!CU)
+ return 0;
+ if (Value.IsDWOIndex) {
+ uint32_t Index = Value.uval;
+ uint64_t Address;
+ if (!CU->getAddrOffsetSectionItem(Index, Address))
+ return 0;
+ return Address;
+ }
+ return Value.uval;
}
uint64_t DWARFFormValue::getReference(const DWARFCompileUnit *cu) const {