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

Clo*_*oud 3 c linker gcc static-libraries objcopy

背景

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

for i in pineapple coconut banana
do
    objcopy --prefix-symbols=${i}_ lib${i}.a
done
Run Code Online (Sandbox Code Playgroud)

现在,我拥有三个具有独特符号的库,并且可以继续编写标头来处理每个库的三个近乎重复的标头/API 文件。


问题

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

Emp*_*ian 5

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

取决于“安全针对什么”。

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

是的,请参见下文。

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

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

库本身内对符号的所有引用是否都会自动更正

是的,他们是。该--prefix-symbols标志会更改定义和未解析的引用(这将导致问题,您很快就会看到)。

IFF 库是完全独立的(除了它本身定义的符号之外,不引用任何符号),然后为所有符号添加前缀将起作用:新重命名的未解析引用现在将调用而不是pineapple_foofoo并且该引用将在链接时解析为根据需要使用新名称重命名的定义。

libc当目标库调用其自身之外的某些内容(例如来自 的任何内容)时,就会出现麻烦。这些调用pineapple_open将带有前缀,因此您将获得对, 或 之类的未解析引用pineapple_printf

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

int pineapple_open(const char *filename, int flag, int mode)
{
   return open(filename, flag, mode);
}
Run Code Online (Sandbox Code Playgroud)

这很乏味,但适用于功能。它破坏的地方是全局变量:errnoh_errno等。

既然您提到了-fPIC,请注意动态库支持取决于_GLOBAL_OFFSET_TABLE_您也不希望重命名。