Page MenuHomePhabricator

[ORC-RT][ORC] Handle dynamic unwind registration for libunwind
ClosedPublic

Authored by housel on Dec 2 2021, 7:22 AM.

Details

Summary

This changes the Orc runtime for ELFNix platforms to use, when available, the __unw_add_dynamic_eh_frame_section interface provided by libunwind for registering .eh_frame sections loaded by JITLink. When libunwind is not being used for unwinding, the ELFNix platform detects this and defaults to the __register_frame interface provided by libgcc_s.

Diff Detail

Event Timeline

housel created this revision.Dec 2 2021, 7:22 AM
housel requested review of this revision.Dec 2 2021, 7:22 AM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptDec 2 2021, 7:22 AM
Herald added subscribers: llvm-commits, Restricted Project. · View Herald Transcript

Hi @housel,

This looks great -- with this applied I was able to use libunwind with the JIT on linux without issues.

I did run in to a config issue with the unit tests -- they seem to point to the wrong libunwind path when libunwind is enabled via -DLLVM_ENABLE_RUNTIMES rather than -DLLVM_ENABLE_PROJECTS. Using the following diff for my regression test config (rather than the changes above) got things working for both configs:

diff --git a/compiler-rt/test/orc/lit.cfg.py b/compiler-rt/test/orc/lit.cfg.py
index 5ce6c8b1fa7f..b2e97cefbf0e 100644
--- a/compiler-rt/test/orc/lit.cfg.py
+++ b/compiler-rt/test/orc/lit.cfg.py
@@ -18,6 +18,11 @@ if config.host_os == 'Darwin':
 else:
   orc_rt_path = '%s/libclang_rt.orc%s.a' % (config.compiler_rt_libdir, config.target_suffix)
 
+if config.libunwind_shared:
+  config.available_features.add('libunwind-available')
+  shared_libunwind_path = os.path.join(config.libunwind_install_dir, 'libunwind.so')
+  config.substitutions.append( ("%shared_libunwind", shared_libunwind_path) )
+
 config.substitutions.append(
     ('%clang ', build_invocation([config.target_cflags])))
 config.substitutions.append(
diff --git a/compiler-rt/test/orc/lit.site.cfg.py.in b/compiler-rt/test/orc/lit.site.cfg.py.in
index d5bb51c9be80..cd0671279741 100644
--- a/compiler-rt/test/orc/lit.site.cfg.py.in
+++ b/compiler-rt/test/orc/lit.site.cfg.py.in
@@ -6,6 +6,8 @@ config.orc_lit_source_dir = "@ORC_LIT_SOURCE_DIR@"
 config.target_cflags = "@ORC_TEST_TARGET_CFLAGS@"
 config.target_arch = "@ORC_TEST_TARGET_ARCH@"
 config.built_with_llvm = ("@COMPILER_RT_STANDALONE_BUILD@" != "TRUE")
+config.libunwind_shared = "@LIBUNWIND_ENABLE_SHARED@"
+config.libunwind_install_dir = "@LLVM_BINARY_DIR@/@LIBUNWIND_INSTALL_LIBRARY_DIR@"
compiler-rt/test/orc/TestCases/FreeBSD/ehframe-default.cpp
9

Why test5?

compiler-rt/test/orc/TestCases/Linux/ehframe-default.cpp
5–29

I think this can be shrunk to:

extern "C" void llvm_jitlink_setTestResultOverride(long Value);

int main(int argc, char *argv[]) {
  llvm_jitlink_setTestResultOverride(1);
  try {
    throw 0;
  } catch (int X) {
    llvm_jitlink_setTestResultOverride(X);
  }
  return 0;
}
compiler-rt/test/orc/TestCases/Linux/ehframe-libunwind.cpp
6–30

Ditto here.

llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp
201–213

MatchAllSymbols shouldn't be needed here: We expect __unw_add_dynamic_eh_frame_section to be exported.

The expectedToOptional bit could be more idiomatically expressed as:

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();

if (SM.size() == 2) {
  // Use _unw_add/remove_dynamic_eh_frame_section
} else {
  // Use __[de]register_frame.
}
Herald added a project: Restricted Project. · View Herald TranscriptApr 28 2022, 1:13 PM
Herald added a subscriber: StephenFan. · View Herald Transcript
housel updated this revision to Diff 426918.May 3 2022, 10:25 PM

Updated in response to comments.

lhames accepted this revision.May 5 2022, 8:55 AM

LGTM. Thanks very much @housel!

This revision is now accepted and ready to land.May 5 2022, 8:55 AM