2018-12-15 02:20
Linux/x32
Pro-Linux berichtet heute von Bestrebungen, die Unterstützung für das x32 ABI aus Linux zu entfernen.
Das x32 ABI ist ein Binärformat für Linux auf Intel-kompatiblen Prozessoren. Es ist als ein Versuch gestartet worden, die Vorteile von i386 und amd64 zu verbinden. x32-Programm laufen nur auf Rechnern mit dem amd64-Befehlssatz, also allen aktuellen Systemen seit ca. 2005. Sie nutzen die Vorteile der zahlreicheren und größen Prozessorregister von amd64 Systemen, verwenden jedoch eine Wortlänge von Adressen von nur 32 Bit. Damit ist der theoretisch adressierbare Speicher pro Prozess auf 4 GB begrenzt, was jedoch für viele Anwendungen ausreichend ist. Durch die kürzeren Pointer werden die Programme kleiner, bei der Ausführung passt mehr Programmcode in die CPU-Caches. Einen Vergleich von x32, i386 und amd64 gibt es auf Wikipedia.
Laut des Artikels ist jedoch fraglich, ob x32 in ausreichenden Umfang genutzt wird, um den Aufwand bei der Pflege im Mainline-Kernel zu rechtfertigen. Nur die Distributionen Debian, Gentoo und Yocto bieten einen eigenen Port mit ausschließlich x32 Paketen an. Debian/x32 ist zudem dem frühen Entwicklungsstadium nie entwachsen.
x32 Programme auf amd64 Distributionen
Jedoch können x32 Programme auch unter dem “normalen” Debian bzw Ubuntu benutzt werden. Um x32-Software ausführen zu können, muss mindestens die GNU-libc für x32 installiert sein.
# apt install libc6-x32
Zudem ist im Debian-Standardkernel der Support für x32 zwar vorhanden, muss
aber mit dem Parameter syscall.x32=y
eingeschaltet werden. Unter
Ubuntu ist das nicht nötig, x32 ist standardmäßig aktiv.
Um auch eigene Programme für x32 (cross-)compilieren zu können, werden zudem die Header benötigt:
# apt install libc6-dev-x32
Damit kann ein C-Programm compiliert werden, z.B.:
$ gcc -mx32 -Wall -o hello hello.c
Das entstehende Programm ist ein 32-Bit Programm für amd64 (x86_64) Systeme und ist dynamisch gegen die x32-libc gelinkt. Wie man sieht, sind alle Pointer 32 Bit lang:
$ file hello
hello: ELF 32-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /libx32/ld-linux-x32.so.2, for GNU/Linux 3.4.0, [...] not stripped
$ ldd hello
linux-vdso.so.1 (0xff99a000)
libc.so.6 => /libx32/libc.so.6 (0xf77ad000)
/libx32/ld-linux-x32.so.2 (0xf7d5f000)
Go/x32
Unter Ubuntu 18.04 LTS lassen sich auch Go-Programme für x32 compilieren und ausführen. Dazu wird der GCC-Go Compiler benötigt:
# apt install gccgo-x86-64-linux-gnux32 gccgo-multilib-x86-64-linux-gnux32
Zum Compilieren des Programmes muss der passende Compiler direkt aufgerufen
werden, ein -mx32
wie bei C genügt nicht.
$ x86_64-linux-gnux32-gccgo -Wall -o hello hello.go
Das Programm wird dynamisch gegen die üblichen Shared Libraries und die
Go-Library von GccGo gelinkt. Letztere wird jedoch vom dynamischen Linker
nicht automatisch gefunden, weil der Pfad für die Go x32 Libraries nicht
in der ldconfig
Konfiguration steht.
$ file hello
hello: ELF 32-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /libx32/ld-linux-x32.so.2, for GNU/Linux 3.4.0, [...] with debug_info, not stripped
$ ldd hello
linux-vdso.so.1 (0xffdba000)
libgo.so.13 => not found
libgcc_s.so.1 => /usr/libx32/libgcc_s.so.1 (0xf7af9000)
libc.so.6 => /libx32/libc.so.6 (0xf7749000)
/libx32/ld-linux-x32.so.2 (0xf7d10000)
Um das Programm auszuführen, kann die benötigte Library mit LD_PRELOAD
vorgeladen werden:
LD_PRELOAD=/usr/x86_64-linux-gnux32/lib/libgo.so.13.0.0 ./hello