From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/14998 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Scherbatiy Alexander Newsgroups: gmane.linux.lib.musl.general Subject: RTLD_LAZY deferred symbol binding Date: Wed, 11 Dec 2019 13:09:36 +0300 Message-ID: <3521821576058976@vla1-2bebf6b1c06e.qloud-c.yandex.net> Reply-To: musl@lists.openwall.com Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="194026"; mail-complaints-to="usenet@blaine.gmane.org" To: musl@lists.openwall.com Original-X-From: musl-return-15014-gllmg-musl=m.gmane.org@lists.openwall.com Wed Dec 11 11:09:52 2019 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by blaine.gmane.org with smtp (Exim 4.89) (envelope-from ) id 1ieywJ-000oNh-UY for gllmg-musl@m.gmane.org; Wed, 11 Dec 2019 11:09:52 +0100 Original-Received: (qmail 19688 invoked by uid 550); 11 Dec 2019 10:09:49 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 19647 invoked from network); 11 Dec 2019 10:09:48 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bell-sw.com; s=mail; t=1576058977; bh=OyMaPMkP/Th1ftSMVK3DRlDyLIGCUvEGgQrL8kjks4I=; h=Message-Id:Date:Subject:To:From; b=eSMpCuMZ8KFwfRnYYxDcEfvKebp3Gi4y4IOGI7WRPsK32Kj5dME2mog5CMKhgMj5s bSZfl8Iw/WTEksjug6gRpZcL4i9bNUK/YpJUr0cmQywxhOd5Q1D/tERBk9TfuBACLe I2Wrh1CnudRyZYTWCvYi2O03Rm/6gIV8h5RHoGEk= Authentication-Results: mxback8q.mail.yandex.net; dkim=pass header.i=@bell-sw.com X-Mailer: Yamail [ http://yandex.ru ] 5.0 Xref: news.gmane.org gmane.linux.lib.musl.general:14998 Archived-At: 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 #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 #include #include 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 --- ---