Differential D56237 Diff 186958 lldb/trunk/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
Changeset View
Changeset View
Standalone View
Standalone View
lldb/trunk/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
//===-- DynamicLoaderWindowsDYLD.cpp --------------------------------*- C++ | //===-- DynamicLoaderWindowsDYLD.cpp --------------------------------*- C++ | ||||
//-*-===// | //-*-===// | ||||
// | // | ||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||||
// See https://llvm.org/LICENSE.txt for license information. | // See https://llvm.org/LICENSE.txt for license information. | ||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||
// | // | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
#include "DynamicLoaderWindowsDYLD.h" | #include "DynamicLoaderWindowsDYLD.h" | ||||
#include "lldb/Core/Module.h" | #include "lldb/Core/Module.h" | ||||
#include "lldb/Core/PluginManager.h" | #include "lldb/Core/PluginManager.h" | ||||
#include "lldb/Target/ExecutionContext.h" | #include "lldb/Target/ExecutionContext.h" | ||||
#include "lldb/Target/Platform.h" | |||||
#include "lldb/Target/Process.h" | #include "lldb/Target/Process.h" | ||||
#include "lldb/Target/RegisterContext.h" | #include "lldb/Target/RegisterContext.h" | ||||
#include "lldb/Target/Target.h" | #include "lldb/Target/Target.h" | ||||
#include "lldb/Target/ThreadPlanStepInstruction.h" | #include "lldb/Target/ThreadPlanStepInstruction.h" | ||||
#include "lldb/Utility/Log.h" | #include "lldb/Utility/Log.h" | ||||
#include "llvm/ADT/Triple.h" | #include "llvm/ADT/Triple.h" | ||||
Show All 33 Lines | DynamicLoader *DynamicLoaderWindowsDYLD::CreateInstance(Process *process, | ||||
} | } | ||||
if (should_create) | if (should_create) | ||||
return new DynamicLoaderWindowsDYLD(process); | return new DynamicLoaderWindowsDYLD(process); | ||||
return nullptr; | 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() { | void DynamicLoaderWindowsDYLD::DidAttach() { | ||||
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); | Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); | ||||
if (log) | if (log) | ||||
log->Printf("DynamicLoaderWindowsDYLD::%s()", __FUNCTION__); | log->Printf("DynamicLoaderWindowsDYLD::%s()", __FUNCTION__); | ||||
ModuleSP executable = GetTargetExecutable(); | ModuleSP executable = GetTargetExecutable(); | ||||
if (!executable.get()) | if (!executable.get()) | ||||
return; | return; | ||||
// Try to fetch the load address of the file from the process, since there | // Try to fetch the load address of the file from the process, since there | ||||
// could be randomization of the load address. | // 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 | // Request the process base address. | ||||
// only send the basename of the executable in the query. I think this is safe | lldb::addr_t image_base = m_process->GetImageInfoAddress(); | ||||
// because I doubt that two executables with the same basenames are loaded in | if (image_base == load_addr) | ||||
// memory... | return; | ||||
FileSpec file_spec( | |||||
executable->GetPlatformFileSpec().GetFilename().GetCString()); | // Rebase the process's modules if there is a mismatch. | ||||
bool is_loaded; | UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_addr, false); | ||||
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); | |||||
} | |||||
ModuleList module_list; | ModuleList module_list; | ||||
module_list.Append(executable); | module_list.Append(executable); | ||||
m_process->GetTarget().ModulesDidLoad(module_list); | m_process->GetTarget().ModulesDidLoad(module_list); | ||||
m_process->LoadModules(); | 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(); } | Status DynamicLoaderWindowsDYLD::CanLoadImage() { return Status(); } | ||||
ConstString DynamicLoaderWindowsDYLD::GetPluginName() { | ConstString DynamicLoaderWindowsDYLD::GetPluginName() { | ||||
return GetPluginNameStatic(); | return GetPluginNameStatic(); | ||||
} | } | ||||
uint32_t DynamicLoaderWindowsDYLD::GetPluginVersion() { return 1; } | uint32_t DynamicLoaderWindowsDYLD::GetPluginVersion() { return 1; } | ||||
▲ Show 20 Lines • Show All 45 Lines • Show Last 20 Lines |