diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -52,7 +52,7 @@ } } - if (debug_aranges->GetNumRanges() == num_debug_aranges) { + if (debug_aranges->GetNumRanges() == num_debug_aranges && cu_offset == 0) { // We got nothing from the debug info, maybe we have a line tables only // situation. Check the line tables and build the arange table from this. SymbolContext sc; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -702,9 +702,9 @@ // We already parsed this compile unit, had out a shared pointer to it cu_sp = comp_unit->shared_from_this(); } else { - if (dwarf_cu.GetOffset() == 0 && GetDebugMapSymfile()) { + if (GetDebugMapSymfile()) { // Let the debug map create the compile unit - cu_sp = m_debug_map_symfile->GetCompileUnit(this); + cu_sp = m_debug_map_symfile->GetCompileUnit(this, dwarf_cu); dwarf_cu.SetUserData(cu_sp.get()); } else { ModuleSP module_sp(m_objfile_sp->GetModule()); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -19,6 +19,7 @@ #include "UniqueDWARFASTType.h" class SymbolFileDWARF; +class DWARFCompileUnit; class DWARFDebugAranges; class DWARFDeclContext; @@ -174,7 +175,10 @@ llvm::sys::TimePoint<> oso_mod_time; lldb_private::Status oso_load_error; OSOInfoSP oso_sp; + // The first compile unit, which appears in the nlist symbol table. lldb::CompUnitSP compile_unit_sp; + // The rest of the compile units that an object file contains. + llvm::SmallVector extra_compile_units_sps; uint32_t first_symbol_index = UINT32_MAX; uint32_t last_symbol_index = UINT32_MAX; uint32_t first_symbol_id = UINT32_MAX; @@ -193,7 +197,17 @@ // Protected Member Functions void InitOSO(); + /// This function actually returns the number of object files, which may be + /// less than the actual number of compile units, since an object file may + /// contain more than one compile unit. SymbolFileDWARFDebugMap looks up the + /// number of compile units by reading the nlist symbol table, which + /// currently, on macOS, only reports one compile unit per object file, and + /// there's no efficient way to calculate the actual number of compile units + /// upfront. uint32_t CalculateNumCompileUnits() override; + + /// This function actually returns the first compile unit the object file at + /// the given index contains. lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; static uint32_t GetOSOIndexFromUserID(lldb::user_id_t uid) { @@ -263,7 +277,11 @@ void SetCompileUnit(SymbolFileDWARF *oso_dwarf, const lldb::CompUnitSP &cu_sp); - lldb::CompUnitSP GetCompileUnit(SymbolFileDWARF *oso_dwarf); + /// Returns the compile unit associated with the dwarf compile unit. This may + /// be one of the extra compile units an object file contains which isn't + /// reachable by ParseCompileUnitAtIndex(uint32_t). + lldb::CompUnitSP GetCompileUnit(SymbolFileDWARF *oso_dwarf, + DWARFCompileUnit &dwarf_cu); CompileUnitInfo *GetCompileUnitInfo(SymbolFileDWARF *oso_dwarf); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -7,7 +7,9 @@ //===----------------------------------------------------------------------===// #include "SymbolFileDWARFDebugMap.h" +#include "DWARFCompileUnit.h" #include "DWARFDebugAranges.h" +#include "DWARFDebugInfo.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" @@ -17,6 +19,7 @@ #include "lldb/Utility/RangeMap.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Timer.h" +#include "lldb/Utility/StreamString.h" //#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT #if defined(DEBUG_OSO_DMAP) @@ -586,25 +589,40 @@ const uint32_t cu_count = GetNumCompileUnits(); if (cu_idx < cu_count) { - Module *oso_module = GetModuleByCompUnitInfo(&m_compile_unit_infos[cu_idx]); + auto &cu_info = m_compile_unit_infos[cu_idx]; + Module *oso_module = GetModuleByCompUnitInfo(&cu_info); 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. + // .o file since each .o file. lldb::user_id_t cu_id = 0; m_compile_unit_infos[cu_idx].compile_unit_sp = std::make_shared( m_objfile_sp->GetModule(), nullptr, so_file_spec, cu_id, eLanguageTypeUnknown, eLazyBoolCalculate); - - if (m_compile_unit_infos[cu_idx].compile_unit_sp) { - SetCompileUnitAtIndex(cu_idx, - m_compile_unit_infos[cu_idx].compile_unit_sp); + if (cu_info.compile_unit_sp) + SetCompileUnitAtIndex(cu_idx, cu_info.compile_unit_sp); + } + // If there's a symbol file also register all the extra compile units. + if (SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo(&cu_info)) { + auto num_dwarf_units = oso_symfile->DebugInfo().GetNumUnits(); + for (size_t i = 0; i < num_dwarf_units; ++i) { + auto *dwarf_unit = oso_symfile->DebugInfo().GetUnitAtIndex(i); + if (auto *dwarf_cu = llvm::dyn_cast(dwarf_unit)) { + // The "main" one was already registered. + if (dwarf_cu->GetID() == 0) + continue; + cu_info.extra_compile_units_sps.push_back( + std::make_shared( + m_objfile_sp->GetModule(), nullptr, so_file_spec, + dwarf_cu->GetID(), eLanguageTypeUnknown, + eLazyBoolCalculate)); + } } } } - comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp; + comp_unit_sp = cu_info.compile_unit_sp; } return comp_unit_sp; @@ -621,6 +639,9 @@ for (uint32_t i = 0; i < cu_count; ++i) { if (&comp_unit == m_compile_unit_infos[i].compile_unit_sp.get()) return &m_compile_unit_infos[i]; + for (auto &extra: m_compile_unit_infos[i].extra_compile_units_sps) + if (&comp_unit == extra.get()) + return &m_compile_unit_infos[i]; } return nullptr; } @@ -1239,7 +1260,7 @@ } lldb::CompUnitSP -SymbolFileDWARFDebugMap::GetCompileUnit(SymbolFileDWARF *oso_dwarf) { +SymbolFileDWARFDebugMap::GetCompileUnit(SymbolFileDWARF *oso_dwarf, DWARFCompileUnit &dwarf_cu) { if (oso_dwarf) { const uint32_t cu_count = GetNumCompileUnits(); for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) { @@ -1247,10 +1268,14 @@ GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]); if (oso_symfile == oso_dwarf) { if (!m_compile_unit_infos[cu_idx].compile_unit_sp) - m_compile_unit_infos[cu_idx].compile_unit_sp = - ParseCompileUnitAtIndex(cu_idx); + ParseCompileUnitAtIndex(cu_idx); + + if (dwarf_cu.GetID() == 0) + return m_compile_unit_infos[cu_idx].compile_unit_sp; - return m_compile_unit_infos[cu_idx].compile_unit_sp; + for (auto &cu : m_compile_unit_infos[cu_idx].extra_compile_units_sps) + if (cu->GetID() == dwarf_cu.GetID()) + return cu; } } }