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.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
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. } |
Why test5?