Випуск стандартної Сі-бібліотеки Cosmopolitan 2.0, що розвивається для файлів, що виконуються.

Опубліковано випуск проекту Cosmopolitan 2.0, який розвиває стандартну Сі-бібліотеку та універсальний формат файлів, який можна використовувати для поширення програм для різних операційних систем без використання інтерпретаторів і віртуальних машин. Отриманий за допомогою компіляції в GCC і Clang результат компонується в універсальний виконуваний файл, що статично зв'язується, який придатний для запуску в будь-якому дистрибутиві Linux, macOS, Windows, FreeBSD, OpenBSD, NetBSD і навіть виклику з BIOS. Код проекту розповсюджується під ліцензією ISC (спрощений варіант MIT/BSD).

Контейнер для формування універсальних виконуваних файлів заснований на суміщенні специфічних для різних операційних систем сегментів та заголовків (PE, ELF, MACHO, OPENBSD) в одному файлі, комбінуючи в ньому кілька різних форматів, що використовуються в Unix, Windows та MacOS. Для забезпечення запуску одного виконуваного файлу в Windows та Unix-системах застосовується трюк, пов'язаний з кодуванням файлів Windows PE у вигляді shell-скрипта, користуючись тим, що Thompson Shell не використовує маркер скриптів "#!". Для створення програм, що включають кілька файлів (компонування всіх ресурсів в один файл), підтримується формування файлу у вигляді спеціально оформленого ZIP-архіву. Схема запропонованого формату (приклад 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…

Спочатку файл вказує мітку «MZqFpD», яка сприймається як заголовок формату Windows PE. Ця послідовність також декодується в інструкції «pop %r10; jno 0x4a; jo 0x4a», а рядок «\177ELF» в інструкцію «jg 0x47», які використовуються для прокидання на точку входу. У Unix-системах виконується shell-код, у якому використовується команда exec з передачею виконуваного коду через неназваний канал. Обмеженням запропонованого методу є можливість запуску в Unix-подібних ОС лише з використанням оболонок, що підтримують режим сумісності з Thompson Shell.

Виклик qemu-x86_64 призначений для реалізації додаткової переносимості та дозволяє виконати скомпільований для архітектури x86_64 код на платформах, відмінних від x86, наприклад, на платах Raspberry Pi та пристроях Apple, укомплектованих процесорами ARM. Проект також може використовуватися для створення самодостатніх програм, що працюють без операційної системи (bare metal). У таких додатках до виконуваного файлу прикріплюється завантажувач, а програма виступає в ролі операційної системи, що завантажується.

У стандартній Си-бібліотеці libc, що розвивається проектом, запропоновано 2024 функції (у першому випуску було близько 1400 функцій). По продуктивності Cosmopolitan працює також швидко як і glibc і помітно випереджає Musl і Newlib, при тому, що Cosmopolitan за розміром коду на порядок менше glibc і відповідає Musl і Newlib. Для оптимізації часто викликаних функцій таких як memcpy і strlen додатково використовується техніка «trickle-down performance», при якій для виклику функції застосовується макрос-обв'язка, в якому компілятор інформується про задіяні в процесі виконання коду регістрах CPU, що дозволяє економити ресурси при збереженні стану CPU рахунок збереження лише змінюваних регістрів.

Серед змін у новому випуску:

  • Змінено схему звернення до внутрішніх ресурсів усередині zip-файлу (при відкритті файлів тепер використовуються звичайні шляхи /zip/… замість звернення за префіксом zip:..). Аналогічно для доступу до дисків Windows надається можливість використання шляхів виду «/c/…» замість «C:/…».
  • Запропоновано новий завантажувач APE (Actually Portable Executable), що визначає формат універсальних файлів, що виконуються. Новий завантажувач використовує mmap для розміщення програми в пам'яті і не змінює вміст на льоту. При необхідності універсальний файл, що виконується, може бути конвертований в звичайні виконувані файли, прив'язані до окремих платформ.
  • На платформі Linux реалізовано можливість використання модуля ядра binfmt_misc для запуску APE-програм. Зазначається, що використання binfmt_misc є найбільш швидким методом запуску.
  • Для Linux запропоновано реалізацію функціональності системних викликів pledge() і unveil(), що розвиваються проектом OpenBSD. Надається API для використання даних дзвінків у програмах мовами C, C++, Python та Redbean, а також утиліта pledge.com для ізоляції довільних процесів.
  • Для складання задіяна утиліта Landlock Make – редакція GNU Make з більш жорсткою перевіркою залежностей та використанням системного виклику Landlock для ізоляції програми від решти системи та підвищення ефективності кешування. Як опція збережена можливості складання і звичайним GNU Make.
  • Реалізовані функції для багатопоточності - _spawn() і _join(), що є універсальними обв'язками над специфічними для різних операційних систем API. Також ведеться робота над реалізацією підтримки POSIX Threads.
  • Надано можливість використання ключового слова _Thread_local для використання окремих для кожного потоку сховищ (TLS, Thread-Local Storage). За замовчуванням C runtime ініціалізує TLS для основного потоку, що призвело до збільшення мінімального розміру файлу з 12 до 16 КБ.
  • У файли, що виконуються, додана підтримка параметрів «—ftrace» і «—strace» для виведення в stderr інформації про всі виклики функцій і системні виклики.
  • Додано підтримку системного виклику closefrom(), що підтримується в Linux 5.9+, FreeBSD 8+ та OpenBSD.
  • На платформі Linux до 10 разів збільшено продуктивність викликів clock_gettime та gettimeofday за рахунок використання механізму vDSO (virtual dynamic shared object), що дає можливість перенести обробник системного виклику в простір користувача та уникнути перемикань контексту.
  • З бібліотеки Musl перенесено математичні функції до роботи з комплексними числами. Прискорено роботу багатьох математичних функцій.
  • Запропоновано функцію nointernet(), яка відключає мережеві можливості.
  • Додані нові функції для ефективного прикріплення рядків: appendd, appendf, appendr, appends, appendw, appendz, kappendf, kvappendf та vappendf.
  • Додано захищений варіант сімейства функцій kprintf(), призначений для роботи при підвищених привілеях.
  • Значно підвищено продуктивність реалізацій SSL, SHA, curve25519 та RSA.

Джерело: opennet.ru

Додати коментар або відгук