diff options
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp')
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp | 73 |
1 files changed, 60 insertions, 13 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp index da97e90c672..af42c5b35c7 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "DWARFDebugRanges.h" +#include "DWARFUnit.h" #include "SymbolFileDWARF.h" #include "lldb/Utility/Stream.h" #include <assert.h> @@ -29,8 +30,6 @@ static dw_addr_t GetBaseAddressMarker(uint32_t addr_size) { DWARFDebugRanges::DWARFDebugRanges() : m_range_map() {} -DWARFDebugRanges::~DWARFDebugRanges() {} - void DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data) { DWARFRangeList range_list; lldb::offset_t offset = 0; @@ -112,23 +111,27 @@ void DWARFDebugRanges::Dump(Stream &s, } } -bool DWARFDebugRanges::FindRanges(dw_addr_t debug_ranges_base, +bool DWARFDebugRanges::FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset, DWARFRangeList &range_list) const { - dw_addr_t debug_ranges_address = debug_ranges_base + debug_ranges_offset; + dw_addr_t debug_ranges_address = cu->GetRangesBase() + debug_ranges_offset; range_map_const_iterator pos = m_range_map.find(debug_ranges_address); if (pos != m_range_map.end()) { range_list = pos->second; + + // All DW_AT_ranges are relative to the base address of the compile + // unit. We add the compile unit base address to make sure all the + // addresses are properly fixed up. + range_list.Slide(cu->GetBaseAddress()); return true; } return false; } -bool DWARFDebugRngLists::ExtractRangeList(const DWARFDataExtractor &data, - uint8_t addrSize, - lldb::offset_t *offset_ptr, - DWARFRangeList &rangeList) { - rangeList.Clear(); +bool DWARFDebugRngLists::ExtractRangeList( + const DWARFDataExtractor &data, uint8_t addrSize, + lldb::offset_t *offset_ptr, std::vector<RngListEntry> &rangeList) { + rangeList.clear(); bool error = false; while (!error) { @@ -139,14 +142,27 @@ bool DWARFDebugRngLists::ExtractRangeList(const DWARFDataExtractor &data, case DW_RLE_start_length: { dw_addr_t begin = data.GetMaxU64(offset_ptr, addrSize); dw_addr_t len = data.GetULEB128(offset_ptr); - rangeList.Append(DWARFRangeList::Entry(begin, len)); + rangeList.push_back({DW_RLE_start_length, begin, len}); break; } case DW_RLE_start_end: { dw_addr_t begin = data.GetMaxU64(offset_ptr, addrSize); dw_addr_t end = data.GetMaxU64(offset_ptr, addrSize); - rangeList.Append(DWARFRangeList::Entry(begin, end - begin)); + rangeList.push_back({DW_RLE_start_end, begin, end}); + break; + } + + case DW_RLE_base_address: { + dw_addr_t base = data.GetMaxU64(offset_ptr, addrSize); + rangeList.push_back({DW_RLE_base_address, base, 0}); + break; + } + + case DW_RLE_offset_pair: { + dw_addr_t begin = data.GetULEB128(offset_ptr); + dw_addr_t end = data.GetULEB128(offset_ptr); + rangeList.push_back({DW_RLE_offset_pair, begin, end}); break; } @@ -162,6 +178,38 @@ bool DWARFDebugRngLists::ExtractRangeList(const DWARFDataExtractor &data, return false; } +bool DWARFDebugRngLists::FindRanges(const DWARFUnit *cu, + dw_offset_t debug_ranges_offset, + DWARFRangeList &range_list) const { + range_list.Clear(); + dw_addr_t debug_ranges_address = cu->GetRangesBase() + debug_ranges_offset; + auto pos = m_range_map.find(debug_ranges_address); + if (pos != m_range_map.end()) { + dw_addr_t BaseAddr = cu->GetBaseAddress(); + for (const RngListEntry &E : pos->second) { + switch (E.encoding) { + case DW_RLE_start_length: + range_list.Append(DWARFRangeList::Entry(E.value0, E.value1)); + break; + case DW_RLE_base_address: + BaseAddr = E.value0; + break; + case DW_RLE_start_end: + range_list.Append(DWARFRangeList::Entry(E.value0, E.value1 - E.value0)); + break; + case DW_RLE_offset_pair: + range_list.Append( + DWARFRangeList::Entry(BaseAddr + E.value0, E.value1 - E.value0)); + break; + default: + llvm_unreachable("unexpected encoding"); + } + } + return true; + } + return false; +} + void DWARFDebugRngLists::Extract(SymbolFileDWARF *dwarf2Data) { const DWARFDataExtractor &data = dwarf2Data->get_debug_rnglists_data(); lldb::offset_t offset = 0; @@ -191,9 +239,8 @@ void DWARFDebugRngLists::Extract(SymbolFileDWARF *dwarf2Data) { Offsets.push_back(data.GetPointer(&offset)); lldb::offset_t listOffset = offset; - DWARFRangeList rangeList; + std::vector<RngListEntry> rangeList; while (offset < end && ExtractRangeList(data, addrSize, &offset, rangeList)) { - rangeList.Sort(); m_range_map[listOffset] = rangeList; listOffset = offset; } |