asmith updated this revision to Diff 186401.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D56237/new/
https://reviews.llvm.org/D56237
Files:
include/lldb/Host/Host.h
source/Host/common/Host.cpp
source/Host/windows/Host.cpp
source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
source/Plugins/Process/Windows/Common/ProcessWindows.cpp
source/Plugins/Process/Windows/Common/ProcessWindows.h
Index: source/Plugins/Process/Windows/Common/ProcessWindows.h
===================================================================
--- source/Plugins/Process/Windows/Common/ProcessWindows.h
+++ source/Plugins/Process/Windows/Common/ProcessWindows.h
@@ -90,6 +90,8 @@
lldb::addr_t GetImageInfoAddress() override;
+ DynamicLoader *GetDynamicLoader() override;
+
// IDebugDelegate overrides.
void OnExitProcess(uint32_t exit_code) override;
void OnDebuggerConnected(lldb::addr_t image_base) override;
@@ -115,6 +117,6 @@
llvm::sys::Mutex m_mutex;
std::unique_ptr<ProcessWindowsData> m_session_data;
};
-}
+} // namespace lldb_private
#endif // liblldb_Plugins_Process_Windows_Common_ProcessWindows_H_
Index: source/Plugins/Process/Windows/Common/ProcessWindows.cpp
===================================================================
--- source/Plugins/Process/Windows/Common/ProcessWindows.cpp
+++ source/Plugins/Process/Windows/Common/ProcessWindows.cpp
@@ -37,6 +37,7 @@
#include "ExceptionRecord.h"
#include "ForwardDecl.h"
#include "LocalDebugDelegate.h"
+#include "Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h"
#include "ProcessWindowsLog.h"
#include "TargetThreadWindows.h"
@@ -864,6 +865,13 @@
return LLDB_INVALID_ADDRESS;
}
+DynamicLoader *ProcessWindows::GetDynamicLoader() {
+ if (m_dyld_ap.get() == NULL)
+ m_dyld_ap.reset(DynamicLoader::FindPlugin(
+ this, DynamicLoaderWindowsDYLD::GetPluginNameStatic().GetCString()));
+ return m_dyld_ap.get();
+}
+
void ProcessWindows::OnExitProcess(uint32_t exit_code) {
// No need to acquire the lock since m_session_data isn't accessed.
Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
@@ -880,9 +888,9 @@
SetProcessExitStatus(GetID(), true, 0, exit_code);
SetPrivateState(eStateExited);
- // If the process exits before any initial stop then notify the debugger
+ // If the process exits before any initial stop then notify the debugger
// of the error otherwise WaitForDebuggerConnection() will be blocked.
- // An example of this issue is when a process fails to load a dependent DLL.
+ // An example of this issue is when a process fails to load a dependent DLL.
if (m_session_data && !m_session_data->m_initial_stop_received) {
Status error(exit_code, eErrorTypeWin32);
OnDebuggerError(error, 0);
@@ -916,12 +924,9 @@
GetTarget().SetExecutableModule(module, eLoadDependentsNo);
}
- bool load_addr_changed;
- module->SetLoadAddress(GetTarget(), image_base, false, load_addr_changed);
-
- ModuleList loaded_modules;
- loaded_modules.Append(module);
- GetTarget().ModulesDidLoad(loaded_modules);
+ auto dyld = static_cast<DynamicLoaderWindowsDYLD *>(GetDynamicLoader());
+ assert(dyld);
+ dyld->OnLoadModule(module, image_base);
// Add the main executable module to the list of pending module loads. We
// can't call GetTarget().ModulesDidLoad() here because we still haven't
@@ -1032,12 +1037,11 @@
// return a corresponding ModuleSP.
Status error;
ModuleSP module = GetTarget().GetSharedModule(module_spec, &error);
- bool load_addr_changed = false;
- module->SetLoadAddress(GetTarget(), module_addr, false, load_addr_changed);
-
- ModuleList loaded_modules;
- loaded_modules.Append(module);
- GetTarget().ModulesDidLoad(loaded_modules);
+ if (error.Success()) {
+ auto dyld = static_cast<DynamicLoaderWindowsDYLD *>(GetDynamicLoader());
+ assert(dyld);
+ dyld->OnLoadModule(module, module_addr);
+ }
}
void ProcessWindows::OnUnloadDll(lldb::addr_t module_addr) {
@@ -1045,9 +1049,9 @@
if (GetTarget().ResolveLoadAddress(module_addr, resolved_addr)) {
ModuleSP module = resolved_addr.GetModule();
if (module) {
- ModuleList unloaded_modules;
- unloaded_modules.Append(module);
- GetTarget().ModulesDidUnload(unloaded_modules, false);
+ auto dyld = static_cast<DynamicLoaderWindowsDYLD *>(GetDynamicLoader());
+ assert(dyld);
+ dyld->OnUnloadModule(module, module_addr);
}
}
}
Index: source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
===================================================================
--- source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
+++ 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 @@
static DynamicLoader *CreateInstance(Process *process, bool force);
+ void OnLoadModule(lldb::ModuleSP module_sp, lldb::addr_t module_addr);
+ void OnUnloadModule(lldb::ModuleSP module_sp, lldb::addr_t module_addr);
+
void DidAttach() override;
void DidLaunch() override;
Status CanLoadImage() override;
@@ -35,6 +40,12 @@
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
Index: source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
===================================================================
--- source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
+++ source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
@@ -1,5 +1,4 @@
-//===-- DynamicLoaderWindowsDYLD.cpp --------------------------------*- C++
-//-*-===//
+//===-- DynamicLoaderWindowsDYLD.cpp -----------------------------*- C++-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -12,6 +11,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,41 +61,100 @@
return nullptr;
}
+void DynamicLoaderWindowsDYLD::OnLoadModule(lldb::ModuleSP module_sp,
+ lldb::addr_t module_addr) {
+ m_loaded_modules[module_sp] = module_addr;
+ UpdateLoadedSectionsCommon(module_sp, module_addr, false);
+}
+
+void DynamicLoaderWindowsDYLD::OnUnloadModule(lldb::ModuleSP module_sp,
+ lldb::addr_t module_addr) {
+ 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;
+ }
+
+ // Third, try through the underlying platform for a host process. This
+ // could happen for the NativeProcessFactory.
+ if (m_process->GetTarget().GetPlatform()->IsHost()) {
+ load_addr = Host::GetProcessBaseAddress(m_process->GetID());
+ if (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));
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
if (log)
log->Printf("DynamicLoaderWindowsDYLD::%s()", __FUNCTION__);
ModuleSP executable = GetTargetExecutable();
-
if (!executable.get())
return;
- // Try to fetch the load address of the file from the process, since there
- // could be randomization of the load address.
-
- // 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);
- }
+ lldb::addr_t load_addr = GetLoadAddress(executable);
+ if (load_addr == LLDB_INVALID_ADDRESS)
+ return;
- ModuleList module_list;
- module_list.Append(executable);
- m_process->GetTarget().ModulesDidLoad(module_list);
- m_process->LoadModules();
+ // Request the process base.
+ lldb::addr_t image_base = m_process->GetImageInfoAddress();
+
+ // Note that the plugin might provide a default base, for example,
+ // the image base in PECOFF other than the virtual load address. Rebase the
+ // process's modules if there is a mismatch.
+ if (image_base != load_addr) {
+ UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_addr, false);
+
+ ModuleList module_list;
+ module_list.Append(executable);
+ m_process->GetTarget().ModulesDidLoad(module_list);
+ 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(); }
Index: source/Host/windows/Host.cpp
===================================================================
--- source/Host/windows/Host.cpp
+++ source/Host/windows/Host.cpp
@@ -170,6 +170,21 @@
return true;
}
+lldb::addr_t Host::GetProcessBaseAddress(lldb::pid_t pid) {
+ AutoHandle snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid));
+ if (!snapshot.IsValid())
+ return LLDB_INVALID_ADDRESS;
+
+ MODULEENTRY32W me;
+ me.dwSize = sizeof(MODULEENTRY32W);
+ if (Module32FirstW(snapshot.get(), &me)) {
+ // The first module is always the EXE or DLL itself.
+ return (addr_t)me.modBaseAddr;
+ }
+
+ return LLDB_INVALID_ADDRESS;
+}
+
HostThread Host::StartMonitoringChildProcess(
const Host::MonitorChildProcessCallback &callback, lldb::pid_t pid,
bool monitor_signals) {
Index: source/Host/common/Host.cpp
===================================================================
--- source/Host/common/Host.cpp
+++ source/Host/common/Host.cpp
@@ -427,6 +427,10 @@
return module_filespec;
}
+lldb::addr_t Host::GetProcessBaseAddress(lldb::pid_t pid) {
+ return LLDB_INVALID_ADDRESS;
+}
+
#endif
#if !defined(__linux__)
Index: include/lldb/Host/Host.h
===================================================================
--- include/lldb/Host/Host.h
+++ include/lldb/Host/Host.h
@@ -196,6 +196,8 @@
static bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info);
+ static lldb::addr_t GetProcessBaseAddress(lldb::pid_t pid);
+
static const lldb::UnixSignalsSP &GetUnixSignals();
/// Launch the process specified in launch_info. The monitoring callback in
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits