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