Index: source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp =================================================================== --- source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp +++ source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp @@ -272,6 +272,7 @@ } bool DYLDRendezvous::AddSOEntriesFromRemote(LoadedModuleInfoList &module_list) { + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); for (auto const &modInfo : module_list.m_list) { bool found = false; for (auto const &existing : m_loaded_modules.m_list) { @@ -289,8 +290,9 @@ return false; // Only add shared libraries and not the executable. - if (!SOEntryIsMainExecutable(entry)) + if (!SOEntryIsMainExecutable(entry)) { m_soentries.push_back(entry); + } } m_loaded_modules = module_list; @@ -332,6 +334,7 @@ bool DYLDRendezvous::AddSOEntries() { SOEntry entry; iterator pos; + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); assert(m_previous.state == eAdd); @@ -395,6 +398,7 @@ bool DYLDRendezvous::TakeSnapshot(SOEntryList &entry_list) { SOEntry entry; + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); if (m_current.map_addr == 0) return false; @@ -410,6 +414,8 @@ if (SOEntryIsMainExecutable(entry)) continue; + LLDB_LOG(log, "TakeSnapshot. New SO entry {0}", + entry.file_spec.GetFilename()); entry_list.push_back(entry); } Index: source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h =================================================================== --- source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h +++ source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h @@ -85,6 +85,10 @@ /// mapped to the address space lldb::addr_t m_vdso_base; + /// Contains AT_BASE, which means a dynamic loader has been + /// mapped to the address space + lldb::addr_t m_interpreter_base; + /// Loaded module list. (link map for each module) std::map> m_loaded_modules; @@ -138,7 +142,11 @@ /// of all dependent modules. virtual void LoadAllCurrentModules(); - void LoadVDSO(lldb_private::ModuleList &modules); + void LoadVDSO(); + + // Loading an interpreter module (if present) assumming m_interpreter_base + // already points to its base address. + lldb::ModuleSP LoadInterpreterModule(); /// Computes a value for m_load_offset returning the computed address on /// success and LLDB_INVALID_ADDRESS on failure. @@ -148,9 +156,10 @@ /// success and LLDB_INVALID_ADDRESS on failure. lldb::addr_t GetEntryPoint(); - /// Evaluate if Aux vectors contain vDSO information + /// Evaluate if Aux vectors contain vDSO and LD information /// in case they do, read and assign the address to m_vdso_base - void EvalVdsoStatus(); + /// and m_interpreter_base. + void EvalSpecialModulesStatus(); /// Loads Module from inferior process. void ResolveExecutableModule(lldb::ModuleSP &module_sp); Index: source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp =================================================================== --- source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -117,7 +117,7 @@ : "", load_offset); - EvalVdsoStatus(); + EvalSpecialModulesStatus(); // if we dont have a load address we cant re-base bool rebase_exec = (load_offset == LLDB_INVALID_ADDRESS) ? false : true; @@ -207,7 +207,7 @@ executable = GetTargetExecutable(); load_offset = ComputeLoadOffset(); - EvalVdsoStatus(); + EvalSpecialModulesStatus(); if (executable.get() && load_offset != LLDB_INVALID_ADDRESS) { ModuleList module_list; @@ -269,6 +269,8 @@ // Shoudn't hit this more than once. entry_break->SetOneShot(true); + + SetRendezvousBreakpoint(); } } @@ -332,35 +334,69 @@ void DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); - addr_t break_addr = m_rendezvous.GetBreakAddress(); + addr_t break_addr; Target &target = m_process->GetTarget(); + if (m_rendezvous.IsValid()) { + break_addr = m_rendezvous.GetBreakAddress(); + } else { + LLDB_LOG(log, + "Rendezvous structure is not set up yet. " + "Tring to locate rendezvous breakpoint in the interpreter " + "by symbol name."); + ModuleSP interpreter = LoadInterpreterModule(); + if (!interpreter) { + LLDB_LOG(log, "Can't find interpreter, rendezvous breakpoint isn't set."); + return; + } + + const Symbol *symbol = nullptr; + static const char *DebugStateCandidates[] = { + "_dl_debug_state", "rtld_db_dlactivity", "__dl_rtld_db_dlactivity", + "r_debug_state", "_r_debug_state", "_rtld_debug_state", + }; + + for (auto name : DebugStateCandidates) { + symbol = interpreter->FindFirstSymbolWithNameAndType(ConstString(name)); + if (symbol) break; + } + if (symbol == nullptr) { + LLDB_LOG(log, "Can't find debug state function in the interpreter."); + return; + } + break_addr = symbol->GetLoadAddress(&m_process->GetTarget()); + if (break_addr == LLDB_INVALID_ADDRESS) { + LLDB_LOG(log, "Can't resolve address of debug state function {0}.", + symbol->GetName()); + return; + } else { + LLDB_LOG( + log, + "Function {0} from module {1} will be used as rendezvous breakpoint.", + symbol->GetName(), interpreter->GetFileSpec().GetFilename()); + } + } + if (m_dyld_bid == LLDB_INVALID_BREAK_ID) { - if (log) - log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 - " setting rendezvous break address at 0x%" PRIx64, - __FUNCTION__, - m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID, - break_addr); + LLDB_LOG(log, + "DynamicLoaderPOSIXDYLD::{0} pid {1}" + " setting rendezvous break address at {2:x}", + __FUNCTION__, + m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID, + break_addr); Breakpoint *dyld_break = target.CreateBreakpoint(break_addr, true, false).get(); dyld_break->SetCallback(RendezvousBreakpointHit, this, true); dyld_break->SetBreakpointKind("shared-library-event"); m_dyld_bid = dyld_break->GetID(); } else { - if (log) - log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 - " reusing break id %" PRIu32 ", address at 0x%" PRIx64, - __FUNCTION__, - m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID, - m_dyld_bid, break_addr); + LLDB_LOG(log, + "DynamicLoaderPOSIXDYLD::{0} pid {1}" + " reusing break id {2}, address at {3:x}", + __FUNCTION__, + m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID, + m_dyld_bid, break_addr); } - - // Make sure our breakpoint is at the right address. - assert(target.GetBreakpointByID(m_dyld_bid) - ->FindLocationByAddress(break_addr) - ->GetBreakpoint() - .GetID() == m_dyld_bid); } bool DynamicLoaderPOSIXDYLD::RendezvousBreakpointHit( @@ -485,7 +521,7 @@ return thread_plan_sp; } -void DynamicLoaderPOSIXDYLD::LoadVDSO(ModuleList &modules) { +void DynamicLoaderPOSIXDYLD::LoadVDSO() { if (m_vdso_base == LLDB_INVALID_ADDRESS) return; @@ -506,13 +542,37 @@ } } +ModuleSP DynamicLoaderPOSIXDYLD::LoadInterpreterModule() { + if (m_interpreter_base == LLDB_INVALID_ADDRESS) return nullptr; + + MemoryRegionInfo info; + Target &target = m_process->GetTarget(); + Status status = m_process->GetMemoryRegionInfo(m_interpreter_base, info); + if (status.Fail()) { + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + LLDB_LOG(log, "Failed to get interpreter region info: {0}", status); + return nullptr; + } + + FileSpec file(info.GetName().GetCString(), false); + ModuleSpec module_spec(file, target.GetArchitecture()); + + if (ModuleSP module_sp = target.GetSharedModule(module_spec)) { + UpdateLoadedSections(module_sp, LLDB_INVALID_ADDRESS, m_interpreter_base, + false); + target.GetImages().AppendIfNeeded(module_sp); + return module_sp; + } + return nullptr; +} + void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() { DYLDRendezvous::iterator I; DYLDRendezvous::iterator E; ModuleList module_list; + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); if (!m_rendezvous.Resolve()) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); if (log) log->Printf("DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD " "rendezvous address", @@ -524,7 +584,7 @@ // that ourselves here. ModuleSP executable = GetTargetExecutable(); m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress(); - LoadVDSO(module_list); + LoadVDSO(); std::vector module_names; for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) @@ -536,6 +596,8 @@ ModuleSP module_sp = LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true); if (module_sp.get()) { + LLDB_LOG(log, "LoadAllCurrentModules loading moduel: {0}", + I->file_spec.GetFilename()); module_list.Append(module_sp); } else { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); @@ -575,11 +637,13 @@ return m_load_offset; } -void DynamicLoaderPOSIXDYLD::EvalVdsoStatus() { - AuxVector::iterator I = m_auxv->FindEntry(AuxVector::AUXV_AT_SYSINFO_EHDR); - +void DynamicLoaderPOSIXDYLD::EvalSpecialModulesStatus() { + auto I = m_auxv->FindEntry(AuxVector::AUXV_AT_SYSINFO_EHDR); if (I != m_auxv->end()) m_vdso_base = I->value; + + I = m_auxv->FindEntry(AuxVector::AUXV_AT_BASE); + if (I != m_auxv->end()) m_interpreter_base = I->value; } addr_t DynamicLoaderPOSIXDYLD::GetEntryPoint() {