#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
extern int interposableFoo();
extern int interposableBar();
extern int callFunc();
static int tryImage(const char* path, int expectedFoo, int expectedBar)
{
void* handle = dlopen(path, RTLD_LAZY);
if ( handle == NULL ) {
printf("dlerror(): %s\n", dlerror());
printf("[FAIL] interpose-then-dlopen %s\n", path);
return 1;
}
__typeof(&callFunc) callFooSym = (__typeof(&callFunc))dlsym(handle, "callFoo");
if ( callFooSym == NULL ) {
printf("dlerror(): %s\n", dlerror());
printf("[FAIL] interpose-then-dlopen %s\n", path);
return 1;
}
int fooResult = callFooSym();
if ( fooResult != expectedFoo ) {
printf("[FAIL] interpose-then-dlopen callFoo() from %s not interposed as it returned %d\n", path, fooResult);
return 1;
}
__typeof(&callFunc) callBarSym = (__typeof(&callFunc))dlsym(handle, "callBar");
if ( callBarSym == NULL ) {
printf("dlerror(): %s\n", dlerror());
printf("[FAIL] interpose-then-dlopen %s\n", path);
return 1;
}
int barResult = callBarSym();
if ( barResult != expectedBar ) {
printf("[FAIL] interpose-then-dlopen callBar() from %s not interposed as it returned %d\n", path, barResult);
return 1;
}
return 0;
}
int main()
{
printf("[BEGIN] interpose-then-dlopen\n");
if (tryImage(RUN_DIR "/libfoo.dylib", 4, 2))
return 0;
if (tryImage(RUN_DIR "/libbar.bundle", 4, 100))
return 0;
printf("[PASS] interpose-then-dlopen\n");
return 0;
}