aboutsummaryrefslogtreecommitdiff
path: root/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp')
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp979
1 files changed, 465 insertions, 514 deletions
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
index 443f97ed0ba1..136bf6561a21 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
@@ -30,631 +30,582 @@ using namespace lldb_private;
/// Locates the address of the rendezvous structure. Returns the address on
/// success and LLDB_INVALID_ADDRESS on failure.
-static addr_t
-ResolveRendezvousAddress(Process *process)
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- addr_t info_location;
- addr_t info_addr;
- Error error;
-
- if (!process)
- {
- if (log)
- log->Printf ("%s null process provided", __FUNCTION__);
- return LLDB_INVALID_ADDRESS;
- }
+static addr_t ResolveRendezvousAddress(Process *process) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ addr_t info_location;
+ addr_t info_addr;
+ Error error;
- // 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 (!process) {
if (log)
- log->Printf ("%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.
- if (info_location == LLDB_INVALID_ADDRESS)
- {
- Target *target = &process->GetTarget();
- if (target)
- {
- ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
- Address addr = obj_file->GetImageInfoAddress(target);
-
- 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);
- }
- else
- {
- if (log)
- log->Printf ("%s FAILED - direct object file approach did not yield a valid address", __FUNCTION__);
- }
- }
- }
-
- if (info_location == LLDB_INVALID_ADDRESS)
- {
+ log->Printf("%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);
+
+ // If the process fails to return an address, fall back to seeing if the local
+ // object file can help us find it.
+ if (info_location == LLDB_INVALID_ADDRESS) {
+ Target *target = &process->GetTarget();
+ if (target) {
+ ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
+ Address addr = obj_file->GetImageInfoAddress(target);
+
+ if (addr.IsValid()) {
+ info_location = addr.GetLoadAddress(target);
if (log)
- log->Printf ("%s FAILED - invalid info address", __FUNCTION__);
- return LLDB_INVALID_ADDRESS;
+ log->Printf(
+ "%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__);
+ }
}
+ }
+ if (info_location == LLDB_INVALID_ADDRESS) {
if (log)
- log->Printf ("%s reading pointer (%" PRIu32 " bytes) from 0x%" PRIx64, __FUNCTION__, process->GetAddressByteSize(), info_location);
+ log->Printf("%s FAILED - invalid info address", __FUNCTION__);
+ return LLDB_INVALID_ADDRESS;
+ }
- 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 ());
- return LLDB_INVALID_ADDRESS;
- }
+ if (log)
+ log->Printf("%s reading pointer (%" PRIu32 " bytes) from 0x%" PRIx64,
+ __FUNCTION__, process->GetAddressByteSize(), info_location);
- if (info_addr == 0)
- {
- if (log)
- log->Printf ("%s FAILED - the rendezvous address contained at 0x%" PRIx64 " returned a null value", __FUNCTION__, info_location);
- return LLDB_INVALID_ADDRESS;
- }
+ 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());
+ return LLDB_INVALID_ADDRESS;
+ }
- return info_addr;
+ if (info_addr == 0) {
+ if (log)
+ log->Printf("%s FAILED - the rendezvous address contained at 0x%" PRIx64
+ " returned a null value",
+ __FUNCTION__, info_location);
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ return info_addr;
}
DYLDRendezvous::DYLDRendezvous(Process *process)
- : m_process(process),
- m_rendezvous_addr(LLDB_INVALID_ADDRESS),
- m_current(),
- m_previous(),
- m_loaded_modules(),
- m_soentries(),
- m_added_soentries(),
- m_removed_soentries()
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
-
- m_thread_info.valid = false;
-
- // Cache a copy of the executable path
- if (m_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());
- }
- else
- {
- if (log)
- log->Printf ("DYLDRendezvous::%s cannot cache exe module path: null executable module pointer", __FUNCTION__);
- }
+ : m_process(process), m_rendezvous_addr(LLDB_INVALID_ADDRESS), m_current(),
+ m_previous(), m_loaded_modules(), m_soentries(), m_added_soentries(),
+ m_removed_soentries() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+
+ m_thread_info.valid = false;
+
+ // Cache a copy of the executable path
+ if (m_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());
+ } else {
+ if (log)
+ log->Printf("DYLDRendezvous::%s cannot cache exe module path: null "
+ "executable module pointer",
+ __FUNCTION__);
}
+ }
}
-bool
-DYLDRendezvous::Resolve()
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+bool DYLDRendezvous::Resolve() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+
+ const size_t word_size = 4;
+ Rendezvous info;
+ size_t address_size;
+ size_t padding;
+ addr_t info_addr;
+ addr_t cursor;
+
+ 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));
+
+ 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);
+
+ if (cursor == LLDB_INVALID_ADDRESS)
+ return false;
- const size_t word_size = 4;
- Rendezvous info;
- size_t address_size;
- size_t padding;
- addr_t info_addr;
- addr_t cursor;
+ if (!(cursor = ReadWord(cursor, &info.version, word_size)))
+ return false;
- 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));
+ if (!(cursor = ReadPointer(cursor + padding, &info.map_addr)))
+ return false;
- 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);
+ if (!(cursor = ReadPointer(cursor, &info.brk)))
+ return false;
- if (cursor == LLDB_INVALID_ADDRESS)
- return false;
+ if (!(cursor = ReadWord(cursor, &info.state, word_size)))
+ return false;
- if (!(cursor = ReadWord(cursor, &info.version, word_size)))
- return false;
+ if (!(cursor = ReadPointer(cursor + padding, &info.ldbase)))
+ return false;
- if (!(cursor = ReadPointer(cursor + padding, &info.map_addr)))
- return false;
+ // The rendezvous was successfully read. Update our internal state.
+ m_rendezvous_addr = info_addr;
+ m_previous = m_current;
+ m_current = info;
- if (!(cursor = ReadPointer(cursor, &info.brk)))
- return false;
+ if (UpdateSOEntries(true))
+ return true;
- if (!(cursor = ReadWord(cursor, &info.state, word_size)))
- return false;
+ return UpdateSOEntries();
+}
- if (!(cursor = ReadPointer(cursor + padding, &info.ldbase)))
- return false;
+bool DYLDRendezvous::IsValid() {
+ return m_rendezvous_addr != LLDB_INVALID_ADDRESS;
+}
- // The rendezvous was successfully read. Update our internal state.
- m_rendezvous_addr = info_addr;
- m_previous = m_current;
- m_current = info;
+bool DYLDRendezvous::UpdateSOEntries(bool fromRemote) {
+ SOEntry entry;
+ LoadedModuleInfoList module_list;
- if (UpdateSOEntries (true))
- return true;
+ // If we can't get the SO info from the remote, return failure.
+ if (fromRemote && m_process->LoadModules(module_list) == 0)
+ return false;
- return UpdateSOEntries();
-}
+ if (!fromRemote && m_current.map_addr == 0)
+ return false;
-bool
-DYLDRendezvous::IsValid()
-{
- return m_rendezvous_addr != LLDB_INVALID_ADDRESS;
+ // 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;
+
+ m_soentries.clear();
+ if (fromRemote)
+ return SaveSOEntriesFromRemote(module_list);
+
+ m_added_soentries.clear();
+ m_removed_soentries.clear();
+ return TakeSnapshot(m_soentries);
+ }
+ 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;
}
-bool
-DYLDRendezvous::UpdateSOEntries(bool fromRemote)
-{
- SOEntry entry;
- LoadedModuleInfoList module_list;
+bool DYLDRendezvous::FillSOEntryFromModuleInfo(
+ LoadedModuleInfoList::LoadedModuleInfo const &modInfo, SOEntry &entry) {
+ addr_t link_map_addr;
+ addr_t base_addr;
+ addr_t dyn_addr;
+ std::string name;
- // If we can't get the SO info from the remote, return failure.
- if (fromRemote && m_process->LoadModules (module_list) == 0)
- return false;
+ if (!modInfo.get_link_map(link_map_addr) || !modInfo.get_base(base_addr) ||
+ !modInfo.get_dynamic(dyn_addr) || !modInfo.get_name(name))
+ return false;
- if (!fromRemote && m_current.map_addr == 0)
- return false;
+ entry.link_addr = link_map_addr;
+ entry.base_addr = base_addr;
+ entry.dyn_addr = dyn_addr;
- // 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;
-
- m_soentries.clear();
- if (fromRemote)
- return SaveSOEntriesFromRemote(module_list);
-
- m_added_soentries.clear();
- m_removed_soentries.clear();
- return TakeSnapshot(m_soentries);
- }
- assert(m_current.state == eConsistent);
+ entry.file_spec.SetFile(name, false);
- // 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();
+ UpdateBaseAddrIfNecessary(entry, name);
- return false;
+ // not needed if we're using ModuleInfos
+ entry.next = 0;
+ entry.prev = 0;
+ entry.path_addr = 0;
+
+ return true;
}
-bool
-DYLDRendezvous::FillSOEntryFromModuleInfo (LoadedModuleInfoList::LoadedModuleInfo const & modInfo,
- SOEntry &entry)
-{
- addr_t link_map_addr;
- addr_t base_addr;
- addr_t dyn_addr;
- std::string name;
-
- if (!modInfo.get_link_map (link_map_addr) ||
- !modInfo.get_base (base_addr) ||
- !modInfo.get_dynamic (dyn_addr) ||
- !modInfo.get_name (name))
- return false;
+bool DYLDRendezvous::SaveSOEntriesFromRemote(
+ LoadedModuleInfoList &module_list) {
+ for (auto const &modInfo : module_list.m_list) {
+ SOEntry entry;
+ if (!FillSOEntryFromModuleInfo(modInfo, entry))
+ return false;
- entry.link_addr = link_map_addr;
- entry.base_addr = base_addr;
- entry.dyn_addr = dyn_addr;
+ // Only add shared libraries and not the executable.
+ if (!SOEntryIsMainExecutable(entry))
+ m_soentries.push_back(entry);
+ }
- entry.file_spec.SetFile(name, false);
+ m_loaded_modules = module_list;
+ return true;
+}
- UpdateBaseAddrIfNecessary(entry, name);
+bool DYLDRendezvous::AddSOEntriesFromRemote(LoadedModuleInfoList &module_list) {
+ for (auto const &modInfo : module_list.m_list) {
+ bool found = false;
+ for (auto const &existing : m_loaded_modules.m_list) {
+ if (modInfo == existing) {
+ found = true;
+ break;
+ }
+ }
- // not needed if we're using ModuleInfos
- entry.next = 0;
- entry.prev = 0;
- entry.path_addr = 0;
+ if (found)
+ continue;
- return true;
+ SOEntry entry;
+ if (!FillSOEntryFromModuleInfo(modInfo, entry))
+ return false;
+
+ // Only add shared libraries and not the executable.
+ if (!SOEntryIsMainExecutable(entry))
+ m_soentries.push_back(entry);
+ }
+
+ m_loaded_modules = module_list;
+ return true;
}
-bool
-DYLDRendezvous::SaveSOEntriesFromRemote(LoadedModuleInfoList &module_list)
-{
- for (auto const & modInfo : module_list.m_list)
- {
- SOEntry entry;
- if (!FillSOEntryFromModuleInfo(modInfo, entry))
- return false;
-
- // Only add shared libraries and not the executable.
- if (!SOEntryIsMainExecutable(entry))
- m_soentries.push_back(entry);
+bool DYLDRendezvous::RemoveSOEntriesFromRemote(
+ LoadedModuleInfoList &module_list) {
+ for (auto const &existing : m_loaded_modules.m_list) {
+ bool found = false;
+ for (auto const &modInfo : module_list.m_list) {
+ if (modInfo == existing) {
+ found = true;
+ break;
+ }
}
- m_loaded_modules = module_list;
- return true;
+ if (found)
+ continue;
-}
+ SOEntry entry;
+ if (!FillSOEntryFromModuleInfo(existing, entry))
+ return false;
+
+ // Only add shared libraries and not the executable.
+ if (!SOEntryIsMainExecutable(entry)) {
+ auto pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
+ if (pos == m_soentries.end())
+ return false;
-bool
-DYLDRendezvous::AddSOEntriesFromRemote(LoadedModuleInfoList &module_list)
-{
- for (auto const & modInfo : module_list.m_list)
- {
- bool found = false;
- for (auto const & existing : m_loaded_modules.m_list)
- {
- if (modInfo == existing)
- {
- found = true;
- break;
- }
- }
-
- if (found)
- continue;
-
- SOEntry entry;
- if (!FillSOEntryFromModuleInfo(modInfo, entry))
- return false;
-
- // Only add shared libraries and not the executable.
- if (!SOEntryIsMainExecutable(entry))
- m_soentries.push_back(entry);
+ m_soentries.erase(pos);
}
+ }
- m_loaded_modules = module_list;
- return true;
+ m_loaded_modules = module_list;
+ return true;
}
-bool
-DYLDRendezvous::RemoveSOEntriesFromRemote(LoadedModuleInfoList &module_list)
-{
- for (auto const & existing : m_loaded_modules.m_list)
- {
- bool found = false;
- for (auto const & modInfo : module_list.m_list)
- {
- if (modInfo == existing)
- {
- found = true;
- break;
- }
- }
-
- if (found)
- continue;
-
- SOEntry entry;
- if (!FillSOEntryFromModuleInfo(existing, entry))
- return false;
-
- // Only add shared libraries and not the executable.
- if (!SOEntryIsMainExecutable(entry))
- {
- auto pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
- if (pos == m_soentries.end())
- return false;
-
- m_soentries.erase(pos);
- }
- }
+bool DYLDRendezvous::AddSOEntries() {
+ SOEntry entry;
+ iterator pos;
- m_loaded_modules = module_list;
- return true;
-}
+ assert(m_previous.state == eAdd);
-bool
-DYLDRendezvous::AddSOEntries()
-{
- SOEntry entry;
- iterator pos;
+ if (m_current.map_addr == 0)
+ return false;
- assert(m_previous.state == eAdd);
+ for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next) {
+ if (!ReadSOEntryFromMemory(cursor, entry))
+ return false;
- if (m_current.map_addr == 0)
- return false;
+ // Only add shared libraries and not the executable.
+ if (SOEntryIsMainExecutable(entry))
+ continue;
- for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next)
- {
- if (!ReadSOEntryFromMemory(cursor, entry))
- return false;
-
- // Only add shared libraries and not the executable.
- if (SOEntryIsMainExecutable(entry))
- continue;
-
- pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
- if (pos == m_soentries.end())
- {
- m_soentries.push_back(entry);
- m_added_soentries.push_back(entry);
- }
+ pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
+ if (pos == m_soentries.end()) {
+ m_soentries.push_back(entry);
+ m_added_soentries.push_back(entry);
}
+ }
- return true;
+ return true;
}
-bool
-DYLDRendezvous::RemoveSOEntries()
-{
- SOEntryList entry_list;
- iterator pos;
+bool DYLDRendezvous::RemoveSOEntries() {
+ SOEntryList entry_list;
+ iterator pos;
- assert(m_previous.state == eDelete);
+ assert(m_previous.state == eDelete);
- if (!TakeSnapshot(entry_list))
- return false;
+ if (!TakeSnapshot(entry_list))
+ return false;
- for (iterator I = begin(); I != end(); ++I)
- {
- pos = std::find(entry_list.begin(), entry_list.end(), *I);
- if (pos == entry_list.end())
- m_removed_soentries.push_back(*I);
- }
+ for (iterator I = begin(); I != end(); ++I) {
+ pos = std::find(entry_list.begin(), entry_list.end(), *I);
+ if (pos == entry_list.end())
+ m_removed_soentries.push_back(*I);
+ }
- m_soentries = entry_list;
- return true;
+ m_soentries = entry_list;
+ return true;
}
-bool
-DYLDRendezvous::SOEntryIsMainExecutable(const SOEntry &entry)
-{
- // On Linux the executable is indicated by an empty path in the entry. On
- // FreeBSD and on Android it is the full path to the executable.
-
- auto triple = m_process->GetTarget().GetArchitecture().GetTriple();
- switch (triple.getOS())
- {
- case llvm::Triple::FreeBSD:
- return entry.file_spec == m_exe_file_spec;
- case llvm::Triple::Linux:
- if (triple.isAndroid())
- return entry.file_spec == m_exe_file_spec;
- return !entry.file_spec;
- default:
- return false;
- }
+bool DYLDRendezvous::SOEntryIsMainExecutable(const SOEntry &entry) {
+ // On Linux the executable is indicated by an empty path in the entry. On
+ // FreeBSD and on Android it is the full path to the executable.
+
+ auto triple = m_process->GetTarget().GetArchitecture().GetTriple();
+ switch (triple.getOS()) {
+ case llvm::Triple::FreeBSD:
+ return entry.file_spec == m_exe_file_spec;
+ case llvm::Triple::Linux:
+ if (triple.isAndroid())
+ return entry.file_spec == m_exe_file_spec;
+ return !entry.file_spec;
+ default:
+ return false;
+ }
}
-bool
-DYLDRendezvous::TakeSnapshot(SOEntryList &entry_list)
-{
- SOEntry entry;
+bool DYLDRendezvous::TakeSnapshot(SOEntryList &entry_list) {
+ SOEntry entry;
- if (m_current.map_addr == 0)
- return false;
+ if (m_current.map_addr == 0)
+ return false;
- // Clear previous entries since we are about to obtain an up to date list.
- entry_list.clear();
+ // Clear previous entries since we are about to obtain an up to date list.
+ entry_list.clear();
- for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next)
- {
- if (!ReadSOEntryFromMemory(cursor, entry))
- return false;
+ for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next) {
+ if (!ReadSOEntryFromMemory(cursor, entry))
+ return false;
- // Only add shared libraries and not the executable.
- if (SOEntryIsMainExecutable(entry))
- continue;
+ // Only add shared libraries and not the executable.
+ if (SOEntryIsMainExecutable(entry))
+ continue;
- entry_list.push_back(entry);
- }
+ entry_list.push_back(entry);
+ }
- return true;
+ return true;
}
-addr_t
-DYLDRendezvous::ReadWord(addr_t addr, uint64_t *dst, size_t size)
-{
- Error error;
+addr_t DYLDRendezvous::ReadWord(addr_t addr, uint64_t *dst, size_t size) {
+ Error error;
- *dst = m_process->ReadUnsignedIntegerFromMemory(addr, size, 0, error);
- if (error.Fail())
- return 0;
+ *dst = m_process->ReadUnsignedIntegerFromMemory(addr, size, 0, error);
+ if (error.Fail())
+ return 0;
- return addr + size;
+ return addr + size;
}
-addr_t
-DYLDRendezvous::ReadPointer(addr_t addr, addr_t *dst)
-{
- Error error;
-
- *dst = m_process->ReadPointerFromMemory(addr, error);
- if (error.Fail())
- return 0;
+addr_t DYLDRendezvous::ReadPointer(addr_t addr, addr_t *dst) {
+ Error error;
- return addr + m_process->GetAddressByteSize();
+ *dst = m_process->ReadPointerFromMemory(addr, error);
+ if (error.Fail())
+ return 0;
+
+ return addr + m_process->GetAddressByteSize();
}
-std::string
-DYLDRendezvous::ReadStringFromMemory(addr_t addr)
-{
- std::string str;
- Error error;
+std::string DYLDRendezvous::ReadStringFromMemory(addr_t addr) {
+ std::string str;
+ Error error;
- if (addr == LLDB_INVALID_ADDRESS)
- return std::string();
+ if (addr == LLDB_INVALID_ADDRESS)
+ return std::string();
- m_process->ReadCStringFromMemory(addr, str, error);
+ m_process->ReadCStringFromMemory(addr, str, error);
- return str;
+ return str;
}
-// Returns true if the load bias reported by the linker is incorrect for the given entry. This
-// function is used to handle cases where we want to work around a bug in the system linker.
-static bool
-isLoadBiasIncorrect(Target& target, const std::string& file_path)
-{
- // On Android L (API 21, 22) the load address of the "/system/bin/linker" isn't filled in
- // correctly.
- uint32_t os_major = 0, os_minor = 0, os_update = 0;
- if (target.GetArchitecture().GetTriple().isAndroid() &&
- target.GetPlatform()->GetOSVersion(os_major, os_minor, os_update) &&
- (os_major == 21 || os_major == 22) &&
- (file_path == "/system/bin/linker" || file_path == "/system/bin/linker64"))
- {
- return true;
- }
+// Returns true if the load bias reported by the linker is incorrect for the
+// given entry. This
+// function is used to handle cases where we want to work around a bug in the
+// system linker.
+static bool isLoadBiasIncorrect(Target &target, const std::string &file_path) {
+ // On Android L (API 21, 22) the load address of the "/system/bin/linker"
+ // isn't filled in
+ // correctly.
+ uint32_t os_major = 0, os_minor = 0, os_update = 0;
+ if (target.GetArchitecture().GetTriple().isAndroid() &&
+ target.GetPlatform()->GetOSVersion(os_major, os_minor, os_update) &&
+ (os_major == 21 || os_major == 22) &&
+ (file_path == "/system/bin/linker" ||
+ file_path == "/system/bin/linker64")) {
+ return true;
+ }
- return false;
+ return false;
}
-void
-DYLDRendezvous::UpdateBaseAddrIfNecessary(SOEntry &entry, std::string const &file_path)
-{
- // If the load bias reported by the linker is incorrect then fetch the load address of the file
- // from the proc file system.
- if (isLoadBiasIncorrect(m_process->GetTarget(), file_path))
- {
- lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
- bool is_loaded = false;
- Error error = m_process->GetFileLoadAddress(entry.file_spec, is_loaded, load_addr);
- if (error.Success() && is_loaded)
- entry.base_addr = load_addr;
- }
+void DYLDRendezvous::UpdateBaseAddrIfNecessary(SOEntry &entry,
+ std::string const &file_path) {
+ // If the load bias reported by the linker is incorrect then fetch the load
+ // address of the file
+ // from the proc file system.
+ if (isLoadBiasIncorrect(m_process->GetTarget(), file_path)) {
+ lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
+ bool is_loaded = false;
+ Error error =
+ m_process->GetFileLoadAddress(entry.file_spec, is_loaded, load_addr);
+ if (error.Success() && is_loaded)
+ entry.base_addr = load_addr;
+ }
}
-bool
-DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry)
-{
- entry.clear();
+bool DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry) {
+ entry.clear();
- entry.link_addr = addr;
-
- if (!(addr = ReadPointer(addr, &entry.base_addr)))
- return false;
+ entry.link_addr = addr;
- // mips adds an extra load offset field to the link map struct on
- // FreeBSD and NetBSD (need to validate other OSes).
- // http://svnweb.freebsd.org/base/head/sys/sys/link_elf.h?revision=217153&view=markup#l57
- const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
- if ((arch.GetTriple().getOS() == llvm::Triple::FreeBSD
- || arch.GetTriple().getOS() == llvm::Triple::NetBSD) &&
- (arch.GetMachine() == llvm::Triple::mips || arch.GetMachine() == llvm::Triple::mipsel
- || arch.GetMachine() == llvm::Triple::mips64 || arch.GetMachine() == llvm::Triple::mips64el))
- {
- addr_t mips_l_offs;
- if (!(addr = ReadPointer(addr, &mips_l_offs)))
- return false;
- if (mips_l_offs != 0 && mips_l_offs != entry.base_addr)
- return false;
- }
-
- if (!(addr = ReadPointer(addr, &entry.path_addr)))
- return false;
-
- if (!(addr = ReadPointer(addr, &entry.dyn_addr)))
- return false;
-
- if (!(addr = ReadPointer(addr, &entry.next)))
- return false;
-
- if (!(addr = ReadPointer(addr, &entry.prev)))
- return false;
+ if (!(addr = ReadPointer(addr, &entry.base_addr)))
+ return false;
- std::string file_path = ReadStringFromMemory(entry.path_addr);
- entry.file_spec.SetFile(file_path, false);
+ // mips adds an extra load offset field to the link map struct on
+ // FreeBSD and NetBSD (need to validate other OSes).
+ // http://svnweb.freebsd.org/base/head/sys/sys/link_elf.h?revision=217153&view=markup#l57
+ const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
+ if ((arch.GetTriple().getOS() == llvm::Triple::FreeBSD ||
+ arch.GetTriple().getOS() == llvm::Triple::NetBSD) &&
+ (arch.GetMachine() == llvm::Triple::mips ||
+ arch.GetMachine() == llvm::Triple::mipsel ||
+ arch.GetMachine() == llvm::Triple::mips64 ||
+ arch.GetMachine() == llvm::Triple::mips64el)) {
+ addr_t mips_l_offs;
+ if (!(addr = ReadPointer(addr, &mips_l_offs)))
+ return false;
+ if (mips_l_offs != 0 && mips_l_offs != entry.base_addr)
+ return false;
+ }
+
+ if (!(addr = ReadPointer(addr, &entry.path_addr)))
+ return false;
- UpdateBaseAddrIfNecessary(entry, file_path);
+ if (!(addr = ReadPointer(addr, &entry.dyn_addr)))
+ return false;
- return true;
-}
+ if (!(addr = ReadPointer(addr, &entry.next)))
+ return false;
+ if (!(addr = ReadPointer(addr, &entry.prev)))
+ return false;
-bool
-DYLDRendezvous::FindMetadata(const char *name, PThreadField field, uint32_t& value)
-{
- Target& target = m_process->GetTarget();
+ std::string file_path = ReadStringFromMemory(entry.path_addr);
+ entry.file_spec.SetFile(file_path, false);
- SymbolContextList list;
- if (!target.GetImages().FindSymbolsWithNameAndType (ConstString(name), eSymbolTypeAny, list))
- return false;
+ UpdateBaseAddrIfNecessary(entry, file_path);
- Address address = list[0].symbol->GetAddress();
- addr_t addr = address.GetLoadAddress (&target);
- if (addr == LLDB_INVALID_ADDRESS)
- return false;
+ return true;
+}
- Error error;
- value = (uint32_t)m_process->ReadUnsignedIntegerFromMemory(addr + field*sizeof(uint32_t), sizeof(uint32_t), 0, error);
- if (error.Fail())
- return false;
+bool DYLDRendezvous::FindMetadata(const char *name, PThreadField field,
+ uint32_t &value) {
+ Target &target = m_process->GetTarget();
- if (field == eSize)
- value /= 8; // convert bits to bytes
+ SymbolContextList list;
+ if (!target.GetImages().FindSymbolsWithNameAndType(ConstString(name),
+ eSymbolTypeAny, list))
+ return false;
- return true;
+ Address address = list[0].symbol->GetAddress();
+ addr_t addr = address.GetLoadAddress(&target);
+ if (addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ Error error;
+ value = (uint32_t)m_process->ReadUnsignedIntegerFromMemory(
+ addr + field * sizeof(uint32_t), sizeof(uint32_t), 0, error);
+ if (error.Fail())
+ return false;
+
+ if (field == eSize)
+ value /= 8; // convert bits to bytes
+
+ return true;
}
-const DYLDRendezvous::ThreadInfo&
-DYLDRendezvous::GetThreadInfo()
-{
- if (!m_thread_info.valid)
- {
- bool ok = true;
+const DYLDRendezvous::ThreadInfo &DYLDRendezvous::GetThreadInfo() {
+ if (!m_thread_info.valid) {
+ bool ok = true;
- ok &= FindMetadata ("_thread_db_pthread_dtvp", eOffset, m_thread_info.dtv_offset);
- ok &= FindMetadata ("_thread_db_dtv_dtv", eSize, m_thread_info.dtv_slot_size);
- ok &= FindMetadata ("_thread_db_link_map_l_tls_modid", eOffset, m_thread_info.modid_offset);
- ok &= FindMetadata ("_thread_db_dtv_t_pointer_val", eOffset, m_thread_info.tls_offset);
+ ok &= FindMetadata("_thread_db_pthread_dtvp", eOffset,
+ m_thread_info.dtv_offset);
+ ok &=
+ FindMetadata("_thread_db_dtv_dtv", eSize, m_thread_info.dtv_slot_size);
+ ok &= FindMetadata("_thread_db_link_map_l_tls_modid", eOffset,
+ m_thread_info.modid_offset);
+ ok &= FindMetadata("_thread_db_dtv_t_pointer_val", eOffset,
+ m_thread_info.tls_offset);
- if (ok)
- m_thread_info.valid = true;
- }
+ if (ok)
+ m_thread_info.valid = true;
+ }
- return m_thread_info;
+ return m_thread_info;
}
-void
-DYLDRendezvous::DumpToLog(Log *log) const
-{
- int state = GetState();
-
- if (!log)
- 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");
-
- iterator I = begin();
- iterator E = end();
-
- if (I != E)
- 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);
- }
+void DYLDRendezvous::DumpToLog(Log *log) const {
+ int state = GetState();
+
+ if (!log)
+ 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");
+
+ iterator I = begin();
+ iterator E = end();
+
+ if (I != E)
+ 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);
+ }
}