#!/bin/sh # program # # dlopen(): # libe.so # liba.so # <- libb.so # <- libd.so # # Expected: dlsym(RTLD_NEXT) finds symbol in order libe.so, liba.so, libb.so, # libd.so . ./test_setup # create libd.so cat > libd.c << EOI int a() { return 1; } EOI # build compile_lib -o libd.so libd.c # create libb.so cat > libb.c << EOI #define __USE_GNU #include int a() { int (*nextA)(); *(void**)&nextA = dlsym(RTLD_NEXT, "a"); return (nextA != 0 ? nextA() : 0) + 2; } EOI # build compile_lib_dl -o libb.so libb.c ./libd.so # create liba.so cat > liba.c << EOI #include int a() { int (*nextA)(); *(void**)&nextA = dlsym(RTLD_NEXT, "a"); return (nextA != 0 ? nextA() : 0) + 4; } EOI # build compile_lib_dl -o liba.so liba.c ./libb.so # create libe.so cat > libe.c << EOI #include int a() { int (*nextA)(); *(void**)&nextA = dlsym(RTLD_NEXT, "a"); return (nextA != 0 ? nextA() : 0) + 8; } EOI # build compile_lib_dl -o libe.so libe.c # create program cat > program.c << EOI #include #include #include int a() { int (*nextA)(); *(void**)&nextA = dlsym(RTLD_NEXT, "a"); return (nextA != 0 ? nextA() : 0) + 16; } int main() { void* liba; void* libe; void* self; libe = dlopen("./libe.so", RTLD_NOW | RTLD_GLOBAL); if (libe == NULL) { fprintf(stderr, "Error opening libe.so: %s\n", dlerror()); exit(117); } liba = dlopen("./liba.so", RTLD_NOW | RTLD_GLOBAL); if (liba == NULL) { fprintf(stderr, "Error opening liba.so: %s\n", dlerror()); exit(117); } return a(); } EOI # build compile_program_dl -o program program.c # run test_run_ok ./program 31