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 
DWARFDebugRanges()16 DWARFDebugRanges::DWARFDebugRanges() : m_range_map() {}
17 
Extract(DWARFContext & context)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(extractor, &current_offset)) {
25       consumeError(std::move(error));
26       return false;
27     }
28     return true;
29   };
30 
31   uint64_t previous_offset = current_offset;
32   while (extractor.isValidOffset(current_offset) && extract_next_list()) {
33     DWARFRangeList &lldb_range_list = m_range_map[previous_offset];
34     lldb_range_list.Reserve(extracted_list.getEntries().size());
35     for (auto &range : extracted_list.getEntries())
36       lldb_range_list.Append(range.StartAddress,
37                              range.EndAddress - range.StartAddress);
38     lldb_range_list.Sort();
39     previous_offset = current_offset;
40   }
41 }
42 
43 DWARFRangeList
FindRanges(const DWARFUnit * cu,dw_offset_t debug_ranges_offset) const44 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(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(cu->GetBaseAddress());
55   return ans;
56 }
57