【问题标题】:Wrapping symbols during linking on OS X在 OS X 上链接期间包装符号
【发布时间】:2017-01-19 09:01:42
【问题描述】:

我试图在链接过程中将一个符号换成另一个符号。据我了解,使用 ld --wrap 选项很容易做到这一点,但在 OS X 上它不可用。有'-idefinition:indirection',这里我试图欺骗main,所以它会打印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(只有它们的对象),但我可以编写任何代码并在链接之前对对象执行任何我需要的操作。

我发现了以下与类似任务相关的问题(并且更好地描述了它) GNU gcc/ld - wrapping a call to symbol with caller and callee defined in the same object file 重读答案,我发现情况相同,符号已经存在,我会发生冲突。

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

【问题讨论】:

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


    【解决方案1】:

    这是否必须在链接而不是运行时完成?请注意完全确定您要执行的操作,因此只需询问即可。

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

    -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
    

    您总是可以让 a.cpp 拥有另一个 foo,例如 original_foo。这样,如果您想要该实现,您可以使用别名将其映射到foo。不完美,但它会大致达到你想要的。您已经在链接处进行了调整,因此它看起来可能是可以接受的。

    【讨论】:

    • 您可以尝试使用 binutils 或 crosstool-ng (homebrew)。它们都包含 objcopy。 objcopy 可让您去除符号。
    • 顺便说一句,您可能只想更改符号的名称,以防它在您拥有的 .o 中的其他地方实际引用。
    • 我终于从 crosstool-ng 解决了我的 gobjcopy 问题
    猜你喜欢
    • 1970-01-01
    • 2014-03-31
    • 1970-01-01
    • 1970-01-01
    • 2016-12-20
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多