Currently, SymbolFileDWARFDebugMap works on the assumption that there is only one compile unit per object file. This patch documents this limitation (when using the general SymbolFile API), and allows users of the concrete SymbolFileDWARFDebugMap class to find out about these extra compile units. Differential Revision: https://reviews.llvm.org/D136114
110 lines
4.0 KiB
C++
110 lines
4.0 KiB
C++
//===-- DWARFCompileUnit.cpp ----------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "DWARFCompileUnit.h"
|
|
#include "DWARFDebugAranges.h"
|
|
#include "SymbolFileDWARFDebugMap.h"
|
|
|
|
#include "lldb/Symbol/CompileUnit.h"
|
|
#include "lldb/Symbol/LineTable.h"
|
|
#include "lldb/Utility/Stream.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
void DWARFCompileUnit::Dump(Stream *s) const {
|
|
s->Printf("0x%8.8x: Compile Unit: length = 0x%8.8x, version = 0x%4.4x, "
|
|
"abbr_offset = 0x%8.8x, addr_size = 0x%2.2x (next CU at "
|
|
"{0x%8.8x})\n",
|
|
GetOffset(), GetLength(), GetVersion(), GetAbbrevOffset(),
|
|
GetAddressByteSize(), GetNextUnitOffset());
|
|
}
|
|
|
|
void DWARFCompileUnit::BuildAddressRangeTable(
|
|
DWARFDebugAranges *debug_aranges) {
|
|
// This function is usually called if there in no .debug_aranges section in
|
|
// order to produce a compile unit level set of address ranges that is
|
|
// accurate.
|
|
|
|
size_t num_debug_aranges = debug_aranges->GetNumRanges();
|
|
|
|
// First get the compile unit DIE only and check contains ranges information.
|
|
const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
|
|
|
|
const dw_offset_t cu_offset = GetOffset();
|
|
if (die) {
|
|
DWARFRangeList ranges;
|
|
const size_t num_ranges =
|
|
die->GetAttributeAddressRanges(this, ranges, /*check_hi_lo_pc=*/true);
|
|
if (num_ranges > 0) {
|
|
for (size_t i = 0; i < num_ranges; ++i) {
|
|
const DWARFRangeList::Entry &range = ranges.GetEntryRef(i);
|
|
debug_aranges->AppendRange(cu_offset, range.GetRangeBase(),
|
|
range.GetRangeEnd());
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (debug_aranges->GetNumRanges() == num_debug_aranges) {
|
|
// We got nothing from the debug info, try to build the arange table from
|
|
// the debug map OSO aranges.
|
|
SymbolContext sc;
|
|
sc.comp_unit = m_dwarf.GetCompUnitForDWARFCompUnit(*this);
|
|
if (sc.comp_unit) {
|
|
SymbolFileDWARFDebugMap *debug_map_sym_file =
|
|
m_dwarf.GetDebugMapSymfile();
|
|
if (debug_map_sym_file) {
|
|
auto *cu_info =
|
|
debug_map_sym_file->GetCompileUnitInfo(&GetSymbolFileDWARF());
|
|
// If there are extra compile units the OSO entries aren't a reliable
|
|
// source of information.
|
|
if (cu_info->compile_units_sps.empty())
|
|
debug_map_sym_file->AddOSOARanges(&m_dwarf, debug_aranges);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (debug_aranges->GetNumRanges() == num_debug_aranges) {
|
|
// We got nothing from the functions, maybe we have a line tables only
|
|
// situation. Check the line tables and build the arange table from this.
|
|
SymbolContext sc;
|
|
sc.comp_unit = m_dwarf.GetCompUnitForDWARFCompUnit(*this);
|
|
if (sc.comp_unit) {
|
|
if (LineTable *line_table = sc.comp_unit->GetLineTable()) {
|
|
LineTable::FileAddressRanges file_ranges;
|
|
const bool append = true;
|
|
const size_t num_ranges =
|
|
line_table->GetContiguousFileAddressRanges(file_ranges, append);
|
|
for (uint32_t idx = 0; idx < num_ranges; ++idx) {
|
|
const LineTable::FileAddressRanges::Entry &range =
|
|
file_ranges.GetEntryRef(idx);
|
|
debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(),
|
|
range.GetRangeEnd());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
DWARFCompileUnit &DWARFCompileUnit::GetNonSkeletonUnit() {
|
|
return llvm::cast<DWARFCompileUnit>(DWARFUnit::GetNonSkeletonUnit());
|
|
}
|
|
|
|
DWARFDIE DWARFCompileUnit::LookupAddress(const dw_addr_t address) {
|
|
if (DIE()) {
|
|
const DWARFDebugAranges &func_aranges = GetFunctionAranges();
|
|
|
|
// Re-check the aranges auto pointer contents in case it was created above
|
|
if (!func_aranges.IsEmpty())
|
|
return GetDIE(func_aranges.FindAddress(address));
|
|
}
|
|
return DWARFDIE();
|
|
}
|