Lanzamiento de la biblioteca C estándar Cosmopolitan 2.0, desarrollada para archivos ejecutables portátiles

Se ha publicado el lanzamiento del proyecto Cosmopolitan 2.0, que desarrolla la biblioteca C estándar y un formato de archivo ejecutable universal que se puede utilizar para distribuir programas para diferentes sistemas operativos sin el uso de intérpretes ni máquinas virtuales. El resultado obtenido al compilar en GCC y Clang se compila en un archivo ejecutable universal vinculado estáticamente que se puede ejecutar en cualquier distribución de Linux, macOS, Windows, FreeBSD, OpenBSD, NetBSD e incluso llamar desde el BIOS. El código del proyecto se distribuye bajo la licencia ISC (una versión simplificada de MIT/BSD).

El contenedor para generar archivos ejecutables universales se basa en combinar segmentos y encabezados específicos de diferentes sistemas operativos (PE, ELF, MACHO, OPENBSD) en un solo archivo, combinando varios formatos diferentes utilizados en Unix, Windows y macOS. Para garantizar que un único archivo ejecutable se ejecute en sistemas Windows y Unix, un truco consiste en codificar archivos de Windows PE como scripts de shell, aprovechando el hecho de que Thompson Shell no utiliza el marcador de script "#!". Para crear programas que incluyan varios archivos (vinculando todos los recursos en un solo archivo), admite la formación de un archivo ejecutable en forma de un archivo ZIP especialmente diseñado. Esquema del formato propuesto (ejemplo de aplicación hello.com):

MZqFpD='SECTOR DE ARRANQUE DEL BIOS' exec 7 $(command -v $0) printf '\177ELF...LINKER-ENCODED-FREEBSD-HEADER' >&7 exec "$0" "$@" exec qemu-x86_64 "$0" "$ @" salida 1 MODO REAL… SEGMENTOS ELF… NOTA DE OPENBSD… ENCABEZADOS MACHO… CÓDIGO Y DATOS… DIRECTORIO POSTAL…

Al principio del archivo se indica la etiqueta "MZqFpD", que se percibe como un encabezado en formato Windows PE. Esta secuencia también se decodifica en la instrucción “pop %r10; jno 0x4a; jo 0x4a", y la línea "\177ELF" a la instrucción "jg 0x47", que se utilizan para reenviar al punto de entrada. Los sistemas Unix ejecutan código shell que utiliza el comando exec y pasa el código ejecutable a través de una tubería sin nombre. Una limitación del método propuesto es la capacidad de ejecutarse en sistemas operativos tipo Unix utilizando únicamente shells que admitan el modo de compatibilidad Thompson Shell.

La llamada qemu-x86_64 proporciona portabilidad adicional y permite que el código compilado para la arquitectura x86_64 se ejecute en plataformas que no sean x86, como placas Raspberry Pi y dispositivos Apple equipados con procesadores ARM. El proyecto también se puede utilizar para crear aplicaciones autónomas que se ejecuten sin un sistema operativo (bare metal). En dichas aplicaciones, se adjunta un gestor de arranque al archivo ejecutable y el programa actúa como un sistema operativo de arranque.

La biblioteca C estándar libc desarrollada por el proyecto ofrece 2024 funciones (en la primera versión había alrededor de 1400 funciones). En términos de rendimiento, Cosmopolitan funciona tan rápido como glibc y está notablemente por delante de Musl y Newlib, a pesar de que Cosmopolitan es un orden de magnitud más pequeño en tamaño de código que glibc y corresponde aproximadamente a Musl y Newlib. Para optimizar funciones llamadas frecuentemente como memcpy y strlen, se utiliza adicionalmente la técnica de "rendimiento de goteo", en la que se utiliza un enlace de macro para llamar a la función, en el que se informa al compilador sobre los registros de la CPU involucrados en la ejecución del código. proceso, que permite ahorrar recursos al guardar el estado de la CPU guardando solo registros modificables.

Entre los cambios en la nueva versión:

  • Se ha cambiado el esquema para acceder a los recursos internos dentro de un archivo zip (al abrir archivos, ahora se utilizan las rutas habituales /zip/... en lugar del prefijo zip:..). De manera similar, para acceder a los discos en Windows, es posible utilizar rutas como “/c/...” en lugar de “C:/...”.
  • Se ha propuesto un nuevo cargador APE (Actually Portable Executable), que define el formato de los archivos ejecutables universales. El nuevo cargador utiliza mmap para colocar el programa en la memoria y ya no cambia el contenido sobre la marcha. Si es necesario, el archivo ejecutable universal se puede convertir en archivos ejecutables normales vinculados a plataformas individuales.
  • En la plataforma Linux, es posible utilizar el módulo del kernel binfmt_misc para ejecutar programas APE. Cabe señalar que utilizar binfmt_misc es el método de inicio más rápido.
  • Para Linux, se ha propuesto una implementación de la funcionalidad de las llamadas al sistema promesa() y unveil() desarrolladas por el proyecto OpenBSD. Se proporciona una API para utilizar estas llamadas en programas en C, C++, Python y Redbean, así como una utilidad de promesa.com para aislar procesos arbitrarios.
  • La compilación utiliza la utilidad Landlock Make, una edición de GNU Make con una verificación de dependencias más estricta y el uso de la llamada al sistema Landlock para aislar el programa del resto del sistema y mejorar la eficiencia del almacenamiento en caché. Como opción, se conserva la capacidad de compilar con GNU Make normal.
  • Se han implementado funciones para subprocesos múltiples: _spawn() y _join(), que son enlaces universales sobre API específicas para diferentes sistemas operativos. También se está trabajando para implementar la compatibilidad con subprocesos POSIX.
  • Es posible utilizar la palabra clave _Thread_local para utilizar almacenamiento separado para cada subproceso (TLS, Thread-Local Storage). De forma predeterminada, el tiempo de ejecución de C inicializa TLS para el subproceso principal, lo que ha provocado que el tamaño mínimo del ejecutable aumente de 12 KB a 16 KB.
  • Se ha agregado soporte para los parámetros “--ftrace” y “--strace” a los archivos ejecutables para generar información sobre todas las llamadas a funciones y llamadas al sistema a stderr.
  • Se agregó soporte para la llamada al sistema closefrom(), compatible con Linux 5.9+, FreeBSD 8+ y OpenBSD.
  • En la plataforma Linux, el rendimiento de las llamadas clock_gettime y gettimeofday se ha incrementado hasta 10 veces mediante el uso del mecanismo vDSO (objeto virtual dinámico compartido), que permite mover el controlador de llamadas del sistema al espacio del usuario y evitar cambios de contexto.
  • Las funciones matemáticas para trabajar con números complejos se han trasladado de la biblioteca Musl. Se ha acelerado el trabajo de muchas funciones matemáticas.
  • Se ha propuesto la función nointernet() para desactivar las capacidades de la red.
  • Se agregaron nuevas funciones para agregar cadenas de manera eficiente: appendd, appendf, appendr, appends, appendw, appendz, kappendf, kvappendf y vappendf.
  • Se agregó una versión protegida de la familia de funciones kprintf(), diseñada para funcionar con privilegios elevados.
  • Rendimiento significativamente mejorado de las implementaciones SSL, SHA, curve25519 y RSA.

Fuente: opennet.ru

Añadir un comentario