我已经为armv7-unknown-linux-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将__cxa_thread_atexit_impl
设置为弱符号(通过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
。幸运的是,我找到了一篇神奇的网页,在这个网页上有人展示了如何修复此问题。不幸的是,它涉及对二进制文件进行十六进制编辑!取出那个
.gnu.version_r
表的偏移量(0x001e4c
),加上GLIBC_2.18
的项偏移量(0x00a0
),然后再加上该地址处结构体的标志字段的偏移量(0x04
)。这将得到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构建程序?
armv7-unknown-linux-muscl
目前还不可用作目标。如果我能让它工作,那么要求 glibc 2.4 是合理的,因为它已经足够老(2006年),并且与 muscl 相比可以节省空间。如果没有办法避免需要 2.18(2013年),那么 muscl 明显是更好的选择。 - Timmmmarmv7-unknown-linux-musclabihf
! - Timmmm