xref: /llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp (revision 4206c37bd11887c2c9dfc99e484753f6b8230a90)
1 //===-- DWARFDebugAranges.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 "DWARFDebugAranges.h"
10 #include "DWARFUnit.h"
11 #include "LogChannelDWARF.h"
12 #include "lldb/Utility/Log.h"
13 #include "lldb/Utility/Timer.h"
14 #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
15 
16 using namespace lldb;
17 using namespace lldb_private;
18 using namespace lldb_private::plugin::dwarf;
19 using llvm::DWARFDebugArangeSet;
20 
21 // Constructor
22 DWARFDebugAranges::DWARFDebugAranges() : m_aranges() {}
23 
24 // Extract
25 void DWARFDebugAranges::extract(const DWARFDataExtractor &debug_aranges_data) {
26   llvm::DWARFDataExtractor dwarf_data = debug_aranges_data.GetAsLLVMDWARF();
27   lldb::offset_t offset = 0;
28 
29   DWARFDebugArangeSet set;
30   Range range;
31   while (dwarf_data.isValidOffset(offset)) {
32     const lldb::offset_t set_offset = offset;
33     if (llvm::Error error = set.extract(dwarf_data, &offset)) {
34       Log *log = GetLog(DWARFLog::DebugInfo);
35       LLDB_LOG_ERROR(log, std::move(error),
36                      "DWARFDebugAranges::extract failed to extract "
37                      ".debug_aranges set at offset {1:x}: {0}",
38                      set_offset);
39       set.clear();
40       return;
41     }
42     const uint64_t cu_offset = set.getCompileUnitDIEOffset();
43     for (const auto &desc : set.descriptors()) {
44       if (desc.Length != 0)
45         m_aranges.Append(
46             RangeToDIE::Entry(desc.Address, desc.Length, cu_offset));
47     }
48   }
49 }
50 
51 void DWARFDebugAranges::Dump(Log *log) const {
52   if (log == nullptr)
53     return;
54 
55   const size_t num_entries = m_aranges.GetSize();
56   for (size_t i = 0; i < num_entries; ++i) {
57     const RangeToDIE::Entry *entry = m_aranges.GetEntryAtIndex(i);
58     if (entry)
59       LLDB_LOG(log, "{0:x8}: [{1:x16} - {2:x16})", entry->data,
60                entry->GetRangeBase(), entry->GetRangeEnd());
61   }
62 }
63 
64 void DWARFDebugAranges::AppendRange(dw_offset_t offset, dw_addr_t low_pc,
65                                     dw_addr_t high_pc) {
66   if (high_pc > low_pc)
67     m_aranges.Append(RangeToDIE::Entry(low_pc, high_pc - low_pc, offset));
68 }
69 
70 void DWARFDebugAranges::Sort(bool minimize) {
71   LLDB_SCOPED_TIMER();
72 
73   m_aranges.Sort();
74   m_aranges.CombineConsecutiveEntriesWithEqualData();
75 }
76 
77 // FindAddress
78 dw_offset_t DWARFDebugAranges::FindAddress(dw_addr_t address) const {
79   const RangeToDIE::Entry *entry = m_aranges.FindEntryThatContains(address);
80   if (entry)
81     return entry->data;
82   return DW_INVALID_OFFSET;
83 }
84