A fost publicat numărul 2.0 al proiectului Cosmopolitan, care dezvoltă biblioteca standard C și un format universal de fișiere executabile, ce poate fi folosit pentru distribuirea aplicațiilor pe diferite sisteme de operare, fără a necesita interpretoare sau mașini virtuale. Rezultatul obținut prin compilarea cu GCC și Clang este combinat într-un fișier executabil universal, ce poate fi rulat pe orice distribuție Linux, macOS, Windows, FreeBSD, OpenBSD, NetBSD și chiar apelat din BIOS. Codul proiectului este distribuit sub licența ISC (o variantă simplificată a MIT/BSD).
Containerul pentru formarea fișierelor executabile universale se bazează pe combinarea segmentelor și antetelor specifice diferitelor sisteme de operare (PE, ELF, MACHO, OPENBSD) într-un singur fișier, combinând mai multe formate diferite utilizate în Unix, Windows și macOS. Pentru a asigura rularea unui fișier executabil pe sistemele Windows și Unix, se aplică un truc legat de codificarea fișierelor Windows PE sub forma unui script shell, având în vedere că Thompson Shell nu folosește markerul de script „#!”. Pentru a crea programe care includ mai multe fișiere (combinând toate resursele într-un singur fișier), este suportată formarea fișierului executabil sub forma unui arhiv ZIP special conceput. Schema formatului propus (exemplu de aplicație 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…
La începutul fișierului se specifică marcajul „MZqFpD”, care este perceput ca un antet pentru formatul Windows PE. Această secvență este, de asemenea, decodată în instrucțiunea „pop %r10 ; jno 0x4a ; jo 0x4a”, iar șirul „\177ELF” în instrucțiunea „jg 0x47”, care sunt utilizate pentru a redirecționa către punctul de intrare. În sistemele Unix, se execută codul shell, în care se utilizează comanda exec pentru a transmite codul executabil printr-un canal nemarcat. O restricție a metodei propuse este că rularea în sistemele de operare Unix-like este posibilă doar atunci când se folosesc shell-uri care suportă modul de compatibilitate cu Thompson Shell.
Apelul qemu-x86_64 este prevăzut pentru a oferi portabilitate suplimentară și permite executarea codului compilat pentru arhitectura x86_64 pe platforme diferite de x86, cum ar fi plăcile Raspberry Pi și dispozitivele Apple echipate cu procesoare ARM. Proiectul poate fi utilizat și pentru a crea aplicații autonome care funcționează fără un sistem de operare (bare metal). În astfel de aplicații, un încărcător este atașat fișierului executabil, iar programul acționează ca un sistem de operare încărcabil.
În biblioteca standard C libc dezvoltată de proiect sunt propuse 2024 de funcții (în prima versiune au fost aproximativ 1400 de funcții). În ceea ce privește performanța, Cosmopolitan funcționează la fel de repede ca glibc și depășește semnificativ Musl și Newlib, având în același timp un cod de dimensiuni cu un ordin mai mic decât glibc și fiind aproximativ comparabil cu Musl și Newlib. Pentru a optimiza funcțiile frecvent apelate, cum ar fi memcpy și strlen, se utilizează o tehnică numită „trickle-down performance”, unde pentru apelul funcției se aplică un macro care informează compilatorul despre registrele CPU utilizate în timpul executării codului, economisind astfel resurse prin salvarea doar a registrelor modificate.
Printre modificările din noua versiune:
- Schema de accesare a resurselor interne din interiorul fișierului zip a fost modificată (la deschiderea fișierelor acum se folosesc căi obișnuite /zip/… în loc de accesarea prin prefixul zip:..). Similar, pentru accesul la discuri în Windows, s-a oferit posibilitatea utilizării căilor de tip „/c/…” în loc de „C:/…”.
- A fost propus un nou încărcător APE (Actually Portable Executable), care definește formatul fișierelor executabile universale. Noul încărcător folosește mmap pentru a plasa programul în memorie și nu mai modifică conținutul în timpul execuției. Dacă este necesar, fișierul executabil universal poate fi convertit în fișiere executabile obișnuite, legate de platforme separate.
- Pe platforma Linux a fost implementată posibilitatea utilizării modulului de kernel binfmt_misc pentru a rula programele APE. Se observă că utilizarea binfmt_misc este cea mai rapidă metodă de inițiere.
- Pentru Linux, a fost propusă implementarea funcționalității apelurilor de sistem pledge() și unveil(), dezvoltate de proiectul OpenBSD. Este disponibil un API pentru utilizarea acestor apeluri în programe scrise în limbile C, C++, Python și Redbean, precum și utilitarul pledge.com pentru izolarea proceselor arbitrare.
- Pentru compilare este utilizat utilitarul Landlock Make — o variantă GNU Make cu verificări mai stricte ale dependențelor și utilizarea apelului de sistem Landlock pentru a izola programul de restul sistemului și a îmbunătăți eficiența cache-ului. Ca opțiune, se menține posibilitatea de compilare și prin intermediul GNU Make obișnuit.
- Sunt implementate funcții pentru multithreading — _spawn() și _join() care reprezintă wrapper-e universale pentru API-urile specifice diferitelor sisteme de operare. De asemenea, se lucrează la implementarea suportului pentru POSIX Threads.
- A fost oferită posibilitatea de a utiliza cuvântul cheie _Thread_local pentru a utiliza stocări separate pentru fiecare fir (TLS, Thread-Local Storage). În mod implicit, runtime-ul C inițializează TLS pentru firul principal, ceea ce a dus la creșterea dimensiunii minime a fișierului executabil de la 12 la 16 KB.
- Fișierelor executabile le-a fost adăugată suportul pentru parametrii „—ftrace” și „—strace” pentru a ieși în stderr informații despre toate apelurile de funcții și apelurile de sistem.
- A fost adăugat suport pentru apelul de sistem closefrom(), suportat în Linux 5.9+, FreeBSD 8+ și OpenBSD.
- Pe platforma Linux, performanța apelurilor clock_gettime și gettimeofday a fost crescută de până la 10 ori datorită utilizării mecanismului vDSO (virtual dynamic shared object), care permite mutarea procesorului apelului de sistem în spațiul utilizatorului și evitarea comutării contextului.
- Funcțiile matematice pentru lucrul cu numere complexe au fost transferate din biblioteca Musl. A fost accelerată funcționarea multor funcții matematice.
- A fost propusă funcția nointernet(), care dezactivează funcționalitățile de rețea.
- Au fost adăugate noi funcții pentru atașarea eficientă a șirurilor: appendd, appendf, appendr, appends, appendw, appendz, kappendf, kvappendf și vappendf.
- A fost adăugată o variantă sigură a familiei funcțiilor kprintf(), destinată să funcționeze cu privilegii ridicate.
- Performanța implementărilor a fost semnificativ crescută SSL, SHA, curve25519 și RSA.
Sursa: opennet.ro
