在OS X上链接期间包装符号

时间:2016-09-11 23:22:41

标签: c++ macos gcc shared-libraries ld

我试图在链接期间将一个符号换成另一个符号。据我所知,这很容易用ld --wrap选项完成,但在OS X上它不可用。有' -idefinition:indirection',这里我是如何欺骗主要因此它将打印42:

a.cpp:

int foo() {
    return 1;
}

b.cpp:

int wrap_foo() {
    return 42;
}

main.cpp:

#include <cstdio>

int foo();
int wrap_foo();

int main() {
    printf("%d\n", foo());
}

我如何构建和链接它们:

$ gcc -c *.cpp
$ gcc -Wl,-i__Z3foov:__Z8wrap_foov *.o
duplicate symbol __Z3foov in:
    a.o
    b.o
ld: 1 duplicate symbol for architecture x86_64

甚至可以实现我想要的目标吗?

编辑: 在我的任务中,我无法控制a.cpp和main.cpp(只有对象),但我可以编写任何代码,并在链接之前对对象执行任何操作。

我发现之前的quistion与之类似的任务相关(并且更好地描述了) GNU gcc/ld - wrapping a call to symbol with caller and callee defined in the same object file 重读答案我看到案例是相同的,符号已经存在,我将发生碰撞。

如何在不触及源代码的情况下从a.o中删除foo?

1 个答案:

答案 0 :(得分:2)

这是否必须在链接与运行时完成?请注意完全确定您要尝试做什么,所以只是问。

使用该链接器命令的问题是它会创建一个新符号,这就是获得重复符号的原因。

-alias symbol_name alternate_symbol_name
                 Create an alias named alternate_symbol_name for the symbol
                 symbol_name.  By default the alias symbol has global visibil-
                 ity.  This option was previous the -idef:indir option.

如果你没有定义foo的a.cpp(即你省略了foo),你可以这样做:

tmp$ gcc -Wl,-alias,__Z8wrap_foov,__Z3foov b.o main.o
tmp$ ./a.out
42

你总能做的是让.cpp有另一个foo,如original_foo。这样,如果您想要该实现,可以使用别名将其映射到foo。不完美,但它会大致达到你想要的效果。您已经完成了在链接上调整它的努力,所以它似乎是可以接受的。