内容简介:翻译自: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
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Hacking Growth
Sean Ellis、Morgan Brown / Crown Business / 2017-4-25 / USD 29.00
The definitive playbook by the pioneers of Growth Hacking, one of the hottest business methodologies in Silicon Valley and beyond. It seems hard to believe today, but there was a time when Airbnb w......一起来看看 《Hacking Growth》 这本书的介绍吧!
图片转BASE64编码
在线图片转Base64编码工具
HSV CMYK 转换工具
HSV CMYK互换工具