Ich habe ein Rust-Programm für armv7-unknown-linux-gnueabihf
kompiliert, und ich möchte, dass es auf einem System läuft, auf dem glibc 2.16 installiert ist. Leider bekomme ich, wenn es ausgeführt wird diesen Fehler:Wie kann ich ein Rust-Programm kompilieren, so dass es __cxa_thread_atexit_impl nicht verwendet?
./foo: /lib/libc.so.6: version `GLIBC_2.18' not found (required by ./foo)
Lauf objdump -T foo
zeigt, dass das einzige Symbol von glibc 2.18 erforderlich ist:
00000000 w DF *UND* 00000000 GLIBC_2.18 __cxa_thread_atexit_impl
Rust makes __cxa_thread_atexit_impl
a weak symbol (wie die kleine w
Flagge von objdump
gesehen), aber GCC ist offensichtlich dumm und obwohl alle Symbole von GLIBC_2.18 schwach sind, macht GLIBC_2.18 selbst immer noch eine starke Anforderung. Sie können sehen, dass mit 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
Beachten Sie, dass GLIBC_2.18
sagt Flags: none
. Es sollte Flags: WEAK
sagen. Glücklicherweise fand ich an amazing page where someone shows how to fix this. Leider beinhaltet es hex bearbeiten die binäre!
die dieser .gnu.version_r
Tabellenversatzes Nimm (0x001e4c
), fügen Sie den für GLIBC_2.18
(0x00a0
) Offset-Eintrag, dann ein für das Flags-Feld der Struktur an dieser Adresse (0x04
) Offsetzumischung. Das gibt 0x001EF0
. Bei dieser Adresse sollte es zwei Nullbytes geben: 0x0000
. Ändern Sie sie in 0x0200
.
Stellen Sie sicher, mit 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
Erfolg! Außer es immer noch nicht funktioniert:
./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
Wie ist die schwach Version noch erforderlich ?! Ich kann nicht darauf warten, dass glibc stirbt.
Gibt es eine Möglichkeit, Rust das Programm zu erstellen, ohne dieses Symbol zu verwenden?
Zu akzeptieren, wenn die Dinge schrecklich sind, ist der einzige Weg (sie werden verbessert) (https://www.musl-libc.org/). Entschuldigung, wenn ich irgendwelche GNU-Entwickler beleidigt habe. – Timmmm
Sie beleidigen absichtlich die * sehr * Leute, die Ihre Frage beantworten können. Ich werde @tumdum als zweites vorschlagen und vorschlagen, dass Sie die kontraproduktiven Teile entfernen. Als Teilantwort gibt es * gute Gründe, warum GLIBC so funktioniert. Und wenn Sie glauben, dass Musl die Antwort ist, was hindert Sie daran, es zu benutzen? –
'armv7-unknown-linux-muscl' ist leider noch nicht als Ziel verfügbar. Auch wenn ich * das * zur Arbeit bringen kann, ist glibc 2.4 alt genug (2006), was es nicht unangemessen macht und es spart Platz im Vergleich zu Muscl. Wenn es keinen Weg gibt, 2.18 (2013) zu fordern, dann ist muscl definitiv eine bessere Option. – Timmmm