3
使用Xcode时,我正在寻找从mach-o包二进制文件中重新导出符号(一个函数),其中符号最初在dylib。如何从依赖包中重新导出dylib符号
我已经试过-sub_library链接器开关,但似乎并没有再出口的dylib符号,可能是因为我不是建立一个dylib我自己(?)
而再出口-L/reexport_library开关似乎在Xcode的链接器中不受支持。
任何想法?
使用Xcode时,我正在寻找从mach-o包二进制文件中重新导出符号(一个函数),其中符号最初在dylib。如何从依赖包中重新导出dylib符号
我已经试过-sub_library链接器开关,但似乎并没有再出口的dylib符号,可能是因为我不是建立一个dylib我自己(?)
而再出口-L/reexport_library开关似乎在Xcode的链接器中不受支持。
任何想法?
如果我正确地理解了你,这可能就是你要找的。我将使用libpthread作为包含想要重新导出的函数的假想dylib。
mybundle.c:
#include <pthread.h>
#include <stdio.h>
void *foo(void *ctx) {
puts((char *)ctx);
return 0;
}
mybundle.exp:
_foo
_pthread_create
_pthread_join
编译束,动态链接到libpthread.dylib:
josh$ gcc -bundle -lpthread -Wl,-exported_symbols_list,mybundle.exp -o mybundle.so mybundle.c
myloader.c:
#include <dlfcn.h>
#include <pthread.h> // merely for type definitions
#include <assert.h>
#include <stdio.h>
int main() {
void *(*foo)(void *ctx);
/* the following cannot be declared globally without changing their names,
as they are already (and unnecessarily) declared in <pthread.h> */
int (*pthread_create)(pthread_t *thrd, const pthread_attr_t *attr, void *(*proc)(void *), void *arg);
int (*pthread_join)(pthread_t thrd, void **val);
void *bundle;
assert(bundle = dlopen("mybundle.so", RTLD_NOW));
assert(foo = dlsym(bundle, "foo"));
assert(pthread_create = dlsym(bundle, "pthread_create"));
assert(pthread_join = dlsym(bundle, "pthread_join"));
pthread_t myThrd;
pthread_create(&myThrd, 0, foo, "in another thread");
pthread_join(myThrd, 0);
return 0;
}
编译装载机:
josh$ gcc myloader.c -o myloader
运行:
josh$ ./myloader
in another thread
观察到myloader是没有办法连接到并行线程,但并行线程功能的加载和通过捆绑包在运行时可用。
感谢jrodatus。我真的很感兴趣从我的包中导出一个符号,它将直接指向它所链接的dylib中的地址。 – Danra
@Danra,根据定义,链接到dylib的AFAIK意味着dylib代码实际上并不包含在bundle中,只有在运行时重定向的“dyld stub”函数存在。任何dylib函数的地址,无论是puts(),printf()还是pthread_create(),在编译时都是不确定的,仅在运行时由dylinker决定。例如,甚至来自foo()的puts()调用实际上也不会引用dylib中的地址,而只是调用dylinker以获取该系统在该运行时恰好具有的任何地址puts()的存根函数的地址(见'otool -tV')。 – jrodatus
@Danra,...因此,在我看来,你可以要求的最好的办法是从bundle中导出本地的dyld存根地址,这就是我的代码所做的(如果我没有弄错的话)。在任何编译的二进制文件上运行'nm'会将链接的dylib驻留函数列为“U”(未定义),因为它们的代码在编译时不存在,因此它们的符号地址是未确定的。或者,也许我只是误解了你? – jrodatus