25#include "llvm/TargetParser/Triple.h"
47 return "Dynamic loader plug-in that watches for shared library "
48 "loads/unloads in Windows processes.";
53 bool should_create = force;
55 const llvm::Triple &triple_ref =
57 if (triple_ref.getOS() == llvm::Triple::Win32)
73 module_sp =
m_process->GetTarget().GetOrCreateModule(
74 module_spec,
true , &
error);
82 module_list.
Append(module_sp);
83 m_process->GetTarget().ModulesDidLoad(module_list);
91 ModuleSP module_sp = it->second.lock();
97 bool full_unload =
true;
99 ModuleSP other_sp = entry.second.lock();
100 if (other_sp == module_sp) {
109 module_list.
Append(module_sp);
110 m_process->GetTarget().ModulesDidUnload(module_list,
false);
126 FileSpec file_spec(executable->GetPlatformFileSpec());
127 bool is_loaded =
false;
129 m_process->GetFileLoadAddress(file_spec, is_loaded, load_addr);
141 LLDB_LOGF(log,
"DynamicLoaderWindowsDYLD::%s()", __FUNCTION__);
172 ObjectFile *object_file = executable->GetObjectFile();
180 executable->ReportWarning(
181 "failed to get load address, assuming image base at {0:x}", load_addr);
185 if (image_base == load_addr)
193 module_list.
Append(executable);
194 m_process->GetTarget().ModulesDidLoad(module_list);
201 LLDB_LOGF(log,
"DynamicLoaderWindowsDYLD::%s()", __FUNCTION__);
215 module_list.
Append(executable);
216 m_process->GetTarget().ModulesDidLoad(module_list);
227 auto arch =
m_process->GetTarget().GetArchitecture();
228 if (arch.GetMachine() != llvm::Triple::x86) {
236 uint64_t
pc = reg_ctx_sp->GetPC();
241 arch,
nullptr,
nullptr,
nullptr,
nullptr,
m_process->GetTarget(), range);
242 if (!disassembler_sp) {
258 if (first_insn ==
nullptr || second_insn ==
nullptr)
261 const char *first_mnemonic = first_insn->GetMnemonic(&exe_ctx);
262 const char *second_mnemonic = second_insn->GetMnemonic(&exe_ctx);
263 if (!first_mnemonic || !second_mnemonic ||
264 strcmp(first_mnemonic,
"jmpl") != 0 ||
265 strcmp(second_mnemonic,
"nop") != 0)
268 assert(first_insn->DoesBranch() && !second_insn->DoesBranch());
281 LLDB_LOG(log,
"no object file for module");
284 std::string object_name;
289 if (!extended_info) {
290 LLDB_LOG(log,
"missing extended info of thread");
295 LLDB_LOG(log,
"extended info of thread is not a dictionary");
301 LLDB_LOG(log,
"missing 'teb_address' in extended thread info");
305 ProcessSP process = thread->GetProcess();
310 uint32_t addr_byte_size = process->GetAddressByteSize();
311 addr_t tls_array_addr = teb_base + 11 * addr_byte_size;
312 llvm::Expected<addr_t> tls_array =
313 process->ReadPointerFromMemory(tls_array_addr);
316 "failed to read TLS array from {1:x16}: {0}",
323 LLDB_LOG(log,
"failed to resolve tls index for {0}", object_name);
327 Target &target = process->GetTarget();
330 LLDB_LOG(log,
"failed to resolve load address of '_tls_index' in {0}",
337 process->ReadUnsignedIntegerFromMemory(tls_index_load_addr, 4, 0,
error);
340 "failed to read '_tls_index' in {1} from {2:x8}: {0}",
341 object_name, tls_index_load_addr);
345 addr_t tls_index_item = *tls_array + tls_index * addr_byte_size;
346 LLDB_LOG(log,
"tls base address for {0} is at {1:x8} + {2:x8} * {3} = {4:x8}",
347 object_name, *tls_array, tls_index, addr_byte_size, tls_index_item);
349 llvm::Expected<addr_t> tls_base =
350 process->ReadPointerFromMemory(tls_index_item);
353 "failed to read tls array in {1} at index {2} ({3:x8}): {0}",
354 object_name, tls_index, tls_index_item);
358 return *tls_base + tls_file_addr;
364 llvm::dyn_cast_or_null<ObjectFilePECOFF>(module->GetObjectFile());
368 module->ResolveFileAddress(tls_index_file_addr, addr))
374 Symtab *symtab =
module->GetSymtab();
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
#define LLDB_LOG_ERROR(log, error,...)
#define LLDB_PLUGIN_DEFINE(PluginName)
lldb::addr_t GetTlsIndexAddress() const
A section + offset based address range class.
A section + offset based address class.
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
lldb::addr_t GetFileAddress() const
Get the file address.
bool IsValid() const
Check if the object state is valid.
llvm::Triple & GetTriple()
Architecture triple accessor.
A uniqued constant string class.
static lldb::DisassemblerSP DisassembleRange(const ArchSpec &arch, const char *plugin_name, const char *flavor, const char *cpu, const char *features, Target &target, llvm::ArrayRef< AddressRange > disasm_ranges, bool force_live_memory=false)
void DidAttach() override
Called after attaching a process.
void DidLaunch() override
Called after launching a process.
lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread, lldb::addr_t tls_file_addr) override
Retrieves the per-module TLS block for a given thread.
static llvm::StringRef GetPluginDescriptionStatic()
llvm::DenseMap< lldb::addr_t, lldb::ModuleWP > m_loaded_modules
Maps load addresses to their corresponding modules.
~DynamicLoaderWindowsDYLD() override
Status CanLoadImage() override
Ask if it is ok to try and load or unload an shared library (image).
static llvm::StringRef GetPluginNameStatic()
void OnLoadModule(lldb::ModuleSP module_sp, const ModuleSpec module_spec, lldb::addr_t module_addr)
lldb::addr_t GetLoadAddress(lldb::ModuleSP executable)
Returns the load address for the given executable module.
DynamicLoaderWindowsDYLD(Process *process)
void OnUnloadModule(lldb::addr_t module_addr)
static DynamicLoader * CreateInstance(Process *process, bool force)
lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread, bool stop) override
Provides a plan to step through the dynamic loader trampoline for the current state of thread.
bool GetTlsIndexAddressForModule(const lldb::ModuleSP &module, Address &addr) const
Process * m_process
The process that this dynamic loader plug-in is tracking.
void UpdateLoadedSectionsCommon(lldb::ModuleSP module, lldb::addr_t base_addr, bool base_addr_is_offset)
lldb::ModuleSP GetTargetExecutable()
Checks to see if the target module has changed, updates the target accordingly and returns the target...
virtual void UpdateLoadedSections(lldb::ModuleSP module, lldb::addr_t link_map_addr, lldb::addr_t base_addr, bool base_addr_is_offset)
Updates the load address of every allocatable section in module.
DynamicLoader(Process *process)
Construct with a process.
void UnloadSectionsCommon(const lldb::ModuleSP module)
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
lldb::InstructionSP GetInstructionAtIndex(size_t idx) const
A collection class for Module objects.
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
A plug-in interface definition class for object file parsers.
std::string GetObjectName() const
virtual lldb_private::Address GetBaseAddress()
Returns base address of this object file.
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
A plug-in interface definition class for debugging a process.
Target & GetTarget()
Get the target object pointer for this module.
bool Success() const
Test for success condition.
bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const
std::shared_ptr< Object > ObjectSP
Address GetAddress() const
Symbol * FindFirstSymbolWithNameAndType(ConstString name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility)
const ArchSpec & GetArchitecture() const
#define LLDB_INVALID_ADDRESS
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
void RegisterMSVCRTCFrameRecognizer(Target &target)
Registers the MSVC run-time check failure frame recognizer with the target.
std::shared_ptr< lldb_private::ThreadPlan > ThreadPlanSP
std::weak_ptr< lldb_private::Module > ModuleWP
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::Disassembler > DisassemblerSP
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
std::shared_ptr< lldb_private::Module > ModuleSP