71struct RegisteredObjectInfo {
72 RegisteredObjectInfo() =
default;
74 RegisteredObjectInfo(std::size_t
Size, jit_code_entry *Entry,
75 OwningBinary<ObjectFile> Obj)
79 jit_code_entry *
Entry;
80 OwningBinary<ObjectFile> Obj;
84typedef llvm::DenseMap<JITEventListener::ObjectKey, RegisteredObjectInfo>
85 RegisteredObjectBufferMap;
91class GDBJITRegistrationListener :
public JITEventListener {
102 RegisteredObjectBufferMap ObjectBufferMap;
105 GDBJITRegistrationListener() =
default;
109 ~GDBJITRegistrationListener()
override;
112 static GDBJITRegistrationListener &instance() {
113 static GDBJITRegistrationListener Instance;
120 void notifyObjectLoaded(ObjectKey K,
const ObjectFile &Obj,
121 const RuntimeDyld::LoadedObjectInfo &L)
override;
126 void notifyFreeingObject(ObjectKey K)
override;
132 void deregisterObjectInternal(RegisteredObjectBufferMap::iterator
I);
136void NotifyDebugger(jit_code_entry* JITCodeEntry) {
151GDBJITRegistrationListener::~GDBJITRegistrationListener() {
153 std::lock_guard<llvm::sys::Mutex> locked(JITDebugLock);
154 for (RegisteredObjectBufferMap::iterator
I = ObjectBufferMap.begin(),
155 E = ObjectBufferMap.end();
159 deregisterObjectInternal(
I);
161 ObjectBufferMap.clear();
164void GDBJITRegistrationListener::notifyObjectLoaded(
166 const RuntimeDyld::LoadedObjectInfo &L) {
168 OwningBinary<ObjectFile> DebugObj =
L.getObjectForDebug(Obj);
174 const char *Buffer = DebugObj.
getBinary()->getMemoryBufferRef().getBufferStart();
175 size_t Size = DebugObj.
getBinary()->getMemoryBufferRef().getBufferSize();
177 std::lock_guard<llvm::sys::Mutex> locked(JITDebugLock);
178 assert(!ObjectBufferMap.contains(K) &&
179 "Second attempt to perform debug registration.");
180 jit_code_entry* JITCodeEntry =
new jit_code_entry();
184 "Allocation failed when registering a JIT entry!\n");
190 RegisteredObjectInfo(
Size, JITCodeEntry, std::move(DebugObj));
191 NotifyDebugger(JITCodeEntry);
195void GDBJITRegistrationListener::notifyFreeingObject(ObjectKey K) {
196 std::lock_guard<llvm::sys::Mutex> locked(JITDebugLock);
197 RegisteredObjectBufferMap::iterator
I = ObjectBufferMap.find(K);
199 if (
I != ObjectBufferMap.end()) {
200 deregisterObjectInternal(
I);
201 ObjectBufferMap.erase(
I);
205void GDBJITRegistrationListener::deregisterObjectInternal(
206 RegisteredObjectBufferMap::iterator
I) {
208 jit_code_entry*& JITCodeEntry =
I->second.Entry;
215 jit_code_entry* PrevEntry = JITCodeEntry->
prev_entry;
216 jit_code_entry* NextEntry = JITCodeEntry->
next_entry;
235 JITCodeEntry =
nullptr;
243 return &GDBJITRegistrationListener::instance();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_ATTRIBUTE_USED
This file defines the DenseMap class.
struct jit_descriptor __jit_debug_descriptor
void __jit_debug_register_code()
static JITEventListener * createGDBRegistrationListener()
JITEventListener()=default
LLVMJITEventListenerRef LLVMCreateGDBRegistrationListener(void)
struct LLVMOpaqueJITEventListener * LLVMJITEventListenerRef
SmartMutex< false > Mutex
Mutex - A standard, always enforced mutex.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
LLVMAttributeRef wrap(Attribute Attr)
struct jit_code_entry * prev_entry
const char * symfile_addr
struct jit_code_entry * next_entry
struct jit_code_entry * relevant_entry
struct jit_code_entry * first_entry