summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Core/LoadedModuleInfoList.h152
-rw-r--r--lldb/include/lldb/Target/Process.h7
-rw-r--r--lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp177
-rw-r--r--lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h29
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp133
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h8
6 files changed, 361 insertions, 145 deletions
diff --git a/lldb/include/lldb/Core/LoadedModuleInfoList.h b/lldb/include/lldb/Core/LoadedModuleInfoList.h
new file mode 100644
index 00000000000..6ba5c2813ec
--- /dev/null
+++ b/lldb/include/lldb/Core/LoadedModuleInfoList.h
@@ -0,0 +1,152 @@
+//===-- LoadedModuleInfoList.h ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_LoadedModuleInfoList_h_
+#define liblldb_LoadedModuleInfoList_h_
+
+// C Includes
+
+// C++ Includes
+#include <vector>
+
+// Other libraries and framework includes
+#include "lldb/lldb-private-forward.h"
+
+namespace lldb_private {
+class LoadedModuleInfoList
+{
+public:
+
+ class LoadedModuleInfo
+ {
+ public:
+
+ enum e_data_point
+ {
+ e_has_name = 0,
+ e_has_base ,
+ e_has_dynamic ,
+ e_has_link_map ,
+ e_num
+ };
+
+ LoadedModuleInfo ()
+ {
+ for (uint32_t i = 0; i < e_num; ++i)
+ m_has[i] = false;
+ };
+
+ void set_name (const std::string & name)
+ {
+ m_name = name;
+ m_has[e_has_name] = true;
+ }
+ bool get_name (std::string & out) const
+ {
+ out = m_name;
+ return m_has[e_has_name];
+ }
+
+ void set_base (const lldb::addr_t base)
+ {
+ m_base = base;
+ m_has[e_has_base] = true;
+ }
+ bool get_base (lldb::addr_t & out) const
+ {
+ out = m_base;
+ return m_has[e_has_base];
+ }
+
+ void set_base_is_offset (bool is_offset)
+ {
+ m_base_is_offset = is_offset;
+ }
+ bool get_base_is_offset(bool & out) const
+ {
+ out = m_base_is_offset;
+ return m_has[e_has_base];
+ }
+
+ void set_link_map (const lldb::addr_t addr)
+ {
+ m_link_map = addr;
+ m_has[e_has_link_map] = true;
+ }
+ bool get_link_map (lldb::addr_t & out) const
+ {
+ out = m_link_map;
+ return m_has[e_has_link_map];
+ }
+
+ void set_dynamic (const lldb::addr_t addr)
+ {
+ m_dynamic = addr;
+ m_has[e_has_dynamic] = true;
+ }
+ bool get_dynamic (lldb::addr_t & out) const
+ {
+ out = m_dynamic;
+ return m_has[e_has_dynamic];
+ }
+
+ bool has_info (e_data_point datum) const
+ {
+ assert (datum < e_num);
+ return m_has[datum];
+ }
+
+ bool
+ operator == (LoadedModuleInfo const &rhs) const
+ {
+ if (e_num != rhs.e_num)
+ return false;
+
+ for (size_t i = 0; i < e_num; ++i)
+ {
+ if (m_has[i] != rhs.m_has[i])
+ return false;
+ }
+
+ return (m_base == rhs.m_base) &&
+ (m_link_map == rhs.m_link_map) &&
+ (m_dynamic == rhs.m_dynamic) &&
+ (m_name == rhs.m_name);
+ }
+ protected:
+
+ bool m_has[e_num];
+ std::string m_name;
+ lldb::addr_t m_link_map;
+ lldb::addr_t m_base;
+ bool m_base_is_offset;
+ lldb::addr_t m_dynamic;
+ };
+
+ LoadedModuleInfoList ()
+ : m_list ()
+ , m_link_map (LLDB_INVALID_ADDRESS)
+ {}
+
+ void add (const LoadedModuleInfo & mod)
+ {
+ m_list.push_back (mod);
+ }
+
+ void clear ()
+ {
+ m_list.clear ();
+ }
+
+ std::vector<LoadedModuleInfo> m_list;
+ lldb::addr_t m_link_map;
+};
+} // namespace lldb_private
+
+#endif // liblldb_LoadedModuleInfoList_h_
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index dfd332346e0..6bb7a3d783d 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -30,6 +30,7 @@
#include "lldb/Core/Communication.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Event.h"
+#include "lldb/Core/LoadedModuleInfoList.h"
#include "lldb/Core/ThreadSafeValue.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/StructuredData.h"
@@ -1152,6 +1153,12 @@ public:
return 0;
}
+ virtual size_t
+ LoadModules (LoadedModuleInfoList &)
+ {
+ return 0;
+ }
+
protected:
virtual JITLoaderList &
GetJITLoaders ();
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
index 09e874a011d..e21c64bee4d 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
@@ -107,6 +107,7 @@ DYLDRendezvous::DYLDRendezvous(Process *process)
m_rendezvous_addr(LLDB_INVALID_ADDRESS),
m_current(),
m_previous(),
+ m_loaded_modules(),
m_soentries(),
m_added_soentries(),
m_removed_soentries()
@@ -181,6 +182,9 @@ DYLDRendezvous::Resolve()
m_previous = m_current;
m_current = info;
+ if (UpdateSOEntries (true))
+ return true;
+
return UpdateSOEntries();
}
@@ -191,18 +195,23 @@ DYLDRendezvous::IsValid()
}
bool
-DYLDRendezvous::UpdateSOEntries()
+DYLDRendezvous::UpdateSOEntries(bool fromRemote)
{
SOEntry entry;
+ LoadedModuleInfoList module_list;
- if (m_current.map_addr == 0)
+ // If we can't get the SO info from the remote, return failure.
+ if (fromRemote && m_process->LoadModules (module_list) == 0)
+ return false;
+
+ if (!fromRemote && m_current.map_addr == 0)
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 TakeSnapshot(m_soentries);
+ 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.
@@ -215,6 +224,9 @@ DYLDRendezvous::UpdateSOEntries()
return false;
m_soentries.clear();
+ if (fromRemote)
+ return SaveSOEntriesFromRemote(module_list);
+
m_added_soentries.clear();
m_removed_soentries.clear();
return TakeSnapshot(m_soentries);
@@ -224,15 +236,133 @@ DYLDRendezvous::UpdateSOEntries()
// Otherwise check the previous state to determine what to expect and update
// accordingly.
if (m_previous.state == eAdd)
- return UpdateSOEntriesForAddition();
+ return fromRemote ? AddSOEntriesFromRemote(module_list) : AddSOEntries();
else if (m_previous.state == eDelete)
- return UpdateSOEntriesForDeletion();
+ return fromRemote ? RemoveSOEntriesFromRemote(module_list) : RemoveSOEntries();
return false;
}
-
+
bool
-DYLDRendezvous::UpdateSOEntriesForAddition()
+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;
+
+ entry.link_addr = link_map_addr;
+ entry.base_addr = base_addr;
+ entry.dyn_addr = dyn_addr;
+
+ entry.file_spec.SetFile(name, false);
+
+ UpdateBaseAddrIfNecessary(entry, name);
+
+ // not needed if we're using ModuleInfos
+ entry.next = 0;
+ entry.prev = 0;
+ entry.path_addr = 0;
+
+ 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);
+ }
+
+ m_loaded_modules = module_list;
+ return true;
+
+}
+
+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_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))
+ {
+ iterator pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
+ if (pos == m_soentries.end())
+ return false;
+
+ m_soentries.erase(pos);
+ }
+ }
+
+ m_loaded_modules = module_list;
+ return true;
+}
+
+bool
+DYLDRendezvous::AddSOEntries()
{
SOEntry entry;
iterator pos;
@@ -263,7 +393,7 @@ DYLDRendezvous::UpdateSOEntriesForAddition()
}
bool
-DYLDRendezvous::UpdateSOEntriesForDeletion()
+DYLDRendezvous::RemoveSOEntries()
{
SOEntryList entry_list;
iterator pos;
@@ -291,7 +421,8 @@ DYLDRendezvous::SOEntryIsMainExecutable(const SOEntry &entry)
// FreeBSD and on Android it is the full path to the executable.
auto triple = m_process->GetTarget().GetArchitecture().GetTriple();
- switch (triple.getOS()) {
+ switch (triple.getOS())
+ {
case llvm::Triple::FreeBSD:
return entry.file_spec == m_exe_file_spec;
case llvm::Triple::Linux:
@@ -386,6 +517,21 @@ isLoadBiasIncorrect(Target& target, const std::string& file_path)
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;
+ }
+}
+
bool
DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry)
{
@@ -427,16 +573,7 @@ DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry)
std::string file_path = ReadStringFromMemory(entry.path_addr);
entry.file_spec.SetFile(file_path, false);
- // 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;
- }
+ UpdateBaseAddrIfNecessary(entry, file_path);
return true;
}
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
index ec5af945ee7..8498116c808 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
@@ -20,6 +20,10 @@
#include "lldb/lldb-types.h"
#include "lldb/Host/FileSpec.h"
+#include "lldb/Core/LoadedModuleInfoList.h"
+
+using lldb_private::LoadedModuleInfoList;
+
namespace lldb_private {
class Process;
}
@@ -201,6 +205,9 @@ protected:
Rendezvous m_current;
Rendezvous m_previous;
+ /// List of currently loaded SO modules
+ LoadedModuleInfoList m_loaded_modules;
+
/// List of SOEntry objects corresponding to the current link map state.
SOEntryList m_soentries;
@@ -240,13 +247,29 @@ protected:
/// Updates the current set of SOEntries, the set of added entries, and the
/// set of removed entries.
bool
- UpdateSOEntries();
+ UpdateSOEntries(bool fromRemote = false);
+
+ bool
+ FillSOEntryFromModuleInfo (LoadedModuleInfoList::LoadedModuleInfo const & modInfo,
+ SOEntry &entry);
+
+ bool
+ SaveSOEntriesFromRemote(LoadedModuleInfoList &module_list);
bool
- UpdateSOEntriesForAddition();
+ AddSOEntriesFromRemote(LoadedModuleInfoList &module_list);
bool
- UpdateSOEntriesForDeletion();
+ RemoveSOEntriesFromRemote(LoadedModuleInfoList &module_list);
+
+ bool
+ AddSOEntries();
+
+ bool
+ RemoveSOEntries();
+
+ void
+ UpdateBaseAddrIfNecessary(SOEntry &entry, std::string const &file_path);
bool
SOEntryIsMainExecutable(const SOEntry &entry);
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 2bf882364cc..856ea35aef9 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -173,118 +173,6 @@ namespace {
} // anonymous namespace end
-class ProcessGDBRemote::GDBLoadedModuleInfoList
-{
-public:
-
- class LoadedModuleInfo
- {
- public:
-
- enum e_data_point
- {
- e_has_name = 0,
- e_has_base ,
- e_has_dynamic ,
- e_has_link_map ,
- e_num
- };
-
- LoadedModuleInfo ()
- {
- for (uint32_t i = 0; i < e_num; ++i)
- m_has[i] = false;
- }
-
- void set_name (const std::string & name)
- {
- m_name = name;
- m_has[e_has_name] = true;
- }
- bool get_name (std::string & out) const
- {
- out = m_name;
- return m_has[e_has_name];
- }
-
- void set_base (const lldb::addr_t base)
- {
- m_base = base;
- m_has[e_has_base] = true;
- }
- bool get_base (lldb::addr_t & out) const
- {
- out = m_base;
- return m_has[e_has_base];
- }
-
- void set_base_is_offset (bool is_offset)
- {
- m_base_is_offset = is_offset;
- }
- bool get_base_is_offset(bool & out) const
- {
- out = m_base_is_offset;
- return m_has[e_has_base];
- }
-
- void set_link_map (const lldb::addr_t addr)
- {
- m_link_map = addr;
- m_has[e_has_link_map] = true;
- }
- bool get_link_map (lldb::addr_t & out) const
- {
- out = m_link_map;
- return m_has[e_has_link_map];
- }
-
- void set_dynamic (const lldb::addr_t addr)
- {
- m_dynamic = addr;
- m_has[e_has_dynamic] = true;
- }
- bool get_dynamic (lldb::addr_t & out) const
- {
- out = m_dynamic;
- return m_has[e_has_dynamic];
- }
-
- bool has_info (e_data_point datum)
- {
- assert (datum < e_num);
- return m_has[datum];
- }
-
- protected:
-
- bool m_has[e_num];
- std::string m_name;
- lldb::addr_t m_link_map;
- lldb::addr_t m_base;
- bool m_base_is_offset;
- lldb::addr_t m_dynamic;
- };
-
- GDBLoadedModuleInfoList ()
- : m_list ()
- , m_link_map (LLDB_INVALID_ADDRESS)
- {}
-
- void add (const LoadedModuleInfo & mod)
- {
- m_list.push_back (mod);
- }
-
- void clear ()
- {
- m_list.clear ();
- }
-
- std::vector<LoadedModuleInfo> m_list;
- lldb::addr_t m_link_map;
-};
-
// TODO Randomly assigning a port is unsafe. We should get an unused
// ephemeral port from the kernel and make sure we reserve it before passing
// it to debugserver.
@@ -3090,7 +2978,7 @@ ProcessGDBRemote::GetImageInfoAddress()
// the loaded module list can also provides a link map address
if (addr == LLDB_INVALID_ADDRESS)
{
- GDBLoadedModuleInfoList list;
+ LoadedModuleInfoList list;
if (GetLoadedModuleList (list).Success())
addr = list.m_link_map;
}
@@ -4742,7 +4630,7 @@ ProcessGDBRemote::GetGDBServerRegisterInfo ()
}
Error
-ProcessGDBRemote::GetLoadedModuleList (GDBLoadedModuleInfoList & list)
+ProcessGDBRemote::GetLoadedModuleList (LoadedModuleInfoList & list)
{
// Make sure LLDB has an XML parser it can use first
if (!XMLDocument::XMLEnabled())
@@ -4786,7 +4674,7 @@ ProcessGDBRemote::GetLoadedModuleList (GDBLoadedModuleInfoList & list)
root_element.ForEachChildElementWithName("library", [log, &list](const XMLNode &library) -> bool {
- GDBLoadedModuleInfoList::LoadedModuleInfo module;
+ LoadedModuleInfoList::LoadedModuleInfo module;
library.ForEachAttribute([log, &module](const llvm::StringRef &name, const llvm::StringRef &value) -> bool {
@@ -4856,7 +4744,7 @@ ProcessGDBRemote::GetLoadedModuleList (GDBLoadedModuleInfoList & list)
return Error();
root_element.ForEachChildElementWithName("library", [log, &list](const XMLNode &library) -> bool {
- GDBLoadedModuleInfoList::LoadedModuleInfo module;
+ LoadedModuleInfoList::LoadedModuleInfo module;
llvm::StringRef name = library.GetAttributeValue("name");
module.set_name(name.str());
@@ -4918,19 +4806,18 @@ ProcessGDBRemote::LoadModuleAtAddress (const FileSpec &file, lldb::addr_t base_a
}
size_t
-ProcessGDBRemote::LoadModules ()
+ProcessGDBRemote::LoadModules (LoadedModuleInfoList &module_list)
{
using lldb_private::process_gdb_remote::ProcessGDBRemote;
// request a list of loaded libraries from GDBServer
- GDBLoadedModuleInfoList module_list;
if (GetLoadedModuleList (module_list).Fail())
return 0;
// get a list of all the modules
ModuleList new_modules;
- for (GDBLoadedModuleInfoList::LoadedModuleInfo & modInfo : module_list.m_list)
+ for (LoadedModuleInfoList::LoadedModuleInfo & modInfo : module_list.m_list)
{
std::string mod_name;
lldb::addr_t mod_base;
@@ -4981,6 +4868,14 @@ ProcessGDBRemote::LoadModules ()
}
return new_modules.GetSize();
+
+}
+
+size_t
+ProcessGDBRemote::LoadModules ()
+{
+ LoadedModuleInfoList module_list;
+ return LoadModules (module_list);
}
Error
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 56b52603eb0..b48edd836a7 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -27,6 +27,7 @@
#include "lldb/Core/StringList.h"
#include "lldb/Core/StructuredData.h"
#include "lldb/Core/ThreadSafeValue.h"
+#include "lldb/Core/LoadedModuleInfoList.h"
#include "lldb/Host/HostThread.h"
#include "lldb/lldb-private-forward.h"
#include "lldb/Utility/StringExtractor.h"
@@ -245,6 +246,9 @@ public:
uint32_t &update) override;
size_t
+ LoadModules(LoadedModuleInfoList &module_list) override;
+
+ size_t
LoadModules() override;
Error
@@ -261,8 +265,6 @@ protected:
friend class GDBRemoteCommunicationClient;
friend class GDBRemoteRegisterContext;
- class GDBLoadedModuleInfoList;
-
//------------------------------------------------------------------
/// Broadcaster event bits definitions.
//------------------------------------------------------------------
@@ -463,7 +465,7 @@ protected:
// Query remote GDBServer for a detailed loaded library list
Error
- GetLoadedModuleList (GDBLoadedModuleInfoList &);
+ GetLoadedModuleList (LoadedModuleInfoList &);
lldb::ModuleSP
LoadModuleAtAddress (const FileSpec &file, lldb::addr_t base_addr, bool value_is_offset);
OpenPOWER on IntegriCloud