Veröffentlichung der Standard-C-Cosmopolitan-Bibliothek 2.0, die für tragbare ausführbare Dateien entwickelt wird.

Die Ausgabe des Projekts Cosmopolitan 2.0 wurde veröffentlicht, das die standardisierte C-Bibliothek und ein universelles Format für ausführbare Dateien entwickelt, das für die Verbreitung von Programmen in verschiedenen Betriebssystemen ohne Interpreter und virtuelle Maschinen verwendet werden kann. Das Ergebnis, das mit GCC und Clang kompiliert wird, wird zu einer statisch verketteten universellen ausführbaren Datei, die in jedem Linux-Distro, macOS, Windows, FreeBSD, OpenBSD, NetBSD und sogar aus dem BIOS heraus ausgeführt werden kann. Der Quellcode des Projekts wird unter der ISC-Lizenz (eine vereinfachte Version von MIT/BSD) verbreitet.

Der Container zur Erstellung universeller ausführbarer Dateien basiert auf der Kombination betriebssystemspezifischer Segmente und Header (PE, ELF, MACHO, OPENBSD) in einer einzigen Datei, indem mehrere unterschiedliche Formate verwendet werden, die in Unix, Windows und macOS gebräuchlich sind. Um die Ausführung einer einzelnen ausführbaren Datei in Windows- und Unix-Systemen zu ermöglichen, wird ein Trick angewendet, bei dem Windows PE-Dateien als Shell-Skript codiert werden, da die Thompson Shell das Skriptmarker-Zeichen „#!“ nicht nutzt. Für die Erstellung von Programmen, die mehrere Dateien umfassen (Kombinierung aller Ressourcen in einer Datei), wird die Erstellung einer ausführbaren Datei als speziell formatierte ZIP-Datei unterstützt. Das 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 MODE… ELF SEGMENTS… OPENBSD NOTE… MACHO HEADERS… CODE AND DATA… ZIP DIRECTORY…

Zu Beginn der Datei wird das Label „MZqFpD“ angegeben, das als Header des Windows PE-Formats interpretiert wird. Diese Sequenz wird auch in die Anweisung „pop %r10 ; jno 0x4a ; jo 0x4a“ dekodiert, und die Zeichenfolge „\177ELF“ in die Anweisung „jg 0x47“, die zur Übergabe an den Einstiegspunkt verwendet werden. In Unix-Systemen wird Shell-Code ausgeführt, in dem der Befehl exec verwendet wird, um den ausführbaren Code über eine anonyme Pipe zu übergeben. Eine Einschränkung der vorgeschlagenen Methode besteht darin, dass sie in Unix-ähnlichen Betriebssystemen nur mit Shells ausgeführt werden kann, die den Kompatibilitätsmodus mit der Thompson Shell unterstützen.

Der Aufruf von qemu-x86_64 ist für die Umsetzung zusätzlicher Portabilität vorgesehen und ermöglicht es, für die Architektur x86_64 kompilierte Codes auf anderen Plattformen als x86 auszuführen, z. B. auf Raspberry Pi-Platinen und Apple-Geräten mit ARM-Prozessoren. Das Projekt kann auch verwendet werden, um eigenständige Anwendungen zu erstellen, die ohne Betriebssystem (bare metal) funktionieren. In solchen Anwendungen wird ein Bootloader an die ausführbare Datei angehängt, wobei das Programm als das zu ladende Betriebssystem agiert.

In der im Rahmen des Projekts entwickelten Standard-C-Bibliothek libc sind 2024 Funktionen vorgesehen (in der ersten Version waren es etwa 1400 Funktionen). In Bezug auf die Leistung arbeitet Cosmopolitan genauso schnell wie glibc und übertrifft Musl und Newlib deutlich, während Cosmopolitan in Bezug auf den Codeumfang um ein Vielfaches kleiner ist als glibc und etwa der Größe von Musl und Newlib entspricht. Zur Optimierung häufig aufgerufener Funktionen wie memcpy und strlen wird eine Technik namens „trickle-down performance“ verwendet, bei der ein Makro-Wrapper für den Funktionsaufruf verwendet wird, das dem Compiler Informationen über die im Verarbeitungsprozess verwendeten CPU-Register bereitstellt, was Ressourcen spart, indem nur die veränderten Register gespeichert werden.

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

  • Das Schema für den Zugriff auf interne Ressourcen in der ZIP-Datei wurde geändert (beim Öffnen von Dateien werden jetzt normale Pfade /zip/... anstelle des Präfixes zip:... verwendet). Ebenso wurde für den Zugriff auf Laufwerke unter Windows die Möglichkeit geschaffen, Pfade im Format „/c/...“ anstelle von „C:/...“ zu verwenden.
  • Ein neuer Bootloader APE (Actually Portable Executable) wurde vorgeschlagen, der das Format universeller ausführbarer Dateien definiert. Der neue Loader verwendet mmap zur Platzierung des Programms im Speicher und ändert den Inhalt nicht mehr zur Laufzeit. Bei Bedarf kann die universelle ausführbare Datei in reguläre ausführbare Dateien konvertiert werden, die an einzelne Plattformen gebunden sind.
  • Auf der Linux-Plattform wurde die Möglichkeit implementiert, das Kernelmodul binfmt_misc zum Ausführen von APE-Programmen zu verwenden. Es wird festgestellt, dass die Verwendung von binfmt_misc die schnellste Methode zur Ausführung ist.
  • Für Linux wurde eine Implementierung der Systemaufrufe pledge() und unveil() entwickelt, die vom OpenBSD-Projekt vorangetrieben wird. Eine API zur Nutzung dieser Aufrufe in Programmen in C, C++, Python und Redbean sowie ein Tool pledge.com zur Isolation beliebiger Prozesse wird bereitgestellt.
  • Für den Build-Prozess wird das Tool Landlock Make verwendet – eine Variante von GNU Make mit strikterer Überprüfung der Abhängigkeiten und der Verwendung des Systemaufrufs Landlock zur Isolierung des Programms von der restlichen Systemumgebung und zur Verbesserung der Cache-Effizienz. Als Option bleibt die Möglichkeit erhalten, auch mit herkömmlichem GNU Make zu bauen.
  • Es wurden Funktionen für Multithreading implementiert – _spawn() und _join(), die universelle Wrapper über die systemspezifischen APIs darstellen. Außerdem wird an der Implementierung der Unterstützung für POSIX-Threads gearbeitet.
  • Es wurde die Möglichkeit eingeführt, das Schlüsselwort _Thread_local zu nutzen, um separate Speicher für jeden Thread (TLS, Thread-Local Storage) zu verwenden. Standardmäßig initialisiert die C-Laufzeit TLS für den Hauptthread, was zu einer Erhöhung der minimalen Größe der ausführbaren Datei von 12 auf 16 KB führte.
  • In die ausführbaren Dateien wurden die Parameter „—ftrace“ und „—strace“ hinzugefügt, um Informationen über alle Funktionsaufrufe und Systemaufrufe an stderr auszugeben.
  • Die Unterstützung für den Systemaufruf closefrom(), der in Linux 5.9+, FreeBSD 8+ und OpenBSD unterstützt wird, wurde hinzugefügt.
  • Auf der Linux-Plattform wurde die Leistung der Aufrufe clock_gettime und gettimeofday um bis zu 10 Mal verbessert, indem der vDSO-Mechanismus (virtual dynamic shared object) genutzt wurde, der es ermöglicht, den Systemaufruf-Handler in den Benutzermodus zu verlagern und Kontexwechsel zu vermeiden.
  • Mathematische Funktionen zur Verarbeitung komplexer Zahlen wurden aus der Musl-Bibliothek übernommen. Viele mathematische Funktionen arbeiten nun schneller.
  • Eine Funktion nointernet() wurde vorgeschlagen, die die Netzwerkfähigkeiten deaktiviert.
  • Neue Funktionen zur effizienten String-Anhang wurden hinzugefügt: appendd, appendf, appendr, appends, appendw, appendz, kappendf, kvappendf und vappendf.
  • Eine sichere Variante der Funktion kprintf() wurde hinzugefügt, die für den Betrieb mit erhöhten Berechtigungen konzipiert ist.
  • Die Leistung der Implementierungen wurde erheblich gesteigert. SSL, SHA, curve25519 und RSA.

Quelle: opennet.ru

60GB SSD 8Gb DDR4