xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1dda28197Spatrick //===-- DWARFCompileUnit.cpp ----------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9061da546Spatrick #include "DWARFCompileUnit.h"
10061da546Spatrick #include "DWARFDebugAranges.h"
11061da546Spatrick #include "SymbolFileDWARFDebugMap.h"
12061da546Spatrick 
13061da546Spatrick #include "lldb/Symbol/CompileUnit.h"
14061da546Spatrick #include "lldb/Symbol/LineTable.h"
15061da546Spatrick #include "lldb/Utility/Stream.h"
16061da546Spatrick 
17061da546Spatrick using namespace lldb;
18061da546Spatrick using namespace lldb_private;
19061da546Spatrick 
Dump(Stream * s) const20061da546Spatrick void DWARFCompileUnit::Dump(Stream *s) const {
21*f6aab3d8Srobert   s->Format(
22*f6aab3d8Srobert 
23*f6aab3d8Srobert       "{0:x16}: Compile Unit: length = {1:x8}, version = {2:x}, "
24*f6aab3d8Srobert       "abbr_offset = {3:x8}, addr_size = {4:x2} (next CU at "
25*f6aab3d8Srobert       "[{5:x16}])\n",
26*f6aab3d8Srobert       GetOffset(), GetLength(), GetVersion(), (uint32_t)GetAbbrevOffset(),
27061da546Spatrick       GetAddressByteSize(), GetNextUnitOffset());
28061da546Spatrick }
29061da546Spatrick 
BuildAddressRangeTable(DWARFDebugAranges * debug_aranges)30061da546Spatrick void DWARFCompileUnit::BuildAddressRangeTable(
31061da546Spatrick     DWARFDebugAranges *debug_aranges) {
32061da546Spatrick   // This function is usually called if there in no .debug_aranges section in
33061da546Spatrick   // order to produce a compile unit level set of address ranges that is
34061da546Spatrick   // accurate.
35061da546Spatrick 
36061da546Spatrick   size_t num_debug_aranges = debug_aranges->GetNumRanges();
37061da546Spatrick 
38dda28197Spatrick   // First get the compile unit DIE only and check contains ranges information.
39061da546Spatrick   const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
40061da546Spatrick 
41061da546Spatrick   const dw_offset_t cu_offset = GetOffset();
42061da546Spatrick   if (die) {
43061da546Spatrick     DWARFRangeList ranges;
44061da546Spatrick     const size_t num_ranges =
45dda28197Spatrick         die->GetAttributeAddressRanges(this, ranges, /*check_hi_lo_pc=*/true);
46061da546Spatrick     if (num_ranges > 0) {
47061da546Spatrick       for (size_t i = 0; i < num_ranges; ++i) {
48061da546Spatrick         const DWARFRangeList::Entry &range = ranges.GetEntryRef(i);
49061da546Spatrick         debug_aranges->AppendRange(cu_offset, range.GetRangeBase(),
50061da546Spatrick                                    range.GetRangeEnd());
51061da546Spatrick       }
52061da546Spatrick 
53dda28197Spatrick       return;
54061da546Spatrick     }
55061da546Spatrick   }
56061da546Spatrick 
57061da546Spatrick   if (debug_aranges->GetNumRanges() == num_debug_aranges) {
58*f6aab3d8Srobert     // We got nothing from the debug info, try to build the arange table from
59*f6aab3d8Srobert     // the debug map OSO aranges.
60061da546Spatrick     SymbolContext sc;
61061da546Spatrick     sc.comp_unit = m_dwarf.GetCompUnitForDWARFCompUnit(*this);
62061da546Spatrick     if (sc.comp_unit) {
63061da546Spatrick       SymbolFileDWARFDebugMap *debug_map_sym_file =
64061da546Spatrick           m_dwarf.GetDebugMapSymfile();
65*f6aab3d8Srobert       if (debug_map_sym_file) {
66*f6aab3d8Srobert         auto *cu_info =
67*f6aab3d8Srobert             debug_map_sym_file->GetCompileUnitInfo(&GetSymbolFileDWARF());
68*f6aab3d8Srobert         // If there are extra compile units the OSO entries aren't a reliable
69*f6aab3d8Srobert         // source of information.
70*f6aab3d8Srobert         if (cu_info->compile_units_sps.empty())
71061da546Spatrick           debug_map_sym_file->AddOSOARanges(&m_dwarf, debug_aranges);
72061da546Spatrick       }
73061da546Spatrick     }
74*f6aab3d8Srobert   }
75061da546Spatrick 
76061da546Spatrick   if (debug_aranges->GetNumRanges() == num_debug_aranges) {
77061da546Spatrick     // We got nothing from the functions, maybe we have a line tables only
78061da546Spatrick     // situation. Check the line tables and build the arange table from this.
79061da546Spatrick     SymbolContext sc;
80061da546Spatrick     sc.comp_unit = m_dwarf.GetCompUnitForDWARFCompUnit(*this);
81061da546Spatrick     if (sc.comp_unit) {
82061da546Spatrick       if (LineTable *line_table = sc.comp_unit->GetLineTable()) {
83061da546Spatrick         LineTable::FileAddressRanges file_ranges;
84061da546Spatrick         const bool append = true;
85061da546Spatrick         const size_t num_ranges =
86061da546Spatrick             line_table->GetContiguousFileAddressRanges(file_ranges, append);
87061da546Spatrick         for (uint32_t idx = 0; idx < num_ranges; ++idx) {
88061da546Spatrick           const LineTable::FileAddressRanges::Entry &range =
89061da546Spatrick               file_ranges.GetEntryRef(idx);
90061da546Spatrick           debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(),
91061da546Spatrick                                      range.GetRangeEnd());
92061da546Spatrick         }
93061da546Spatrick       }
94061da546Spatrick     }
95061da546Spatrick   }
96061da546Spatrick }
97be691f3bSpatrick 
GetNonSkeletonUnit()98be691f3bSpatrick DWARFCompileUnit &DWARFCompileUnit::GetNonSkeletonUnit() {
99be691f3bSpatrick   return llvm::cast<DWARFCompileUnit>(DWARFUnit::GetNonSkeletonUnit());
100be691f3bSpatrick }
101be691f3bSpatrick 
LookupAddress(const dw_addr_t address)102be691f3bSpatrick DWARFDIE DWARFCompileUnit::LookupAddress(const dw_addr_t address) {
103be691f3bSpatrick   if (DIE()) {
104be691f3bSpatrick     const DWARFDebugAranges &func_aranges = GetFunctionAranges();
105be691f3bSpatrick 
106be691f3bSpatrick     // Re-check the aranges auto pointer contents in case it was created above
107be691f3bSpatrick     if (!func_aranges.IsEmpty())
108be691f3bSpatrick       return GetDIE(func_aranges.FindAddress(address));
109be691f3bSpatrick   }
110be691f3bSpatrick   return DWARFDIE();
111be691f3bSpatrick }
112