summaryrefslogtreecommitdiff
path: root/lib/DebugInfo/DWARF/DWARFFormValue.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/DebugInfo/DWARF/DWARFFormValue.cpp')
-rw-r--r--lib/DebugInfo/DWARF/DWARFFormValue.cpp82
1 files changed, 61 insertions, 21 deletions
diff --git a/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/lib/DebugInfo/DWARF/DWARFFormValue.cpp
index 1aa43c6b6517..7719fea63120 100644
--- a/lib/DebugInfo/DWARF/DWARFFormValue.cpp
+++ b/lib/DebugInfo/DWARF/DWARFFormValue.cpp
@@ -308,6 +308,7 @@ bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
break;
case DW_FORM_GNU_addr_index:
case DW_FORM_GNU_str_index:
+ case DW_FORM_addrx:
case DW_FORM_strx:
Value.uval = Data.getULEB128(OffsetPtr);
break;
@@ -330,6 +331,29 @@ bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
return true;
}
+void DWARFFormValue::dumpSectionedAddress(raw_ostream &OS,
+ DIDumpOptions DumpOpts,
+ SectionedAddress SA) const {
+ OS << format("0x%016" PRIx64, SA.Address);
+ dumpAddressSection(U->getContext().getDWARFObj(), OS, DumpOpts,
+ SA.SectionIndex);
+}
+
+void DWARFFormValue::dumpAddressSection(const DWARFObject &Obj, raw_ostream &OS,
+ DIDumpOptions DumpOpts,
+ uint64_t SectionIndex) {
+ if (!DumpOpts.Verbose || SectionIndex == -1ULL)
+ return;
+ ArrayRef<SectionName> SectionNames = Obj.getSectionNames();
+ const auto &SecRef = SectionNames[SectionIndex];
+
+ OS << " \"" << SecRef.Name << '\"';
+
+ // Print section index if name is not unique.
+ if (!SecRef.IsNameUnique)
+ OS << format(" [%" PRIu64 "]", SectionIndex);
+}
+
void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
uint64_t UValue = Value.uval;
bool CURelativeOffset = false;
@@ -338,15 +362,21 @@ void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
: nulls();
switch (Form) {
case DW_FORM_addr:
- AddrOS << format("0x%016" PRIx64, UValue);
+ dumpSectionedAddress(AddrOS, DumpOpts, {Value.uval, Value.SectionIndex});
break;
+ case DW_FORM_addrx:
+ case DW_FORM_addrx1:
+ case DW_FORM_addrx2:
+ case DW_FORM_addrx3:
+ case DW_FORM_addrx4:
case DW_FORM_GNU_addr_index: {
- AddrOS << format(" indexed (%8.8x) address = ", (uint32_t)UValue);
- uint64_t Address;
+ Optional<SectionedAddress> A = U->getAddrOffsetSectionItem(UValue);
+ if (!A || DumpOpts.Verbose)
+ AddrOS << format("indexed (%8.8x) address = ", (uint32_t)UValue);
if (U == nullptr)
OS << "<invalid dwarf unit>";
- else if (U->getAddrOffsetSectionItem(UValue, Address))
- AddrOS << format("0x%016" PRIx64, Address);
+ else if (A)
+ dumpSectionedAddress(AddrOS, DumpOpts, *A);
else
OS << "<no .debug_addr section>";
break;
@@ -387,16 +417,16 @@ void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
switch (Form) {
case DW_FORM_exprloc:
case DW_FORM_block:
- OS << format("<0x%" PRIx64 "> ", UValue);
+ AddrOS << format("<0x%" PRIx64 "> ", UValue);
break;
case DW_FORM_block1:
- OS << format("<0x%2.2x> ", (uint8_t)UValue);
+ AddrOS << format("<0x%2.2x> ", (uint8_t)UValue);
break;
case DW_FORM_block2:
- OS << format("<0x%4.4x> ", (uint16_t)UValue);
+ AddrOS << format("<0x%4.4x> ", (uint16_t)UValue);
break;
case DW_FORM_block4:
- OS << format("<0x%8.8x> ", (uint32_t)UValue);
+ AddrOS << format("<0x%8.8x> ", (uint32_t)UValue);
break;
default:
break;
@@ -407,7 +437,7 @@ void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
// UValue contains size of block
const uint8_t *EndDataPtr = DataPtr + UValue;
while (DataPtr < EndDataPtr) {
- OS << format("%2.2x ", *DataPtr);
+ AddrOS << format("%2.2x ", *DataPtr);
++DataPtr;
}
} else
@@ -438,7 +468,7 @@ void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
case DW_FORM_strx4:
case DW_FORM_GNU_str_index:
if (DumpOpts.Verbose)
- OS << format(" indexed (%8.8x) string = ", (uint32_t)UValue);
+ OS << format("indexed (%8.8x) string = ", (uint32_t)UValue);
dumpString(OS);
break;
case DW_FORM_GNU_strp_alt:
@@ -501,8 +531,9 @@ void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
if (CURelativeOffset) {
if (DumpOpts.Verbose)
OS << " => {";
- WithColor(OS, HighlightColor::Address).get()
- << format("0x%8.8" PRIx64, UValue + (U ? U->getOffset() : 0));
+ if (DumpOpts.ShowAddresses)
+ WithColor(OS, HighlightColor::Address).get()
+ << format("0x%8.8" PRIx64, UValue + (U ? U->getOffset() : 0));
if (DumpOpts.Verbose)
OS << "}";
}
@@ -536,10 +567,12 @@ Optional<const char *> DWARFFormValue::getAsCString() const {
if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx ||
Form == DW_FORM_strx1 || Form == DW_FORM_strx2 || Form == DW_FORM_strx3 ||
Form == DW_FORM_strx4) {
- uint64_t StrOffset;
- if (!U || !U->getStringOffsetSectionItem(Offset, StrOffset))
+ if (!U)
+ return None;
+ Optional<uint64_t> StrOffset = U->getStringOffsetSectionItem(Offset);
+ if (!StrOffset)
return None;
- Offset = StrOffset;
+ Offset = *StrOffset;
}
// Prefer the Unit's string extractor, because for .dwo it will point to
// .debug_str.dwo, while the Context's extractor always uses .debug_str.
@@ -554,16 +587,23 @@ Optional<const char *> DWARFFormValue::getAsCString() const {
}
Optional<uint64_t> DWARFFormValue::getAsAddress() const {
+ if (auto SA = getAsSectionedAddress())
+ return SA->Address;
+ return None;
+}
+Optional<SectionedAddress> DWARFFormValue::getAsSectionedAddress() const {
if (!isFormClass(FC_Address))
return None;
- if (Form == DW_FORM_GNU_addr_index) {
+ if (Form == DW_FORM_GNU_addr_index || Form == DW_FORM_addrx) {
uint32_t Index = Value.uval;
- uint64_t Result;
- if (!U || !U->getAddrOffsetSectionItem(Index, Result))
+ if (!U)
+ return None;
+ Optional<SectionedAddress> SA = U->getAddrOffsetSectionItem(Index);
+ if (!SA)
return None;
- return Result;
+ return SA;
}
- return Value.uval;
+ return {{Value.uval, Value.SectionIndex}};
}
Optional<uint64_t> DWARFFormValue::getAsReference() const {