-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[loader]: Re-export symbols for C embedding, rename to libjulia-internal
#38160
Conversation
@yuyichao I requested your review because I believe this was a central issue with regards to your objections to the @JeffBezanson I re-named @vtjnash I think we're going to need to come up with function trampoline analogues that can work on any assembler. So far it looks like |
No, as I said, the caller is still required to provide more information than before. |
beca37a
to
c3329e1
Compare
d99f8cd
to
97b7a03
Compare
894a5ab
to
1b64ab6
Compare
800948d
to
04bb53b
Compare
87cf577
to
c510f04
Compare
Looks like this is ready to merge. Keno and I confirmed that you can get unwind info from within a trampoline by segfaulting within the trampoline and seeing the correct unwind trace (despite the fact that the trampoline function itself was referred to as an unknown function). |
c510f04
to
1195d21
Compare
…rnal` We first rename `libjulia` to `libjulia-internal`, and `libjulialoader` to `libjulia` so as to reduce confusion from the outside; `libjulia` is the entrypoint for all usecases, and `libjulia-internal` just so happens to be the chunk that contains all the actual code and linkage to other libraries. To support C linking against `libjulia` in a natural way, we must re-export our symbols from `libjulia-internal`. In order to do this we create function trampolines from `libjulia` to `libjulia-internal` and we define all symbols within `libjulia` to be filled in by the initialization routines of `libjulia-internal`. The function and data symbols are now maintained in lists stored in `src/jl_exported_*.inc`. These lists are consumed by `cli/Makefile` where bindings are generated for them to be re-exported. The function trampolines are all naked functions that contain an architecture- appropriate `jmp` instruction to `jl_*_addr` symbols, which are initialized within `loader_export_symbols()` to point to the actual function addresses within `libjulia-internal`. The data symbols are merely defined as `void *` pointers within the loader, then imported into `libjulia-internal` by the C linker. This backwards-dependency is slightly confusing, but it allows the symbols to live within `libjulia` while being initialized by `libjulia-internal`. At first glance it appears to be a circular dependency, however since `libjulia` loads `libjulia-internal` through `dlopen()` first, then `libjulia-internal` finds `libjulia` already loaded, the circular dependency is a non-issue. C code that wishes to link against `libjulia` should do so directly, and the values of all symbols, while initially being NULL, will be set to their correct values after initialization through `load_libjulia_internal()` is complete.
1195d21
to
6735cb6
Compare
Green flush! Let's go. |
The soname was changed in #38160 to be libjulia.so.1.6 instead of libjulia.so.1, but probably not on purpose. This contradicts what is written in the comment in Make.inc and it breaks e.g. libcxxwrap_julia_jll which is linked against libjulia.so.1. See JuliaPackaging/Yggdrasil#2233
They work with Julia in the build tree but not with the nightly binaries. More specifically, running
I get
|
@staticfloat I get a similar error as @GunnarFarneback above when trying to build the Fedora RPM package for Julia 1.6.0-beta. Any idea about how we can fix out of tree builds? (More precisely, I get an error when trying to load openlibm.) |
Milan, can you open a new issue with all the relevant info please? Thanks! |
Sure: see #39523. |
…#38748) The soname was changed in JuliaLang#38160 to be libjulia.so.1.6 instead of libjulia.so.1, but probably not on purpose. This contradicts what is written in the comment in Make.inc and it breaks e.g. libcxxwrap_julia_jll which is linked against libjulia.so.1. See JuliaPackaging/Yggdrasil#2233
Previously the `@snoopl` functionality from SnoopCompile wasn't unit tested at all, and so it was broken in #38160, which changed the requirements for exporting C functions from the julia-internal shared lib. This commit restores the functionality by exporting it correctly, and also adds a unit test for snoopl, to make sure it isn't broken in the future. Sorry that we didn't test it in the first place! :)
* Fix SnoopCompile's `snoopl` macro and add test. Previously the `@snoopl` functionality from SnoopCompile wasn't unit tested at all, and so it was broken in #38160, which changed the requirements for exporting C functions from the julia-internal shared lib. This commit restores the functionality by exporting it correctly, and also adds a unit test for snoopl, to make sure it isn't broken in the future. Sorry that we didn't test it in the first place! :)
* Fix SnoopCompile's `snoopl` macro and add test. Previously the `@snoopl` functionality from SnoopCompile wasn't unit tested at all, and so it was broken in JuliaLang#38160, which changed the requirements for exporting C functions from the julia-internal shared lib. This commit restores the functionality by exporting it correctly, and also adds a unit test for snoopl, to make sure it isn't broken in the future. Sorry that we didn't test it in the first place! :)
* Fix SnoopCompile's `snoopl` macro and add test. Previously the `@snoopl` functionality from SnoopCompile wasn't unit tested at all, and so it was broken in JuliaLang#38160, which changed the requirements for exporting C functions from the julia-internal shared lib. This commit restores the functionality by exporting it correctly, and also adds a unit test for snoopl, to make sure it isn't broken in the future. Sorry that we didn't test it in the first place! :)
We first rename
libjulia
tolibjulia-internal
, andlibjulialoader
to
libjulia
so as to reduce confusion from the outside;libjulia
isthe entrypoint for all usecases, and
libjulia-internal
just so happensto be the chunk that contains all the actual code and linkage to other
libraries.
To support C linking against
libjulia
in a natural way, we mustre-export our symbols from
libjulia-internal
. In order to do this wecreate function trampolines from
libjulia
tolibjulia-internal
andwe define all symbols within
libjulia
to be filled in by theinitialization routines of
libjulia-internal
.The function and data symbols are now maintained in lists stored in
src/jl_exported_*.list
. These lists are consumed bycli/Makefile
where bindings are generated for them to be re-exported. The function
trampolines are all of the form:
where the
jl_foo_addr
is initialized withinloader_export_symbols()
:The data symbols are merely defined as
void *
pointers within theloader, then imported into
libjulia-internal
by the C linker. Thisbackwards-dependency is slightly confusing, but it allows the symbols to
live within
libjulia
while being initialized bylibjulia-internal
.At first glance it appears to be a circular dependency, however since
libjulia
loadslibjulia-internal
throughdlopen()
first, thenlibjulia-internal
findslibjulia
already loaded, the circulardependency is a non-issue. C code that wishes to link against
libjulia
should do so directly, and the values of all symbols, whileinitially being NULL, will be set to their correct values after
initialization through
load_libjulia_internal()
is complete.