diff options
| author | George Rimar <grimar@accesssoftek.com> | 2018-11-02 09:03:25 +0000 |
|---|---|---|
| committer | George Rimar <grimar@accesssoftek.com> | 2018-11-02 09:03:25 +0000 |
| commit | 5497f6580e6e6a80cae07eac768f6217dcb3b3ab (patch) | |
| tree | e20809f5b4c2a7776ba0cf5e35e5f154bcfdbfe6 /lldb/source | |
| parent | 15da7684db33fe15ad8b2589573d2bfce556f6b7 (diff) | |
| download | bcm5719-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')
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); |

