diff --git a/lldb/include/lldb/Symbol/UnwindTable.h b/lldb/include/lldb/Symbol/UnwindTable.h index f0ce7047de2d1..26826e5d1b497 100644 --- a/lldb/include/lldb/Symbol/UnwindTable.h +++ b/lldb/include/lldb/Symbol/UnwindTable.h @@ -57,6 +57,10 @@ class UnwindTable { ArchSpec GetArchitecture(); + /// Called after a SymbolFile has been added to a Module to add any new + /// unwind sections that may now be available. + void Update(); + private: void Dump(Stream &s); diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp index 51ba034d25a45..1ce45df0b179e 100644 --- a/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp @@ -1046,6 +1046,8 @@ SymbolFile *Module::GetSymbolFile(bool can_create, Stream *feedback_strm) { m_symfile_up.reset( SymbolVendor::FindPlugin(shared_from_this(), feedback_strm)); m_did_load_symfile = true; + if (m_unwind_table) + m_unwind_table->Update(); } } } @@ -1371,9 +1373,9 @@ void Module::SectionFileAddressesChanged() { UnwindTable &Module::GetUnwindTable() { if (!m_unwind_table) { - m_unwind_table.emplace(*this); if (!m_symfile_spec) SymbolLocator::DownloadSymbolFileAsync(GetUUID()); + m_unwind_table.emplace(*this); } return *m_unwind_table; } @@ -1491,15 +1493,10 @@ void Module::SetSymbolFileFileSpec(const FileSpec &file) { // one obj_file->ClearSymtab(); - // Clear the unwind table too, as that may also be affected by the - // symbol file information. - m_unwind_table.reset(); - // The symbol file might be a directory bundle ("/tmp/a.out.dSYM") // instead of a full path to the symbol file within the bundle // ("/tmp/a.out.dSYM/Contents/Resources/DWARF/a.out"). So we need to // check this - if (FileSystem::Instance().IsDirectory(file)) { std::string new_path(file.GetPath()); std::string old_path(obj_file->GetFileSpec().GetPath()); diff --git a/lldb/source/Symbol/UnwindTable.cpp b/lldb/source/Symbol/UnwindTable.cpp index 3c1a5187b1105..11bedf3d6052e 100644 --- a/lldb/source/Symbol/UnwindTable.cpp +++ b/lldb/source/Symbol/UnwindTable.cpp @@ -84,6 +84,51 @@ void UnwindTable::Initialize() { } } +void UnwindTable::Update() { + if (!m_initialized) + return Initialize(); + + std::lock_guard guard(m_mutex); + + ObjectFile *object_file = m_module.GetObjectFile(); + if (!object_file) + return; + + if (!m_object_file_unwind_up) + m_object_file_unwind_up = object_file->CreateCallFrameInfo(); + + SectionList *sl = m_module.GetSectionList(); + if (!sl) + return; + + SectionSP sect = sl->FindSectionByType(eSectionTypeEHFrame, true); + if (!m_eh_frame_up && sect) { + m_eh_frame_up = std::make_unique( + *object_file, sect, DWARFCallFrameInfo::EH); + } + + sect = sl->FindSectionByType(eSectionTypeDWARFDebugFrame, true); + if (!m_debug_frame_up && sect) { + m_debug_frame_up = std::make_unique( + *object_file, sect, DWARFCallFrameInfo::DWARF); + } + + sect = sl->FindSectionByType(eSectionTypeCompactUnwind, true); + if (!m_compact_unwind_up && sect) { + m_compact_unwind_up = + std::make_unique(*object_file, sect); + } + + sect = sl->FindSectionByType(eSectionTypeARMexidx, true); + if (!m_arm_unwind_up && sect) { + SectionSP sect_extab = sl->FindSectionByType(eSectionTypeARMextab, true); + if (sect_extab.get()) { + m_arm_unwind_up = + std::make_unique(*object_file, sect, sect_extab); + } + } +} + UnwindTable::~UnwindTable() = default; std::optional