我有一组三个几乎相同的静态c库(用-fPIC
编译),我无法重新编译它们。所有库都导出相同的符号,因此我可以将它们捆绑在一起的唯一方法是通过objcopy
修改带有每个静态库前缀的符号,即:
for i in pineapple coconut banana
do
objcopy --prefix-symbols=${i}_ lib${i}.a
done
现在,我有三个带有唯一符号的库,并且可以继续编写标题来处理每个库的三个近似重复的头文件/ API文件。
只是重命名一个像这样安全的库的导出符号吗?它是否有任何“陷阱”或不可预见的后果可能导致运行时的稳定性问题?是否所有对库中符号的引用都会自动更正,或者某些库代码(除了dlsym()
调用之外)是否会尝试引用旧符号和段错误?
答案 0 :(得分:2)
只是重命名一个像这样安全的库的导出符号吗?
取决于“安全抵御什么”。
是否有任何“陷阱”或不可预见的后果
是的,见下文。
可能会在运行时导致稳定性问题?
没有。如果您设法链接最终的二进制文件(一个大的IF),那么生成的二进制文件将起作用。
对库中符号的所有引用都是自动更正的
是的,他们是。 --prefix-symbols
标志会更改定义和未解析的引用(这会导致问题,因为您会立即看到)。
IFF库是完全自包含的(不引用除它自己定义的符号之外的任何符号),然后前缀所有符号都可行:新重命名的未解析引用现在将调用{{1而不是pineapple_foo
,此引用将在链接时使用新名称解析为重命名的定义,正如所需。
当目标库调用自身之外的东西时(例如来自foo
的任何东西),就会出现问题。这些调用也会带有前缀,因此您将获得对libc
或pineapple_open
等内容的未解析引用。
您可能会想:我只会在其他地方提供替代品:
pineapple_printf
这很乏味,但适用于功能。它突破的地方是全局变量:int pineapple_open(const char *filename, int flag, int mode)
{
return open(filename, flag, mode);
}
,errno
等等。
由于您提到了h_errno
,请注意动态库支持取决于您不想重命名的-fPIC
。
答案 1 :(得分:0)
假设库是从多个源文件构造的,从库中导出的符号几乎肯定会被库中的其他位置引用。因此,更改符号名称将导致以后出现链接问题。