macOS 上的符号插入

Symbol interposition on macOS

我有一个链接到共享库的程序 libfoo。我想在我的程序中覆盖 libfoo 中的一个函数,以便从 libfoo 中对该函数的内部调用解析为我程序中的定义。 (对于上下文,我的目的是模拟库函数以进行测试。)

这个问题与这个问题有点相关:。这是该问题的示例:

// foo.c
void dispatch_write_hello(void) {
    fprintf(stderr, "hello\n");
}

void print_hello(void) {
    dispatch_write_hello();
}

// main.c
extern void print_hello(void);

void dispatch_write_hello(void) {
    fprintf(stderr, "overridden\n");
}

int main(int argc, char **argv) {
    print_hello();
    return 0;
}

这是它在 linux 上的作用:

$ clang -shared -fPIC foo.c -o libfoo.so
$ clang main.c -L. -lfoo
$ LD_LIBRARY_PATH=. ./a.out
overridden

这是我想要的行为,但在 macOS 上我得到了这个:

$ clang -dynamiclib -fPIC foo.c -o libfoo.dylib
$ clang main.c -L. -lfoo
$ ./a.out
hello

如何在 macOS 上实现 linux 示例的行为?最好我想要一种适用于 linux 和 macOS 的方法,但我想如果我需要使用特定于 macOS 的构建标志 and/or 环境变量也没关系。

我可以通过在构建库时添加 -Wl,-flat_namespace 来实现这一点。

(我还尝试了一些来自互联网的其他民间传说,包括 -Wl,-force_flat_namespace 链接程序时,或 运行 使用 DYLD_FORCE_FLAT_NAMESPACE=1 的程序,但似乎都不起作用。)