You could automatically generate trampoline functions for all symbols in dlopen
-ed library. Trampolines would be seen as normal functions in application but would internally redirect to real code in library. Here's a simple 5-minute PoC:
$ cat lib.h
// Dynamic library header
#ifndef LIB_H
#define LIB_H
extern void foo(int);
extern void bar(int);
extern void baz(int);
#endif
$ cat lib.c
// Dynamic library implementation
#include <stdio.h>
void foo(int x) {
printf("Called library foo: %d
", x);
}
void bar(int x) {
printf("Called library baz: %d
", x);
}
void baz(int x) {
printf("Called library baz: %d
", x);
}
$ cat main.c
// Main application
#include <dlfcn.h>
#include <stdio.h>
#include <lib.h>
// Should be autogenerated
void *fptrs[100];
void init_trampoline_table(void *h) {
fptrs[0] = dlsym(h, "foo");
fptrs[1] = dlsym(h, "bar");
fptrs[2] = dlsym(h, "baz");
}
int main() {
void *h = dlopen("./lib.so", RTLD_LAZY);
init_trampoline_table(h);
printf("Calling wrappers
");
foo(123);
bar(456);
baz(789);
printf("Returned from wrappers
");
return 0;
}
$ cat trampolines.S
// Trampoline code.
// Should be autogenerated. Each wrapper gets its own index in table.
// TODO: abort if table wasn't initialized.
.text
.globl foo
foo:
jmp *fptrs
.globl bar
bar:
jmp *fptrs+8
.globl baz
baz:
jmp *fptrs+16
$ gcc -fPIC -shared -O2 lib.c -o lib.so
$ gcc -I. -O2 main.c trampolines.S -ldl
$ ./a.out
Calling wrappers
Called library foo: 123
Called library baz: 456
Called library baz: 789
Returned from wrappers
Note that application code in main.c
is using only local functions (which wrap library functions) and does not have to mess with function pointers at all (apart from initializing redirection table at startup which should be autogenerated code anyway).
EDIT: I've created a standalone tool Implib.so to automate creation of stub libraries like in example above. This turned out to be more or less equivalent to well known Windows DLL import libraries.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…