Sortie de la bibliothèque standard C Cosmopolitan 2.0, développée pour les fichiers exécutables portables

La version du projet Cosmopolitan 2.0 a été publiée, développant la bibliothèque C standard et un format de fichier exécutable universel qui peut être utilisé pour distribuer des programmes pour différents systèmes d'exploitation sans utiliser d'interprètes ni de machines virtuelles. Le résultat obtenu en compilant dans GCC et Clang est compilé dans un fichier exécutable universel lié statiquement qui peut être exécuté sur n'importe quelle distribution Linux, macOS, Windows, FreeBSD, OpenBSD, NetBSD et même appelé depuis le BIOS. Le code du projet est distribué sous licence ISC (une version simplifiée de MIT/BSD).

Le conteneur de génération de fichiers exécutables universels est basé sur la combinaison de segments et d'en-têtes spécifiques à différents systèmes d'exploitation (PE, ELF, MACHO, OPENBSD) dans un seul fichier, combinant plusieurs formats différents utilisés sous Unix, Windows et macOS. Pour garantir qu'un seul fichier exécutable s'exécute sur les systèmes Windows et Unix, une astuce consiste à encoder les fichiers Windows PE sous forme de scripts shell, en tirant parti du fait que Thompson Shell n'utilise pas le marqueur de script "#!". Pour créer des programmes comprenant plusieurs fichiers (liant toutes les ressources en un seul fichier), il prend en charge la formation d'un fichier exécutable sous la forme d'une archive ZIP spécialement conçue. Schéma du format proposé (exemple d'application 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 MODE RÉEL… SEGMENTS ELF… NOTE OPENBSD… EN-TÊTES MACHO… CODE ET DONNÉES… RÉPERTOIRE ZIP…

Au début du fichier, l'étiquette « MZqFpD » est indiquée, qui est perçue comme un en-tête au format Windows PE. Cette séquence est également décodée dans l'instruction « pop %r10 ; jno 0x4a ; jo 0x4a", et la ligne "\177ELF" à l'instruction "jg 0x47", qui servent à renvoyer vers le point d'entrée. Les systèmes Unix exécutent un code shell qui utilise la commande exec, en transmettant le code exécutable via un canal sans nom. Une limitation de la méthode proposée est la possibilité de s'exécuter sur des systèmes d'exploitation de type Unix en utilisant uniquement des shells prenant en charge le mode de compatibilité Thompson Shell.

L'appel qemu-x86_64 offre une portabilité supplémentaire et permet au code compilé pour l'architecture x86_64 de s'exécuter sur des plates-formes non x86, telles que les cartes Raspberry Pi et les appareils Apple équipés de processeurs ARM. Le projet peut également être utilisé pour créer des applications autonomes qui s'exécutent sans système d'exploitation (bare metal). Dans de telles applications, un chargeur de démarrage est attaché au fichier exécutable et le programme agit comme un système d'exploitation amorçable.

La bibliothèque C standard libc développée par le projet propose 2024 fonctions (dans la première version, il y avait environ 1400 fonctions). En termes de performances, Cosmopolitan fonctionne aussi vite que la glibc et est sensiblement en avance sur Musl et Newlib, malgré le fait que Cosmopolitan est d'un ordre de grandeur plus petit en taille de code que la glibc et correspond approximativement à Musl et Newlib. Pour optimiser les fonctions fréquemment appelées telles que memcpy et strlen, la technique du « trickle-down performance » est également utilisée, dans laquelle une liaison de macro est utilisée pour appeler la fonction, dans laquelle le compilateur est informé des registres CPU impliqués dans l'exécution du code. processus, qui permet d'économiser des ressources lors de la sauvegarde de l'état du processeur en enregistrant uniquement les registres modifiables.

Parmi les changements de la nouvelle version :

  • Le schéma d'accès aux ressources internes d'un fichier zip a été modifié (lors de l'ouverture des fichiers, les chemins habituels /zip/... sont désormais utilisés au lieu d'utiliser le préfixe zip:..). De même, pour accéder aux disques sous Windows, il est possible d'utiliser des chemins comme « /c/... » au lieu de « C:/... ».
  • Un nouveau chargeur APE (Actually Portable Executable) a été proposé, qui définit le format des fichiers exécutables universels. Le nouveau chargeur utilise mmap pour placer le programme en mémoire et ne modifie plus le contenu à la volée. Si nécessaire, le fichier exécutable universel peut être converti en fichiers exécutables classiques liés à des plates-formes individuelles.
  • Sur la plateforme Linux, il est possible d'utiliser le module noyau binfmt_misc pour exécuter des programmes APE. Il est à noter que l'utilisation de binfmt_misc est la méthode de lancement la plus rapide.
  • Pour Linux, une implémentation de la fonctionnalité des appels système promise() et unveil() développés par le projet OpenBSD a été proposée. Une API est fournie pour utiliser ces appels dans des programmes en C, C++, Python et Redbean, ainsi qu'un utilitaire promise.com pour isoler les processus arbitraires.
  • La version utilise l'utilitaire Landlock Make - une édition de GNU Make avec une vérification des dépendances plus stricte et l'utilisation de l'appel système Landlock pour isoler le programme du reste du système et améliorer l'efficacité de la mise en cache. En option, la possibilité de construire avec GNU Make standard est conservée.
  • Des fonctions de multithreading ont été implémentées - _spawn() et _join(), qui sont des liaisons universelles sur des API spécifiques à différents systèmes d'exploitation. Des travaux sont également en cours pour implémenter la prise en charge de POSIX Threads.
  • Il est possible d'utiliser le mot-clé _Thread_local pour utiliser un stockage séparé pour chaque thread (TLS, Thread-Local Storage). Par défaut, le runtime C initialise TLS pour le thread principal, ce qui a entraîné une augmentation de la taille minimale de l'exécutable de 12 Ko à 16 Ko.
  • La prise en charge des paramètres « --ftrace » et « --strace » a été ajoutée aux fichiers exécutables pour afficher des informations sur tous les appels de fonction et les appels système vers stderr.
  • Ajout de la prise en charge de l'appel système closefrom(), pris en charge sur Linux 5.9+, FreeBSD 8+ et OpenBSD.
  • Sur la plateforme Linux, les performances des appels clock_gettime et gettimeofday ont été augmentées jusqu'à 10 fois grâce à l'utilisation du mécanisme vDSO (virtual Dynamic Shared Object), qui permet de déplacer le gestionnaire d'appels système vers l'espace utilisateur et d'éviter les changements de contexte.
  • Les fonctions mathématiques permettant de travailler avec des nombres complexes ont été déplacées de la bibliothèque Musl. Le travail de nombreuses fonctions mathématiques a été accéléré.
  • La fonction nointernet() a été proposée pour désactiver les fonctionnalités réseau.
  • Ajout de nouvelles fonctions pour ajouter efficacement des chaînes : appendd, appendf, appendr, appends, appendw, appendz, kappendf, kvappendf et vappendf.
  • Ajout d'une version protégée de la famille de fonctions kprintf(), conçue pour fonctionner avec des privilèges élevés.
  • Performances considérablement améliorées des implémentations SSL, SHA, Curve25519 et RSA.

Source: opennet.ru

Ajouter un commentaire