15ffd83dbSDimitry Andric //===-- DWARFCompileUnit.cpp ----------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #include "DWARFCompileUnit.h"
100b57cec5SDimitry Andric #include "DWARFDebugAranges.h"
110b57cec5SDimitry Andric #include "SymbolFileDWARFDebugMap.h"
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "lldb/Symbol/CompileUnit.h"
140b57cec5SDimitry Andric #include "lldb/Symbol/LineTable.h"
150b57cec5SDimitry Andric #include "lldb/Utility/Stream.h"
160b57cec5SDimitry Andric
170b57cec5SDimitry Andric using namespace lldb;
180b57cec5SDimitry Andric using namespace lldb_private;
19*5f757f3fSDimitry Andric using namespace lldb_private::plugin::dwarf;
200b57cec5SDimitry Andric
Dump(Stream * s) const210b57cec5SDimitry Andric void DWARFCompileUnit::Dump(Stream *s) const {
22bdd1243dSDimitry Andric s->Format(
23bdd1243dSDimitry Andric
24bdd1243dSDimitry Andric "{0:x16}: Compile Unit: length = {1:x8}, version = {2:x}, "
25bdd1243dSDimitry Andric "abbr_offset = {3:x8}, addr_size = {4:x2} (next CU at "
26bdd1243dSDimitry Andric "[{5:x16}])\n",
27bdd1243dSDimitry Andric GetOffset(), GetLength(), GetVersion(), (uint32_t)GetAbbrevOffset(),
280b57cec5SDimitry Andric GetAddressByteSize(), GetNextUnitOffset());
290b57cec5SDimitry Andric }
300b57cec5SDimitry Andric
BuildAddressRangeTable(DWARFDebugAranges * debug_aranges)310b57cec5SDimitry Andric void DWARFCompileUnit::BuildAddressRangeTable(
320b57cec5SDimitry Andric DWARFDebugAranges *debug_aranges) {
330b57cec5SDimitry Andric // This function is usually called if there in no .debug_aranges section in
340b57cec5SDimitry Andric // order to produce a compile unit level set of address ranges that is
350b57cec5SDimitry Andric // accurate.
360b57cec5SDimitry Andric
370b57cec5SDimitry Andric size_t num_debug_aranges = debug_aranges->GetNumRanges();
380b57cec5SDimitry Andric
395ffd83dbSDimitry Andric // First get the compile unit DIE only and check contains ranges information.
400b57cec5SDimitry Andric const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
410b57cec5SDimitry Andric
420b57cec5SDimitry Andric const dw_offset_t cu_offset = GetOffset();
430b57cec5SDimitry Andric if (die) {
4406c3fb27SDimitry Andric DWARFRangeList ranges =
4506c3fb27SDimitry Andric die->GetAttributeAddressRanges(this, /*check_hi_lo_pc=*/true);
4606c3fb27SDimitry Andric for (const DWARFRangeList::Entry &range : ranges)
470b57cec5SDimitry Andric debug_aranges->AppendRange(cu_offset, range.GetRangeBase(),
480b57cec5SDimitry Andric range.GetRangeEnd());
490b57cec5SDimitry Andric
5006c3fb27SDimitry Andric if (!ranges.IsEmpty())
515ffd83dbSDimitry Andric return;
520b57cec5SDimitry Andric }
530b57cec5SDimitry Andric
540b57cec5SDimitry Andric if (debug_aranges->GetNumRanges() == num_debug_aranges) {
55bdd1243dSDimitry Andric // We got nothing from the debug info, try to build the arange table from
56bdd1243dSDimitry Andric // the debug map OSO aranges.
570b57cec5SDimitry Andric SymbolContext sc;
580b57cec5SDimitry Andric sc.comp_unit = m_dwarf.GetCompUnitForDWARFCompUnit(*this);
590b57cec5SDimitry Andric if (sc.comp_unit) {
600b57cec5SDimitry Andric SymbolFileDWARFDebugMap *debug_map_sym_file =
610b57cec5SDimitry Andric m_dwarf.GetDebugMapSymfile();
62bdd1243dSDimitry Andric if (debug_map_sym_file) {
63bdd1243dSDimitry Andric auto *cu_info =
64bdd1243dSDimitry Andric debug_map_sym_file->GetCompileUnitInfo(&GetSymbolFileDWARF());
65bdd1243dSDimitry Andric // If there are extra compile units the OSO entries aren't a reliable
66bdd1243dSDimitry Andric // source of information.
67bdd1243dSDimitry Andric if (cu_info->compile_units_sps.empty())
680b57cec5SDimitry Andric debug_map_sym_file->AddOSOARanges(&m_dwarf, debug_aranges);
690b57cec5SDimitry Andric }
700b57cec5SDimitry Andric }
71bdd1243dSDimitry Andric }
720b57cec5SDimitry Andric
730b57cec5SDimitry Andric if (debug_aranges->GetNumRanges() == num_debug_aranges) {
740b57cec5SDimitry Andric // We got nothing from the functions, maybe we have a line tables only
750b57cec5SDimitry Andric // situation. Check the line tables and build the arange table from this.
760b57cec5SDimitry Andric SymbolContext sc;
770b57cec5SDimitry Andric sc.comp_unit = m_dwarf.GetCompUnitForDWARFCompUnit(*this);
780b57cec5SDimitry Andric if (sc.comp_unit) {
790b57cec5SDimitry Andric if (LineTable *line_table = sc.comp_unit->GetLineTable()) {
800b57cec5SDimitry Andric LineTable::FileAddressRanges file_ranges;
810b57cec5SDimitry Andric const bool append = true;
820b57cec5SDimitry Andric const size_t num_ranges =
830b57cec5SDimitry Andric line_table->GetContiguousFileAddressRanges(file_ranges, append);
840b57cec5SDimitry Andric for (uint32_t idx = 0; idx < num_ranges; ++idx) {
850b57cec5SDimitry Andric const LineTable::FileAddressRanges::Entry &range =
860b57cec5SDimitry Andric file_ranges.GetEntryRef(idx);
870b57cec5SDimitry Andric debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(),
880b57cec5SDimitry Andric range.GetRangeEnd());
890b57cec5SDimitry Andric }
900b57cec5SDimitry Andric }
910b57cec5SDimitry Andric }
920b57cec5SDimitry Andric }
930b57cec5SDimitry Andric }
94e8d8bef9SDimitry Andric
GetNonSkeletonUnit()95e8d8bef9SDimitry Andric DWARFCompileUnit &DWARFCompileUnit::GetNonSkeletonUnit() {
96e8d8bef9SDimitry Andric return llvm::cast<DWARFCompileUnit>(DWARFUnit::GetNonSkeletonUnit());
97e8d8bef9SDimitry Andric }
98e8d8bef9SDimitry Andric
LookupAddress(const dw_addr_t address)99e8d8bef9SDimitry Andric DWARFDIE DWARFCompileUnit::LookupAddress(const dw_addr_t address) {
100e8d8bef9SDimitry Andric if (DIE()) {
101e8d8bef9SDimitry Andric const DWARFDebugAranges &func_aranges = GetFunctionAranges();
102e8d8bef9SDimitry Andric
103e8d8bef9SDimitry Andric // Re-check the aranges auto pointer contents in case it was created above
104e8d8bef9SDimitry Andric if (!func_aranges.IsEmpty())
105e8d8bef9SDimitry Andric return GetDIE(func_aranges.FindAddress(address));
106e8d8bef9SDimitry Andric }
107e8d8bef9SDimitry Andric return DWARFDIE();
108e8d8bef9SDimitry Andric }
109