È stata pubblicata la versione del progetto Cosmopolitan 2.0, che sviluppa la libreria standard C e un formato universale di file eseguibili, utilizzabile per distribuire programmi su diversi sistemi operativi senza ricorrere a interpreti e macchine virtuali. Il risultato ottenuto mediante compilazione in GCC e Clang viene assemblato in un file eseguibile universale a collegamento statico, adatto per l'esecuzione in qualsiasi distribuzione di Linux, macOS, Windows, FreeBSD, OpenBSD, NetBSD, e persino per essere richiamato dal BIOS. Il codice del progetto è distribuito sotto licenza ISC (una versione semplificata di MIT/BSD).
Il contenitore per la creazione di file eseguibili universali si basa sulla combinazione di segmenti e intestazioni specifici per diversi sistemi operativi (PE, ELF, MACHO, OPENBSD) in un unico file, combinando diversi formati utilizzati in Unix, Windows e macOS. Per garantire l'esecuzione di un file eseguibile sia in Windows che nei sistemi Unix, si utilizza un trucco che consiste nel codificare i file Windows PE come uno script shell, sfruttando il fatto che la Thompson Shell non utilizza il marker di script «#!». Per creare programmi che includono più file (assemblando tutte le risorse in un unico file), è supportata la generazione di un file eseguibile come uno ZIP-archivio appositamente formattato. Lo schema del formato proposto (esempio dell'applicazione 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…
All'inizio del file è presente un'etichetta «MZqFpD», che viene percepita come intestazione del formato Windows PE. Questa sequenza è anche decodificata nell'istruzione «pop %r10 ; jno 0x4a ; jo 0x4a», mentre la stringa «\177ELF» nell'istruzione «jg 0x47», che vengono utilizzate per indirizzare il punto d'ingresso. Nei sistemi Unix, viene eseguito il codice shell, utilizzando il comando exec per passare il codice eseguibile tramite una pipe anonima. Una limitazione del metodo proposto è che l'esecuzione nei sistemi operativi simili a Unix è possibile solo utilizzando shell che supportano la modalità di compatibilità con la Thompson Shell.
La chiamata a qemu-x86_64 è prevista per implementare una portabilità aggiuntiva e consente di eseguire il codice compilato per l'architettura x86_64 su piattaforme diverse da x86, come le schede Raspberry Pi e i dispositivi Apple equipaggiati con processori ARM. Il progetto può anche essere utilizzato per creare applicazioni autosufficienti che funzionano senza un sistema operativo (bare metal). In tali applicazioni, un caricatore viene allegato al file eseguibile e il programma funge da sistema operativo avviabile.
Nella libreria standard C libc sviluppata dal progetto sono state proposte 2024 funzioni (nella prima versione erano circa 1400 funzioni). Per prestazioni, Cosmopolitan funziona rapidamente quanto glibc e supera nettamente Musl e Newlib, pur essendo il codice di Cosmopolitan significativamente più piccolo rispetto a glibc e paragonabile a Musl e Newlib. Per ottimizzare funzioni frequentemente chiamate, come memcpy e strlen, viene utilizzata una tecnica di «trickle-down performance», in cui per la chiamata di una funzione si applica un macro-wrapper che informa il compilatore sui registri CPU coinvolti nel processo di esecuzione del codice, consentendo un risparmio di risorse mantenendo lo stato della CPU solo per i registri modificati.
Tra le novità della nuova versione:
- È stato modificato il modo di accedere alle risorse interne all'interno del file zip (quando si aprono file ora si utilizzano percorsi normali /zip/... invece di riferirsi con il prefisso zip:..). Analogamente, per l'accesso ai dischi su Windows è ora possibile utilizzare percorsi come «/c/...» invece di «C:/...».
- È stato proposto un nuovo caricatore APE (Actually Portable Executable), che definisce il formato dei file eseguibili universali. Il nuovo caricatore utilizza mmap per collocare il programma in memoria e non modifica più il contenuto al volo. Se necessario, un file eseguibile universale può essere convertito in normali file eseguibili legati a piattaforme specifiche.
- Su piattaforma Linux è stata implementata la possibilità di utilizzare il modulo del kernel binfmt_misc per avviare programmi APE. Si segnala che l'uso di binfmt_misc è il metodo di avvio più rapido.
- Per Linux è stata proposta l'implementazione della funzionalità delle chiamate di sistema pledge() e unveil(), sviluppate dal progetto OpenBSD. Viene fornito un API per utilizzare queste chiamate in programmi nelle lingue C, C++, Python e Redbean, e anche uno strumento pledge.com per isolare processi arbitrari.
- Per la compilazione viene utilizzato lo strumento Landlock Make — una versione di GNU Make con un controllo delle dipendenze più rigoroso e l'uso della system call Landlock per isolare il programma dal resto del sistema e migliorare l'efficienza della memorizzazione nella cache. È mantenuta la possibilità di compilare anche con il classico GNU Make.
- Sono state implementate funzioni per il multithreading — _spawn() e _join(), che fungono da wrapper universali per API specifiche di diversi sistemi operativi. Si sta inoltre lavorando per implementare il supporto per i POSIX Threads.
- È stata fornita la possibilità di utilizzare la parola chiave _Thread_local per utilizzare archivi separati per ogni thread (TLS, Thread-Local Storage). Di default, il runtime C inizializza il TLS per il thread principale, il che ha portato a un aumento della dimensione minima del file eseguibile da 12 a 16 KB.
- Nei file eseguibili è stato aggiunto il supporto per i parametri "—ftrace" e "—strace" per stampare in stderr le informazioni su tutte le chiamate a funzioni e system call.
- Aggiunto il supporto per la system call closefrom(), supportata in Linux 5.9+, FreeBSD 8+ e OpenBSD.
- Sulla piattaforma Linux, le performance delle chiamate a clock_gettime e gettimeofday sono state aumentate fino a 10 volte grazie all'uso del meccanismo vDSO (virtual dynamic shared object), che consente di spostare il gestore della system call nello spazio utente ed evitare i cambiamenti di contesto.
- Sono state trasferite dalla libreria Musl funzioni matematiche per lavorare con numeri complessi. È stata accelerata l'esecuzione di molte funzioni matematiche.
- È stata proposta la funzione nointernet(), che disabilita le capacità di rete.
- Aggiunte nuove funzioni per l'append efficiente delle stringhe: appendd, appendf, appendr, appends, appendw, appendz, kappendf, kvappendf e vappendf.
- Aggiunta una variante protetta della famiglia di funzioni kprintf(), destinata all'uso con privilegi elevati.
- Le performance delle implementazioni sono state notevolmente migliorate SSL, SHA, curve25519 e RSA.
Fonte: opennet.ru
