summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/SymbolFile
diff options
context:
space:
mode:
authorGeorge Rimar <grimar@accesssoftek.com>2018-11-02 09:03:25 +0000
committerGeorge Rimar <grimar@accesssoftek.com>2018-11-02 09:03:25 +0000
commit5497f6580e6e6a80cae07eac768f6217dcb3b3ab (patch)
treee20809f5b4c2a7776ba0cf5e35e5f154bcfdbfe6 /lldb/source/Plugins/SymbolFile
parent15da7684db33fe15ad8b2589573d2bfce556f6b7 (diff)
downloadbcm5719-llvm-5497f6580e6e6a80cae07eac768f6217dcb3b3ab.tar.gz
bcm5719-llvm-5497f6580e6e6a80cae07eac768f6217dcb3b3ab.zip
[LLDB] - Add support for DW_FORM_rnglistx and relative DW_RLE_* entries.
This adds support for DW_RLE_base_addressx, DW_RLE_startx_endx, DW_RLE_startx_length, DW_FORM_rnglistx. Differential revision: https://reviews.llvm.org/D53929 llvm-svn: 345958
Diffstat (limited to 'lldb/source/Plugins/SymbolFile')
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp37
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp60
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h9
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp3
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp2
5 files changed, 90 insertions, 21 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index 91f8a45e0be..7531aeac709 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -157,6 +157,7 @@ bool DWARFDebugInfoEntry::FastExtract(
// signed or unsigned LEB 128 values
case DW_FORM_addrx:
+ case DW_FORM_rnglistx:
case DW_FORM_sdata:
case DW_FORM_udata:
case DW_FORM_ref_udata:
@@ -387,6 +388,13 @@ void DWARFDebugInfoEntry::DumpAncestry(SymbolFileDWARF *dwarf2Data,
Dump(dwarf2Data, cu, s, recurse_depth);
}
+static dw_offset_t GetRangesOffset(const DWARFDebugRangesBase *debug_ranges,
+ DWARFFormValue &form_value) {
+ if (form_value.Form() == DW_FORM_rnglistx)
+ return debug_ranges->GetOffset(form_value.Unsigned());
+ return form_value.Unsigned();
+}
+
//----------------------------------------------------------------------
// GetDIENamesAndRanges
//
@@ -464,7 +472,7 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
case DW_AT_ranges: {
const DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges();
if (debug_ranges)
- debug_ranges->FindRanges(cu, form_value.Unsigned(), ranges);
+ debug_ranges->FindRanges(cu, GetRangesOffset(debug_ranges, form_value), ranges);
else
cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError(
"{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64
@@ -748,11 +756,13 @@ void DWARFDebugInfoEntry::DumpAttribute(
} break;
case DW_AT_ranges: {
- lldb::offset_t ranges_offset = form_value.Unsigned();
+ if (!dwarf2Data)
+ break;
+ lldb::offset_t ranges_offset =
+ GetRangesOffset(dwarf2Data->DebugRanges(), form_value);
dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0;
- if (dwarf2Data)
- DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(),
- &ranges_offset, base_addr);
+ DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(),
+ &ranges_offset, base_addr);
} break;
default:
@@ -1062,12 +1072,11 @@ size_t DWARFDebugInfoEntry::GetAttributeAddressRanges(
bool check_specification_or_abstract_origin) const {
ranges.Clear();
- dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(
- dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET,
- check_specification_or_abstract_origin);
- if (debug_ranges_offset != DW_INVALID_OFFSET) {
+ DWARFFormValue form_value;
+ if (GetAttributeValue(dwarf2Data, cu, DW_AT_ranges, form_value)) {
if (DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges())
- debug_ranges->FindRanges(cu, debug_ranges_offset, ranges);
+ debug_ranges->FindRanges(cu, GetRangesOffset(debug_ranges, form_value),
+ ranges);
} else if (check_hi_lo_pc) {
dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
@@ -1718,12 +1727,12 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
((function_die != NULL) || (block_die != NULL));
}
} else {
- dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(
- dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET);
- if (debug_ranges_offset != DW_INVALID_OFFSET) {
+ DWARFFormValue form_value;
+ if (GetAttributeValue(dwarf2Data, cu, DW_AT_ranges, form_value)) {
DWARFRangeList ranges;
DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges();
- debug_ranges->FindRanges(cu, debug_ranges_offset, ranges);
+ debug_ranges->FindRanges(
+ cu, GetRangesOffset(debug_ranges, form_value), ranges);
if (ranges.FindEntryThatContains(address)) {
found_address = true;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
index 36771e55003..a0436dd7ffa 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
@@ -128,6 +128,11 @@ bool DWARFDebugRanges::FindRanges(const DWARFUnit *cu,
return false;
}
+uint64_t DWARFDebugRanges::GetOffset(size_t Index) const {
+ lldbassert(false && "DW_FORM_rnglistx is not present before DWARF5");
+ return 0;
+}
+
bool DWARFDebugRngLists::ExtractRangeList(
const DWARFDataExtractor &data, uint8_t addrSize,
lldb::offset_t *offset_ptr, std::vector<RngListEntry> &rangeList) {
@@ -166,9 +171,27 @@ bool DWARFDebugRngLists::ExtractRangeList(
break;
}
+ case DW_RLE_base_addressx: {
+ dw_addr_t base = data.GetULEB128(offset_ptr);
+ rangeList.push_back({DW_RLE_base_addressx, base, 0});
+ break;
+ }
+
+ case DW_RLE_startx_endx: {
+ dw_addr_t start = data.GetULEB128(offset_ptr);
+ dw_addr_t end = data.GetULEB128(offset_ptr);
+ rangeList.push_back({DW_RLE_startx_endx, start, end});
+ break;
+ }
+
+ case DW_RLE_startx_length: {
+ dw_addr_t start = data.GetULEB128(offset_ptr);
+ dw_addr_t length = data.GetULEB128(offset_ptr);
+ rangeList.push_back({DW_RLE_startx_length, start, length});
+ break;
+ }
+
default:
- // Next encodings are not yet supported:
- // DW_RLE_base_addressx, DW_RLE_startx_endx, DW_RLE_startx_length.
lldbassert(0 && "unknown range list entry encoding");
error = true;
}
@@ -177,6 +200,15 @@ bool DWARFDebugRngLists::ExtractRangeList(
return false;
}
+static uint64_t ReadAddressFromDebugAddrSection(const DWARFUnit *cu,
+ uint32_t index) {
+ uint32_t index_size = cu->GetAddressByteSize();
+ dw_offset_t addr_base = cu->GetAddrBase();
+ lldb::offset_t offset = addr_base + index * index_size;
+ return cu->GetSymbolFileDWARF()->get_debug_addr_data().GetMaxU64(&offset,
+ index_size);
+}
+
bool DWARFDebugRngLists::FindRanges(const DWARFUnit *cu,
dw_offset_t debug_ranges_offset,
DWARFRangeList &range_list) const {
@@ -200,6 +232,21 @@ bool DWARFDebugRngLists::FindRanges(const DWARFUnit *cu,
range_list.Append(
DWARFRangeList::Entry(BaseAddr + E.value0, E.value1 - E.value0));
break;
+ case DW_RLE_base_addressx: {
+ BaseAddr = ReadAddressFromDebugAddrSection(cu, E.value0);
+ break;
+ }
+ case DW_RLE_startx_endx: {
+ dw_addr_t start = ReadAddressFromDebugAddrSection(cu, E.value0);
+ dw_addr_t end = ReadAddressFromDebugAddrSection(cu, E.value1);
+ range_list.Append(DWARFRangeList::Entry(start, end - start));
+ break;
+ }
+ case DW_RLE_startx_length: {
+ dw_addr_t start = ReadAddressFromDebugAddrSection(cu, E.value0);
+ range_list.Append(DWARFRangeList::Entry(start, E.value1));
+ break;
+ }
default:
llvm_unreachable("unexpected encoding");
}
@@ -214,7 +261,8 @@ void DWARFDebugRngLists::Extract(SymbolFileDWARF *dwarf2Data) {
lldb::offset_t offset = 0;
uint64_t length = data.GetU32(&offset);
- if (length == 0xffffffff)
+ bool isDwarf64 = (length == 0xffffffff);
+ if (isDwarf64)
length = data.GetU64(&offset);
lldb::offset_t end = offset + length;
@@ -232,7 +280,7 @@ void DWARFDebugRngLists::Extract(SymbolFileDWARF *dwarf2Data) {
uint32_t offsetsAmount = data.GetU32(&offset);
for (uint32_t i = 0; i < offsetsAmount; ++i)
- Offsets.push_back(data.GetPointer(&offset));
+ Offsets.push_back(data.GetMaxU64(&offset, isDwarf64 ? 8 : 4));
lldb::offset_t listOffset = offset;
std::vector<RngListEntry> rangeList;
@@ -241,3 +289,7 @@ void DWARFDebugRngLists::Extract(SymbolFileDWARF *dwarf2Data) {
listOffset = offset;
}
}
+
+uint64_t DWARFDebugRngLists::GetOffset(size_t Index) const {
+ return Offsets[Index];
+}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
index b346d9291a4..5790f448ba8 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
@@ -22,15 +22,17 @@ public:
virtual void Extract(SymbolFileDWARF *dwarf2Data) = 0;
virtual bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
DWARFRangeList &range_list) const = 0;
+ virtual uint64_t GetOffset(size_t Index) const = 0;
};
class DWARFDebugRanges final : public DWARFDebugRangesBase {
public:
DWARFDebugRanges();
- virtual void Extract(SymbolFileDWARF *dwarf2Data) override;
- virtual bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
- DWARFRangeList &range_list) const override;
+ void Extract(SymbolFileDWARF *dwarf2Data) override;
+ bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
+ DWARFRangeList &range_list) const override;
+ uint64_t GetOffset(size_t Index) const override;
static void Dump(lldb_private::Stream &s,
const lldb_private::DWARFDataExtractor &debug_ranges_data,
@@ -58,6 +60,7 @@ public:
void Extract(SymbolFileDWARF *dwarf2Data) override;
bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
DWARFRangeList &range_list) const override;
+ uint64_t GetOffset(size_t Index) const override;
protected:
bool ExtractRangeList(const lldb_private::DWARFDataExtractor &data,
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
index a70572858d9..c888d0bc3e6 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -248,6 +248,7 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
m_value.value.uval = data.GetU64(offset_ptr);
break;
case DW_FORM_addrx:
+ case DW_FORM_rnglistx:
case DW_FORM_strx:
case DW_FORM_udata:
case DW_FORM_ref_udata:
@@ -393,6 +394,7 @@ bool DWARFFormValue::SkipValue(dw_form_t form,
// signed or unsigned LEB 128 values
case DW_FORM_addrx:
+ case DW_FORM_rnglistx:
case DW_FORM_sdata:
case DW_FORM_udata:
case DW_FORM_ref_udata:
@@ -777,6 +779,7 @@ bool DWARFFormValue::FormIsSupported(dw_form_t form) {
switch (form) {
case DW_FORM_addr:
case DW_FORM_addrx:
+ case DW_FORM_rnglistx:
case DW_FORM_block2:
case DW_FORM_block4:
case DW_FORM_data2:
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index 271f44f24b9..7236a0599e6 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -309,6 +309,8 @@ void DWARFUnit::ExtractDIEsEndCheck(lldb::offset_t offset) const {
void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
SetAddrBase(
cu_die.GetAttributeValueAsUnsigned(m_dwarf, this, DW_AT_addr_base, 0));
+ SetRangesBase(cu_die.GetAttributeValueAsUnsigned(m_dwarf, this,
+ DW_AT_rnglists_base, 0));
uint64_t base_addr = cu_die.GetAttributeValueAsAddress(
m_dwarf, this, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
OpenPOWER on IntegriCloud