Lansarea bibliotecii C standard Cosmopolitan 2.0, dezvoltată pentru fișiere executabile portabile

A fost publicată lansarea proiectului Cosmopolitan 2.0, dezvoltând biblioteca standard C și un format de fișier executabil universal care poate fi folosit pentru a distribui programe pentru diferite sisteme de operare fără utilizarea de interpreți și mașini virtuale. Rezultatul obținut prin compilarea în GCC și Clang este compilat într-un fișier executabil universal legat static, care 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 versiune simplificată a MIT/BSD).

Containerul pentru generarea fișierelor executabile universale se bazează pe combinarea segmentelor și anteturilor 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 vă asigura că un singur fișier executabil rulează pe sistemele Windows și Unix, un truc este să codificați fișierele Windows PE ca scripturi shell, profitând de faptul că Thompson Shell nu folosește marcatorul de script „#!”. Pentru a crea programe care includ mai multe fișiere (care leagă toate resursele într-un singur fișier), acceptă formarea unui fișier executabil sub forma unei arhive ZIP special concepute. Schema formatului propus (exemplu aplicație hello.com):

MZqFpD='BIOS BOOT SECTOR' exec 7 $(comandă -v $0) printf '\177ELF...LINKER-ENCODED-FREEBSD-HEADER' >&7 exec "$0" "$@" exec qemu-x86_64 "$0" "$ @" ieși din 1 MOD REAL… SEGMENTE ELF… NOTĂ OPENBSD… ANTETE MACHO… COD ȘI DATE… DIRECTOR ZIP…

La începutul fișierului, este indicată eticheta „MZqFpD”, care este percepută ca un antet în format Windows PE. Această secvență este decodificată și în instrucțiunea „pop %r10; jno 0x4a ; jo 0x4a", și linia "\177ELF" la instrucțiunea "jg 0x47", care sunt folosite pentru a redirecționa către punctul de intrare. Sistemele Unix rulează cod shell care utilizează comanda exec, trecând codul executabil printr-o conductă fără nume. O limitare a metodei propuse este capacitatea de a rula pe sisteme de operare asemănătoare Unix numai folosind shell-uri care acceptă modul de compatibilitate Thompson Shell.

Apelul qemu-x86_64 oferă portabilitate suplimentară și permite ca codul compilat pentru arhitectura x86_64 să ruleze pe platforme non-x86, cum ar fi plăcile Raspberry Pi și dispozitivele Apple echipate cu procesoare ARM. Proiectul poate fi folosit și pentru a crea aplicații autonome care rulează fără un sistem de operare (bare metal). În astfel de aplicații, un bootloader este atașat la fișierul executabil, iar programul acționează ca un sistem de operare bootabil.

Librăria standard C libc dezvoltată de proiect oferă 2024 de funcții (în prima ediție erau aproximativ 1400 de funcții). În ceea ce privește performanța, Cosmopolitan funcționează la fel de rapid ca glibc și este vizibil înaintea lui Musl și Newlib, în ​​ciuda faptului că Cosmopolitan este cu un ordin de mărime mai mic ca dimensiunea codului decât glibc și corespunde aproximativ cu Musl și Newlib. Pentru a optimiza funcțiile denumite frecvent precum memcpy și strlen, se folosește suplimentar tehnica „trick-down performance”, în care se folosește o legare macro pentru apelarea funcției, în care compilatorul este informat despre registrele CPU implicate în execuția codului proces, care permite salvarea resurselor la salvarea stării CPU prin salvarea doar a registrelor modificabile.

Printre modificările din noua versiune:

  • Schema de accesare a resurselor interne din interiorul unui fișier zip a fost schimbată (la deschiderea fișierelor, căile obișnuite /zip/... sunt acum folosite în loc de a utiliza prefixul zip:..). În mod similar, pentru a accesa discuri în Windows, este posibil să folosiți căi precum „/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 din mers. Dacă este necesar, fișierul executabil universal poate fi convertit în fișiere executabile obișnuite legate de platforme individuale.
  • Pe platforma Linux, este posibil să utilizați modulul kernel binfmt_misc pentru a rula programe APE. Este de notat că utilizarea binfmt_misc este cea mai rapidă metodă de lansare.
  • Pentru Linux, a fost propusă o implementare a funcționalității apelurilor de sistem pledge() și unveil() dezvoltate de proiectul OpenBSD. Este furnizat un API pentru utilizarea acestor apeluri în programe în C, C++, Python și Redbean, precum și un utilitar pledge.com pentru izolarea proceselor arbitrare.
  • Construcția folosește utilitarul Landlock Make - o ediție a GNU Make cu verificare mai strictă a dependenței și utilizarea apelului de sistem Landlock pentru a izola programul de restul sistemului și pentru a îmbunătăți eficiența stocării în cache. Ca opțiune, se păstrează capacitatea de a construi cu GNU Make obișnuit.
  • Au fost implementate funcții pentru multithreading - _spawn() și _join(), care sunt legături universale peste API-uri specifice diferitelor sisteme de operare. De asemenea, se lucrează pentru implementarea suportului POSIX Threads.
  • Este posibil să utilizați cuvântul cheie _Thread_local pentru a utiliza stocare separată pentru fiecare fir (TLS, Thread-Local Storage). În mod implicit, timpul de execuție C inițializează TLS pentru firul principal, ceea ce a determinat creșterea dimensiunii minime executabile de la 12 la 16 KB.
  • Suportul pentru parametrii „--ftrace” și „--strace” a fost adăugat la fișierele executabile pentru a scoate informații despre toate apelurile de funcții și apelurile de sistem către stderr.
  • S-a adăugat suport pentru apelul de sistem closefrom(), acceptat pe Linux 5.9+, FreeBSD 8+ și OpenBSD.
  • Pe platforma Linux, performanța apelurilor clock_gettime și gettimeofday a fost mărită de până la 10 ori prin utilizarea mecanismului vDSO (virtual dynamic shared object), care face posibilă mutarea gestionarului apelurilor de sistem în spațiul utilizatorului și evitarea schimbărilor de context.
  • Funcțiile matematice pentru lucrul cu numere complexe au fost mutate din biblioteca Musl. Lucrarea multor funcții matematice a fost accelerată.
  • Funcția nointernet() a fost propusă pentru a dezactiva capabilitățile rețelei.
  • S-au adăugat funcții noi pentru adăugarea eficientă a șirurilor de caractere: appendd, appendf, appendr, appends, appendw, appendz, kappendf, kvappendf și vappendf.
  • S-a adăugat o versiune protejată a familiei de funcții kprintf(), concepută pentru a funcționa cu privilegii ridicate.
  • Performanța îmbunătățită semnificativ a implementărilor SSL, SHA, curve25519 și RSA.

Sursa: opennet.ru

Adauga un comentariu