Контейнер для формирования универсальных исполняемых файлов основан на совмещении специфичных для разных операционных систем сегментов и заголовков (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.
Источник: http://www.opennet.ru/opennews/art.shtml?num=57663