LLVM: lib/ExecutionEngine/GDBRegistrationListener.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
16#include
17
18using namespace llvm;
20
21
22extern "C" {
23
29
35 };
36
39
40
44 };
45
46
47
48
50
51
53}
54
55namespace {
56
57
58
59
60
61
62
63
64
65
69}
70
71struct RegisteredObjectInfo {
72 RegisteredObjectInfo() = default;
73
74 RegisteredObjectInfo(std::size_t Size, jit_code_entry *Entry,
75 OwningBinary Obj)
77
78 std::size_t Size;
79 jit_code_entry *Entry;
80 OwningBinary Obj;
81};
82
83
84typedef llvm::DenseMap<JITEventListener::ObjectKey, RegisteredObjectInfo>
85 RegisteredObjectBufferMap;
86
87
88
89
90
91class GDBJITRegistrationListener : public JITEventListener {
92
93
94
95
96
97
99
100
101
102 RegisteredObjectBufferMap ObjectBufferMap;
103
104
105 GDBJITRegistrationListener() = default;
106
107
108
109 ~GDBJITRegistrationListener() override;
110
111public:
112 static GDBJITRegistrationListener &instance() {
113 static GDBJITRegistrationListener Instance;
114 return Instance;
115 }
116
117
118
119
120 void notifyObjectLoaded(ObjectKey K, const ObjectFile &Obj,
121 const RuntimeDyld::LoadedObjectInfo &L) override;
122
123
124
125
126 void notifyFreeingObject(ObjectKey K) override;
127
128private:
129
130
131
132 void deregisterObjectInternal(RegisteredObjectBufferMap::iterator I);
133};
134
135
136void NotifyDebugger(jit_code_entry* JITCodeEntry) {
138
139
142 JITCodeEntry->next_entry = NextEntry;
143 if (NextEntry) {
144 NextEntry->prev_entry = JITCodeEntry;
145 }
149}
150
151GDBJITRegistrationListener::~GDBJITRegistrationListener() {
152
153 std::lock_guardllvm::sys::Mutex locked(JITDebugLock);
154 for (RegisteredObjectBufferMap::iterator I = ObjectBufferMap.begin(),
155 E = ObjectBufferMap.end();
157
158
159 deregisterObjectInternal(I);
160 }
161 ObjectBufferMap.clear();
162}
163
164void GDBJITRegistrationListener::notifyObjectLoaded(
166 const RuntimeDyld::LoadedObjectInfo &L) {
167
168 OwningBinary DebugObj = L.getObjectForDebug(Obj);
169
170
172 return;
173
174 const char *Buffer = DebugObj.getBinary()->getMemoryBufferRef().getBufferStart();
175 size_t Size = DebugObj.getBinary()->getMemoryBufferRef().getBufferSize();
176
177 std::lock_guardllvm::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();
181
182 if (!JITCodeEntry) {
184 "Allocation failed when registering a JIT entry!\n");
185 } else {
188
189 ObjectBufferMap[K] =
190 RegisteredObjectInfo(Size, JITCodeEntry, std::move(DebugObj));
191 NotifyDebugger(JITCodeEntry);
192 }
193}
194
195void GDBJITRegistrationListener::notifyFreeingObject(ObjectKey K) {
196 std::lock_guardllvm::sys::Mutex locked(JITDebugLock);
197 RegisteredObjectBufferMap::iterator I = ObjectBufferMap.find(K);
198
199 if (I != ObjectBufferMap.end()) {
200 deregisterObjectInternal(I);
201 ObjectBufferMap.erase(I);
202 }
203}
204
205void GDBJITRegistrationListener::deregisterObjectInternal(
206 RegisteredObjectBufferMap::iterator I) {
207
208 jit_code_entry*& JITCodeEntry = I->second.Entry;
209
210
211 {
213
214
215 jit_code_entry* PrevEntry = JITCodeEntry->prev_entry;
216 jit_code_entry* NextEntry = JITCodeEntry->next_entry;
217
218 if (NextEntry) {
220 }
221 if (PrevEntry) {
223 }
224 else {
227 }
228
229
232 }
233
234 delete JITCodeEntry;
235 JITCodeEntry = nullptr;
236}
237
238}
239
240namespace llvm {
241
243 return &GDBJITRegistrationListener::instance();
244}
245
246}
247
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
@ JIT_UNREGISTER_FN
Definition GDBRegistrationListener.cpp:27
@ JIT_REGISTER_FN
Definition GDBRegistrationListener.cpp:26
void __jit_debug_register_code()
static JITEventListener * createGDBRegistrationListener()
Definition GDBRegistrationListener.cpp:242
JITEventListener()=default
LLVMJITEventListenerRef LLVMCreateGDBRegistrationListener(void)
Definition GDBRegistrationListener.cpp:248
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