|
Message-Id: <3521821576058976@vla1-2bebf6b1c06e.qloud-c.yandex.net> Date: Wed, 11 Dec 2019 13:09:36 +0300 From: Scherbatiy Alexander <alexander.scherbatiy@...l-sw.com> To: musl@...ts.openwall.com Subject: RTLD_LAZY deferred symbol binding Hello, musl libc release 1.1.17 has new feature [1]: - RTLD_LAZY deferred symbol binding, functionally equivalent to lazy binding The lazy bindings section [2] gives more details on it: Newer versions of musl implement “deferred binding” in place of lazy binding, whereby binding is deferred until a subsequent dlopen call that introduces new symbols, rather than at the point of the function call. It is still is not clear for me what is a difference between of lazy and deferred binding. I wrote a simple example there a shared library with an unresolved symbols is loaded by dlopen with RTLD_LAZY option (source code is at the end of the email). It works on my Ubuntu desktop but fails on Alpine linux 3.10.3 with musl libc 1.1.22 (x86_64) with message: "dlopen failed: Error relocating bin/shared/libshared_lib.so: unresolved_function: symbol not found" What is a good example that can show how the new "deferred symbol binding" feature works so it fails before muls libc 1.1.17 and starts working after it? [1] https://git.musl-libc.org/cgit/musl/tree/WHATSNEW [2] https://wiki.musl-libc.org/functional-differences-from-glibc.html Thanks, Alexander. Loading a shared library with unresolved symbols example: --- include/resolved_lib.h --- void resolved_function(); --- include/unresolved_lib.h --- void unresolved_function(); --- include/shared_lib.h --- void call_resolved_function(); void call_unresolved_function(); --- src/resolved_impl.c --- #include <stdio.h> #include "resolved_lib.h" void resolved_function() { printf("call resolved function.\n"); } --- src/shared_lib.c --- #include "shared_lib.h" #include "resolved_lib.h" #include "unresolved_lib.h" void call_resolved_function() { resolved_function(); } void call_unresolved_function() { unresolved_function(); } --- src/main.c --- #include <stdio.h> #include <stdlib.h> #include <dlfcn.h> void call_resolved_function_dynamic() { const char *lib_path = "bin/shared/libshared_lib.so"; void (*call_resolved_function)(void); void *handle = dlopen(lib_path, RTLD_LAZY); if (!handle) { fprintf(stderr, "dlopen failed: %s\n", dlerror()); exit(EXIT_FAILURE); } *(void **) (&call_resolved_function) = dlsym(handle, "call_resolved_function"); char *error = dlerror(); if (error != NULL) { fprintf(stderr, "%s\n", error); exit(EXIT_FAILURE); } (*call_resolved_function)(); dlclose(handle); } int main(int argc, char* argv[]) { printf("call main.\n"); call_resolved_function_dynamic(); } --- --- # build sources gcc -c -fPIC src/resolved_impl.c -Iinclude -o bin/shared/resolved_impl.o gcc -c -fPIC src/shared_lib.c -Iinclude -o bin/shared/shared_lib.o gcc -shared bin/shared/shared_lib.o bin/shared/resolved_impl.o -Iinclude -o bin/shared/libshared_lib.so gcc -c src/main.c -Iinclude -o bin/main.o gcc bin/main.o -ldl -o bin/main # run export LD_LIBRARY_PATH=./bin/shared ./bin/main --- ---
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.