Pavel Labath wrote in D73206: The internal representation of DebugNames and Apple indexes is fixed by the relevant (pseudo-)standards, so we can't really change it. The question is how to efficiently (and cleanly) convert from the internal representation to some common thing. The conversion from AppleIndex to DIERef is trivial (which is not surprising as it was the first and the overall design was optimized for that). With debug_names, the situation gets more tricky. The internal representation of debug_names uses CU-relative DIE offsets, but DIERef wants an absolute offset. That means the index has to do more work to produce the common representation. And it needs to do that for all results, even though a lot of the index users are really interested only in a single entry. With the switch to user_id_t, _all_ indexes would have to do some extra work to encode it, only for their users to have to immediately decode it back. Having a iterator/callback based api would allow us to minimize the impact of that, as it would only need to happen for the entries that are really used. And /I think/ we could make it interface returns DWARFDies directly, and each index converts to that using the most direct approach available. Jan Kratochvil: It also makes all the callers shorter as they no longer need to fetch DWARFDIE from DIERef (and handling if not found by ReportInvalidDIERef) but the callers are already served DWARFDIE which they need. In some cases the DWARFDIE had to be fetched both by callee (DWARFIndex implementation) and caller. Differential Revision: https://reviews.llvm.org/D77970
132 lines
4.4 KiB
C++
132 lines
4.4 KiB
C++
//===-- SymbolFileDWARFDwo.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 "SymbolFileDWARFDwo.h"
|
|
|
|
#include "lldb/Core/Section.h"
|
|
#include "lldb/Expression/DWARFExpression.h"
|
|
#include "lldb/Symbol/ObjectFile.h"
|
|
#include "lldb/Utility/LLDBAssert.h"
|
|
#include "llvm/Support/Casting.h"
|
|
|
|
#include "DWARFCompileUnit.h"
|
|
#include "DWARFDebugInfo.h"
|
|
#include "DWARFUnit.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
char SymbolFileDWARFDwo::ID;
|
|
|
|
SymbolFileDWARFDwo::SymbolFileDWARFDwo(SymbolFileDWARF &base_symbol_file,
|
|
ObjectFileSP objfile, uint32_t id)
|
|
: SymbolFileDWARF(objfile, objfile->GetSectionList(
|
|
/*update_module_section_list*/ false)),
|
|
m_base_symbol_file(base_symbol_file) {
|
|
SetID(user_id_t(id) << 32);
|
|
|
|
// Parsing of the dwarf unit index is not thread-safe, so we need to prime it
|
|
// to enable subsequent concurrent lookups.
|
|
m_context.GetAsLLVM().getCUIndex();
|
|
}
|
|
|
|
DWARFCompileUnit *SymbolFileDWARFDwo::GetDWOCompileUnitForHash(uint64_t hash) {
|
|
if (const llvm::DWARFUnitIndex &index = m_context.GetAsLLVM().getCUIndex()) {
|
|
if (const llvm::DWARFUnitIndex::Entry *entry = index.getFromHash(hash)) {
|
|
if (auto *unit_contrib = entry->getContribution())
|
|
return llvm::dyn_cast_or_null<DWARFCompileUnit>(
|
|
DebugInfo().GetUnitAtOffset(DIERef::Section::DebugInfo,
|
|
unit_contrib->Offset));
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
DWARFCompileUnit *cu = FindSingleCompileUnit();
|
|
if (!cu)
|
|
return nullptr;
|
|
if (hash !=
|
|
cu->GetUnitDIEOnly().GetAttributeValueAsUnsigned(DW_AT_GNU_dwo_id, 0))
|
|
return nullptr;
|
|
return cu;
|
|
}
|
|
|
|
DWARFCompileUnit *SymbolFileDWARFDwo::FindSingleCompileUnit() {
|
|
DWARFDebugInfo &debug_info = DebugInfo();
|
|
|
|
// Right now we only support dwo files with one compile unit. If we don't have
|
|
// type units, we can just check for the unit count.
|
|
if (!debug_info.ContainsTypeUnits() && debug_info.GetNumUnits() == 1)
|
|
return llvm::cast<DWARFCompileUnit>(debug_info.GetUnitAtIndex(0));
|
|
|
|
// Otherwise, we have to run through all units, and find the compile unit that
|
|
// way.
|
|
DWARFCompileUnit *cu = nullptr;
|
|
for (size_t i = 0; i < debug_info.GetNumUnits(); ++i) {
|
|
if (auto *candidate =
|
|
llvm::dyn_cast<DWARFCompileUnit>(debug_info.GetUnitAtIndex(i))) {
|
|
if (cu)
|
|
return nullptr; // More that one CU found.
|
|
cu = candidate;
|
|
}
|
|
}
|
|
return cu;
|
|
}
|
|
|
|
SymbolFileDWARF::DIEToTypePtr &SymbolFileDWARFDwo::GetDIEToType() {
|
|
return GetBaseSymbolFile().GetDIEToType();
|
|
}
|
|
|
|
SymbolFileDWARF::DIEToVariableSP &SymbolFileDWARFDwo::GetDIEToVariable() {
|
|
return GetBaseSymbolFile().GetDIEToVariable();
|
|
}
|
|
|
|
SymbolFileDWARF::DIEToClangType &
|
|
SymbolFileDWARFDwo::GetForwardDeclDieToClangType() {
|
|
return GetBaseSymbolFile().GetForwardDeclDieToClangType();
|
|
}
|
|
|
|
SymbolFileDWARF::ClangTypeToDIE &
|
|
SymbolFileDWARFDwo::GetForwardDeclClangTypeToDie() {
|
|
return GetBaseSymbolFile().GetForwardDeclClangTypeToDie();
|
|
}
|
|
|
|
void SymbolFileDWARFDwo::GetObjCMethods(
|
|
lldb_private::ConstString class_name,
|
|
llvm::function_ref<bool(DWARFDIE die)> callback) {
|
|
GetBaseSymbolFile().GetObjCMethods(class_name, callback);
|
|
}
|
|
|
|
UniqueDWARFASTTypeMap &SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap() {
|
|
return GetBaseSymbolFile().GetUniqueDWARFASTTypeMap();
|
|
}
|
|
|
|
lldb::TypeSP SymbolFileDWARFDwo::FindDefinitionTypeForDWARFDeclContext(
|
|
const DWARFDeclContext &die_decl_ctx) {
|
|
return GetBaseSymbolFile().FindDefinitionTypeForDWARFDeclContext(
|
|
die_decl_ctx);
|
|
}
|
|
|
|
lldb::TypeSP SymbolFileDWARFDwo::FindCompleteObjCDefinitionTypeForDIE(
|
|
const DWARFDIE &die, lldb_private::ConstString type_name,
|
|
bool must_be_implementation) {
|
|
return GetBaseSymbolFile().FindCompleteObjCDefinitionTypeForDIE(
|
|
die, type_name, must_be_implementation);
|
|
}
|
|
|
|
llvm::Expected<TypeSystem &>
|
|
SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) {
|
|
return GetBaseSymbolFile().GetTypeSystemForLanguage(language);
|
|
}
|
|
|
|
DWARFDIE
|
|
SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) {
|
|
if (die_ref.dwo_num() == GetDwoNum())
|
|
return DebugInfo().GetDIE(die_ref);
|
|
return GetBaseSymbolFile().GetDIE(die_ref);
|
|
}
|