Skip to content

Commit ff2b0ce

Browse files
committed
Hooked GDB to JITEventlistener, cleaned up jitlayers interface
1 parent f8d82cc commit ff2b0ce

File tree

3 files changed

+9
-93
lines changed

3 files changed

+9
-93
lines changed

src/codegen.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7471,6 +7471,11 @@ extern "C" void *jl_init_llvm(void)
74717471
jl_data_layout.reset(DL);
74727472
#endif
74737473

7474+
// Register GDB event listener
7475+
#ifdef JL_DEBUG_BUILD
7476+
jl_ExecutionEngine->RegisterJITEventListener(JITEventListener::createGDBRegistrationListener());
7477+
#endif
7478+
74747479
#ifdef JL_USE_INTEL_JITEVENTS
74757480
if (jl_using_intel_jitevents)
74767481
jl_ExecutionEngine->RegisterJITEventListener(JITEventListener::createIntelJITEventListener());

src/jitlayers.cpp

Lines changed: 4 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ namespace llvm {
5454
#include <llvm/IR/DataLayout.h>
5555
#include <llvm/Support/DynamicLibrary.h>
5656

57-
5857
#include <llvm/Support/raw_ostream.h>
5958
#include <llvm/Support/FormattedStream.h>
6059
#include <llvm/ADT/StringMap.h>
@@ -284,72 +283,6 @@ void jl_add_optimization_passes(LLVMPassManagerRef PM, int opt_level) {
284283
addOptimizationPasses(unwrap(PM), opt_level);
285284
}
286285

287-
// ------------------------ TEMPORARILY COPIED FROM LLVM -----------------
288-
// This must be kept in sync with gdb/gdb/jit.h .
289-
extern "C" {
290-
291-
typedef enum {
292-
JIT_NOACTION = 0,
293-
JIT_REGISTER_FN,
294-
JIT_UNREGISTER_FN
295-
} jit_actions_t;
296-
297-
struct jit_code_entry {
298-
struct jit_code_entry *next_entry;
299-
struct jit_code_entry *prev_entry;
300-
const char *symfile_addr;
301-
uint64_t symfile_size;
302-
};
303-
304-
struct jit_descriptor {
305-
uint32_t version;
306-
// This should be jit_actions_t, but we want to be specific about the
307-
// bit-width.
308-
uint32_t action_flag;
309-
struct jit_code_entry *relevant_entry;
310-
struct jit_code_entry *first_entry;
311-
};
312-
313-
// We put information about the JITed function in this global, which the
314-
// debugger reads. Make sure to specify the version statically, because the
315-
// debugger checks the version before we can set it during runtime.
316-
extern struct jit_descriptor __jit_debug_descriptor;
317-
318-
LLVM_ATTRIBUTE_NOINLINE extern void __jit_debug_register_code();
319-
}
320-
321-
namespace {
322-
323-
// Use a local variable to hold the addresses to avoid generating a PLT
324-
// on the function call.
325-
// It messes up the GDB lookup logic with dynamically linked LLVM.
326-
// (Ref https://sourceware.org/bugzilla/show_bug.cgi?id=20633)
327-
// Use `volatile` to make sure the call always loads this slot.
328-
void (*volatile jit_debug_register_code)() = __jit_debug_register_code;
329-
330-
using namespace llvm;
331-
using namespace llvm::object;
332-
using namespace llvm::orc;
333-
334-
/// Do the registration.
335-
void NotifyDebugger(jit_code_entry *JITCodeEntry)
336-
{
337-
__jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
338-
339-
// Insert this entry at the head of the list.
340-
JITCodeEntry->prev_entry = nullptr;
341-
jit_code_entry *NextEntry = __jit_debug_descriptor.first_entry;
342-
JITCodeEntry->next_entry = NextEntry;
343-
if (NextEntry) {
344-
NextEntry->prev_entry = JITCodeEntry;
345-
}
346-
__jit_debug_descriptor.first_entry = JITCodeEntry;
347-
__jit_debug_descriptor.relevant_entry = JITCodeEntry;
348-
jit_debug_register_code();
349-
}
350-
}
351-
// ------------------------ END OF TEMPORARY COPY FROM LLVM -----------------
352-
353286
#if defined(_OS_LINUX_) || defined(_OS_WINDOWS_) || defined(_OS_FREEBSD_)
354287
// Resolve non-lock free atomic functions in the libatomic1 library.
355288
// This is the library that provides support for c11/c++11 atomic operations.
@@ -387,7 +320,7 @@ template <typename ObjT, typename LoadResult>
387320
void JuliaOJIT::DebugObjectRegistrar::registerObject(RTDyldObjHandleT H, const ObjT &Object,
388321
const LoadResult &LO)
389322
{
390-
OwningBinary<object::ObjectFile> SavedObject = LO->getObjectForDebug(*Object);
323+
object::OwningBinary<object::ObjectFile> SavedObject = LO->getObjectForDebug(*Object);
391324

392325
// If the debug object is unavailable, save (a copy of) the original object
393326
// for our backtraces
@@ -396,16 +329,15 @@ void JuliaOJIT::DebugObjectRegistrar::registerObject(RTDyldObjHandleT H, const O
396329
// ownership of the original buffer
397330
auto NewBuffer = MemoryBuffer::getMemBufferCopy(Object->getData(),
398331
Object->getFileName());
399-
auto NewObj = ObjectFile::createObjectFile(NewBuffer->getMemBufferRef());
332+
auto NewObj = object::ObjectFile::createObjectFile(NewBuffer->getMemBufferRef());
400333
assert(NewObj);
401-
SavedObject = OwningBinary<object::ObjectFile>(std::move(*NewObj),
334+
SavedObject = object::OwningBinary<object::ObjectFile>(std::move(*NewObj),
402335
std::move(NewBuffer));
403336
}
404337
else {
405-
NotifyGDB(SavedObject);
338+
JIT.NotifyFinalizer(*(SavedObject.getBinary()), *LO);
406339
}
407340

408-
JIT.NotifyFinalizer(*Object, *LO);
409341
SavedObjects.push_back(std::move(SavedObject));
410342

411343
ORCNotifyObjectEmitted(JuliaListener.get(), *Object,
@@ -436,7 +368,6 @@ void JuliaOJIT::DebugObjectRegistrar::registerObject(RTDyldObjHandleT H, const O
436368
}
437369
}
438370

439-
// TODO: hook up RegisterJITEventListener, instead of hard-coding the GDB and JuliaListener targets
440371
template <typename ObjSetT, typename LoadResult>
441372
void JuliaOJIT::DebugObjectRegistrar::operator()(RTDyldObjHandleT H,
442373
const ObjSetT &Objects, const LoadResult &LOS)
@@ -456,24 +387,6 @@ void JuliaOJIT::DebugObjectRegistrar::operator()(RTDyldObjHandleT H,
456387
#endif
457388
}
458389

459-
void JuliaOJIT::DebugObjectRegistrar::NotifyGDB(OwningBinary<object::ObjectFile> &DebugObj)
460-
{
461-
const char *Buffer = DebugObj.getBinary()->getMemoryBufferRef().getBufferStart();
462-
size_t Size = DebugObj.getBinary()->getMemoryBufferRef().getBufferSize();
463-
464-
assert(Buffer && "Attempt to register a null object with a debugger.");
465-
jit_code_entry *JITCodeEntry = new jit_code_entry();
466-
467-
if (!JITCodeEntry) {
468-
jl_printf(JL_STDERR, "WARNING: Allocation failed when registering a JIT entry!\n");
469-
}
470-
else {
471-
JITCodeEntry->symfile_addr = Buffer;
472-
JITCodeEntry->symfile_size = Size;
473-
474-
NotifyDebugger(JITCodeEntry);
475-
}
476-
}
477390

478391
object::OwningBinary<object::ObjectFile> JuliaOJIT::CompilerT::operator()(Module &M)
479392
{

src/jitlayers.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ using RTDyldObjHandleT = orc::ObjectLinkingLayerBase::ObjSetHandleT;
103103

104104
class JuliaOJIT {
105105
// Custom object emission notification handler for the JuliaOJIT
106-
// TODO: hook up RegisterJITEventListener, instead of hard-coding the GDB and JuliaListener targets
107106
class DebugObjectRegistrar {
108107
public:
109108
DebugObjectRegistrar(JuliaOJIT &JIT);
@@ -112,7 +111,6 @@ class JuliaOJIT {
112111
private:
113112
template <typename ObjT, typename LoadResult>
114113
void registerObject(RTDyldObjHandleT H, const ObjT &Object, const LoadResult &LO);
115-
void NotifyGDB(object::OwningBinary<object::ObjectFile> &DebugObj);
116114
std::vector<object::OwningBinary<object::ObjectFile>> SavedObjects;
117115
std::unique_ptr<JITEventListener> JuliaListener;
118116
JuliaOJIT &JIT;

0 commit comments

Comments
 (0)