diff options
Diffstat (limited to 'development/ldso/deepbind')
-rw-r--r-- | development/ldso/deepbind/.gitignore | 2 | ||||
-rw-r--r-- | development/ldso/deepbind/Makefile | 19 | ||||
-rw-r--r-- | development/ldso/deepbind/lib.c | 23 | ||||
-rw-r--r-- | development/ldso/deepbind/main.c | 40 |
4 files changed, 84 insertions, 0 deletions
diff --git a/development/ldso/deepbind/.gitignore b/development/ldso/deepbind/.gitignore new file mode 100644 index 0000000..a80e8fd --- /dev/null +++ b/development/ldso/deepbind/.gitignore @@ -0,0 +1,2 @@ +*.so +main diff --git a/development/ldso/deepbind/Makefile b/development/ldso/deepbind/Makefile new file mode 100644 index 0000000..6fc4eb1 --- /dev/null +++ b/development/ldso/deepbind/Makefile @@ -0,0 +1,19 @@ +run: build + LD_PRELOAD=./libprel.so ./main + +debug: build + #LD_DEBUG_OUTPUT=ldso + LD_DEBUG=scopes,symbols,bindings LD_PRELOAD=./libprel.so ./main + +build: + gcc -g -o libprel.so lib.c -DNAME=\"prel\" -fPIC -shared + gcc -g -o libdeep.so lib.c -DNAME=\"deep\" -fPIC -shared + gcc -g -o libnodp.so lib.c -DNAME=\"nodp\" -fPIC -shared + gcc -g -o liblink.so lib.c -DNAME=\"link\" -fPIC -shared + gcc -g -o main main.c ./liblink.so -ldl + +fmt: + clang-format -i *.c + +clean: + $(RM) *.so main diff --git a/development/ldso/deepbind/lib.c b/development/ldso/deepbind/lib.c new file mode 100644 index 0000000..e18a4ce --- /dev/null +++ b/development/ldso/deepbind/lib.c @@ -0,0 +1,23 @@ +#define _GNU_SOURCE +#include <dlfcn.h> +#include <stdio.h> + +#ifndef NAME +#define NAME "" +#endif + +void test() { + puts(NAME ":test()"); + + // Lookup next symbol from the libraries scope, which will search only in the + // libraries LOCAL scope, starting from the next object after the current one. + (void)dlsym(RTLD_NEXT, "next_lib" NAME); + + // Global lookup from the libraries scope, which will search libraries in the + // GLOBAL scope and the libraries LOCAL scope. The order in which the scopes + // are searched depends on whether the library was loaded (a) with DEEPBIND or + // (b) not. whether this library was loaded with DEEPBIND). In the first case, + // the LOCAL scope is searched first, where in the latter, the GLOBAL scope is + // searched first. + (void)dlsym(RTLD_DEFAULT, "default_lib" NAME); +} diff --git a/development/ldso/deepbind/main.c b/development/ldso/deepbind/main.c new file mode 100644 index 0000000..6d93520 --- /dev/null +++ b/development/ldso/deepbind/main.c @@ -0,0 +1,40 @@ +#include <dlfcn.h> +#include <stdio.h> + +int main() { + puts("-- deep --"); + // Load library into its own LOCAL scope with DEEPBINDING, meaning that + // symbols will first resolve to the library + its dependencies first before + // considering global symbols. + void* h1 = dlopen("./libdeep.so", RTLD_LAZY | RTLD_LOCAL | RTLD_DEEPBIND); + if (h1) { + // Lookup symbol in the libraries LOCAL scope (library + its own + // dependencies). + void (*test_fn)() = dlsym(h1, "test"); + test_fn(); + + // Lookup non-existing symbol in the libraries LOCAL scope (library + its + // own dependencies). + (void)dlsym(h1, "libdeep_main"); + } + + puts("-- nodp --"); + // Load library into its own LOCAL scope. + void* h2 = dlopen("./libnodp.so", RTLD_LOCAL | RTLD_LAZY); + if (h2) { + // Lookup symbol in the libraries LOCAL scope (library + its own + // dependencies). + void (*test_fn)() = dlsym(h2, "test"); + test_fn(); + + // Lookup non-existing symbol in the libraries LOCAL scope (library + its + // own dependencies). + (void)dlsym(h2, "libnodp_main"); + } + + puts("-- main --"); + // Lookup non-existing symbol in the GLOBAL scope. + (void)dlsym(RTLD_DEFAULT, "default_main"); + + return 0; +} |