Veröffentlichung der Standard-C-Bibliothek Cosmopolitan 2.0, entwickelt für portable ausführbare Dateien

Die Veröffentlichung des Projekts Cosmopolitan 2.0 wurde veröffentlicht, das die Standard-C-Bibliothek und ein universelles ausführbares Dateiformat entwickelt, mit dem Programme für verschiedene Betriebssysteme ohne den Einsatz von Interpretern und virtuellen Maschinen verteilt werden können. Das durch das Kompilieren in GCC und Clang erhaltene Ergebnis wird in eine statisch verknüpfte universelle ausführbare Datei kompiliert, die auf jeder Linux-Distribution, macOS, Windows, FreeBSD, OpenBSD, NetBSD ausgeführt und sogar vom BIOS aufgerufen werden kann. Der Projektcode wird unter der ISC-Lizenz (einer vereinfachten Version von MIT/BSD) vertrieben.

Der Container zur Generierung universeller ausführbarer Dateien basiert auf der Kombination von Segmenten und Headern, die für verschiedene Betriebssysteme (PE, ELF, MACHO, OPENBSD) spezifisch sind, in einer Datei und kombiniert mehrere verschiedene Formate, die in Unix, Windows und macOS verwendet werden. Um sicherzustellen, dass eine einzelne ausführbare Datei auf Windows- und Unix-Systemen ausgeführt wird, besteht ein Trick darin, Windows PE-Dateien als Shell-Skripte zu kodieren und dabei die Tatsache auszunutzen, dass Thompson Shell nicht die Skriptmarkierung „#!“ verwendet. Um Programme zu erstellen, die mehrere Dateien umfassen (alle Ressourcen in einer Datei verknüpfen), unterstützt es die Bildung einer ausführbaren Datei in Form eines speziell entwickelten ZIP-Archivs. Schema des vorgeschlagenen Formats (Beispielanwendung hello.com):

MZqFpD='BIOS BOOT SECTOR' exec 7 $(command -v $0) printf '\177ELF...LINKER-ENCODED-FREEBSD-HEADER' >&7 exec "$0" "$@" exec qemu-x86_64 "$0" "$ @" Exit 1 REAL-MODUS… ELF-SEGMENTE… OPENBSD-HINWEIS… MACHO-HEADER… CODE UND DATEN… ZIP-VERZEICHNIS…

Am Anfang der Datei ist die Bezeichnung „MZqFpD“ angegeben, die als Header im Windows PE-Format wahrgenommen wird. Diese Sequenz wird auch in der Anweisung „pop %r10; jno 0x4a ; jo 0x4a“ und die Zeile „\177ELF“ an die Anweisung „jg 0x47“, die zur Weiterleitung zum Einstiegspunkt verwendet werden. Unix-Systeme führen Shell-Code aus, der den Befehl exec verwendet und den ausführbaren Code über eine unbenannte Pipe weiterleitet. Eine Einschränkung der vorgeschlagenen Methode besteht darin, dass sie auf Unix-ähnlichen Betriebssystemen nur mit Shells ausgeführt werden kann, die den Thompson Shell-Kompatibilitätsmodus unterstützen.

Der qemu-x86_64-Aufruf bietet zusätzliche Portabilität und ermöglicht die Ausführung von für die x86_64-Architektur kompiliertem Code auf Nicht-x86-Plattformen wie Raspberry Pi-Boards und Apple-Geräten mit ARM-Prozessoren. Mit dem Projekt können auch eigenständige Anwendungen erstellt werden, die ohne Betriebssystem (Bare Metal) laufen. Bei solchen Anwendungen wird ein Bootloader an die ausführbare Datei angehängt und das Programm fungiert als bootfähiges Betriebssystem.

Die vom Projekt entwickelte Standard-C-Bibliothek libc bietet 2024 Funktionen (im ersten Release waren es etwa 1400 Funktionen). In Bezug auf die Leistung arbeitet Cosmopolitan genauso schnell wie Glibc und liegt deutlich vor Musl und Newlib, obwohl Cosmopolitan eine Größenordnung kleinerer Codegröße als Glibc ist und ungefähr Musl und Newlib entspricht. Um häufig aufgerufene Funktionen wie memcpy und strlen zu optimieren, kommt zusätzlich die „Trickle-Down-Performance“-Technik zum Einsatz, bei der zum Aufruf der Funktion eine Makrobindung genutzt wird, bei der der Compiler über die an der Codeausführung beteiligten CPU-Register informiert wird Prozess, der beim Speichern des CPU-Status Ressourcen spart, indem nur veränderbare Register gespeichert werden.

Zu den Änderungen in der neuen Version gehören:

  • Das Schema für den Zugriff auf interne Ressourcen innerhalb einer ZIP-Datei wurde geändert (beim Öffnen von Dateien werden jetzt die üblichen /zip/...-Pfade anstelle des Präfixes zip:.. verwendet). Ebenso ist es für den Zugriff auf Datenträger in Windows möglich, Pfade wie „/c/...“ anstelle von „C:/…“ zu verwenden.
  • Es wurde ein neuer APE-Loader (Actually Portable Executable) vorgeschlagen, der das Format universeller ausführbarer Dateien definiert. Der neue Loader verwendet mmap, um das Programm im Speicher abzulegen, und ändert den Inhalt nicht mehr im laufenden Betrieb. Bei Bedarf kann die universelle ausführbare Datei in reguläre ausführbare Dateien umgewandelt werden, die an einzelne Plattformen gebunden sind.
  • Auf der Linux-Plattform ist es möglich, das Kernelmodul binfmt_misc zum Ausführen von APE-Programmen zu verwenden. Es wird darauf hingewiesen, dass die Verwendung von binfmt_misc die schnellste Startmethode ist.
  • Für Linux wurde eine Implementierung der Funktionalität der vom OpenBSD-Projekt entwickelten Systemaufrufe pledge() und discover() vorgeschlagen. Es wird eine API zur Verwendung dieser Aufrufe in Programmen in C, C++, Python und Redbean sowie ein pledge.com-Dienstprogramm zum Isolieren beliebiger Prozesse bereitgestellt.
  • Der Build verwendet das Dienstprogramm Landlock Make – eine Edition von GNU Make mit strengerer Abhängigkeitsprüfung und der Verwendung des Landlock-Systemaufrufs, um das Programm vom Rest des Systems zu isolieren und die Caching-Effizienz zu verbessern. Als Option bleibt die Möglichkeit erhalten, mit regulärem GNU Make zu erstellen.
  • Es wurden Funktionen für Multithreading implementiert – _spawn() und _join(), bei denen es sich um universelle Bindungen über APIs handelt, die für verschiedene Betriebssysteme spezifisch sind. Außerdem wird an der Implementierung der POSIX-Threads-Unterstützung gearbeitet.
  • Mit dem Schlüsselwort _Thread_local ist es möglich, für jeden Thread einen separaten Speicher zu verwenden (TLS, Thread-Local Storage). Standardmäßig initialisiert die C-Laufzeit TLS für den Hauptthread, was dazu geführt hat, dass die minimale Größe der ausführbaren Datei von 12 KB auf 16 KB gestiegen ist.
  • Unterstützung für die Parameter „--ftrace“ und „--strace“ wurde zu ausführbaren Dateien hinzugefügt, um Informationen über alle Funktionsaufrufe und Systemaufrufe an stderr auszugeben.
  • Unterstützung für den Systemaufruf closefrom() hinzugefügt, unterstützt unter Linux 5.9+, FreeBSD 8+ und OpenBSD.
  • Auf der Linux-Plattform wurde die Leistung der Aufrufe „clock_gettime“ und „gettimeofday“ durch die Verwendung des vDSO-Mechanismus (Virtual Dynamic Shared Object) um das Zehnfache gesteigert, der es ermöglicht, den Systemaufruf-Handler in den Benutzerbereich zu verschieben und Kontextwechsel zu vermeiden.
  • Mathematische Funktionen für die Arbeit mit komplexen Zahlen wurden aus der Musl-Bibliothek verschoben. Die Arbeit vieler mathematischer Funktionen wurde beschleunigt.
  • Die Funktion nointernet() wurde vorgeschlagen, um Netzwerkfunktionen zu deaktivieren.
  • Neue Funktionen zum effizienten Anhängen von Zeichenfolgen hinzugefügt: appendd, appendf, appendr, appends, appendw, appendz, kappendf, kvappendf und vappendf.
  • Eine geschützte Version der kprintf()-Funktionsfamilie wurde hinzugefügt, die für die Arbeit mit erhöhten Rechten konzipiert ist.
  • Deutlich verbesserte Leistung von SSL-, SHA-, Curve25519- und RSA-Implementierungen.

Source: opennet.ru

Kommentar hinzufügen