summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/DynamicLoader/Windows-DYLD
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/DynamicLoader/Windows-DYLD')
-rw-r--r--lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp96
-rw-r--r--lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h11
2 files changed, 92 insertions, 15 deletions
diff --git a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
index 727a4ae5cc4..f45d7116dcf 100644
--- a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
@@ -12,6 +12,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
@@ -61,6 +62,56 @@ DynamicLoader *DynamicLoaderWindowsDYLD::CreateInstance(Process *process,
return nullptr;
}
+void DynamicLoaderWindowsDYLD::OnLoadModule(const ModuleSpec &module_spec,
+ lldb::addr_t module_addr) {
+ // Confusingly, there is no Target::AddSharedModule. Instead, calling
+ // GetSharedModule() with a new module will add it to the module list and
+ // return a corresponding ModuleSP.
+ Status error;
+ ModuleSP module_sp =
+ m_process->GetTarget().GetSharedModule(module_spec, &error);
+ if (error.Fail())
+ return;
+
+ m_loaded_modules[module_sp] = module_addr;
+ UpdateLoadedSectionsCommon(module_sp, module_addr, false);
+}
+
+void DynamicLoaderWindowsDYLD::OnUnloadModule(lldb::addr_t module_addr) {
+ Address resolved_addr;
+ if (!m_process->GetTarget().ResolveLoadAddress(module_addr, resolved_addr))
+ return;
+
+ ModuleSP module_sp = resolved_addr.GetModule();
+ if (module_sp) {
+ m_loaded_modules.erase(module_sp);
+ UnloadSectionsCommon(module_sp);
+ }
+}
+
+lldb::addr_t DynamicLoaderWindowsDYLD::GetLoadAddress(ModuleSP executable) {
+ // First, see if the load address is already cached.
+ auto it = m_loaded_modules.find(executable);
+ if (it != m_loaded_modules.end() && it->second != LLDB_INVALID_ADDRESS)
+ return it->second;
+
+ lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
+
+ // Second, try to get it through the process plugins. For a remote process,
+ // the remote platform will be responsible for providing it.
+ FileSpec file_spec(executable->GetPlatformFileSpec());
+ bool is_loaded = false;
+ Status status =
+ m_process->GetFileLoadAddress(file_spec, is_loaded, load_addr);
+ // Servers other than lldb server could respond with a bogus address.
+ if (status.Success() && is_loaded && load_addr != LLDB_INVALID_ADDRESS) {
+ m_loaded_modules[executable] = load_addr;
+ return load_addr;
+ }
+
+ return LLDB_INVALID_ADDRESS;
+}
+
void DynamicLoaderWindowsDYLD::DidAttach() {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
if (log)
@@ -73,21 +124,17 @@ void DynamicLoaderWindowsDYLD::DidAttach() {
// Try to fetch the load address of the file from the process, since there
// could be randomization of the load address.
+ lldb::addr_t load_addr = GetLoadAddress(executable);
+ if (load_addr == LLDB_INVALID_ADDRESS)
+ return;
- // It might happen that the remote has a different dir for the file, so we
- // only send the basename of the executable in the query. I think this is safe
- // because I doubt that two executables with the same basenames are loaded in
- // memory...
- FileSpec file_spec(
- executable->GetPlatformFileSpec().GetFilename().GetCString());
- bool is_loaded;
- addr_t base_addr = 0;
- lldb::addr_t load_addr;
- Status error = m_process->GetFileLoadAddress(file_spec, is_loaded, load_addr);
- if (error.Success() && is_loaded) {
- base_addr = load_addr;
- UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, base_addr, false);
- }
+ // Request the process base address.
+ lldb::addr_t image_base = m_process->GetImageInfoAddress();
+ if (image_base == load_addr)
+ return;
+
+ // Rebase the process's modules if there is a mismatch.
+ UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_addr, false);
ModuleList module_list;
module_list.Append(executable);
@@ -95,7 +142,26 @@ void DynamicLoaderWindowsDYLD::DidAttach() {
m_process->LoadModules();
}
-void DynamicLoaderWindowsDYLD::DidLaunch() {}
+void DynamicLoaderWindowsDYLD::DidLaunch() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf("DynamicLoaderWindowsDYLD::%s()", __FUNCTION__);
+
+ ModuleSP executable = GetTargetExecutable();
+ if (!executable.get())
+ return;
+
+ lldb::addr_t load_addr = GetLoadAddress(executable);
+ if (load_addr != LLDB_INVALID_ADDRESS) {
+ // Update the loaded sections so that the breakpoints can be resolved.
+ UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_addr, false);
+
+ ModuleList module_list;
+ module_list.Append(executable);
+ m_process->GetTarget().ModulesDidLoad(module_list);
+ m_process->LoadModules();
+ }
+}
Status DynamicLoaderWindowsDYLD::CanLoadImage() { return Status(); }
diff --git a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
index 5eb39008573..ef859255db1 100644
--- a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
+++ b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
@@ -12,6 +12,8 @@
#include "lldb/Target/DynamicLoader.h"
#include "lldb/lldb-forward.h"
+#include <map>
+
namespace lldb_private {
class DynamicLoaderWindowsDYLD : public DynamicLoader {
@@ -27,6 +29,9 @@ public:
static DynamicLoader *CreateInstance(Process *process, bool force);
+ void OnLoadModule(const ModuleSpec &module_spec, lldb::addr_t module_addr);
+ void OnUnloadModule(lldb::addr_t module_addr);
+
void DidAttach() override;
void DidLaunch() override;
Status CanLoadImage() override;
@@ -35,6 +40,12 @@ public:
ConstString GetPluginName() override;
uint32_t GetPluginVersion() override;
+
+protected:
+ lldb::addr_t GetLoadAddress(lldb::ModuleSP executable);
+
+private:
+ std::map<lldb::ModuleSP, lldb::addr_t> m_loaded_modules;
};
} // namespace lldb_private
OpenPOWER on IntegriCloud