You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			119 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			119 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //===-- DynamicLoaderWindowsDYLD.cpp --------------------------------*- C++
 | |
| //-*-===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "DynamicLoaderWindowsDYLD.h"
 | |
| 
 | |
| #include "lldb/Core/PluginManager.h"
 | |
| #include "lldb/Target/ExecutionContext.h"
 | |
| #include "lldb/Target/Process.h"
 | |
| #include "lldb/Target/RegisterContext.h"
 | |
| #include "lldb/Target/Target.h"
 | |
| #include "lldb/Target/ThreadPlanStepInstruction.h"
 | |
| 
 | |
| #include "llvm/ADT/Triple.h"
 | |
| 
 | |
| using namespace lldb;
 | |
| using namespace lldb_private;
 | |
| 
 | |
| DynamicLoaderWindowsDYLD::DynamicLoaderWindowsDYLD(Process *process)
 | |
|     : DynamicLoader(process) {}
 | |
| 
 | |
| DynamicLoaderWindowsDYLD::~DynamicLoaderWindowsDYLD() {}
 | |
| 
 | |
| void DynamicLoaderWindowsDYLD::Initialize() {
 | |
|   PluginManager::RegisterPlugin(GetPluginNameStatic(),
 | |
|                                 GetPluginDescriptionStatic(), CreateInstance);
 | |
| }
 | |
| 
 | |
| void DynamicLoaderWindowsDYLD::Terminate() {}
 | |
| 
 | |
| ConstString DynamicLoaderWindowsDYLD::GetPluginNameStatic() {
 | |
|   static ConstString g_plugin_name("windows-dyld");
 | |
|   return g_plugin_name;
 | |
| }
 | |
| 
 | |
| const char *DynamicLoaderWindowsDYLD::GetPluginDescriptionStatic() {
 | |
|   return "Dynamic loader plug-in that watches for shared library "
 | |
|          "loads/unloads in Windows processes.";
 | |
| }
 | |
| 
 | |
| DynamicLoader *DynamicLoaderWindowsDYLD::CreateInstance(Process *process,
 | |
|                                                         bool force) {
 | |
|   bool should_create = force;
 | |
|   if (!should_create) {
 | |
|     const llvm::Triple &triple_ref =
 | |
|         process->GetTarget().GetArchitecture().GetTriple();
 | |
|     if (triple_ref.getOS() == llvm::Triple::Win32)
 | |
|       should_create = true;
 | |
|   }
 | |
| 
 | |
|   if (should_create)
 | |
|     return new DynamicLoaderWindowsDYLD(process);
 | |
| 
 | |
|   return nullptr;
 | |
| }
 | |
| 
 | |
| void DynamicLoaderWindowsDYLD::DidAttach() {}
 | |
| 
 | |
| void DynamicLoaderWindowsDYLD::DidLaunch() {}
 | |
| 
 | |
| Status DynamicLoaderWindowsDYLD::CanLoadImage() { return Status(); }
 | |
| 
 | |
| ConstString DynamicLoaderWindowsDYLD::GetPluginName() {
 | |
|   return GetPluginNameStatic();
 | |
| }
 | |
| 
 | |
| uint32_t DynamicLoaderWindowsDYLD::GetPluginVersion() { return 1; }
 | |
| 
 | |
| ThreadPlanSP
 | |
| DynamicLoaderWindowsDYLD::GetStepThroughTrampolinePlan(Thread &thread,
 | |
|                                                        bool stop) {
 | |
|   auto arch = m_process->GetTarget().GetArchitecture();
 | |
|   if (arch.GetMachine() != llvm::Triple::x86) {
 | |
|     return ThreadPlanSP();
 | |
|   }
 | |
| 
 | |
|   uint64_t pc = thread.GetRegisterContext()->GetPC();
 | |
|   // Max size of an instruction in x86 is 15 bytes.
 | |
|   AddressRange range(pc, 2 * 15);
 | |
| 
 | |
|   ExecutionContext exe_ctx(m_process->GetTarget());
 | |
|   DisassemblerSP disassembler_sp = Disassembler::DisassembleRange(
 | |
|       arch, nullptr, nullptr, exe_ctx, range, true);
 | |
|   if (!disassembler_sp) {
 | |
|     return ThreadPlanSP();
 | |
|   }
 | |
| 
 | |
|   InstructionList *insn_list = &disassembler_sp->GetInstructionList();
 | |
|   if (insn_list == nullptr) {
 | |
|     return ThreadPlanSP();
 | |
|   }
 | |
| 
 | |
|   // First instruction in a x86 Windows trampoline is going to be an indirect
 | |
|   // jump through the IAT and the next one will be a nop (usually there for
 | |
|   // alignment purposes). e.g.:
 | |
|   //     0x70ff4cfc <+956>: jmpl   *0x7100c2a8
 | |
|   //     0x70ff4d02 <+962>: nop
 | |
| 
 | |
|   auto first_insn = insn_list->GetInstructionAtIndex(0);
 | |
|   auto second_insn = insn_list->GetInstructionAtIndex(1);
 | |
| 
 | |
|   if (first_insn == nullptr || second_insn == nullptr ||
 | |
|       strcmp(first_insn->GetMnemonic(&exe_ctx), "jmpl") != 0 ||
 | |
|       strcmp(second_insn->GetMnemonic(&exe_ctx), "nop") != 0) {
 | |
|     return ThreadPlanSP();
 | |
|   }
 | |
| 
 | |
|   assert(first_insn->DoesBranch() && !second_insn->DoesBranch());
 | |
| 
 | |
|   return ThreadPlanSP(new ThreadPlanStepInstruction(
 | |
|       thread, false, false, eVoteNoOpinion, eVoteNoOpinion));
 | |
| }
 |