From 508f1444865a770accdb87a3dfd1ec7146fb74e7 Mon Sep 17 00:00:00 2001 From: Devajith Valaparambil Sreeramaswamy Date: Tue, 12 May 2026 14:12:00 +0200 Subject: [PATCH] [cling][JIT] Inject ORC perf symbols into the process JITDylib LLVM ORC's perf support plugin expects the symbols `llvm_orc_registerJITLoaderPerf*` to be resolvable through the process symbol table. When ROOT is built, these symbols are hidden in libCling.so and cannot be resolved. Enabling perf fails when the plugin attempts to look them up. This is similar to the existing manual symbol injection for compiler-rt helpers on macOS and for symbols in libc_nonshared.a. --- .../cling/lib/Interpreter/IncrementalJIT.cpp | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/interpreter/cling/lib/Interpreter/IncrementalJIT.cpp b/interpreter/cling/lib/Interpreter/IncrementalJIT.cpp index 821ef7f6d5100..c468b050cabf3 100644 --- a/interpreter/cling/lib/Interpreter/IncrementalJIT.cpp +++ b/interpreter/cling/lib/Interpreter/IncrementalJIT.cpp @@ -44,14 +44,28 @@ using namespace llvm; using namespace llvm::jitlink; using namespace llvm::orc; -static LLVM_ATTRIBUTE_USED void linkComponents() { - errs() << "Linking in runtime functions\n" - << (void*)&llvm_orc_registerJITLoaderPerfStart << '\n' - << (void*)&llvm_orc_registerJITLoaderPerfEnd << '\n' - << (void*)&llvm_orc_registerJITLoaderPerfImpl << '\n'; -} - namespace { + static SymbolMap GetListOfPerfSymbols(const LLJIT& Jit) { + // ORC's perf support plugin looks up these runtime entry points through the + // process symbol table. In ROOT, the symbols will remain hidden inside + // libCling.so. Explicitly inject them into the JITDylib. + static const std::pair NamePtrList[] = { + {"llvm_orc_registerJITLoaderPerfStart", + (void*)&llvm_orc_registerJITLoaderPerfStart}, + {"llvm_orc_registerJITLoaderPerfEnd", + (void*)&llvm_orc_registerJITLoaderPerfEnd}, + {"llvm_orc_registerJITLoaderPerfImpl", + (void*)&llvm_orc_registerJITLoaderPerfImpl}, + }; + + SymbolMap PerfSymbols; + for (const auto& NamePtr : NamePtrList) { + PerfSymbols[Jit.mangleAndIntern(NamePtr.first)] = { + orc::ExecutorAddr::fromPtr(NamePtr.second), JITSymbolFlags::Exported}; + } + return PerfSymbols; + } + // This could potentially be upstreamed, similar to enableDebuggerSupport() Error enablePerfSupport(LLJIT& J) { auto* ObjLinkingLayer = @@ -66,6 +80,9 @@ namespace { "Process symbols are not available", inconvertibleErrorCode()); + // Manually define the symbols + cantFail(ProcessSymsJD->define(absoluteSymbols(GetListOfPerfSymbols(J)))); + auto& ES = J.getExecutionSession(); const auto& TT = J.getTargetTriple();