//===----- GDBRegistrationListener.cpp - Registers objects with GDB -------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "llvm-c/ExecutionEngine.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ExecutionEngine/JITEventListener.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Mutex.h" #include <mutex> usingnamespacellvm; usingnamespacellvm::object; // This must be kept in sync with gdb/gdb/jit.h . extern "C" { jit_actions_t; struct jit_code_entry { … }; struct jit_descriptor { … }; // We put information about the JITed function in this global, which the // debugger reads. Make sure to specify the version statically, because the // debugger checks the version before we can set it during runtime. extern struct jit_descriptor __jit_debug_descriptor; // Debuggers puts a breakpoint in this function. extern "C" void __jit_debug_register_code(); } namespace { // FIXME: lli aims to provide both, RuntimeDyld and JITLink, as the dynamic // loaders for its JIT implementations. And they both offer debugging via the // GDB JIT interface, which builds on the two well-known symbol names below. // As these symbols must be unique across the linked executable, we can only // define them in one of the libraries and make the other depend on it. // OrcTargetProcess is a minimal stub for embedding a JIT client in remote // executors. For the moment it seems reasonable to have the definition there // and let ExecutionEngine depend on it, until we find a better solution. // LLVM_ATTRIBUTE_USED void requiredSymbolDefinitionsFromOrcTargetProcess() { … } struct RegisteredObjectInfo { … }; // Buffer for an in-memory object file in executable memory RegisteredObjectBufferMap; /// Global access point for the JIT debugging interface designed for use with a /// singleton toolbox. Handles thread-safe registration and deregistration of /// object files that are in executable memory managed by the client of this /// class. class GDBJITRegistrationListener : public JITEventListener { … }; /// Do the registration. void NotifyDebugger(jit_code_entry* JITCodeEntry) { … } GDBJITRegistrationListener::~GDBJITRegistrationListener() { … } void GDBJITRegistrationListener::notifyObjectLoaded( ObjectKey K, const ObjectFile &Obj, const RuntimeDyld::LoadedObjectInfo &L) { … } void GDBJITRegistrationListener::notifyFreeingObject(ObjectKey K) { … } void GDBJITRegistrationListener::deregisterObjectInternal( RegisteredObjectBufferMap::iterator I) { … } } // end namespace namespace llvm { JITEventListener* JITEventListener::createGDBRegistrationListener() { … } } // namespace llvm LLVMJITEventListenerRef LLVMCreateGDBRegistrationListener(void) { … }