[llvm] [llvm-c] Expose debug object registration in Orc C-API bindings (PR #73257)
Stefan Gränitz via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 24 08:00:57 PST 2023
https://github.com/weliveindetail updated https://github.com/llvm/llvm-project/pull/73257
>From 5b93cab0f0d4cd43dab720ffb4a952a66a99ec79 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20Gr=C3=A4nitz?= <stefan.graenitz at gmail.com>
Date: Thu, 23 Nov 2023 09:41:30 +0100
Subject: [PATCH 1/3] [llvm-c] Expose debug object registration in Orc bindings
---
llvm/include/llvm-c/Orc.h | 19 +++++++++++++
.../ExecutionEngine/Orc/OrcV2CBindings.cpp | 28 +++++++++++++++++++
2 files changed, 47 insertions(+)
diff --git a/llvm/include/llvm-c/Orc.h b/llvm/include/llvm-c/Orc.h
index 304833cca2d4332..633f191b9836941 100644
--- a/llvm/include/llvm-c/Orc.h
+++ b/llvm/include/llvm-c/Orc.h
@@ -1206,6 +1206,25 @@ void LLVMOrcObjectLayerEmit(LLVMOrcObjectLayerRef ObjLayer,
LLVMOrcMaterializationResponsibilityRef R,
LLVMMemoryBufferRef ObjBuffer);
+/**
+ * Install the plugin that submits debug objects to the executor. Out-of-process
+ * executors must provide the llvm_orc_registerJITLoaderGDBWrapper symbol.
+ *
+ * RequireDebugSectionsFlag lets the plugin pass debug objects only if they
+ * contain actual debug info. Turning this off may allow minimal debugging based
+ * on raw symbol names. It may cause significant memory and transport overhead
+ * for objects built with a release configuration.
+ *
+ * AutoRegisterCodeFlag lets the executor notify the debugger for each new debug
+ * object. This is a good default mode, but it may cause significant overhead
+ * when adding many modules in sequence. When turned off, the user has to issue
+ * the call to __jit_debug_register_code() on the executor side manually.
+ */
+LLVMErrorRef
+LLVMOrcObjectLayerRegisterPluginJITLoaderGDB(LLVMOrcObjectLayerRef ObjLayer,
+ LLVMBool RequireDebugSectionsFlag,
+ LLVMBool AutoRegisterCodeFlag);
+
/**
* Dispose of an ObjectLayer.
*/
diff --git a/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp b/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp
index a73aec6d98c64c9..871a9b44306ac49 100644
--- a/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp
@@ -11,10 +11,13 @@
#include "llvm-c/OrcEE.h"
#include "llvm-c/TargetMachine.h"
+#include "llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h"
+#include "llvm/ExecutionEngine/Orc/EPCDebugObjectRegistrar.h"
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
using namespace llvm;
@@ -863,6 +866,31 @@ void LLVMOrcObjectLayerEmit(LLVMOrcObjectLayerRef ObjLayer,
std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer)));
}
+LLVMErrorRef
+LLVMOrcObjectLayerRegisterPluginJITLoaderGDB(LLVMOrcObjectLayerRef ObjLayer,
+ LLVMBool RequireDebugSectionsFlag,
+ LLVMBool AutoRegisterCodeFlag) {
+ ExecutionSession &ES = unwrap(ObjLayer)->getExecutionSession();
+ auto Registrar = createJITLoaderGDBRegistrar(ES);
+ if (!Registrar)
+ return wrap(Registrar.takeError());
+
+ auto *ObjLinkingLayer = cast<ObjectLinkingLayer>(unwrap(ObjLayer));
+ if (!ObjLinkingLayer)
+ return wrap(
+ createStringError(inconvertibleErrorCode(),
+ "No debug support for given object layer type"));
+
+ ObjLinkingLayer->addPlugin(std::make_unique<DebugObjectManagerPlugin>(
+ ES, std::move(*Registrar), RequireDebugSectionsFlag,
+ AutoRegisterCodeFlag));
+
+ auto TargetProcessFn = &llvm_orc_registerJITLoaderGDBWrapper;
+ (void)TargetProcessFn;
+
+ return LLVMErrorSuccess;
+}
+
void LLVMOrcDisposeObjectLayer(LLVMOrcObjectLayerRef ObjLayer) {
delete unwrap(ObjLayer);
}
>From c9060de4f90e9a84b7b8acf2c0c8d6da2c13cd72 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20Gr=C3=A4nitz?= <stefan.graenitz at gmail.com>
Date: Thu, 23 Nov 2023 18:03:00 +0100
Subject: [PATCH 2/3] [llvm-c] Add unit test for Orc debug object registration
---
.../ExecutionEngine/Orc/OrcCAPITest.cpp | 66 +++++++++++++++++++
1 file changed, 66 insertions(+)
diff --git a/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp b/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp
index cbdd4af47e1d47d..6f72d5ddc5dca91 100644
--- a/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp
@@ -13,6 +13,7 @@
#include "gtest/gtest.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
+#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IRReader/IRReader.h"
@@ -27,6 +28,7 @@ using namespace llvm;
using namespace llvm::orc;
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ThreadSafeModule, LLVMOrcThreadSafeModuleRef)
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ObjectLayer, LLVMOrcObjectLayerRef)
// OrcCAPITestBase contains several helper methods and pointers for unit tests
// written for the LLVM-C API. It provides the following helpers:
@@ -494,6 +496,70 @@ TEST_F(OrcCAPITestBase, AddObjectBuffer) {
ASSERT_TRUE(!!SumAddr);
}
+// 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 "C" struct jit_descriptor __jit_debug_descriptor;
+}
+
+#if defined(_AIX)
+TEST_F(OrcCAPITestBase, DISABLED_RegisterJITLoaderGDB) {
+#else
+TEST_F(OrcCAPITestBase, RegisterJITLoaderGDB) {
+#endif
+ LLVMOrcObjectLayerRef ObjLayer = LLVMOrcLLJITGetObjLinkingLayer(Jit);
+ auto *ObjLinkingLayer = cast<orc::ObjectLinkingLayer>(unwrap(ObjLayer));
+ ASSERT_TRUE(ObjLinkingLayer);
+
+ constexpr bool RequireDebugSectionsFlag = false;
+ constexpr bool AutoRegisterCodeFlag = true;
+ LLVMErrorRef E = LLVMOrcObjectLayerRegisterPluginJITLoaderGDB(
+ ObjLayer, RequireDebugSectionsFlag, AutoRegisterCodeFlag);
+ if (E)
+ FAIL() << "Failed to register plugin to ObjLinkingLayer (triple = "
+ << TargetTriple << "): " << toString(E);
+
+ ASSERT_EQ(__jit_debug_descriptor.first_entry, nullptr);
+
+ LLVMMemoryBufferRef ObjBuffer = createTestObject(SumExample, "sum.ll");
+ if (LLVMErrorRef E =
+ LLVMOrcObjectLayerAddObjectFile(ObjLayer, MainDylib, ObjBuffer))
+ FAIL() << "Failed to add object file to ObjLinkingLayer (triple = "
+ << TargetTriple << "): " << toString(E);
+
+ LLVMOrcJITTargetAddress SumAddr;
+ if (LLVMErrorRef E = LLVMOrcLLJITLookup(Jit, &SumAddr, "sum"))
+ FAIL() << "Symbol \"sum\" was not added into JIT (triple = " << TargetTriple
+ << "): " << toString(E);
+
+ ASSERT_NE(__jit_debug_descriptor.first_entry, nullptr);
+}
+
#if defined(_AIX)
TEST_F(OrcCAPITestBase, DISABLED_ExecutionTest) {
#else
>From 786088e41a92428f9573b4da37ea6c8a1b04d0f0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20Gr=C3=A4nitz?= <stefan.graenitz at gmail.com>
Date: Thu, 23 Nov 2023 21:32:22 +0100
Subject: [PATCH 3/3] [llvm-c] Run RegisterJITLoaderGDB test only on native
__ELF__ targets
---
llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp b/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp
index 6f72d5ddc5dca91..88b47be82689f2b 100644
--- a/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp
@@ -527,7 +527,7 @@ struct jit_descriptor {
extern "C" struct jit_descriptor __jit_debug_descriptor;
}
-#if defined(_AIX)
+#if not defined(__ELF__)
TEST_F(OrcCAPITestBase, DISABLED_RegisterJITLoaderGDB) {
#else
TEST_F(OrcCAPITestBase, RegisterJITLoaderGDB) {
More information about the llvm-commits
mailing list