Skip to content

Instantly share code, notes, and snippets.

@chris-se
Created June 24, 2022 11:34
Show Gist options
  • Save chris-se/e8fe3678dc7bf74f46b9a202e5e4399e to your computer and use it in GitHub Desktop.
Save chris-se/e8fe3678dc7bf74f46b9a202e5e4399e to your computer and use it in GitHub Desktop.
rpath interaction with ld.so and dlopen example
#!/bin/sh
set -xe
gcc -fPIC -Wall -shared -Wl,-soname,libtest3.so.0 -o libtest3/libtest3.so.0 libtest3/libtest3.c
gcc -fPIC -Wall -shared -Wl,-soname,libtest2.so.0 -o libtest2/libtest2.so.0 libtest2/libtest2.c
gcc -fPIC -Wall -shared -Wl,-soname,libtest1.so.0 -o libtest1/libtest1.so.0 libtest1/libtest1.c libtest2/libtest2.so.0 -ldl
gcc -fPIC -Wall -o prog/prog prog/main.c -Wl,-rpath-link,libtest2 -Wl,-rpath,$PWD/libtest1:$PWD/libtest2:$PWD/libtest3 libtest1/libtest1.so.0
# - Calling prog/prog won't work because library not found
# - add $PWD/libtest2 to LD_LIBRARY_PATH and it will say that dlopen() failed
# - add both $PWD/libtest2 and $PWD/libtest3 to LD_LIBRARY_PATH and it will work
# - Alterantively, set rpath on libtest1 (that requires libtest2 and libtest3),
# and it will work w/o LD_LIBRARY_PATH
# gcc -fPIC -Wall -shared -Wl,-soname,libtest1.so.0 -o libtest1/libtest1.so.0 -Wl,-rpath,$PWD/libtest2:$PWD/libtest3 libtest1/libtest1.c libtest2/libtest2.so.0 -ldl
// place this file in a subdirectory libtest1
#include <dlfcn.h>
#include <stdio.h>
extern int get_v2(void);
typedef int (*int_getter)(void);
int get_sum()
{
int_getter get_v3 = NULL;
void* handle = dlopen("libtest3.so.0", RTLD_NOW | RTLD_GLOBAL);
if (!handle) {
fprintf(stderr, "Error loading libtest3.so.0: %s\n", dlerror());
return -1;
}
get_v3 = (int_getter) dlsym(handle, "get_v3");
if (!get_v3) {
fprintf(stderr, "Error locating get_v3 in libtest3.so.0: %s\n", dlerror());
return -1;
}
return get_v2() + get_v3();
}
// place this file in a subdirectory libtest2
extern int get_v2()
{
return 23;
}
// place this file in a subdirectory libtest3
extern int get_v3()
{
return 42;
}
// place this file in a subdirectory prog
#include <stdio.h>
extern int get_sum(void);
int main()
{
printf("The sum is: %d\n", get_sum());
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment