diff options
Diffstat (limited to 'contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp')
-rw-r--r-- | contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp index ac60af5336ed..160faa74af23 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -76,7 +76,8 @@ DynamicLoaderPOSIXDYLD::DynamicLoaderPOSIXDYLD(Process *process) m_load_offset(LLDB_INVALID_ADDRESS), m_entry_point(LLDB_INVALID_ADDRESS), m_auxv(), m_dyld_bid(LLDB_INVALID_BREAK_ID), m_vdso_base(LLDB_INVALID_ADDRESS), - m_interpreter_base(LLDB_INVALID_ADDRESS) {} + m_interpreter_base(LLDB_INVALID_ADDRESS), m_initial_modules_added(false) { +} DynamicLoaderPOSIXDYLD::~DynamicLoaderPOSIXDYLD() { if (m_dyld_bid != LLDB_INVALID_BREAK_ID) { @@ -101,6 +102,7 @@ void DynamicLoaderPOSIXDYLD::DidAttach() { ModuleSP executable_sp = GetTargetExecutable(); ResolveExecutableModule(executable_sp); + m_rendezvous.UpdateExecutablePath(); // find the main process load offset addr_t load_offset = ComputeLoadOffset(); @@ -418,14 +420,38 @@ void DynamicLoaderPOSIXDYLD::RefreshModules() { ModuleList &loaded_modules = m_process->GetTarget().GetImages(); - if (m_rendezvous.ModulesDidLoad()) { + if (m_rendezvous.ModulesDidLoad() || !m_initial_modules_added) { ModuleList new_modules; - E = m_rendezvous.loaded_end(); - for (I = m_rendezvous.loaded_begin(); I != E; ++I) { + // If this is the first time rendezvous breakpoint fires, we need + // to take care of adding all the initial modules reported by + // the loader. This is necessary to list ld-linux.so on Linux, + // and all DT_NEEDED entries on *BSD. + if (m_initial_modules_added) { + I = m_rendezvous.loaded_begin(); + E = m_rendezvous.loaded_end(); + } else { + I = m_rendezvous.begin(); + E = m_rendezvous.end(); + m_initial_modules_added = true; + } + for (; I != E; ++I) { ModuleSP module_sp = LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true); if (module_sp.get()) { + if (module_sp->GetObjectFile()->GetBaseAddress().GetLoadAddress( + &m_process->GetTarget()) == m_interpreter_base && + module_sp != m_interpreter_module.lock()) { + // If this is a duplicate instance of ld.so, unload it. We may end up + // with it if we load it via a different path than before (symlink + // vs real path). + // TODO: remove this once we either fix library matching or avoid + // loading the interpreter when setting the rendezvous breakpoint. + UnloadSections(module_sp); + loaded_modules.Remove(module_sp); + continue; + } + loaded_modules.AppendIfNeeded(module_sp); new_modules.Append(module_sp); } @@ -544,6 +570,7 @@ ModuleSP DynamicLoaderPOSIXDYLD::LoadInterpreterModule() { true /* notify */)) { UpdateLoadedSections(module_sp, LLDB_INVALID_ADDRESS, m_interpreter_base, false); + m_interpreter_module = module_sp; return module_sp; } return nullptr; |