aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
diff options
context:
space:
mode:
authorStefan Gränitz <stefan.graenitz@gmail.com>2021-03-02 12:37:48 +0100
committerStefan Gränitz <stefan.graenitz@gmail.com>2021-03-02 15:07:35 +0100
commitef2389235c5dec03be93f8c9585cd9416767ef4c (patch)
tree3e3439a9525825670011836aa935da1825a61f9c /llvm/tools/llvm-jitlink/llvm-jitlink.cpp
parent171849c2881bc11c82173588596cca8f539ef81d (diff)
downloadllvm-ef2389235c5dec03be93f8c9585cd9416767ef4c.zip
llvm-ef2389235c5dec03be93f8c9585cd9416767ef4c.tar.gz
llvm-ef2389235c5dec03be93f8c9585cd9416767ef4c.tar.bz2
[Orc] Add JITLink debug support plugin for ELF x86-64
Add a new ObjectLinkingLayer plugin `DebugObjectManagerPlugin` and infrastructure to handle creation of `DebugObject`s as well as their registration in OrcTargetProcess. The current implementation only covers ELF on x86-64, but the infrastructure is not limited to that. The journey starts with a new `LinkGraph` / `JITLinkContext` pair being created for a `MaterializationResponsibility` in ORC's `ObjectLinkingLayer`. It sends a `notifyMaterializing()` notification, which is forwarded to all registered plugins. The `DebugObjectManagerPlugin` aims to create a `DebugObject` form the provided target triple and object buffer. (Future implementations might create `DebugObject`s from a `LinkGraph` in other ways.) On success it will track it as the pending `DebugObject` for the `MaterializationResponsibility`. This patch only implements the `ELFDebugObject` for `x86-64` targets. It follows the RuntimeDyld approach for debug object setup: it captures a copy of the input object, parses all section headers and prepares to patch their load-address fields with their final addresses in target memory. It instructs the plugin to report the section load-addresses once they are available. The plugin overrides `modifyPassConfig()` and installs a JITLink post-allocation pass to capture them. Once JITLink emitted the finalized executable, the plugin emits and registers the `DebugObject`. For emission it requests a new `JITLinkMemoryManager::Allocation` with a single read-only segment, copies the object with patched section load-addresses over to working memory and triggers finalization to target memory. For registration, it notifies the `DebugObjectRegistrar` provided in the constructor and stores the previously pending`DebugObject` as registered for the corresponding MaterializationResponsibility. The `DebugObjectRegistrar` registers the `DebugObject` with the target process. `llvm-jitlink` uses the `TPCDebugObjectRegistrar`, which calls `llvm_orc_registerJITLoaderGDBWrapper()` in the target process via `TargetProcessControl` to emit a `jit_code_entry` compatible with the GDB JIT interface [1]. So far the implementation only supports registration and no removal. It appears to me that it wouldn't raise any new design questions, so I left this as an addition for the near future. [1] https://sourceware.org/gdb/current/onlinedocs/gdb/JIT-Interface.html Reviewed By: lhames Differential Revision: https://reviews.llvm.org/D97335
Diffstat (limited to 'llvm/tools/llvm-jitlink/llvm-jitlink.cpp')
-rw-r--r--llvm/tools/llvm-jitlink/llvm-jitlink.cpp13
1 files changed, 13 insertions, 0 deletions
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
index 108dd61..fd5331a 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
@@ -15,9 +15,13 @@
#include "llvm-jitlink.h"
#include "llvm/BinaryFormat/Magic.h"
+#include "llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h"
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
+#include "llvm/ExecutionEngine/Orc/TPCDebugObjectRegistrar.h"
#include "llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h"
#include "llvm/ExecutionEngine/Orc/TPCEHFrameRegistrar.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
@@ -155,6 +159,12 @@ static cl::opt<std::string> OutOfProcessExecutorConnect(
ExitOnError ExitOnErr;
+LLVM_ATTRIBUTE_USED void linkComponents() {
+ errs() << (void *)&llvm_orc_registerEHFrameSectionWrapper
+ << (void *)&llvm_orc_deregisterEHFrameSectionWrapper
+ << (void *)&llvm_orc_registerJITLoaderGDBWrapper;
+}
+
namespace llvm {
static raw_ostream &
@@ -842,6 +852,9 @@ Session::Session(std::unique_ptr<TargetProcessControl> TPC, Error &Err)
ObjLayer.addPlugin(std::make_unique<EHFrameRegistrationPlugin>(
ES, ExitOnErr(TPCEHFrameRegistrar::Create(*this->TPC))));
+ ObjLayer.addPlugin(std::make_unique<DebugObjectManagerPlugin>(
+ ES, ExitOnErr(createJITLoaderGDBRegistrar(*this->TPC))));
+
ObjLayer.addPlugin(std::make_unique<JITLinkSessionPlugin>(*this));
// Process any harness files.