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
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to