如何重新打包 gnu gcc 标准库 stdc++、gcc 和 gcc_eh?
在不修改和重新编译 gnu gcc 和 stdc++ 库构建的情况下,我需要能够使用不同的嵌入 soname 重现这些库的动态加载版本。
我想我会很聪明,使用可用的静态版本并用如下内容重新打包它们: ld -E -shared -static "-lstdc++" -lgcc -lgcc_eh -o librepackaged_standard.so
librepacked_standard.so 已创建,没有警告或错误,但 ldd 报告它不是动态库,而 readelf 仅报告这些基本符号:
Symbol table '.symtab' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000201000 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
2: 0000000000201000 0 NOTYPE GLOBAL DEFAULT ABS _edata
3: 0000000000201000 0 NOTYPE GLOBAL DEFAULT ABS _end
我不确定为什么 ld 没有引入所有静态定义的符号。我也不知道是否需要提供任何其他特殊参数才能使其正常工作。
另一种选择是,是否有一种已知的跨平台方法来简单地更改嵌入原始 elf 库中的 soname。我目前只关心 elf 格式的二进制文件。我对编写自己的工具来更改现有二进制文件中的 .soname 不感兴趣。
更新: 没有编译任何符号的原因是 ld
处理静态二进制文件的方式与 .o 文件不同。默认情况下,它不会从 .a 文件导入任何符号,除非链接线上的另一个库需要它们。我通过提供 --whole-archive 选项修复了这个问题。
然而,这给了我另一个错误,在创建共享对象时不能使用relocation R_X86_64_32S against
_ZSt12_S_first_one';使用 -fPIC和
重新编译无法读取符号:错误值` 它们都来自 bitset.o 存档中的 libstdc++.a。因此,我不能只是将 .a 重新编译为动态库,因为默认情况下,GNU GCC 编译不会使用 PIC 选项编译用于静态库的目标文件。
这让我不得不寻找一个 elf 工具或重新编译 GNU GCC 并对其构建进行修改。
正如其中一个答案所述,许可问题可能是任何这些方法的一个问题。我最好的答案是,我们需要改变我们的需求,并找到一个不涉及以任何方式更改或重新打包 GCC 标准库的不同解决方案。
Without modifying and recompiling the gnu gcc and stdc++ library builds, I need to be able to reproduce dynamic loading versions of those libraries with a different embedded soname.
I thought I would be clever and use the available static versions and repackage them with something like this:ld -E -shared -static "-lstdc++" -lgcc -lgcc_eh -o librepackaged_standard.so
librepacked_standard.so is created, without warnings or errors, but ldd reports its not a dynamic library and readelf reports only these basic symbols:
Symbol table '.symtab' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000201000 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
2: 0000000000201000 0 NOTYPE GLOBAL DEFAULT ABS _edata
3: 0000000000201000 0 NOTYPE GLOBAL DEFAULT ABS _end
I am unsure why ld isn't bringing in all of the symbols defined statically. I also don't know if there are any other special parameters I need to give it for this to work.
Another option is if there is a know cross platform way to simply change the soname embedded in the original elf libraries. I'm currently only concerned with elf formatted binaries. I am not interested in writting my own tool to change the .soname in existing binaries.
UPDATE:
The reason no symbols were getting compiled is because ld
handles static binaries differently than .o files. By default it does not import any symbols from the .a file unless they are required by a another library on the link line. I fixed that by provided the --whole-archive option.
However that gives me another error, relocation R_X86_64_32S against
_ZSt12_S_first_one' can not be used when making a shared object; recompile with -fPICand
could not read symbols: Bad value` They are both from libstdc++.a in the bitset.o archive. So I can't just recompile the .a's into a dynamic library because the GNU GCC compile, by default, does not compile the object files used for the static libraries with the PIC option.
That leaves me with finding an elf tool or recompiling GNU GCC with modifications to its build.
As stated by one of the answers, licensing issues could be a concern with any of these approaches. My best answer is that we need to change to our requirements and find a different solution that doesn't involve changing or repackaging the GCC standard libraries in any fashion.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
没有符号被编译到共享库中的原因是
ld
处理静态二进制文件的方式与 .o 文件不同。默认情况下,它不会从 .a 文件导入任何符号,除非链接线上的另一个库需要它们。该特定问题的答案是使用 --whole-archive 选项并直接链接 .a 文件通常有效。但是,要使其工作,静态存档中包含的 .o 文件需要在编译时使用 -fPIC 选项进行编译。但是,用于静态库的目标文件不是使用可用静态库中的该选项进行编译的。
因此,更改 SONAME 的解决方案是使用 ELF 二进制实用程序或重建修改后的 GNU GCC 以使用不同的 SONAME。
由于在这种情况下存在许可问题,任何解决方案对于该项目都不实用,因为它不是开源的,并且我们不希望要求为我们的所有平台重新分发 GNU GCC 的修改源版本。
The reason no symbols were getting compiled into the shared library is because
ld
handles static binaries differently than .o files. By default it does not import any symbols from the .a file unless they are required by a another library on the link line. The answer to that particular issue is to use the --whole-archive option and linking the .a files directly mostly works.However, for this to work the .o files included in the static archive need to have been compiled using the -fPIC option at compile time. However the object files used for the static libraries are not compiled with that option in the static libraries available.
So, the solution to changing the SONAME is to use an ELF binary utility or rebuilding GNU GCC modified to use different SONAMEs.
Since there are licensing concerns in this situation any of the solutions are not practical for the project because it is not open source and we do not want the requirement to redistribute a modified source version of GNU GCC for all our platforms.
-static
可能会取消-shared
。-static
probably undid the-shared
.