julia
9427f339 - jl_dlfind: do not find symbols in library dependencies (#58815)

Commit
151 days ago
jl_dlfind: do not find symbols in library dependencies (#58815) A `ccall` without a specific library finds one with `jl_dlfind`, which calls `jl_dlsym` on each of the following libraries, in order: - `libjulia-internal` - `libjulia` - The current executable - (On Windows): `kernel32`, `crtdll`, `ntdll`, `ws2_32` The semantics of using `dlsym` (this does not apply to `GetProcAddress`) with a specific handle are a little weird: the library and its dependencies are searched, even if the provided symbol would resolve somewhere else if used in the library. On macOS and Linux, this causes all of the calls to libc functions in Base go through the handle for `libjulia-internal`, making it difficult to hook functions. For example, `-fsanitize=thread` on clang intercepts malloc and free by defining them in the executable; calls to malloc from Julia code would go to the original libc version while calls to free in `libjulia-internal` would go to the hooked version. This change makes `jl_dlfind` return a handle only if the symbol is found in that library and not one of its dependencies. ## Example `a.c`: ```c void b_func(void); void c_func(void) { puts("c override from a"); } int main() { puts("a"); b_func(); } ``` `b.c`: ```c define _GNU_SOURCE #include <stdio.h> #include <dlfcn.h> void c_func(void); void b_func(void) { puts("b"); c_func(); /* How jl_libjulia_internal_handle is set by jl_find_dynamic_library_by_addr */ Dl_info info; dladdr(&b_func, &info); void *hdl = dlopen(info.dli_fname, RTLD_NOW | RTLD_NOLOAD | RTLD_LOCAL); void *(*dl_c_func)(void) = dlsym(hdl, "c_func"); dl_c_func(); } ``` `c.c`: ```c #include <stdio.h> void c_func(void) { puts("c"); } ``` ``` $ cc -g -fPIC -shared -o libc.so c.c $ cc -g -fPIC -shared -o libb.so b.c libc.so $ cc -Wl,-rpath,. -g -fPIC -o main a.c libb.so libc.so $ ./main a b c override from a c ```
Author
Parents
Loading