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/PluginManager.h" 14 #include "lldb/Target/ExecutionContext.h" 15 #include "lldb/Target/Process.h" 16 #include "lldb/Target/RegisterContext.h" 17 #include "lldb/Target/Target.h" 18 #include "lldb/Target/ThreadPlanStepInstruction.h" 19 20 #include "llvm/ADT/Triple.h" 21 22 using namespace lldb; 23 using namespace lldb_private; 24 25 DynamicLoaderWindowsDYLD::DynamicLoaderWindowsDYLD(Process *process) 26 : DynamicLoader(process) {} 27 28 DynamicLoaderWindowsDYLD::~DynamicLoaderWindowsDYLD() {} 29 30 void DynamicLoaderWindowsDYLD::Initialize() { 31 PluginManager::RegisterPlugin(GetPluginNameStatic(), 32 GetPluginDescriptionStatic(), CreateInstance); 33 } 34 35 void DynamicLoaderWindowsDYLD::Terminate() {} 36 37 ConstString DynamicLoaderWindowsDYLD::GetPluginNameStatic() { 38 static ConstString g_plugin_name("windows-dyld"); 39 return g_plugin_name; 40 } 41 42 const char *DynamicLoaderWindowsDYLD::GetPluginDescriptionStatic() { 43 return "Dynamic loader plug-in that watches for shared library " 44 "loads/unloads in Windows processes."; 45 } 46 47 DynamicLoader *DynamicLoaderWindowsDYLD::CreateInstance(Process *process, 48 bool force) { 49 bool should_create = force; 50 if (!should_create) { 51 const llvm::Triple &triple_ref = 52 process->GetTarget().GetArchitecture().GetTriple(); 53 if (triple_ref.getOS() == llvm::Triple::Win32) 54 should_create = true; 55 } 56 57 if (should_create) 58 return new DynamicLoaderWindowsDYLD(process); 59 60 return nullptr; 61 } 62 63 void DynamicLoaderWindowsDYLD::DidAttach() {} 64 65 void DynamicLoaderWindowsDYLD::DidLaunch() {} 66 67 Status DynamicLoaderWindowsDYLD::CanLoadImage() { return Status(); } 68 69 ConstString DynamicLoaderWindowsDYLD::GetPluginName() { 70 return GetPluginNameStatic(); 71 } 72 73 uint32_t DynamicLoaderWindowsDYLD::GetPluginVersion() { return 1; } 74 75 ThreadPlanSP 76 DynamicLoaderWindowsDYLD::GetStepThroughTrampolinePlan(Thread &thread, 77 bool stop) { 78 auto arch = m_process->GetTarget().GetArchitecture(); 79 if (arch.GetMachine() != llvm::Triple::x86) { 80 return ThreadPlanSP(); 81 } 82 83 uint64_t pc = thread.GetRegisterContext()->GetPC(); 84 // Max size of an instruction in x86 is 15 bytes. 85 AddressRange range(pc, 2 * 15); 86 87 ExecutionContext exe_ctx(m_process->GetTarget()); 88 DisassemblerSP disassembler_sp = Disassembler::DisassembleRange( 89 arch, nullptr, nullptr, exe_ctx, range, true); 90 if (!disassembler_sp) { 91 return ThreadPlanSP(); 92 } 93 94 InstructionList *insn_list = &disassembler_sp->GetInstructionList(); 95 if (insn_list == nullptr) { 96 return ThreadPlanSP(); 97 } 98 99 // First instruction in a x86 Windows trampoline is going to be an indirect 100 // jump through the IAT and the next one will be a nop (usually there for 101 // alignment purposes). e.g.: 102 // 0x70ff4cfc <+956>: jmpl *0x7100c2a8 103 // 0x70ff4d02 <+962>: nop 104 105 auto first_insn = insn_list->GetInstructionAtIndex(0); 106 auto second_insn = insn_list->GetInstructionAtIndex(1); 107 108 if (first_insn == nullptr || second_insn == nullptr || 109 strcmp(first_insn->GetMnemonic(&exe_ctx), "jmpl") != 0 || 110 strcmp(second_insn->GetMnemonic(&exe_ctx), "nop") != 0) { 111 return ThreadPlanSP(); 112 } 113 114 assert(first_insn->DoesBranch() && !second_insn->DoesBranch()); 115 116 return ThreadPlanSP(new ThreadPlanStepInstruction( 117 thread, false, false, eVoteNoOpinion, eVoteNoOpinion)); 118 } 119