1 //===-- DynamicLoaderWindowsDYLD.cpp --------------------------------*- C++ 2 //-*-===// 3 // 4 // The LLVM Compiler Infrastructure 5 // 6 // This file is distributed under the University of Illinois Open Source 7 // License. See LICENSE.TXT for details. 8 // 9 //===----------------------------------------------------------------------===// 10 11 #include "DynamicLoaderWindowsDYLD.h" 12 13 #include "lldb/Core/Module.h" 14 #include "lldb/Core/PluginManager.h" 15 #include "lldb/Target/ExecutionContext.h" 16 #include "lldb/Target/Process.h" 17 #include "lldb/Target/RegisterContext.h" 18 #include "lldb/Target/Target.h" 19 #include "lldb/Target/ThreadPlanStepInstruction.h" 20 #include "lldb/Utility/Log.h" 21 22 #include "llvm/ADT/Triple.h" 23 24 using namespace lldb; 25 using namespace lldb_private; 26 27 DynamicLoaderWindowsDYLD::DynamicLoaderWindowsDYLD(Process *process) 28 : DynamicLoader(process) {} 29 30 DynamicLoaderWindowsDYLD::~DynamicLoaderWindowsDYLD() {} 31 32 void DynamicLoaderWindowsDYLD::Initialize() { 33 PluginManager::RegisterPlugin(GetPluginNameStatic(), 34 GetPluginDescriptionStatic(), CreateInstance); 35 } 36 37 void DynamicLoaderWindowsDYLD::Terminate() {} 38 39 ConstString DynamicLoaderWindowsDYLD::GetPluginNameStatic() { 40 static ConstString g_plugin_name("windows-dyld"); 41 return g_plugin_name; 42 } 43 44 const char *DynamicLoaderWindowsDYLD::GetPluginDescriptionStatic() { 45 return "Dynamic loader plug-in that watches for shared library " 46 "loads/unloads in Windows processes."; 47 } 48 49 DynamicLoader *DynamicLoaderWindowsDYLD::CreateInstance(Process *process, 50 bool force) { 51 bool should_create = force; 52 if (!should_create) { 53 const llvm::Triple &triple_ref = 54 process->GetTarget().GetArchitecture().GetTriple(); 55 if (triple_ref.getOS() == llvm::Triple::Win32) 56 should_create = true; 57 } 58 59 if (should_create) 60 return new DynamicLoaderWindowsDYLD(process); 61 62 return nullptr; 63 } 64 65 void DynamicLoaderWindowsDYLD::DidAttach() { 66 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); 67 if (log) 68 log->Printf("DynamicLoaderWindowsDYLD::%s()", __FUNCTION__); 69 70 DidLaunch(); 71 72 m_process->LoadModules(); 73 } 74 75 void DynamicLoaderWindowsDYLD::DidLaunch() { 76 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); 77 if (log) 78 log->Printf("DynamicLoaderWindowsDYLD::%s()", __FUNCTION__); 79 80 ModuleSP executable = GetTargetExecutable(); 81 82 if (!executable.get()) 83 return; 84 85 // Try to fetch the load address of the file from the process, since there 86 // could be randomization of the load address. 87 88 // It might happen that the remote has a different dir for the file, so we 89 // only send the basename of the executable in the query. I think this is safe 90 // because I doubt that two executables with the same basenames are loaded in 91 // memory... 92 FileSpec file_spec( 93 executable->GetPlatformFileSpec().GetFilename().GetCString()); 94 bool is_loaded; 95 addr_t base_addr = 0; 96 lldb::addr_t load_addr; 97 Status error = m_process->GetFileLoadAddress(file_spec, is_loaded, load_addr); 98 if (error.Success() && is_loaded) { 99 base_addr = load_addr; 100 } 101 102 UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, base_addr, false); 103 104 ModuleList module_list; 105 module_list.Append(executable); 106 m_process->GetTarget().ModulesDidLoad(module_list); 107 } 108 109 Status DynamicLoaderWindowsDYLD::CanLoadImage() { return Status(); } 110 111 ConstString DynamicLoaderWindowsDYLD::GetPluginName() { 112 return GetPluginNameStatic(); 113 } 114 115 uint32_t DynamicLoaderWindowsDYLD::GetPluginVersion() { return 1; } 116 117 ThreadPlanSP 118 DynamicLoaderWindowsDYLD::GetStepThroughTrampolinePlan(Thread &thread, 119 bool stop) { 120 auto arch = m_process->GetTarget().GetArchitecture(); 121 if (arch.GetMachine() != llvm::Triple::x86) { 122 return ThreadPlanSP(); 123 } 124 125 uint64_t pc = thread.GetRegisterContext()->GetPC(); 126 // Max size of an instruction in x86 is 15 bytes. 127 AddressRange range(pc, 2 * 15); 128 129 ExecutionContext exe_ctx(m_process->GetTarget()); 130 DisassemblerSP disassembler_sp = Disassembler::DisassembleRange( 131 arch, nullptr, nullptr, exe_ctx, range, true); 132 if (!disassembler_sp) { 133 return ThreadPlanSP(); 134 } 135 136 InstructionList *insn_list = &disassembler_sp->GetInstructionList(); 137 if (insn_list == nullptr) { 138 return ThreadPlanSP(); 139 } 140 141 // First instruction in a x86 Windows trampoline is going to be an indirect 142 // jump through the IAT and the next one will be a nop (usually there for 143 // alignment purposes). e.g.: 144 // 0x70ff4cfc <+956>: jmpl *0x7100c2a8 145 // 0x70ff4d02 <+962>: nop 146 147 auto first_insn = insn_list->GetInstructionAtIndex(0); 148 auto second_insn = insn_list->GetInstructionAtIndex(1); 149 150 if (first_insn == nullptr || second_insn == nullptr || 151 strcmp(first_insn->GetMnemonic(&exe_ctx), "jmpl") != 0 || 152 strcmp(second_insn->GetMnemonic(&exe_ctx), "nop") != 0) { 153 return ThreadPlanSP(); 154 } 155 156 assert(first_insn->DoesBranch() && !second_insn->DoesBranch()); 157 158 return ThreadPlanSP(new ThreadPlanStepInstruction( 159 thread, false, false, eVoteNoOpinion, eVoteNoOpinion)); 160 } 161