1 //===- JITLoaderGDB.h - Register objects via GDB JIT interface -*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h" 10 11 #include "llvm/ExecutionEngine/JITSymbol.h" 12 #include "llvm/Support/BinaryStreamReader.h" 13 #include "llvm/Support/FormatVariadic.h" 14 15 #include <cstdint> 16 #include <mutex> 17 #include <utility> 18 19 #define DEBUG_TYPE "orc" 20 21 // First version as landed in August 2009 22 static constexpr uint32_t JitDescriptorVersion = 1; 23 24 // Keep in sync with gdb/gdb/jit.h 25 extern "C" { 26 27 typedef enum { 28 JIT_NOACTION = 0, 29 JIT_REGISTER_FN, 30 JIT_UNREGISTER_FN 31 } jit_actions_t; 32 33 struct jit_code_entry { 34 struct jit_code_entry *next_entry; 35 struct jit_code_entry *prev_entry; 36 const char *symfile_addr; 37 uint64_t symfile_size; 38 }; 39 40 struct jit_descriptor { 41 uint32_t version; 42 // This should be jit_actions_t, but we want to be specific about the 43 // bit-width. 44 uint32_t action_flag; 45 struct jit_code_entry *relevant_entry; 46 struct jit_code_entry *first_entry; 47 }; 48 49 // We put information about the JITed function in this global, which the 50 // debugger reads. Make sure to specify the version statically, because the 51 // debugger checks the version before we can set it during runtime. 52 struct jit_descriptor __jit_debug_descriptor = {JitDescriptorVersion, 0, 53 nullptr, nullptr}; 54 55 // Debuggers that implement the GDB JIT interface put a special breakpoint in 56 // this function. 57 LLVM_ATTRIBUTE_NOINLINE void __jit_debug_register_code() { 58 // The noinline and the asm prevent calls to this function from being 59 // optimized out. 60 #if !defined(_MSC_VER) 61 asm volatile("" ::: "memory"); 62 #endif 63 } 64 } 65 66 using namespace llvm; 67 using namespace llvm::orc; 68 69 // Register debug object, return error message or null for success. 70 static void appendJITDebugDescriptor(const char *ObjAddr, size_t Size) { 71 LLVM_DEBUG({ 72 dbgs() << "Adding debug object to GDB JIT interface " 73 << formatv("([{0:x16} -- {1:x16}])", 74 reinterpret_cast<uintptr_t>(ObjAddr), 75 reinterpret_cast<uintptr_t>(ObjAddr + Size)) 76 << "\n"; 77 }); 78 79 jit_code_entry *E = new jit_code_entry; 80 E->symfile_addr = ObjAddr; 81 E->symfile_size = Size; 82 E->prev_entry = nullptr; 83 84 // Serialize rendezvous with the debugger as well as access to shared data. 85 static std::mutex JITDebugLock; 86 std::lock_guard<std::mutex> Lock(JITDebugLock); 87 88 // Insert this entry at the head of the list. 89 jit_code_entry *NextEntry = __jit_debug_descriptor.first_entry; 90 E->next_entry = NextEntry; 91 if (NextEntry) { 92 NextEntry->prev_entry = E; 93 } 94 95 __jit_debug_descriptor.first_entry = E; 96 __jit_debug_descriptor.relevant_entry = E; 97 __jit_debug_descriptor.action_flag = JIT_REGISTER_FN; 98 } 99 100 extern "C" orc::shared::CWrapperFunctionResult 101 llvm_orc_registerJITLoaderGDBAllocAction(const char *Data, size_t Size) { 102 using namespace orc::shared; 103 return WrapperFunction<SPSError(SPSExecutorAddrRange, bool)>::handle( 104 Data, Size, 105 [](ExecutorAddrRange R, bool AutoRegisterCode) { 106 appendJITDebugDescriptor(R.Start.toPtr<const char *>(), 107 R.size()); 108 // Run into the rendezvous breakpoint. 109 if (AutoRegisterCode) 110 __jit_debug_register_code(); 111 return Error::success(); 112 }) 113 .release(); 114 } 115 116 extern "C" orc::shared::CWrapperFunctionResult 117 llvm_orc_registerJITLoaderGDBWrapper(const char *Data, uint64_t Size) { 118 using namespace orc::shared; 119 return WrapperFunction<SPSError(SPSExecutorAddrRange, bool)>::handle( 120 Data, Size, 121 [](ExecutorAddrRange R, bool AutoRegisterCode) { 122 appendJITDebugDescriptor(R.Start.toPtr<const char *>(), 123 R.size()); 124 // Run into the rendezvous breakpoint. 125 if (AutoRegisterCode) 126 __jit_debug_register_code(); 127 return Error::success(); 128 }) 129 .release(); 130 } 131