objcopy对静态库的不可预见的后果

时间:2017-11-23 22:34:11

标签: c gcc linker static-libraries objcopy

背景

我有一组三个几乎相同的静态库(用-fPIC编译),我无法重新编译它们。所有库都导出相同的符号,因此我可以将它们捆绑在一起的唯一方法是通过objcopy修改带有每个静态库前缀的符号,即:

for i in pineapple coconut banana
do
    objcopy --prefix-symbols=${i}_ lib${i}.a
done

现在,我有三个带有唯一符号的库,并且可以继续编写标题来处理每个库的三个近似重复的头文件/ API文件。

问题

只是重命名一个像这样安全的库的导出符号吗?它是否有任何“陷阱”或不可预见的后果可能导致运行时的稳定性问题?是否所有对库中符号的引用都会自动更正,或者某些库代码(除了dlsym()调用之外)是否会尝试引用旧符号和段错误?

2 个答案:

答案 0 :(得分:2)

  

只是重命名一个像这样安全的库的导出符号吗?

取决于“安全抵御什么”。

  

是否有任何“陷阱”或不可预见的后果

是的,见下文。

  

可能会在运行时导致稳定性问题?

没有。如果您设法链接最终的二进制文件(一个大的IF),那么生成的二进制文件将起作用。

  

对库中符号的所有引用都是自动更正的

是的,他们是。 --prefix-symbols标志会更改定义和未解析的引用(这会导致问题,因为您会立即看到)。

IFF库是完全自包含的(不引用除它自己定义的符号之外的任何符号),然后前缀所有符号都可行:新重命名的未解析引用现在将调用{{1而不是pineapple_foo,此引用将在链接时使用新名称解析为重命名的定义,正如所需。

当目标库调用自身之外的东西时(例如来自foo的任何东西),就会出现问题。这些调用会带有前缀,因此您将获得对libcpineapple_open等内容的未解析引用。

您可能会想:我只会在其他地方提供替代品:

pineapple_printf

这很乏味,但适用于功能。它突破的地方是全局变量:int pineapple_open(const char *filename, int flag, int mode) { return open(filename, flag, mode); } errno等等。

由于您提到了h_errno,请注意动态库支持取决于您不想重命名的-fPIC

答案 1 :(得分:0)

假设库是从多个源文件构造的,从库中导出的符号几乎肯定会被库中的其他位置引用。因此,更改符号名称将导致以后出现链接问题。