[DWARF] Centralize user_id <-> DWARFDIE conversions
Summary: The logic for translating a user_id into a DWARFDIE was replicated in several places. This removes that redundancy and settles on a single implementation in SymbolFileDWARF. The reason for choosing that instead of DIERef was that we were always immediately converting the returned DIERef into a DWARFDIE anyway, which meant that one had to specify the SymbolFileDWARF argument twice (once to get the DIERef, and once to get the actual DIE). Also, passing a higher-level object (SymbolFileDWARF) into a lower-level one (DIERef) seemed like a less intuitive arrangement than doing things the other way around. Reviewers: JDevlieghere, clayborg, aprantl Subscribers: tberghammer, jankratochvil, lldb-commits Differential Revision: https://reviews.llvm.org/D61648 llvm-svn: 360246
This commit is contained in:
parent
2788ad3ee2
commit
2841e6edc8
|
@ -13,29 +13,6 @@
|
|||
#include "SymbolFileDWARF.h"
|
||||
#include "SymbolFileDWARFDebugMap.h"
|
||||
|
||||
DIERef::DIERef(lldb::user_id_t uid, SymbolFileDWARF *dwarf)
|
||||
: cu_offset(DW_INVALID_OFFSET), die_offset(uid & 0xffffffff) {
|
||||
SymbolFileDWARFDebugMap *debug_map = dwarf->GetDebugMapSymfile();
|
||||
if (debug_map) {
|
||||
const uint32_t oso_idx = debug_map->GetOSOIndexFromUserID(uid);
|
||||
SymbolFileDWARF *actual_dwarf = debug_map->GetSymbolFileByOSOIndex(oso_idx);
|
||||
if (actual_dwarf) {
|
||||
DWARFDebugInfo *debug_info = actual_dwarf->DebugInfo();
|
||||
if (debug_info) {
|
||||
DWARFUnit *dwarf_cu =
|
||||
debug_info->GetCompileUnitContainingDIEOffset(die_offset);
|
||||
if (dwarf_cu) {
|
||||
cu_offset = dwarf_cu->GetOffset();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
die_offset = DW_INVALID_OFFSET;
|
||||
} else {
|
||||
cu_offset = uid >> 32;
|
||||
}
|
||||
}
|
||||
|
||||
DIERef::DIERef(const DWARFFormValue &form_value)
|
||||
: cu_offset(DW_INVALID_OFFSET), die_offset(DW_INVALID_OFFSET) {
|
||||
if (form_value.IsValid()) {
|
||||
|
@ -49,16 +26,3 @@ DIERef::DIERef(const DWARFFormValue &form_value)
|
|||
die_offset = form_value.Reference();
|
||||
}
|
||||
}
|
||||
|
||||
lldb::user_id_t DIERef::GetUID(SymbolFileDWARF *dwarf) const {
|
||||
// Each SymbolFileDWARF will set its ID to what is expected.
|
||||
//
|
||||
// SymbolFileDWARF, when used for DWARF with .o files on MacOSX, has the
|
||||
// ID set to the compile unit index.
|
||||
//
|
||||
// SymbolFileDWARFDwo sets the ID to the compile unit offset.
|
||||
if (dwarf && die_offset != DW_INVALID_OFFSET)
|
||||
return dwarf->GetID() | die_offset;
|
||||
else
|
||||
return LLDB_INVALID_UID;
|
||||
}
|
||||
|
|
|
@ -20,20 +20,8 @@ struct DIERef {
|
|||
|
||||
DIERef(dw_offset_t c, dw_offset_t d) : cu_offset(c), die_offset(d) {}
|
||||
|
||||
// In order to properly decode a lldb::user_id_t back into a DIERef we
|
||||
// need the DWARF file since it knows if DWARF in .o files is being used
|
||||
// (MacOSX) or if DWO files are being used. The encoding of the user ID
|
||||
// differs between the two types of DWARF.
|
||||
explicit DIERef(lldb::user_id_t uid, SymbolFileDWARF *dwarf);
|
||||
|
||||
explicit DIERef(const DWARFFormValue &form_value);
|
||||
|
||||
// In order to properly encode a DIERef unto a lldb::user_id_t we need
|
||||
// the DWARF file since it knows if DWARF in .o files is being used
|
||||
// (MacOSX) or if DWO files are being used. The encoding of the user ID
|
||||
// differs between the two types of DWARF.
|
||||
lldb::user_id_t GetUID(SymbolFileDWARF *dwarf) const;
|
||||
|
||||
bool operator<(const DIERef &ref) const {
|
||||
return die_offset < ref.die_offset;
|
||||
}
|
||||
|
|
|
@ -524,7 +524,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
|
|||
|
||||
type_sp = std::make_shared<Type>(
|
||||
die.GetID(), dwarf, type_name_const_str, byte_size, nullptr,
|
||||
DIERef(encoding_uid).GetUID(dwarf), encoding_data_type, &decl,
|
||||
dwarf->GetUID(DIERef(encoding_uid)), encoding_data_type, &decl,
|
||||
clang_type, resolve_state);
|
||||
|
||||
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
|
||||
|
@ -763,7 +763,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
|
|||
// it and cache the fact that we found a complete type for this die
|
||||
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
|
||||
clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(
|
||||
dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID(), dwarf)));
|
||||
dwarf->GetDIE(type_sp->GetID()));
|
||||
if (defn_decl_ctx)
|
||||
LinkDeclContextToDIE(defn_decl_ctx, die);
|
||||
return type_sp;
|
||||
|
@ -1067,8 +1067,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
|
|||
// die
|
||||
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
|
||||
clang::DeclContext *defn_decl_ctx =
|
||||
GetCachedClangDeclContextForDIE(dwarf->DebugInfo()->GetDIE(
|
||||
DIERef(type_sp->GetID(), dwarf)));
|
||||
GetCachedClangDeclContextForDIE(
|
||||
dwarf->GetDIE(type_sp->GetID()));
|
||||
if (defn_decl_ctx)
|
||||
LinkDeclContextToDIE(defn_decl_ctx, die);
|
||||
return type_sp;
|
||||
|
@ -1112,7 +1112,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
|
|||
|
||||
type_sp = std::make_shared<Type>(
|
||||
die.GetID(), dwarf, type_name_const_str, byte_size, nullptr,
|
||||
DIERef(encoding_form).GetUID(dwarf), Type::eEncodingIsUID, &decl,
|
||||
dwarf->GetUID(DIERef(encoding_form)), Type::eEncodingIsUID, &decl,
|
||||
clang_type, Type::eResolveStateForward);
|
||||
|
||||
if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
|
||||
|
@ -1383,22 +1383,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
|
|||
// We uniqued the parent class of this function to another
|
||||
// class so we now need to associate all dies under
|
||||
// "decl_ctx_die" to DIEs in the DIE for "class_type"...
|
||||
SymbolFileDWARF *class_symfile = NULL;
|
||||
DWARFDIE class_type_die;
|
||||
DWARFDIE class_type_die = dwarf->GetDIE(class_type->GetID());
|
||||
|
||||
SymbolFileDWARFDebugMap *debug_map_symfile =
|
||||
dwarf->GetDebugMapSymfile();
|
||||
if (debug_map_symfile) {
|
||||
class_symfile = debug_map_symfile->GetSymbolFileByOSOIndex(
|
||||
SymbolFileDWARFDebugMap::GetOSOIndexFromUserID(
|
||||
class_type->GetID()));
|
||||
class_type_die = class_symfile->DebugInfo()->GetDIE(
|
||||
DIERef(class_type->GetID(), dwarf));
|
||||
} else {
|
||||
class_symfile = dwarf;
|
||||
class_type_die = dwarf->DebugInfo()->GetDIE(
|
||||
DIERef(class_type->GetID(), dwarf));
|
||||
}
|
||||
if (class_type_die) {
|
||||
std::vector<DWARFDIE> failures;
|
||||
|
||||
|
@ -1822,7 +1808,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
|
|||
ConstString empty_name;
|
||||
type_sp = std::make_shared<Type>(
|
||||
die.GetID(), dwarf, empty_name, array_element_bit_stride / 8,
|
||||
nullptr, DIERef(type_die_form).GetUID(dwarf),
|
||||
nullptr, dwarf->GetUID(DIERef(type_die_form)),
|
||||
Type::eEncodingIsUID, &decl, clang_type,
|
||||
Type::eResolveStateFull);
|
||||
type_sp->SetEncodingType(element_type);
|
||||
|
|
|
@ -75,7 +75,9 @@ uint64_t DWARFBaseDIE::GetAttributeValueAsAddress(const dw_attr_t attr,
|
|||
}
|
||||
|
||||
lldb::user_id_t DWARFBaseDIE::GetID() const {
|
||||
return GetDIERef().GetUID(GetDWARF());
|
||||
if (IsValid())
|
||||
return GetDWARF()->GetUID(*this);
|
||||
return LLDB_INVALID_UID;
|
||||
}
|
||||
|
||||
const char *DWARFBaseDIE::GetName() const {
|
||||
|
|
|
@ -1243,7 +1243,7 @@ void SymbolFileDWARF::ParseDeclsForContext(CompilerDeclContext decl_ctx) {
|
|||
ast_parser->GetDeclForUIDFromDWARF(decl);
|
||||
}
|
||||
|
||||
SymbolFileDWARF *SymbolFileDWARF::GetDWARFForUID(lldb::user_id_t uid) {
|
||||
SymbolFileDWARF::DecodedUID SymbolFileDWARF::DecodeUID(lldb::user_id_t uid) {
|
||||
// This method can be called without going through the symbol vendor so we
|
||||
// need to lock the module.
|
||||
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
|
||||
|
@ -1254,28 +1254,25 @@ SymbolFileDWARF *SymbolFileDWARF::GetDWARFForUID(lldb::user_id_t uid) {
|
|||
// references to other DWARF objects and we must be ready to receive a
|
||||
// "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
|
||||
// instance.
|
||||
SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile();
|
||||
if (debug_map)
|
||||
return debug_map->GetSymbolFileByOSOIndex(
|
||||
if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile()) {
|
||||
SymbolFileDWARF *dwarf = debug_map->GetSymbolFileByOSOIndex(
|
||||
debug_map->GetOSOIndexFromUserID(uid));
|
||||
return this;
|
||||
return {dwarf, {DW_INVALID_OFFSET, dw_offset_t(uid)}};
|
||||
}
|
||||
return {this, {dw_offset_t(uid >> 32), dw_offset_t(uid)}};
|
||||
}
|
||||
|
||||
DWARFDIE
|
||||
SymbolFileDWARF::GetDIEFromUID(lldb::user_id_t uid) {
|
||||
SymbolFileDWARF::GetDIE(lldb::user_id_t uid) {
|
||||
// This method can be called without going through the symbol vendor so we
|
||||
// need to lock the module.
|
||||
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
|
||||
// Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we
|
||||
// must make sure we use the correct DWARF file when resolving things. On
|
||||
// MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
|
||||
// SymbolFileDWARF classes, one for each .o file. We can often end up with
|
||||
// references to other DWARF objects and we must be ready to receive a
|
||||
// "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
|
||||
// instance.
|
||||
SymbolFileDWARF *dwarf = GetDWARFForUID(uid);
|
||||
if (dwarf)
|
||||
return dwarf->GetDIE(DIERef(uid, dwarf));
|
||||
|
||||
DecodedUID decoded = DecodeUID(uid);
|
||||
|
||||
if (decoded.dwarf)
|
||||
return decoded.dwarf->GetDIE(decoded.ref);
|
||||
|
||||
return DWARFDIE();
|
||||
}
|
||||
|
||||
|
@ -1284,10 +1281,9 @@ CompilerDecl SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid) {
|
|||
// need to lock the module.
|
||||
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
|
||||
// Anytime we have a lldb::user_id_t, we must get the DIE by calling
|
||||
// SymbolFileDWARF::GetDIEFromUID(). See comments inside the
|
||||
// SymbolFileDWARF::GetDIEFromUID() for details.
|
||||
DWARFDIE die = GetDIEFromUID(type_uid);
|
||||
if (die)
|
||||
// SymbolFileDWARF::GetDIE(). See comments inside the
|
||||
// SymbolFileDWARF::GetDIE() for details.
|
||||
if (DWARFDIE die = GetDIE(type_uid))
|
||||
return die.GetDecl();
|
||||
return CompilerDecl();
|
||||
}
|
||||
|
@ -1298,10 +1294,9 @@ SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) {
|
|||
// need to lock the module.
|
||||
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
|
||||
// Anytime we have a lldb::user_id_t, we must get the DIE by calling
|
||||
// SymbolFileDWARF::GetDIEFromUID(). See comments inside the
|
||||
// SymbolFileDWARF::GetDIEFromUID() for details.
|
||||
DWARFDIE die = GetDIEFromUID(type_uid);
|
||||
if (die)
|
||||
// SymbolFileDWARF::GetDIE(). See comments inside the
|
||||
// SymbolFileDWARF::GetDIE() for details.
|
||||
if (DWARFDIE die = GetDIE(type_uid))
|
||||
return die.GetDeclContext();
|
||||
return CompilerDeclContext();
|
||||
}
|
||||
|
@ -1312,10 +1307,9 @@ SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
|
|||
// need to lock the module.
|
||||
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
|
||||
// Anytime we have a lldb::user_id_t, we must get the DIE by calling
|
||||
// SymbolFileDWARF::GetDIEFromUID(). See comments inside the
|
||||
// SymbolFileDWARF::GetDIEFromUID() for details.
|
||||
DWARFDIE die = GetDIEFromUID(type_uid);
|
||||
if (die)
|
||||
// SymbolFileDWARF::GetDIE(). See comments inside the
|
||||
// SymbolFileDWARF::GetDIE() for details.
|
||||
if (DWARFDIE die = GetDIE(type_uid))
|
||||
return die.GetContainingDeclContext();
|
||||
return CompilerDeclContext();
|
||||
}
|
||||
|
@ -1325,10 +1319,9 @@ Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) {
|
|||
// need to lock the module.
|
||||
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
|
||||
// Anytime we have a lldb::user_id_t, we must get the DIE by calling
|
||||
// SymbolFileDWARF::GetDIEFromUID(). See comments inside the
|
||||
// SymbolFileDWARF::GetDIEFromUID() for details.
|
||||
DWARFDIE type_die = GetDIEFromUID(type_uid);
|
||||
if (type_die)
|
||||
// SymbolFileDWARF::GetDIE(). See comments inside the
|
||||
// SymbolFileDWARF::GetDIE() for details.
|
||||
if (DWARFDIE type_die = GetDIE(type_uid))
|
||||
return type_die.ResolveType();
|
||||
else
|
||||
return nullptr;
|
||||
|
@ -1338,8 +1331,7 @@ llvm::Optional<SymbolFile::ArrayInfo>
|
|||
SymbolFileDWARF::GetDynamicArrayInfoForUID(
|
||||
lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
|
||||
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
|
||||
DWARFDIE type_die = GetDIEFromUID(type_uid);
|
||||
if (type_die)
|
||||
if (DWARFDIE type_die = GetDIE(type_uid))
|
||||
return DWARFASTParser::ParseChildArrayInfo(type_die, exe_ctx);
|
||||
else
|
||||
return llvm::None;
|
||||
|
@ -3105,7 +3097,7 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
|
|||
return 0;
|
||||
|
||||
if (sc.function) {
|
||||
DWARFDIE function_die = info->GetDIE(DIERef(sc.function->GetID(), this));
|
||||
DWARFDIE function_die = GetDIE(sc.function->GetID());
|
||||
|
||||
const dw_addr_t func_lo_pc = function_die.GetAttributeValueAsAddress(
|
||||
DW_AT_low_pc, LLDB_INVALID_ADDRESS);
|
||||
|
@ -3531,7 +3523,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
|
|||
|
||||
if (symbol_context_scope) {
|
||||
SymbolFileTypeSP type_sp(
|
||||
new SymbolFileType(*this, DIERef(type_die_form).GetUID(this)));
|
||||
new SymbolFileType(*this, GetUID(DIERef(type_die_form))));
|
||||
|
||||
if (const_value.Form() && type_sp && type_sp->GetType())
|
||||
location.CopyOpcodeData(
|
||||
|
@ -3668,7 +3660,7 @@ size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc,
|
|||
// variable to it
|
||||
const DWARFDIE concrete_block_die =
|
||||
FindBlockContainingSpecification(
|
||||
DIERef(sc.function->GetID(), this),
|
||||
GetDIE(sc.function->GetID()),
|
||||
sc_parent_die.GetOffset());
|
||||
if (concrete_block_die)
|
||||
block = sc.function->GetBlock(true).FindBlockByID(
|
||||
|
@ -3770,7 +3762,7 @@ CollectCallEdges(DWARFDIE function_die) {
|
|||
|
||||
std::vector<lldb_private::CallEdge>
|
||||
SymbolFileDWARF::ParseCallEdgesInFunction(UserID func_id) {
|
||||
DWARFDIE func_die = GetDIEFromUID(func_id.GetID());
|
||||
DWARFDIE func_die = GetDIE(func_id.GetID());
|
||||
if (func_die.IsValid())
|
||||
return CollectCallEdges(func_die);
|
||||
return {};
|
||||
|
|
|
@ -134,11 +134,6 @@ public:
|
|||
bool assert_not_being_parsed = true,
|
||||
bool resolve_function_context = false);
|
||||
|
||||
SymbolFileDWARF *GetDWARFForUID(lldb::user_id_t uid);
|
||||
|
||||
DWARFDIE
|
||||
GetDIEFromUID(lldb::user_id_t uid);
|
||||
|
||||
lldb_private::CompilerDecl GetDeclForUID(lldb::user_id_t uid) override;
|
||||
|
||||
lldb_private::CompilerDeclContext
|
||||
|
@ -289,6 +284,14 @@ public:
|
|||
|
||||
virtual DWARFDIE GetDIE(const DIERef &die_ref);
|
||||
|
||||
DWARFDIE GetDIE(lldb::user_id_t uid);
|
||||
|
||||
lldb::user_id_t GetUID(const DWARFBaseDIE &die) {
|
||||
return GetID() | die.GetOffset();
|
||||
}
|
||||
|
||||
lldb::user_id_t GetUID(const DIERef &ref) { return GetID() | ref.die_offset; }
|
||||
|
||||
virtual std::unique_ptr<SymbolFileDWARFDwo>
|
||||
GetDwoSymbolFileForCompileUnit(DWARFUnit &dwarf_cu,
|
||||
const DWARFDebugInfoEntry &cu_die);
|
||||
|
@ -440,6 +443,12 @@ protected:
|
|||
return m_forward_decl_clang_type_to_die;
|
||||
}
|
||||
|
||||
struct DecodedUID {
|
||||
SymbolFileDWARF *dwarf;
|
||||
DIERef ref;
|
||||
};
|
||||
DecodedUID DecodeUID(lldb::user_id_t uid);
|
||||
|
||||
SymbolFileDWARFDwp *GetDwpSymbolFile();
|
||||
|
||||
lldb::ModuleWP m_debug_map_module_wp;
|
||||
|
|
Loading…
Reference in New Issue