Skip to content

Instantly share code, notes, and snippets.

@jethrogb
Created September 23, 2015 06:51
Show Gist options
  • Save jethrogb/78fe252a649655508be2 to your computer and use it in GitHub Desktop.
Save jethrogb/78fe252a649655508be2 to your computer and use it in GitHub Desktop.
all: test-dl test-lrpath1 test-lrpath2 test-lsoname1 test-lsoname2 test-lsymver1 test-lsymver2
.SECONDARY:
clean:
rm -rf 1 2 libuse* libdef* test-* foo*.o
test-dl: test.c
gcc $< -ldl -o $@
# -fuse-ld=gold should only be necessary on Ubuntu 14.04
test-l%: test.c libuse%.so
gcc -DWITH_LINK='"$*"' -fuse-ld=gold -L. $< -luse$* -ldl -o $@
libuserpath%.so: %/libdefrpath.so
gcc -fPIC -shared -DWITH_VERSION=$* -L$* -Wl,-rpath,./$* usever.c -ldefrpath -o $@
1 2:
mkdir -p $@
%/libdefrpath.so: foo%.o %
gcc -shared $< -o $@
libusesoname%.so: libdefsoname.so.%
ln -sf $< libdefsoname.so
gcc -fPIC -shared -DWITH_VERSION=$* -L. usever.c -ldefsoname -o $@
libdefsoname.so.%: foo%.o
gcc -shared -Wl,-h,$@ $< -o $@
libusesymver%.so: libdefsymver.so
gcc -fPIC -shared -DWITH_VERSION=$* -DWITH_SYMVER='"$*"' -L. usever.c -ldefsymver -o $@
libdefsymver.so: foo1.symver.o foo2.symver.o symver.map
gcc -shared -Wl,-z,muldefs -Wl,--version-script,symver.map foo1.symver.o foo2.symver.o -o $@
foo%.o: foo%.c
gcc -fPIC -c $< -o $@
foo%.symver.o: foo%.c
gcc -fPIC -DSYMVER -c $< -o $@
#include <stdio.h>
#ifdef SYMVER
__asm__(".symver foo,foo@VERS_1.1");
#endif
void foo() {
puts("Hello from foo 1");
}
#include <stdio.h>
#ifdef SYMVER
__asm__(".symver foo,foo@VERS_1.2");
#endif
void foo() {
puts("Hello from foo 2");
}
VERS_1.1 { foo; };
VERS_1.2 { foo; };
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dlfcn.h>
#ifdef WITH_LINK
extern void use_foo();
#endif
static void call_foo(const char* arg) {
#ifdef WITH_LINK
if (0==strcmp(arg,"lt")) {
puts("call_foo using link-time linkage:");
use_foo();
} else
#endif
if (0==strncmp(arg,"dl,",3)) {
printf("call_foo using %s:\n",arg);
arg+=3;
int flags=RTLD_LOCAL;
if (0==strncmp(arg,"lazy,",5)) {
arg+=5;
flags|=RTLD_LAZY;
} else if (0==strncmp(arg,"now,",4)) {
arg+=4;
flags|=RTLD_NOW;
} else {
puts("Must specify lazy or now!");
return;
}
void* lib;
int pseudo_lib=1;
if (0==strcmp(arg,"default")) {
lib=RTLD_DEFAULT;
} else if (0==strcmp(arg,"next")) {
lib=RTLD_NEXT;
} else {
lib=dlopen(arg,flags);
pseudo_lib=0;
}
if (pseudo_lib || lib) {
void* fun=dlsym(lib,"use_foo");
if (fun)
((void(*)())fun)();
else
puts("Error in dlsym");
if (!pseudo_lib) dlclose(lib);
} else {
puts("Error in dlopen");
}
} else {
printf("Unknown call style: %s\n",arg);
}
}
void main(int argc, char** argv) {
if (argc==1) {
printf("Usage: %s "
#ifdef WITH_LINK
"lt|"
#endif
"dl,(lazy|now),(default|next|libname.so) ...\n",argv[0]);
return;
}
printf("WITH_LINK: %s\n",
#ifdef WITH_LINK
WITH_LINK
#else
"(undefined)"
#endif
);
printf("LD_LIBRARY_PATH: %s\n",getenv("LD_LIBRARY_PATH"));
int i;
for (i=1;i<argc;i++) call_foo(argv[i]);
FILE* fp=fopen("/proc/self/maps","r");
if (fp) {
char buf[4096];
size_t bytes_read;
while (!feof(fp)) {
bytes_read=fread(buf,1,sizeof(buf),fp);
fwrite(buf,1,bytes_read,stdout);
}
}
}
#include <stdio.h>
#ifdef WITH_SYMVER
__asm__(".symver foo,foo@VERS_1." WITH_SYMVER);
#endif
extern void foo();
void use_foo() {
printf("Hello from use_foo WITH_VERSION=%d\n",WITH_VERSION);
foo();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment