sgraenitz updated this revision to Diff 167109.
sgraenitz marked an inline comment as done.
sgraenitz added a comment.
Skip AddOSOARanges() if the OSO debug map entry has multiple compile units.
https://reviews.llvm.org/D52375
Files:
include/lldb/Symbol/Symtab.h
source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
source/Symbol/Symtab.cpp
Index: source/Symbol/Symtab.cpp
===================================================================
--- source/Symbol/Symtab.cpp
+++ source/Symbol/Symtab.cpp
@@ -509,6 +509,16 @@
return indexes.size() - prev_size;
}
+bool Symtab::HasSymbolWithTypeAndFlags(lldb::SymbolType symbol_type,
+ uint32_t flags_value) const {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ for (const Symbol &symbol : m_symbols)
+ if (symbol.GetType() == symbol_type && symbol.GetFlags() == flags_value)
+ return true;
+
+ return false;
+}
+
uint32_t Symtab::AppendSymbolIndexesWithType(SymbolType symbol_type,
Debug symbol_debug_type,
Visibility symbol_visibility,
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -131,7 +131,11 @@
uint32_t GetPluginVersion() override;
protected:
- enum { kHaveInitializedOSOs = (1 << 0), kNumFlags };
+ enum {
+ kHaveInitializedOSOs = (1 << 0),
+ kHaveCheckedCUInfos = (1 << 1),
+ kNumFlags
+ };
friend class DebugMapModule;
friend struct DIERef;
@@ -172,13 +176,17 @@
first_symbol_id(UINT32_MAX), last_symbol_id(UINT32_MAX),
file_range_map(), file_range_map_valid(false) {}
+ bool Init(lldb_private::Symbol *so, lldb_private::Symbol *oso);
const FileRangeMap &GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile);
};
//------------------------------------------------------------------
// Protected Member Functions
//------------------------------------------------------------------
void InitOSO();
+ bool HasCompileUnits();
+ void ReportErrorInitOSO(lldb_private::Symbol *so_symbol,
+ lldb_private::Symbol *oso_symbol, uint32_t oso_idx);
static uint32_t GetOSOIndexFromUserID(lldb::user_id_t uid) {
return (uint32_t)((uid >> 32ull) - 1ull);
@@ -247,6 +255,11 @@
lldb::CompUnitSP GetCompileUnit(SymbolFileDWARF *oso_dwarf);
+ lldb::CompUnitSP GetCompileUnitByIndex(SymbolFileDWARF *oso_dwarf,
+ uint32_t cu_idx);
+ lldb::CompUnitSP GetCompileUnitByOffset(SymbolFileDWARF *oso_dwarf,
+ dw_offset_t cu_offset);
+
CompileUnitInfo *GetCompileUnitInfo(SymbolFileDWARF *oso_dwarf);
lldb::TypeSP
@@ -297,6 +310,8 @@
// Member Variables
//------------------------------------------------------------------
std::bitset<kNumFlags> m_flags;
+ bool m_has_compile_unit_infos;
+ std::vector<lldb::offset_t> m_oso_compile_unit_offset;
std::vector<CompileUnitInfo> m_compile_unit_infos;
std::vector<uint32_t> m_func_indexes; // Sorted by address
std::vector<uint32_t> m_glob_indexes;
@@ -373,7 +388,7 @@
LinkOSOLineTable(SymbolFileDWARF *oso_symfile,
lldb_private::LineTable *line_table);
- size_t AddOSOARanges(SymbolFileDWARF *dwarf2Data,
+ size_t AddOSOARanges(SymbolFileDWARF *dwarf2Data, dw_offset_t cu_offset,
DWARFDebugAranges *debug_aranges);
};
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -37,6 +37,7 @@
#include "lldb/Symbol/VariableList.h"
#include "llvm/Support/ScopedPrinter.h"
+#include "DWARFCompileUnit.h"
#include "LogChannelDWARF.h"
#include "SymbolFileDWARF.h"
@@ -169,6 +170,23 @@
return file_range_map;
}
+bool SymbolFileDWARFDebugMap::CompileUnitInfo::Init(Symbol *so, Symbol *oso) {
+ if (!so || so->GetType() != eSymbolTypeSourceFile)
+ return false;
+
+ if (!oso || oso->GetType() != eSymbolTypeObjectFile)
+ return false;
+
+ if (so->GetSiblingIndex() == UINT32_MAX)
+ return false;
+
+ llvm::StringRef so_file_name = so->GetName().GetStringRef();
+ so_file.SetFile(so_file_name, false, FileSpec::Style::native);
+ oso_mod_time = llvm::sys::toTimePoint(oso->GetIntegerValue(0));
+ oso_path = oso->GetName();
+ return true;
+}
+
class DebugMapModule : public Module {
public:
DebugMapModule(const ModuleSP &exe_module_sp, uint32_t cu_idx,
@@ -251,61 +269,63 @@
}
SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFile *ofile)
- : SymbolFile(ofile), m_flags(), m_compile_unit_infos(), m_func_indexes(),
- m_glob_indexes(),
+ : SymbolFile(ofile), m_flags(), m_has_compile_unit_infos(false),
+ m_compile_unit_infos(), m_func_indexes(), m_glob_indexes(),
m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {}
SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() {}
void SymbolFileDWARFDebugMap::InitializeObject() {}
-void SymbolFileDWARFDebugMap::InitOSO() {
- if (m_flags.test(kHaveInitializedOSOs))
- return;
-
- m_flags.set(kHaveInitializedOSOs);
-
- // If the object file has been stripped, there is no sense in looking further
- // as all of the debug symbols for the debug map will not be available
- if (m_obj_file->IsStripped())
- return;
-
- // Also make sure the file type is some sort of executable. Core files, debug
- // info files (dSYM), object files (.o files), and stub libraries all can
- switch (m_obj_file->GetType()) {
+static bool IsExecutableType(ObjectFile::Type type) {
+ switch (type) {
case ObjectFile::eTypeInvalid:
case ObjectFile::eTypeCoreFile:
case ObjectFile::eTypeDebugInfo:
case ObjectFile::eTypeObjectFile:
case ObjectFile::eTypeStubLibrary:
case ObjectFile::eTypeUnknown:
case ObjectFile::eTypeJIT:
- return;
+ return false;
case ObjectFile::eTypeExecutable:
case ObjectFile::eTypeDynamicLinker:
case ObjectFile::eTypeSharedLibrary:
- break;
+ return true;
}
+}
- // In order to get the abilities of this plug-in, we look at the list of
- // N_OSO entries (object files) from the symbol table and make sure that
- // these files exist and also contain valid DWARF. If we get any of that then
- // we return the abilities of the first N_OSO's DWARF.
+static uint32_t GetOSOSymbolFlags() {
+ // When a mach-o symbol is encoded, the n_type field is encoded in bits
+ // 23:16, and the n_desc field is encoded in bits 15:0.
+ //
+ // N_OSO object file symbols have a flags value as follows:
+ // bits 23:16 == 0x66 (N_OSO)
+ // bits 15: 0 == 0x0001 (specifies this is a debug map object file)
+ return 0x660001u;
+}
+
+void SymbolFileDWARFDebugMap::InitOSO() {
+ if (m_flags.test(kHaveInitializedOSOs))
+ return;
+
+ m_flags.set(kHaveInitializedOSOs);
+
+ // If the object file has been stripped, there is no sense in looking further
+ // as all of the debug symbols for the debug map will not be available
+ if (m_obj_file->IsStripped())
+ return;
+
+ // Also make sure the file type is some sort of executable.
+ if (!IsExecutableType(m_obj_file->GetType()))
+ return;
Symtab *symtab = m_obj_file->GetSymtab();
if (symtab) {
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
std::vector<uint32_t> oso_indexes;
- // When a mach-o symbol is encoded, the n_type field is encoded in bits
- // 23:16, and the n_desc field is encoded in bits 15:0.
- //
- // To find all N_OSO entries that are part of the DWARF + debug map we find
- // only object file symbols with the flags value as follows: bits 23:16 ==
- // 0x66 (N_OSO) bits 15: 0 == 0x0001 (specifies this is a debug map object
- // file)
- const uint32_t k_oso_symbol_flags_value = 0x660001u;
+ const uint32_t k_oso_symbol_flags_value = GetOSOSymbolFlags();
const uint32_t oso_index_count =
symtab->AppendSymbolIndexesWithTypeAndFlagsValue(
@@ -340,67 +360,97 @@
}
m_debug_map.Sort();
- m_compile_unit_infos.resize(oso_index_count);
+ assert(m_compile_unit_infos.empty());
+ assert(m_oso_compile_unit_offset.empty());
for (uint32_t i = 0; i < oso_index_count; ++i) {
const uint32_t so_idx = oso_indexes[i] - 1;
const uint32_t oso_idx = oso_indexes[i];
- const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx);
- const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx);
- if (so_symbol && oso_symbol &&
- so_symbol->GetType() == eSymbolTypeSourceFile &&
- oso_symbol->GetType() == eSymbolTypeObjectFile) {
- m_compile_unit_infos[i].so_file.SetFile(
- so_symbol->GetName().AsCString(), false, FileSpec::Style::native);
- m_compile_unit_infos[i].oso_path = oso_symbol->GetName();
- m_compile_unit_infos[i].oso_mod_time =
- llvm::sys::toTimePoint(oso_symbol->GetIntegerValue(0));
+ Symbol *so_symbol = symtab->SymbolAtIndex(so_idx);
+ Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx);
+
+ // oso_info is the basis for the individual cu_infos below.
+ CompileUnitInfo oso_info;
+ if (!oso_info.Init(so_symbol, oso_symbol)) {
+ ReportErrorInitOSO(so_symbol, oso_symbol, oso_idx);
+ continue;
+ }
+
+ SymbolFileDWARF *sym_file = GetSymbolFileByCompUnitInfo(&oso_info);
+ if (!sym_file)
+ continue;
+
+ const auto &debug_info_data = sym_file->get_debug_info_data();
+ auto ExtractNext = [sym_file, &debug_info_data](lldb::offset_t offs) {
+ return DWARFCompileUnit::Extract(sym_file, debug_info_data, &offs);
+ };
+
+ for (DWARFUnitSP cu_sp = ExtractNext(0); cu_sp != nullptr;
+ cu_sp = ExtractNext(cu_sp->GetNextCompileUnitOffset())) {
+ // FIXME: Multiple OSO entries with multiple CUs may be a rare, but
+ // while I am here, I should store CU OFFSETS BY OSO ENTRY! It may
+ // move to m_oso_entry_info.
+ m_oso_compile_unit_offset.push_back(cu_sp->GetOffset());
+
+ // Make a copy of the oso_info and add compile unit specific data.
+ //
+ // FIXME: There is no CU-specific data currently, because symbol
+ // ranges are the same for all CUs and the offset is stored
+ // separately. It may be turned into a m_oso_entry_info.
+ m_compile_unit_infos.push_back(oso_info);
+ CompileUnitInfo &cu_info = m_compile_unit_infos.back();
+
uint32_t sibling_idx = so_symbol->GetSiblingIndex();
- // The sibling index can't be less that or equal to the current index
- // "i"
- if (sibling_idx == UINT32_MAX) {
- m_obj_file->GetModule()->ReportError(
- "N_SO in symbol with UID %u has invalid sibling in debug map, "
- "please file a bug and attach the binary listed in this error",
- so_symbol->GetID());
- } else {
- const Symbol *last_symbol = symtab->SymbolAtIndex(sibling_idx - 1);
- m_compile_unit_infos[i].first_symbol_index = so_idx;
- m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1;
- m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
- m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
-
- if (log)
- log->Printf("Initialized OSO 0x%8.8x: file=%s", i,
- oso_symbol->GetName().GetCString());
- }
- } else {
- if (oso_symbol == NULL)
- m_obj_file->GetModule()->ReportError(
- "N_OSO symbol[%u] can't be found, please file a bug and attach "
- "the binary listed in this error",
- oso_idx);
- else if (so_symbol == NULL)
- m_obj_file->GetModule()->ReportError(
- "N_SO not found for N_OSO symbol[%u], please file a bug and "
- "attach the binary listed in this error",
- oso_idx);
- else if (so_symbol->GetType() != eSymbolTypeSourceFile)
- m_obj_file->GetModule()->ReportError(
- "N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], "
- "please file a bug and attach the binary listed in this error",
- so_symbol->GetType(), oso_idx);
- else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
- m_obj_file->GetModule()->ReportError(
- "N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], "
- "please file a bug and attach the binary listed in this error",
- oso_symbol->GetType(), oso_idx);
+ const Symbol *last_symbol = symtab->SymbolAtIndex(sibling_idx - 1);
+
+ // For (regular) objects with only one compile unit, there is a
+ // bidirectional mapping between a symtab slice and a compile unit.
+ // LTO objects do not allow such a mapping and so we assign the full
+ // symtab range to all compile units of the same oso_entry.
+ cu_info.first_symbol_index = so_idx;
+ cu_info.last_symbol_index = sibling_idx - 1;
+ cu_info.first_symbol_id = so_symbol->GetID();
+ cu_info.last_symbol_id = last_symbol->GetID();
}
+
+ if (log)
+ log->Printf("Initialized OSO 0x%8.8x: file=%s", i,
+ oso_symbol->GetName().GetCString());
}
}
}
}
+void SymbolFileDWARFDebugMap::ReportErrorInitOSO(Symbol *so_symbol,
+ Symbol *oso_symbol,
+ uint32_t oso_idx) {
+ if (oso_symbol == NULL)
+ m_obj_file->GetModule()->ReportError(
+ "N_OSO symbol[%u] can't be found, please file a bug and attach "
+ "the binary listed in this error",
+ oso_idx);
+ else if (so_symbol == NULL)
+ m_obj_file->GetModule()->ReportError(
+ "N_SO not found for N_OSO symbol[%u], please file a bug and "
+ "attach the binary listed in this error",
+ oso_idx);
+ else if (so_symbol->GetType() != eSymbolTypeSourceFile)
+ m_obj_file->GetModule()->ReportError(
+ "N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], "
+ "please file a bug and attach the binary listed in this error",
+ so_symbol->GetType(), oso_idx);
+ else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
+ m_obj_file->GetModule()->ReportError(
+ "N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], "
+ "please file a bug and attach the binary listed in this error",
+ oso_symbol->GetType(), oso_idx);
+ else if (so_symbol->GetSiblingIndex() == UINT32_MAX)
+ m_obj_file->GetModule()->ReportError(
+ "N_SO in symbol with UID %u has invalid sibling in debug map, "
+ "please file a bug and attach the binary listed in this error",
+ so_symbol->GetID());
+}
+
Module *SymbolFileDWARFDebugMap::GetModuleByOSOIndex(uint32_t oso_idx) {
const uint32_t cu_count = GetNumCompileUnits();
if (oso_idx < cu_count)
@@ -547,20 +597,40 @@
// N_OSO entries (object files) from the symbol table and make sure that
// these files exist and also contain valid DWARF. If we get any of that then
// we return the abilities of the first N_OSO's DWARF.
+ if (HasCompileUnits())
+ return SymbolFile::CompileUnits | SymbolFile::Functions |
+ SymbolFile::Blocks | SymbolFile::GlobalVariables |
+ SymbolFile::LocalVariables | SymbolFile::VariableTypes |
+ SymbolFile::LineTables;
- const uint32_t oso_index_count = GetNumCompileUnits();
- if (oso_index_count > 0) {
- InitOSO();
- if (!m_compile_unit_infos.empty()) {
- return SymbolFile::CompileUnits | SymbolFile::Functions |
- SymbolFile::Blocks | SymbolFile::GlobalVariables |
- SymbolFile::LocalVariables | SymbolFile::VariableTypes |
- SymbolFile::LineTables;
- }
- }
return 0;
}
+bool SymbolFileDWARFDebugMap::HasCompileUnits() {
+ if (m_flags.test(kHaveCheckedCUInfos))
+ return m_has_compile_unit_infos;
+
+ m_flags.set(kHaveCheckedCUInfos);
+
+ // If the object file has been stripped, there is no sense in looking further
+ // as all of the debug symbols for the debug map will not be available.
+ //
+ // FIXME: This should be renamed to IsStrippedOrMissing()
+ if (m_obj_file->IsStripped())
+ return false;
+
+ if (!IsExecutableType(m_obj_file->GetType()))
+ return false;
+
+ assert(m_has_compile_unit_infos == false && "Arrive here only once");
+
+ if (Symtab *symtab = m_obj_file->GetSymtab())
+ m_has_compile_unit_infos = symtab->HasSymbolWithTypeAndFlags(
+ eSymbolTypeObjectFile, GetOSOSymbolFlags());
+
+ return m_has_compile_unit_infos;
+}
+
uint32_t SymbolFileDWARFDebugMap::GetNumCompileUnits() {
InitOSO();
return m_compile_unit_infos.size();
@@ -575,12 +645,10 @@
if (oso_module) {
FileSpec so_file_spec;
if (GetFileSpecForSO(cu_idx, so_file_spec)) {
- // User zero as the ID to match the compile unit at offset zero in each
- // .o file since each .o file can only have one compile unit for now.
- lldb::user_id_t cu_id = 0;
- m_compile_unit_infos[cu_idx].compile_unit_sp.reset(
- new CompileUnit(m_obj_file->GetModule(), NULL, so_file_spec, cu_id,
- eLanguageTypeUnknown, eLazyBoolCalculate));
+ lldb::user_id_t cu_offset = m_oso_compile_unit_offset[cu_idx];
+ m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit(
+ m_obj_file->GetModule(), NULL, so_file_spec, cu_offset,
+ eLanguageTypeUnknown, eLazyBoolCalculate));
if (m_compile_unit_infos[cu_idx].compile_unit_sp) {
// Let our symbol vendor know about this compile unit
@@ -734,6 +802,15 @@
if (sc.symbol != NULL) {
resolved_flags |= eSymbolContextSymbol;
+ // FIXME: Search by symbol Index/ID will NOT return the correct info for
+ // objects with multiple compile units. We cannot safely match slices of
+ // the symtab with individual units (it's very likely that optimization
+ // mixed it up), and so all compile units from such objects share the
+ // full symbol range.
+ //
+ // For the moment this is not a problem here, because we only use the
+ // compile unit info to find the module, which is invariant across all
+ // compile units of one object file.
uint32_t oso_idx = 0;
CompileUnitInfo *comp_unit_info =
GetCompileUnitInfoForSymbolWithID(sc.symbol->GetID(), &oso_idx);
@@ -1244,6 +1321,32 @@
llvm_unreachable("this shouldn't happen");
}
+lldb::CompUnitSP
+SymbolFileDWARFDebugMap::GetCompileUnitByIndex(SymbolFileDWARF *oso_dwarf,
+ uint32_t cu_idx) {
+ assert(cu_idx < GetNumCompileUnits() && "CU index out of range");
+ auto &cu_info = m_compile_unit_infos[cu_idx];
+ if (!cu_info.compile_unit_sp)
+ cu_info.compile_unit_sp = ParseCompileUnitAtIndex(cu_idx);
+
+ return cu_info.compile_unit_sp;
+}
+
+lldb::CompUnitSP
+SymbolFileDWARFDebugMap::GetCompileUnitByOffset(SymbolFileDWARF *oso_dwarf,
+ dw_offset_t cu_offset) {
+ auto begin = m_oso_compile_unit_offset.begin();
+ auto end = m_oso_compile_unit_offset.end();
+ auto it = std::lower_bound(begin, end, cu_offset);
+
+ if (it != end) {
+ uint32_t cu_idx = std::distance(begin, it);
+ return GetCompileUnitByIndex(oso_dwarf, cu_idx);
+ }
+
+ return nullptr;
+}
+
SymbolFileDWARFDebugMap::CompileUnitInfo *
SymbolFileDWARFDebugMap::GetCompileUnitInfo(SymbolFileDWARF *oso_dwarf) {
if (oso_dwarf) {
@@ -1380,6 +1483,16 @@
addr_module->GetSymbolVendor()->GetSymbolFile()));
if (cu_info) {
const lldb::addr_t oso_file_addr = addr.GetFileAddress();
+
+ // FIXME: Search by symbol Index/ID will NOT return the correct info for
+ // objects with multiple compile units. We cannot safely match slices of
+ // the symtab with individual units (it's very likely that optimization
+ // mixed it up), and so all compile units from such objects share the
+ // full symbol range.
+ //
+ // For the moment this is not a problem here, because we only use the
+ // compile unit info to find the module, which is invariant across all
+ // compile units of one object file.
const FileRangeMap::Entry *oso_range_entry =
cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
if (oso_range_entry) {
@@ -1407,7 +1520,16 @@
size_t
SymbolFileDWARFDebugMap::AddOSOARanges(SymbolFileDWARF *dwarf2Data,
+ dw_offset_t cu_offset,
DWARFDebugAranges *debug_aranges) {
+ // For OSO debug map entries with multiple CUs, we can't map between symtab
+ // entries and CUs. Thus, each CU's FileRangeMap will be populated from the
+ // entire symtab range of that OSO debug map entry. The loop below would add
+ // invalid entries (from other CUs of this OSO debug map entry) and we had to
+ // test each of them in SymbolFileDWARF::ResolveSymbolContext().
+ if (m_compile_unit_infos.size() > 1)
+ return 0;
+
size_t num_line_entries_added = 0;
if (debug_aranges && dwarf2Data) {
CompileUnitInfo *compile_unit_info = GetCompileUnitInfo(dwarf2Data);
@@ -1417,7 +1539,7 @@
for (size_t idx = 0; idx < file_range_map.GetSize(); idx++) {
const FileRangeMap::Entry *entry = file_range_map.GetEntryAtIndex(idx);
if (entry) {
- debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(),
+ debug_aranges->AppendRange(cu_offset, entry->GetRangeBase(),
entry->GetRangeEnd());
num_line_entries_added++;
}
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -275,7 +275,7 @@
lldb_private::CompileUnit *
GetCompUnitForDWARFCompUnit(DWARFUnit *dwarf_cu,
- uint32_t cu_idx = UINT32_MAX);
+ uint32_t cu_idx = DW_INVALID_INDEX);
virtual size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name,
DIEArray &method_die_offsets);
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -781,9 +781,25 @@
if (dwarf_cu->GetSymbolFileDWARF() != this) {
return dwarf_cu->GetSymbolFileDWARF()->ParseCompileUnit(dwarf_cu,
cu_idx);
- } else if (dwarf_cu->GetOffset() == 0 && GetDebugMapSymfile()) {
+ } else if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile()) {
+ assert(debug_map == m_debug_map_symfile &&
+ "debug_map is a nested instance derived from SymbolFile, "
+ "NOT SymbolFileDWARF");
+
// Let the debug map create the compile unit
- cu_sp = m_debug_map_symfile->GetCompileUnit(this);
+ if (debug_map->GetNumCompileUnits() == 1) {
+ cu_sp = debug_map->GetCompileUnit(this);
+ } else if (cu_idx != UINT32_MAX) {
+ cu_sp = debug_map->GetCompileUnitByIndex(this, cu_idx);
+ } else {
+ lldb::offset_t cu_offset = dwarf_cu->GetOffset();
+ if (cu_offset != DW_INVALID_OFFSET) {
+ cu_sp = debug_map->GetCompileUnitByOffset(this, cu_offset);
+ } else {
+ llvm_unreachable("Need more info to find the correct CU");
+ }
+ }
+
dwarf_cu->SetUserData(cu_sp.get());
} else {
ModuleSP module_sp(m_obj_file->GetModule());
Index: source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -426,8 +426,17 @@
const dw_offset_t cu_offset = GetOffset();
if (die) {
DWARFRangeList ranges;
+
+ // DW_AT_low/high_pc attributes of DW_TAG_compile_unit are no suitable
+ // fallback for deducing code address ranges. It can have outdated data or
+ // result in overlapping ranges, e.g. if the CUs actual code is interleaved.
+ // Instead BuildAddressRangeTable() below will index the DWARF and generate
+ // the address ranges table manually, based on DW_AT_low/high_pc attributes
+ // of nested DW_TAG_subprogram tags.
+ static constexpr bool check_hi_lo_pc = false;
const size_t num_ranges =
- die->GetAttributeAddressRanges(dwarf, this, ranges, false);
+ die->GetAttributeAddressRanges(dwarf, this, ranges, check_hi_lo_pc);
+
if (num_ranges > 0) {
// This compile unit has DW_AT_ranges, assume this is correct if it is
// present since clang no longer makes .debug_aranges by default and it
@@ -477,7 +486,7 @@
}
}
} else
- debug_map_sym_file->AddOSOARanges(dwarf, debug_aranges);
+ debug_map_sym_file->AddOSOARanges(dwarf, cu_offset, debug_aranges);
}
}
Index: include/lldb/Symbol/Symtab.h
===================================================================
--- include/lldb/Symbol/Symtab.h
+++ include/lldb/Symbol/Symtab.h
@@ -56,6 +56,10 @@
Symbol *FindSymbolWithType(lldb::SymbolType symbol_type,
Debug symbol_debug_type,
Visibility symbol_visibility, uint32_t &start_idx);
+
+ bool HasSymbolWithTypeAndFlags(lldb::SymbolType symbol_type,
+ uint32_t flags_value) const;
+
//----------------------------------------------------------------------
/// Get the parent symbol for the given symbol.
///
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits