内容简介:翻译自:https://stackoverflow.com/questions/39744926/how-can-i-compile-a-rust-program-so-it-doesnt-use-cxa-thread-atexit-impl
-gnueabihf编译了一个Rust程序,我想让它在安装了glibc 2.16的系统上运行.不幸的是,在运行它时我收到此错误:
./foo: /lib/libc.so.6: version `GLIBC_2.18' not found (required by ./foo)
运行objdump -T foo表明glibc 2.18需要的唯一符号是:
00000000 w DF *UND* 00000000 GLIBC_2.18 __cxa_thread_atexit_impl
Rust makes __cxa_thread_atexit_impl
a weak symbol
(从objdump的小w旗看到),然而GCC显然是愚蠢的,尽管GLIBC_2.18中的所有符号都很弱,但仍然使GLIBC_2.18本身成为强烈要求.你可以用readelf看到:
$readelf -V foo ... Version needs section '.gnu.version_r' contains 5 entries: Addr: 0x0000000000001e4c Offset: 0x001e4c Link: 6 (.dynstr) 000000: Version: 1 File: ld-linux-armhf.so.3 Cnt: 1 0x0010: Name: GLIBC_2.4 Flags: none Version: 9 0x0020: Version: 1 File: librt.so.1 Cnt: 1 0x0030: Name: GLIBC_2.4 Flags: none Version: 5 0x0040: Version: 1 File: libgcc_s.so.1 Cnt: 4 0x0050: Name: GCC_4.3.0 Flags: none Version: 10 0x0060: Name: GCC_3.0 Flags: none Version: 7 0x0070: Name: GCC_3.5 Flags: none Version: 6 0x0080: Name: GCC_3.3.1 Flags: none Version: 4 0x0090: Version: 1 File: libc.so.6 Cnt: 2 0x00a0: Name: GLIBC_2.18 Flags: none Version: 8 0x00b0: Name: GLIBC_2.4 Flags: none Version: 3 0x00c0: Version: 1 File: libpthread.so.0 Cnt: 1 0x00d0: Name: GLIBC_2.4 Flags: none Version: 2
请注意,GLIBC_2.18说Flags:none.应该说Flags:WEAK.幸运的是我找到了 an amazing page where someone shows how to fix this .不幸的是它涉及十六进制编辑二进制文件!
获取.gnu.version_r表(0x001e4c)的偏移量,为GLIBC_2.18(0x00a0)添加条目偏移量,然后在该地址(0x04)处为结构的flags字段添加偏移量.这给出了0x001EF0.在该地址处应该有两个零字节:0x0000.将它们更改为0x0200.
使用readelf验证:
Version needs section '.gnu.version_r' contains 5 entries: Addr: 0x0000000000001e4c Offset: 0x001e4c Link: 6 (.dynstr) 000000: Version: 1 File: ld-linux-armhf.so.3 Cnt: 1 0x0010: Name: GLIBC_2.4 Flags: none Version: 9 0x0020: Version: 1 File: librt.so.1 Cnt: 1 0x0030: Name: GLIBC_2.4 Flags: none Version: 5 0x0040: Version: 1 File: libgcc_s.so.1 Cnt: 4 0x0050: Name: GCC_4.3.0 Flags: none Version: 10 0x0060: Name: GCC_3.0 Flags: none Version: 7 0x0070: Name: GCC_3.5 Flags: none Version: 6 0x0080: Name: GCC_3.3.1 Flags: none Version: 4 0x0090: Version: 1 File: libc.so.6 Cnt: 2 0x00a0: Name: GLIBC_2.18 Flags: WEAK Version: 8 0x00b0: Name: GLIBC_2.4 Flags: none Version: 3 0x00c0: Version: 1 File: libpthread.so.0 Cnt: 1 0x00d0: Name: GLIBC_2.4 Flags: none Version: 2
成功!除了它仍然不起作用:
./foo: /lib/libc.so.6: weak version `GLIBC_2.18' not found (required by ./foo) ./foo: relocation error: ./foo: symbol __cxa_thread_atexit_impl, version GLIBC_2.18 not defined in file libc.so.6 with link time reference
弱版本如何仍然需要?!我等不及glibc死了.
有没有办法让Rust在不使用此符号的情况下构建程序?
你需要一个为glibc 2.16或更早版本编译的Rust工具链. glibc 2.17可能也有效,因为它缺少__cxa_thread_atexit_impl,因此它不会在二进制文件中携带GLIBC_2.18符号版本.
在Rust代码中使用弱符号并不是特别有用,因为GNU的特定版本的ELF符号版本控制没有弱符号版本.我们最终可能会改变它,但是现在,解决这个问题的最好方法是使用足够旧的 工具 链进行编译.
另一种选择是将符号反向移植到您使用的glibc中.这应该是一个相当孤立的backport,可能包含这些提交:
> Avoid unconditional __call_tls_dtors calls in static linking.
> Also use l_tls_dtor_count to decide on object unload (BZ #18657)
> Harden tls_dtor_list with pointer mangling [BZ #19018]
(我没有尝试过后退到glibc 2.16,但就这些事情而言,看起来并不是特别困难.)
翻译自:https://stackoverflow.com/questions/39744926/how-can-i-compile-a-rust-program-so-it-doesnt-use-cxa-thread-atexit-impl
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
程序员2005精华本
《程序员》杂志社 / 电子工业 / 2006-1 / 45.00元
本书为集结了《程序员》杂志与《msdn开发精选》杂志精华。分上、下两册,内容包括人物&报道、管理与实践、程序员手册、年鉴、《程序员》技术专题、《msdn开发精选》文章精选等。一起来看看 《程序员2005精华本》 这本书的介绍吧!