1 | //===-- DWARFDebugRanges.cpp ----------------------------------------------===// |
---|---|
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "DWARFDebugRanges.h" |
10 | #include "DWARFUnit.h" |
11 | #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" |
12 | |
13 | using namespace lldb_private; |
14 | using namespace lldb_private::plugin::dwarf; |
15 | |
16 | DWARFDebugRanges::DWARFDebugRanges() : m_range_map() {} |
17 | |
18 | void DWARFDebugRanges::Extract(DWARFContext &context) { |
19 | llvm::DWARFDataExtractor extractor = |
20 | context.getOrLoadRangesData().GetAsLLVMDWARF(); |
21 | llvm::DWARFDebugRangeList extracted_list; |
22 | uint64_t current_offset = 0; |
23 | auto extract_next_list = [&] { |
24 | if (auto error = extracted_list.extract(data: extractor, offset_ptr: ¤t_offset)) { |
25 | consumeError(Err: std::move(error)); |
26 | return false; |
27 | } |
28 | return true; |
29 | }; |
30 | |
31 | uint64_t previous_offset = current_offset; |
32 | while (extractor.isValidOffset(offset: current_offset) && extract_next_list()) { |
33 | DWARFRangeList &lldb_range_list = m_range_map[previous_offset]; |
34 | lldb_range_list.Reserve(size: extracted_list.getEntries().size()); |
35 | for (auto &range : extracted_list.getEntries()) |
36 | lldb_range_list.Append(base: range.StartAddress, |
37 | size: range.EndAddress - range.StartAddress); |
38 | lldb_range_list.Sort(); |
39 | previous_offset = current_offset; |
40 | } |
41 | } |
42 | |
43 | DWARFRangeList |
44 | DWARFDebugRanges::FindRanges(const DWARFUnit *cu, |
45 | dw_offset_t debug_ranges_offset) const { |
46 | dw_addr_t debug_ranges_address = cu->GetRangesBase() + debug_ranges_offset; |
47 | auto pos = m_range_map.find(x: debug_ranges_address); |
48 | DWARFRangeList ans = |
49 | pos == m_range_map.end() ? DWARFRangeList() : pos->second; |
50 | |
51 | // All DW_AT_ranges are relative to the base address of the compile |
52 | // unit. We add the compile unit base address to make sure all the |
53 | // addresses are properly fixed up. |
54 | ans.Slide(slide: cu->GetBaseAddress()); |
55 | return ans; |
56 | } |
57 |