Skip to content

Commit

Permalink
[DWARF] Centralize user_id <-> DWARFDIE conversions
Browse files Browse the repository at this point in the history
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
  • Loading branch information
labath authored and MrSidims committed May 24, 2019
1 parent 8a44eee commit 2aebdac
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 114 deletions.
36 changes: 0 additions & 36 deletions lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp
Expand Up @@ -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()) {
Expand All @@ -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;
}
12 changes: 0 additions & 12 deletions lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
Expand Up @@ -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;
}
Expand Down
30 changes: 8 additions & 22 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
Expand Up @@ -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();
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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;

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));
}
DWARFDIE class_type_die = dwarf->GetDIE(class_type->GetID());

if (class_type_die) {
std::vector<DWARFDIE> failures;

Expand Down Expand Up @@ -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);
Expand Down
4 changes: 3 additions & 1 deletion lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
Expand Up @@ -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 {
Expand Down
68 changes: 30 additions & 38 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
Expand Up @@ -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());
Expand All @@ -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();
}

Expand All @@ -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();
}
Expand All @@ -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();
}
Expand All @@ -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();
}
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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 {};
Expand Down
19 changes: 14 additions & 5 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
Expand Up @@ -134,11 +134,6 @@ class SymbolFileDWARF : public lldb_private::SymbolFile,
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
Expand Down Expand Up @@ -289,6 +284,14 @@ class SymbolFileDWARF : public lldb_private::SymbolFile,

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);
Expand Down Expand Up @@ -440,6 +443,12 @@ class SymbolFileDWARF : public lldb_private::SymbolFile,
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;
Expand Down

0 comments on commit 2aebdac

Please sign in to comment.