Skip to content

Commit

Permalink
Merge pull request #28407 from DokFaust/df/GDBlistener
Browse files Browse the repository at this point in the history
Hooked GDB to JITEventListener, cleaned jitlayers GDB interface
  • Loading branch information
vchuravy authored Aug 16, 2018
2 parents e23515d + ff2b0ce commit d936625
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 93 deletions.
5 changes: 5 additions & 0 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7471,6 +7471,11 @@ extern "C" void *jl_init_llvm(void)
jl_data_layout.reset(DL);
#endif

// Register GDB event listener
#ifdef JL_DEBUG_BUILD
jl_ExecutionEngine->RegisterJITEventListener(JITEventListener::createGDBRegistrationListener());
#endif

#ifdef JL_USE_INTEL_JITEVENTS
if (jl_using_intel_jitevents)
jl_ExecutionEngine->RegisterJITEventListener(JITEventListener::createIntelJITEventListener());
Expand Down
95 changes: 4 additions & 91 deletions src/jitlayers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ namespace llvm {
#include <llvm/IR/DataLayout.h>
#include <llvm/Support/DynamicLibrary.h>


#include <llvm/Support/raw_ostream.h>
#include <llvm/Support/FormattedStream.h>
#include <llvm/ADT/StringMap.h>
Expand Down Expand Up @@ -284,72 +283,6 @@ void jl_add_optimization_passes(LLVMPassManagerRef PM, int opt_level) {
addOptimizationPasses(unwrap(PM), opt_level);
}

// ------------------------ TEMPORARILY COPIED FROM LLVM -----------------
// This must be kept in sync with gdb/gdb/jit.h .
extern "C" {

typedef enum {
JIT_NOACTION = 0,
JIT_REGISTER_FN,
JIT_UNREGISTER_FN
} jit_actions_t;

struct jit_code_entry {
struct jit_code_entry *next_entry;
struct jit_code_entry *prev_entry;
const char *symfile_addr;
uint64_t symfile_size;
};

struct jit_descriptor {
uint32_t version;
// This should be jit_actions_t, but we want to be specific about the
// bit-width.
uint32_t action_flag;
struct jit_code_entry *relevant_entry;
struct jit_code_entry *first_entry;
};

// 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;

LLVM_ATTRIBUTE_NOINLINE extern void __jit_debug_register_code();
}

namespace {

// Use a local variable to hold the addresses to avoid generating a PLT
// on the function call.
// It messes up the GDB lookup logic with dynamically linked LLVM.
// (Ref https://sourceware.org/bugzilla/show_bug.cgi?id=20633)
// Use `volatile` to make sure the call always loads this slot.
void (*volatile jit_debug_register_code)() = __jit_debug_register_code;

using namespace llvm;
using namespace llvm::object;
using namespace llvm::orc;

/// Do the registration.
void NotifyDebugger(jit_code_entry *JITCodeEntry)
{
__jit_debug_descriptor.action_flag = JIT_REGISTER_FN;

// Insert this entry at the head of the list.
JITCodeEntry->prev_entry = nullptr;
jit_code_entry *NextEntry = __jit_debug_descriptor.first_entry;
JITCodeEntry->next_entry = NextEntry;
if (NextEntry) {
NextEntry->prev_entry = JITCodeEntry;
}
__jit_debug_descriptor.first_entry = JITCodeEntry;
__jit_debug_descriptor.relevant_entry = JITCodeEntry;
jit_debug_register_code();
}
}
// ------------------------ END OF TEMPORARY COPY FROM LLVM -----------------

#if defined(_OS_LINUX_) || defined(_OS_WINDOWS_) || defined(_OS_FREEBSD_)
// Resolve non-lock free atomic functions in the libatomic1 library.
// This is the library that provides support for c11/c++11 atomic operations.
Expand Down Expand Up @@ -387,7 +320,7 @@ template <typename ObjT, typename LoadResult>
void JuliaOJIT::DebugObjectRegistrar::registerObject(RTDyldObjHandleT H, const ObjT &Object,
const LoadResult &LO)
{
OwningBinary<object::ObjectFile> SavedObject = LO->getObjectForDebug(*Object);
object::OwningBinary<object::ObjectFile> SavedObject = LO->getObjectForDebug(*Object);

// If the debug object is unavailable, save (a copy of) the original object
// for our backtraces
Expand All @@ -396,16 +329,15 @@ void JuliaOJIT::DebugObjectRegistrar::registerObject(RTDyldObjHandleT H, const O
// ownership of the original buffer
auto NewBuffer = MemoryBuffer::getMemBufferCopy(Object->getData(),
Object->getFileName());
auto NewObj = ObjectFile::createObjectFile(NewBuffer->getMemBufferRef());
auto NewObj = object::ObjectFile::createObjectFile(NewBuffer->getMemBufferRef());
assert(NewObj);
SavedObject = OwningBinary<object::ObjectFile>(std::move(*NewObj),
SavedObject = object::OwningBinary<object::ObjectFile>(std::move(*NewObj),
std::move(NewBuffer));
}
else {
NotifyGDB(SavedObject);
JIT.NotifyFinalizer(*(SavedObject.getBinary()), *LO);
}

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

ORCNotifyObjectEmitted(JuliaListener.get(), *Object,
Expand Down Expand Up @@ -436,7 +368,6 @@ void JuliaOJIT::DebugObjectRegistrar::registerObject(RTDyldObjHandleT H, const O
}
}

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

void JuliaOJIT::DebugObjectRegistrar::NotifyGDB(OwningBinary<object::ObjectFile> &DebugObj)
{
const char *Buffer = DebugObj.getBinary()->getMemoryBufferRef().getBufferStart();
size_t Size = DebugObj.getBinary()->getMemoryBufferRef().getBufferSize();

assert(Buffer && "Attempt to register a null object with a debugger.");
jit_code_entry *JITCodeEntry = new jit_code_entry();

if (!JITCodeEntry) {
jl_printf(JL_STDERR, "WARNING: Allocation failed when registering a JIT entry!\n");
}
else {
JITCodeEntry->symfile_addr = Buffer;
JITCodeEntry->symfile_size = Size;

NotifyDebugger(JITCodeEntry);
}
}

object::OwningBinary<object::ObjectFile> JuliaOJIT::CompilerT::operator()(Module &M)
{
Expand Down
2 changes: 0 additions & 2 deletions src/jitlayers.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ using RTDyldObjHandleT = orc::ObjectLinkingLayerBase::ObjSetHandleT;

class JuliaOJIT {
// Custom object emission notification handler for the JuliaOJIT
// TODO: hook up RegisterJITEventListener, instead of hard-coding the GDB and JuliaListener targets
class DebugObjectRegistrar {
public:
DebugObjectRegistrar(JuliaOJIT &JIT);
Expand All @@ -112,7 +111,6 @@ class JuliaOJIT {
private:
template <typename ObjT, typename LoadResult>
void registerObject(RTDyldObjHandleT H, const ObjT &Object, const LoadResult &LO);
void NotifyGDB(object::OwningBinary<object::ObjectFile> &DebugObj);
std::vector<object::OwningBinary<object::ObjectFile>> SavedObjects;
std::unique_ptr<JITEventListener> JuliaListener;
JuliaOJIT &JIT;
Expand Down

0 comments on commit d936625

Please sign in to comment.