diff options
Diffstat (limited to 'contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp')
-rw-r--r-- | contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp | 232 |
1 files changed, 135 insertions, 97 deletions
diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp index 0d736738ebb5..737599303a60 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp @@ -33,16 +33,14 @@ static addr_t ResolveRendezvousAddress(Process *process) { Status error; if (!process) { - if (log) - log->Printf("%s null process provided", __FUNCTION__); + LLDB_LOGF(log, "%s null process provided", __FUNCTION__); return LLDB_INVALID_ADDRESS; } // Try to get it from our process. This might be a remote process and might // grab it via some remote-specific mechanism. info_location = process->GetImageInfoAddress(); - if (log) - log->Printf("%s info_location = 0x%" PRIx64, __FUNCTION__, info_location); + LLDB_LOGF(log, "%s info_location = 0x%" PRIx64, __FUNCTION__, info_location); // If the process fails to return an address, fall back to seeing if the // local object file can help us find it. @@ -54,42 +52,38 @@ static addr_t ResolveRendezvousAddress(Process *process) { if (addr.IsValid()) { info_location = addr.GetLoadAddress(target); - if (log) - log->Printf( - "%s resolved via direct object file approach to 0x%" PRIx64, - __FUNCTION__, info_location); + LLDB_LOGF(log, + "%s resolved via direct object file approach to 0x%" PRIx64, + __FUNCTION__, info_location); } else { - if (log) - log->Printf("%s FAILED - direct object file approach did not yield a " - "valid address", - __FUNCTION__); + LLDB_LOGF(log, + "%s FAILED - direct object file approach did not yield a " + "valid address", + __FUNCTION__); } } } if (info_location == LLDB_INVALID_ADDRESS) { - if (log) - log->Printf("%s FAILED - invalid info address", __FUNCTION__); + LLDB_LOGF(log, "%s FAILED - invalid info address", __FUNCTION__); return LLDB_INVALID_ADDRESS; } - if (log) - log->Printf("%s reading pointer (%" PRIu32 " bytes) from 0x%" PRIx64, - __FUNCTION__, process->GetAddressByteSize(), info_location); + LLDB_LOGF(log, "%s reading pointer (%" PRIu32 " bytes) from 0x%" PRIx64, + __FUNCTION__, process->GetAddressByteSize(), info_location); info_addr = process->ReadPointerFromMemory(info_location, error); if (error.Fail()) { - if (log) - log->Printf("%s FAILED - could not read from the info location: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, "%s FAILED - could not read from the info location: %s", + __FUNCTION__, error.AsCString()); return LLDB_INVALID_ADDRESS; } if (info_addr == 0) { - if (log) - log->Printf("%s FAILED - the rendezvous address contained at 0x%" PRIx64 - " returned a null value", - __FUNCTION__, info_location); + LLDB_LOGF(log, + "%s FAILED - the rendezvous address contained at 0x%" PRIx64 + " returned a null value", + __FUNCTION__, info_location); return LLDB_INVALID_ADDRESS; } @@ -109,14 +103,13 @@ DYLDRendezvous::DYLDRendezvous(Process *process) Module *exe_mod = m_process->GetTarget().GetExecutableModulePointer(); if (exe_mod) { m_exe_file_spec = exe_mod->GetPlatformFileSpec(); - if (log) - log->Printf("DYLDRendezvous::%s exe module executable path set: '%s'", - __FUNCTION__, m_exe_file_spec.GetCString()); + LLDB_LOGF(log, "DYLDRendezvous::%s exe module executable path set: '%s'", + __FUNCTION__, m_exe_file_spec.GetCString()); } else { - if (log) - log->Printf("DYLDRendezvous::%s cannot cache exe module path: null " - "executable module pointer", - __FUNCTION__); + LLDB_LOGF(log, + "DYLDRendezvous::%s cannot cache exe module path: null " + "executable module pointer", + __FUNCTION__); } } } @@ -133,17 +126,16 @@ bool DYLDRendezvous::Resolve() { address_size = m_process->GetAddressByteSize(); padding = address_size - word_size; - if (log) - log->Printf("DYLDRendezvous::%s address size: %" PRIu64 - ", padding %" PRIu64, - __FUNCTION__, uint64_t(address_size), uint64_t(padding)); + LLDB_LOGF(log, + "DYLDRendezvous::%s address size: %" PRIu64 ", padding %" PRIu64, + __FUNCTION__, uint64_t(address_size), uint64_t(padding)); if (m_rendezvous_addr == LLDB_INVALID_ADDRESS) cursor = info_addr = ResolveRendezvousAddress(m_process); else cursor = info_addr = m_rendezvous_addr; - if (log) - log->Printf("DYLDRendezvous::%s cursor = 0x%" PRIx64, __FUNCTION__, cursor); + LLDB_LOGF(log, "DYLDRendezvous::%s cursor = 0x%" PRIx64, __FUNCTION__, + cursor); if (cursor == LLDB_INVALID_ADDRESS) return false; @@ -168,7 +160,10 @@ bool DYLDRendezvous::Resolve() { m_previous = m_current; m_current = info; - if (UpdateSOEntries(true)) + if (m_current.map_addr == 0) + return false; + + if (UpdateSOEntriesFromRemote()) return true; return UpdateSOEntries(); @@ -178,53 +173,91 @@ bool DYLDRendezvous::IsValid() { return m_rendezvous_addr != LLDB_INVALID_ADDRESS; } -bool DYLDRendezvous::UpdateSOEntries(bool fromRemote) { - SOEntry entry; - LoadedModuleInfoList module_list; +DYLDRendezvous::RendezvousAction DYLDRendezvous::GetAction() const { + switch (m_current.state) { + + case eConsistent: + switch (m_previous.state) { + // When the previous and current states are consistent this is the first + // time we have been asked to update. Just take a snapshot of the + // currently loaded modules. + case eConsistent: + return eTakeSnapshot; + // If we are about to add or remove a shared object clear out the current + // state and take a snapshot of the currently loaded images. + case eAdd: + return eAddModules; + case eDelete: + return eRemoveModules; + } + break; - // If we can't get the SO info from the remote, return failure. - if (fromRemote && m_process->LoadModules(module_list) == 0) - return false; + case eAdd: + case eDelete: + // Some versions of the android dynamic linker might send two + // notifications with state == eAdd back to back. Ignore them until we + // get an eConsistent notification. + if (!(m_previous.state == eConsistent || + (m_previous.state == eAdd && m_current.state == eDelete))) + return eNoAction; + + return eTakeSnapshot; + } + + return eNoAction; +} + +bool DYLDRendezvous::UpdateSOEntriesFromRemote() { + auto action = GetAction(); - if (!fromRemote && m_current.map_addr == 0) + if (action == eNoAction) return false; - // When the previous and current states are consistent this is the first time - // we have been asked to update. Just take a snapshot of the currently - // loaded modules. - if (m_previous.state == eConsistent && m_current.state == eConsistent) - return fromRemote ? SaveSOEntriesFromRemote(module_list) - : TakeSnapshot(m_soentries); - - // If we are about to add or remove a shared object clear out the current - // state and take a snapshot of the currently loaded images. - if (m_current.state == eAdd || m_current.state == eDelete) { - // Some versions of the android dynamic linker might send two notifications - // with state == eAdd back to back. Ignore them until we get an eConsistent - // notification. - if (!(m_previous.state == eConsistent || - (m_previous.state == eAdd && m_current.state == eDelete))) - return false; + if (action == eTakeSnapshot) { + m_added_soentries.clear(); + m_removed_soentries.clear(); + // We already have the loaded list from the previous update so no need to + // find all the modules again. + if (!m_loaded_modules.m_list.empty()) + return true; + } + + llvm::Expected<LoadedModuleInfoList> module_list = + m_process->GetLoadedModuleList(); + if (!module_list) { + llvm::consumeError(module_list.takeError()); + return false; + } + switch (action) { + case eTakeSnapshot: m_soentries.clear(); - if (fromRemote) - return SaveSOEntriesFromRemote(module_list); + return SaveSOEntriesFromRemote(*module_list); + case eAddModules: + return AddSOEntriesFromRemote(*module_list); + case eRemoveModules: + return RemoveSOEntriesFromRemote(*module_list); + case eNoAction: + return false; + } + llvm_unreachable("Fully covered switch above!"); +} +bool DYLDRendezvous::UpdateSOEntries() { + switch (GetAction()) { + case eTakeSnapshot: + m_soentries.clear(); m_added_soentries.clear(); m_removed_soentries.clear(); return TakeSnapshot(m_soentries); + case eAddModules: + return AddSOEntries(); + case eRemoveModules: + return RemoveSOEntries(); + case eNoAction: + return false; } - assert(m_current.state == eConsistent); - - // Otherwise check the previous state to determine what to expect and update - // accordingly. - if (m_previous.state == eAdd) - return fromRemote ? AddSOEntriesFromRemote(module_list) : AddSOEntries(); - else if (m_previous.state == eDelete) - return fromRemote ? RemoveSOEntriesFromRemote(module_list) - : RemoveSOEntries(); - - return false; + llvm_unreachable("Fully covered switch above!"); } bool DYLDRendezvous::FillSOEntryFromModuleInfo( @@ -255,7 +288,7 @@ bool DYLDRendezvous::FillSOEntryFromModuleInfo( } bool DYLDRendezvous::SaveSOEntriesFromRemote( - LoadedModuleInfoList &module_list) { + const LoadedModuleInfoList &module_list) { for (auto const &modInfo : module_list.m_list) { SOEntry entry; if (!FillSOEntryFromModuleInfo(modInfo, entry)) @@ -270,7 +303,8 @@ bool DYLDRendezvous::SaveSOEntriesFromRemote( return true; } -bool DYLDRendezvous::AddSOEntriesFromRemote(LoadedModuleInfoList &module_list) { +bool DYLDRendezvous::AddSOEntriesFromRemote( + const LoadedModuleInfoList &module_list) { for (auto const &modInfo : module_list.m_list) { bool found = false; for (auto const &existing : m_loaded_modules.m_list) { @@ -288,8 +322,10 @@ bool DYLDRendezvous::AddSOEntriesFromRemote(LoadedModuleInfoList &module_list) { return false; // Only add shared libraries and not the executable. - if (!SOEntryIsMainExecutable(entry)) + if (!SOEntryIsMainExecutable(entry)) { m_soentries.push_back(entry); + m_added_soentries.push_back(entry); + } } m_loaded_modules = module_list; @@ -297,7 +333,7 @@ bool DYLDRendezvous::AddSOEntriesFromRemote(LoadedModuleInfoList &module_list) { } bool DYLDRendezvous::RemoveSOEntriesFromRemote( - LoadedModuleInfoList &module_list) { + const LoadedModuleInfoList &module_list) { for (auto const &existing : m_loaded_modules.m_list) { bool found = false; for (auto const &modInfo : module_list.m_list) { @@ -321,6 +357,7 @@ bool DYLDRendezvous::RemoveSOEntriesFromRemote( return false; m_soentries.erase(pos); + m_removed_soentries.push_back(entry); } } @@ -521,9 +558,10 @@ bool DYLDRendezvous::FindMetadata(const char *name, PThreadField field, Target &target = m_process->GetTarget(); SymbolContextList list; - if (!target.GetImages().FindSymbolsWithNameAndType(ConstString(name), - eSymbolTypeAny, list)) - return false; + target.GetImages().FindSymbolsWithNameAndType(ConstString(name), + eSymbolTypeAny, list); + if (list.IsEmpty()) + return false; Address address = list[0].symbol->GetAddress(); addr_t addr = address.GetLoadAddress(&target); @@ -569,16 +607,16 @@ void DYLDRendezvous::DumpToLog(Log *log) const { return; log->PutCString("DYLDRendezvous:"); - log->Printf(" Address: %" PRIx64, GetRendezvousAddress()); - log->Printf(" Version: %" PRIu64, GetVersion()); - log->Printf(" Link : %" PRIx64, GetLinkMapAddress()); - log->Printf(" Break : %" PRIx64, GetBreakAddress()); - log->Printf(" LDBase : %" PRIx64, GetLDBase()); - log->Printf(" State : %s", - (state == eConsistent) - ? "consistent" - : (state == eAdd) ? "add" : (state == eDelete) ? "delete" - : "unknown"); + LLDB_LOGF(log, " Address: %" PRIx64, GetRendezvousAddress()); + LLDB_LOGF(log, " Version: %" PRIu64, GetVersion()); + LLDB_LOGF(log, " Link : %" PRIx64, GetLinkMapAddress()); + LLDB_LOGF(log, " Break : %" PRIx64, GetBreakAddress()); + LLDB_LOGF(log, " LDBase : %" PRIx64, GetLDBase()); + LLDB_LOGF(log, " State : %s", + (state == eConsistent) + ? "consistent" + : (state == eAdd) ? "add" + : (state == eDelete) ? "delete" : "unknown"); iterator I = begin(); iterator E = end(); @@ -587,11 +625,11 @@ void DYLDRendezvous::DumpToLog(Log *log) const { log->PutCString("DYLDRendezvous SOEntries:"); for (int i = 1; I != E; ++I, ++i) { - log->Printf("\n SOEntry [%d] %s", i, I->file_spec.GetCString()); - log->Printf(" Base : %" PRIx64, I->base_addr); - log->Printf(" Path : %" PRIx64, I->path_addr); - log->Printf(" Dyn : %" PRIx64, I->dyn_addr); - log->Printf(" Next : %" PRIx64, I->next); - log->Printf(" Prev : %" PRIx64, I->prev); + LLDB_LOGF(log, "\n SOEntry [%d] %s", i, I->file_spec.GetCString()); + LLDB_LOGF(log, " Base : %" PRIx64, I->base_addr); + LLDB_LOGF(log, " Path : %" PRIx64, I->path_addr); + LLDB_LOGF(log, " Dyn : %" PRIx64, I->dyn_addr); + LLDB_LOGF(log, " Next : %" PRIx64, I->next); + LLDB_LOGF(log, " Prev : %" PRIx64, I->prev); } } |