All problems in computer science can be solved by another level of indirection. (Butler Lampson)
call *TABLE[printf@symtab]
#define foo@symtab 1 #define printf@symtab 2 ... void *TABLE[N_SYMBOLS]; void load(struct loader *ld) { TABLE[foo@symtab] = ld->resolve("foo"); TABLE[foo@printf] = ld->resolve("printf"); ... }
Offset Info Type Sym. Name + Addend ... 000000003fe0 000300000006 R_X86_64_GLOB_DAT printf@GLIBC_2.2.5 + 0 ...
int printf(const char *, ...); void foo();
ff 25 00 00 00 00 call *FOO_OFFSET(%rip)
e8 00 00 00 00 call <reloc>
printf@plt: jmp *PRINTF_OFFSET(%rip)
extern int x
mov $1, offset_of_x(%rip)
mov GOT[x], %rdi mov $1, (%rdi)
__attribute__((visibility("hidden")))
LD_PRELOAD=./mylib.so ./a.out