[llvm] cd3f274 - [ORC][ORC-RT][ELF] Move selection of eh-frame registration APIs into orc-rt.

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 6 09:32:02 PDT 2023


Author: Lang Hames
Date: 2023-04-06T16:31:55Z
New Revision: cd3f2749ed156492f8d50bad7055a0d68b9bea05

URL: https://github.com/llvm/llvm-project/commit/cd3f2749ed156492f8d50bad7055a0d68b9bea05
DIFF: https://github.com/llvm/llvm-project/commit/cd3f2749ed156492f8d50bad7055a0d68b9bea05.diff

LOG: [ORC][ORC-RT][ELF] Move selection of eh-frame registration APIs into orc-rt.

ORC's ELF platform support prefers the newer libunwind registration functions
(__unw_add_dynamic_eh_frame_section, __unw_remove_dynamic_eh_frame_section) when
they're available, and falls back to the older registration functions
(__register_frame, __deregister_frame) when they're not.

Until now the choice of registration functions has been made on the controller
side in ELFNixPlatform: The platform JITDylib was searched for the registration
functions and aliases set depending on which ones were found. This patch drops
that selection logic from ELFNixPlatform and instead uses weak imports of the
registration functions in elfnix_platform.cpp to identify which ones are
available and choose which ones to use.

This has a few small benefits:
(1) The registration functions don't need to be defined in the same JITDylib as
the ORC runtime -- it's sufficient for them to be defined in a JITDylib that the
ORC runtime's JITDylib links against.

(2) THe elfnix_platfrom code is more readable, as we don't have to dig into
ELFNixPlatform.cpp on the controller side to discover the definition of the
registration aliases.

(3) We may save a separate round-trip to look up the registration APIs (the
lookup will be folded into the ordinary external symbol lookup when linking the
runtime).

Added: 
    

Modified: 
    compiler-rt/lib/orc/elfnix_platform.cpp
    llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/orc/elfnix_platform.cpp b/compiler-rt/lib/orc/elfnix_platform.cpp
index 23184df7656ec..c087e71038f95 100644
--- a/compiler-rt/lib/orc/elfnix_platform.cpp
+++ b/compiler-rt/lib/orc/elfnix_platform.cpp
@@ -12,6 +12,7 @@
 
 #include "elfnix_platform.h"
 #include "common.h"
+#include "compiler.h"
 #include "error.h"
 #include "wrapper_function_utils.h"
 
@@ -33,8 +34,13 @@ ORC_RT_JIT_DISPATCH_TAG(__orc_rt_elfnix_symbol_lookup_tag)
 
 // eh-frame registration functions, made available via aliases
 // installed by the Platform
-extern "C" void __orc_rt_register_eh_frame_section(const void *);
-extern "C" void __orc_rt_deregister_eh_frame_section(const void *);
+extern "C" void __register_frame(const void *);
+extern "C" void __deregister_frame(const void *);
+
+extern "C" void
+__unw_add_dynamic_eh_frame_section(const void *) ORC_RT_WEAK_IMPORT;
+extern "C" void
+__unw_remove_dynamic_eh_frame_section(const void *) ORC_RT_WEAK_IMPORT;
 
 namespace {
 
@@ -96,8 +102,7 @@ class ELFNixPlatformRuntimeState {
   static ELFNixPlatformRuntimeState &get();
   static void destroy();
 
-  ELFNixPlatformRuntimeState(void *DSOHandle)
-      : PlatformJDDSOHandle(DSOHandle) {}
+  ELFNixPlatformRuntimeState(void *DSOHandle);
 
   // Delete copy and move constructors.
   ELFNixPlatformRuntimeState(const ELFNixPlatformRuntimeState &) = delete;
@@ -143,6 +148,10 @@ class ELFNixPlatformRuntimeState {
 
   void *PlatformJDDSOHandle;
 
+  // Frame registration functions:
+  void (*registerEHFrameSection)(const void *) = nullptr;
+  void (*deregisterEHFrameSection)(const void *) = nullptr;
+
   // FIXME: Move to thread-state.
   std::string DLFcnError;
 
@@ -171,11 +180,22 @@ void ELFNixPlatformRuntimeState::destroy() {
   delete MOPS;
 }
 
+ELFNixPlatformRuntimeState::ELFNixPlatformRuntimeState(void *DSOHandle)
+    : PlatformJDDSOHandle(DSOHandle) {
+  if (__unw_add_dynamic_eh_frame_section &&
+      __unw_remove_dynamic_eh_frame_section) {
+    registerEHFrameSection = __unw_add_dynamic_eh_frame_section;
+    deregisterEHFrameSection = __unw_remove_dynamic_eh_frame_section;
+  } else {
+    registerEHFrameSection = __register_frame;
+    deregisterEHFrameSection = __deregister_frame;
+  }
+}
+
 Error ELFNixPlatformRuntimeState::registerObjectSections(
     ELFNixPerObjectSectionsToRegister POSR) {
   if (POSR.EHFrameSection.Start)
-    __orc_rt_register_eh_frame_section(
-        POSR.EHFrameSection.Start.toPtr<const char *>());
+    registerEHFrameSection(POSR.EHFrameSection.Start.toPtr<const char *>());
 
   if (POSR.ThreadDataSection.Start) {
     if (auto Err = registerThreadDataSection(
@@ -189,8 +209,7 @@ Error ELFNixPlatformRuntimeState::registerObjectSections(
 Error ELFNixPlatformRuntimeState::deregisterObjectSections(
     ELFNixPerObjectSectionsToRegister POSR) {
   if (POSR.EHFrameSection.Start)
-    __orc_rt_deregister_eh_frame_section(
-        POSR.EHFrameSection.Start.toPtr<const char *>());
+    deregisterEHFrameSection(POSR.EHFrameSection.Start.toPtr<const char *>());
 
   return Error::success();
 }

diff  --git a/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp
index 8e71375e56ef7..1bb4ecdff2991 100644
--- a/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp
@@ -207,46 +207,6 @@ ELFNixPlatform::standardPlatformAliases(ExecutionSession &ES,
   SymbolAliasMap Aliases;
   addAliases(ES, Aliases, requiredCXXAliases());
   addAliases(ES, Aliases, standardRuntimeUtilityAliases());
-
-  // Determine whether or not the libunwind extended-API function for
-  // dynamically registering an entire .eh_frame section is available.
-  // If it is not, we assume that libgcc_s is being used, and alias to
-  // its __register_frame with the same functionality.
-  auto RTRegisterFrame = ES.intern("__orc_rt_register_eh_frame_section");
-  auto LibUnwindRegisterFrame = ES.intern("__unw_add_dynamic_eh_frame_section");
-  auto RTDeregisterFrame = ES.intern("__orc_rt_deregister_eh_frame_section");
-  auto LibUnwindDeregisterFrame =
-      ES.intern("__unw_remove_dynamic_eh_frame_section");
-  auto SM = ES.lookup(makeJITDylibSearchOrder(&PlatformJD),
-                      SymbolLookupSet()
-                          .add(LibUnwindRegisterFrame,
-                               SymbolLookupFlags::WeaklyReferencedSymbol)
-                          .add(LibUnwindDeregisterFrame,
-                               SymbolLookupFlags::WeaklyReferencedSymbol));
-  if (!SM) { // Weak-ref means no "missing symbol" errors, so this must be
-             // something more serious that we should report.
-    return SM.takeError();
-  } else if (SM->size() == 2) {
-    LLVM_DEBUG({
-      dbgs() << "Using libunwind " << LibUnwindRegisterFrame
-             << " for unwind info registration\n";
-    });
-    Aliases[std::move(RTRegisterFrame)] = {LibUnwindRegisterFrame,
-                                           JITSymbolFlags::Exported};
-    Aliases[std::move(RTDeregisterFrame)] = {LibUnwindDeregisterFrame,
-                                             JITSymbolFlags::Exported};
-  } else {
-    // Since LLVM libunwind is not present, we assume that unwinding
-    // is provided by libgcc
-    LLVM_DEBUG({
-      dbgs() << "Using libgcc __register_frame for unwind info registration\n";
-    });
-    Aliases[std::move(RTRegisterFrame)] = {ES.intern("__register_frame"),
-                                           JITSymbolFlags::Exported};
-    Aliases[std::move(RTDeregisterFrame)] = {ES.intern("__deregister_frame"),
-                                             JITSymbolFlags::Exported};
-  }
-
   return Aliases;
 }
 


        


More information about the llvm-commits mailing list