Выпуск стандартной Си-библиотеки 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 0×4a; jo 0×4a», а строка »\177ELF» в инструкцию «jg 0×47», которые применяются для проброса на точку входа. В 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.



Источник: http://www.opennet.ru/opennews/art.shtml? num=57663

© OpenNet