diff options
Diffstat (limited to 'source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp')
| -rw-r--r-- | source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp | 102 |
1 files changed, 72 insertions, 30 deletions
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp index fdef1026f3c6..6330b42ca14a 100644 --- a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -14,6 +14,7 @@ #include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" +#include "lldb/Target/Platform.h" #include "lldb/Core/Section.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/Process.h" @@ -119,24 +120,41 @@ DynamicLoaderPOSIXDYLD::DidAttach() if (log) log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " reloaded auxv data", __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID); - ModuleSP executable_sp = GetTargetExecutable(); - ModuleSpec process_module_spec; - if (GetProcessModuleSpec(process_module_spec)) - { - if (executable_sp == nullptr || !executable_sp->MatchesModuleSpec(process_module_spec)) - { - executable_sp.reset(new Module(process_module_spec)); - assert(m_process != nullptr); - m_process->GetTarget().SetExecutableModule(executable_sp, false); - } - } + // ask the process if it can load any of its own modules + m_process->LoadModules (); + + ModuleSP executable_sp = GetTargetExecutable (); + ResolveExecutableModule (executable_sp); - addr_t load_offset = ComputeLoadOffset(); + // find the main process load offset + addr_t load_offset = ComputeLoadOffset (); if (log) log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " executable '%s', load_offset 0x%" PRIx64, __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID, executable_sp ? executable_sp->GetFileSpec().GetPath().c_str () : "<null executable>", load_offset); + // if we dont have a load address we cant re-base + bool rebase_exec = (load_offset == LLDB_INVALID_ADDRESS) ? false : true; + + // if we have a valid executable + if (executable_sp.get()) + { + lldb_private::ObjectFile * obj = executable_sp->GetObjectFile(); + if (obj) + { + // don't rebase if the module already has a load address + Target & target = m_process->GetTarget (); + Address addr = obj->GetImageInfoAddress (&target); + if (addr.GetLoadAddress (&target) != LLDB_INVALID_ADDRESS) + rebase_exec = false; + } + } + else + { + // no executable, nothing to re-base + rebase_exec = false; + } - if (executable_sp && load_offset != LLDB_INVALID_ADDRESS) + // if the target executable should be re-based + if (rebase_exec) { ModuleList module_list; @@ -396,8 +414,7 @@ DynamicLoaderPOSIXDYLD::RefreshModules() E = m_rendezvous.loaded_end(); for (I = m_rendezvous.loaded_begin(); I != E; ++I) { - FileSpec file(I->path.c_str(), true); - ModuleSP module_sp = LoadModuleAtAddress(file, I->link_addr, I->base_addr); + ModuleSP module_sp = LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr); if (module_sp.get()) { loaded_modules.AppendIfNeeded(module_sp); @@ -414,9 +431,8 @@ DynamicLoaderPOSIXDYLD::RefreshModules() E = m_rendezvous.unloaded_end(); for (I = m_rendezvous.unloaded_begin(); I != E; ++I) { - FileSpec file(I->path.c_str(), true); - ModuleSpec module_spec (file); - ModuleSP module_sp = + ModuleSpec module_spec{I->file_spec}; + ModuleSP module_sp = loaded_modules.FindFirstModule (module_spec); if (module_sp.get()) @@ -507,9 +523,7 @@ DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) { - const char *module_path = I->path.c_str(); - FileSpec file(module_path, false); - ModuleSP module_sp = LoadModuleAtAddress(file, I->link_addr, I->base_addr); + ModuleSP module_sp = LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr); if (module_sp.get()) { module_list.Append(module_sp); @@ -519,7 +533,7 @@ DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); if (log) log->Printf("DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64, - __FUNCTION__, module_path, I->base_addr); + __FUNCTION__, I->file_spec.GetCString(), I->base_addr); } } @@ -625,17 +639,45 @@ DynamicLoaderPOSIXDYLD::GetThreadLocalData (const lldb::ModuleSP module, const l return tls_block; } -bool -DynamicLoaderPOSIXDYLD::GetProcessModuleSpec (ModuleSpec& module_spec) +void +DynamicLoaderPOSIXDYLD::ResolveExecutableModule (lldb::ModuleSP &module_sp) { + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + if (m_process == nullptr) - return false; + return; + + auto &target = m_process->GetTarget (); + const auto platform_sp = target.GetPlatform (); - auto& target = m_process->GetTarget (); ProcessInstanceInfo process_info; - if (!target.GetPlatform ()->GetProcessInfo (m_process->GetID (), process_info)) - return false; + if (!platform_sp->GetProcessInfo (m_process->GetID (), process_info)) + { + if (log) + log->Printf ("DynamicLoaderPOSIXDYLD::%s - failed to get process info for pid %" PRIu64, + __FUNCTION__, m_process->GetID ()); + return; + } + + if (log) + log->Printf ("DynamicLoaderPOSIXDYLD::%s - got executable by pid %" PRIu64 ": %s", + __FUNCTION__, m_process->GetID (), process_info.GetExecutableFile ().GetPath ().c_str ()); + + ModuleSpec module_spec (process_info.GetExecutableFile (), process_info.GetArchitecture ()); + if (module_sp && module_sp->MatchesModuleSpec (module_spec)) + return; + + auto error = platform_sp->ResolveExecutable (module_spec, module_sp, nullptr); + if (error.Fail ()) + { + StreamString stream; + module_spec.Dump (stream); + + if (log) + log->Printf ("DynamicLoaderPOSIXDYLD::%s - failed to resolve executable with module spec \"%s\": %s", + __FUNCTION__, stream.GetString ().c_str (), error.AsCString ()); + return; + } - module_spec = ModuleSpec (process_info.GetExecutableFile (), process_info.GetArchitecture ()); - return true; + target.SetExecutableModule (module_sp, false); } |
