diff options
Diffstat (limited to 'contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp')
-rw-r--r-- | contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp new file mode 100644 index 000000000000..ec4c297cf7e1 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -0,0 +1,108 @@ +//===-- 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; +using namespace lldb_private::plugin::dwarf; + +void DWARFCompileUnit::Dump(Stream *s) const { + s->Format( + + "{0:x16}: Compile Unit: length = {1:x8}, version = {2:x}, " + "abbr_offset = {3:x8}, addr_size = {4:x2} (next CU at " + "[{5:x16}])\n", + GetOffset(), GetLength(), GetVersion(), (uint32_t)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 = + die->GetAttributeAddressRanges(this, /*check_hi_lo_pc=*/true); + for (const DWARFRangeList::Entry &range : ranges) + debug_aranges->AppendRange(cu_offset, range.GetRangeBase(), + range.GetRangeEnd()); + + if (!ranges.IsEmpty()) + 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(); +} |