Index: include/lldb/Host/Host.h =================================================================== --- include/lldb/Host/Host.h +++ include/lldb/Host/Host.h @@ -197,6 +197,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 Index: source/Host/common/Host.cpp =================================================================== --- source/Host/common/Host.cpp +++ source/Host/common/Host.cpp @@ -428,6 +428,10 @@ return module_filespec; } +lldb::addr_t Host::GetProcessBaseAddress(lldb::pid_t pid) { + return LLDB_INVALID_ADDRESS; +} + #endif #if !defined(__linux__) Index: source/Host/windows/Host.cpp =================================================================== --- source/Host/windows/Host.cpp +++ source/Host/windows/Host.cpp @@ -171,6 +171,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/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h =================================================================== --- source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h +++ source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h @@ -36,6 +36,9 @@ ConstString GetPluginName() override; uint32_t GetPluginVersion() override; + +protected: + lldb::addr_t GetLoadAddress(lldb::ModuleSP executable); }; } // 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++-*-===// // // The LLVM Compiler Infrastructure // @@ -62,41 +61,56 @@ return nullptr; } +lldb::addr_t DynamicLoaderWindowsDYLD::GetLoadAddress(ModuleSP executable) { + lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; + + if (m_process->GetID() == LLDB_INVALID_PROCESS_ID) + return LLDB_INVALID_ADDRESS; + + // First, try to get the load address 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) + return load_addr; + + // Second, try through the underlying platform. + load_addr = Host::GetProcessBaseAddress(m_process->GetID()); + if (load_addr != LLDB_INVALID_ADDRESS) + return load_addr; + + return LLDB_INVALID_ADDRESS; +} + void DynamicLoaderWindowsDYLD::DidAttach() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + // To be implemented. +} + +void DynamicLoaderWindowsDYLD::DidLaunch() { + 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); - ModuleList module_list; - module_list.Append(executable); - m_process->GetTarget().ModulesDidLoad(module_list); - m_process->LoadModules(); -} + 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); -void DynamicLoaderWindowsDYLD::DidLaunch() {} + ModuleList module_list; + module_list.Append(executable); + m_process->GetTarget().ModulesDidLoad(module_list); + m_process->LoadModules(); + } +} Status DynamicLoaderWindowsDYLD::CanLoadImage() { return Status(); }