Lançamento da biblioteca C padrão Cosmopolitan 2.0, desenvolvida para arquivos executáveis ​​​​portáteis

Foi publicado o lançamento do projeto Cosmopolitan 2.0, desenvolvendo a biblioteca C padrão e um formato de arquivo executável universal que pode ser usado para distribuir programas para diferentes sistemas operacionais sem o uso de interpretadores e máquinas virtuais. O resultado obtido pela compilação em GCC e Clang é compilado em um arquivo executável universal vinculado estaticamente que pode ser executado em qualquer distribuição Linux, macOS, Windows, FreeBSD, OpenBSD, NetBSD e até mesmo chamado a partir do BIOS. O código do projeto é distribuído sob a licença ISC (uma versão simplificada do MIT/BSD).

O contêiner para geração de arquivos executáveis ​​universais é baseado na combinação de segmentos e cabeçalhos específicos de diferentes sistemas operacionais (PE, ELF, MACHO, OPENBSD) em um arquivo, combinando vários formatos diferentes usados ​​em Unix, Windows e macOS. Para garantir que um único arquivo executável seja executado em sistemas Windows e Unix, um truque é codificar os arquivos do Windows PE como scripts de shell, aproveitando o fato de que o Thompson Shell não usa o marcador de script "#!". Para criar programas que incluam vários arquivos (ligando todos os recursos em um arquivo), ele suporta a formação de um arquivo executável na forma de um arquivo ZIP especialmente projetado. Esquema do formato proposto (exemplo de aplicação 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" "$ @" sair 1 MODO REAL… SEGMENTOS ELF… NOTA OPENBSD… CABEÇALHOS MACHO… CÓDIGO E DADOS… DIRETÓRIO ZIP…

No início do arquivo é indicado o rótulo “MZqFpD”, que é percebido como um cabeçalho no formato Windows PE. Esta sequência também é decodificada na instrução “pop %r10; jno 0x4a; jo 0x4a", e a linha "\177ELF" para a instrução "jg 0x47", que são usadas para encaminhar para o ponto de entrada. Os sistemas Unix executam código shell que usa o comando exec, passando o código executável por meio de um canal sem nome. Uma limitação do método proposto é a capacidade de execução em sistemas operacionais do tipo Unix usando apenas shells que suportam o modo de compatibilidade Thompson Shell.

A chamada qemu-x86_64 fornece portabilidade adicional e permite que o código compilado para a arquitetura x86_64 seja executado em plataformas não x86, como placas Raspberry Pi e dispositivos Apple equipados com processadores ARM. O projeto também pode ser usado para criar aplicativos independentes que rodam sem sistema operacional (bare metal). Nesses aplicativos, um bootloader é anexado ao arquivo executável e o programa atua como um sistema operacional inicializável.

A biblioteca C padrão libc desenvolvida pelo projeto oferece 2024 funções (na primeira versão havia cerca de 1400 funções). Em termos de desempenho, o Cosmopolitan funciona tão rápido quanto o glibc e está visivelmente à frente do Musl e do Newlib, apesar do Cosmopolitan ser uma ordem de magnitude menor em tamanho de código do que o glibc e corresponder aproximadamente ao Musl e ao Newlib. Para otimizar funções frequentemente chamadas, como memcpy e strlen, é utilizada adicionalmente a técnica de “desempenho trickle-down”, na qual uma ligação de macro é usada para chamar a função, na qual o compilador é informado sobre os registros da CPU envolvidos na execução do código processo, que permite economizar recursos ao salvar o estado da CPU, salvando apenas registros alteráveis.

Entre as mudanças no novo lançamento:

  • O esquema de acesso aos recursos internos dentro de um arquivo zip foi alterado (ao abrir arquivos, os caminhos usuais /zip/... agora são usados ​​em vez do prefixo zip:..). Da mesma forma, para acessar discos no Windows, é possível usar caminhos como “/c/...” em vez de “C:/...”.
  • Foi proposto um novo carregador APE (Actually Portable Executable), que define o formato dos arquivos executáveis ​​​​universais. O novo carregador usa mmap para colocar o programa na memória e não altera mais o conteúdo na hora. Se necessário, o arquivo executável universal pode ser convertido em arquivos executáveis ​​regulares vinculados a plataformas individuais.
  • Na plataforma Linux, é possível usar o módulo do kernel binfmt_misc para executar programas APE. Observa-se que usar binfmt_misc é o método de inicialização mais rápido.
  • Para Linux, foi proposta uma implementação da funcionalidade das chamadas de sistema commit() e desvelar() desenvolvidas pelo projeto OpenBSD. É fornecida uma API para usar essas chamadas em programas em C, C++, Python e Redbean, bem como um utilitário commit.com para isolar processos arbitrários.
  • A compilação usa o utilitário Landlock Make - uma edição do GNU Make com verificação de dependência mais rigorosa e o uso da chamada de sistema Landlock para isolar o programa do resto do sistema e melhorar a eficiência do cache. Como opção, a capacidade de construir com o GNU Make regular é mantida.
  • Funções para multithreading foram implementadas - _spawn() e _join(), que são ligações universais sobre APIs específicas para diferentes sistemas operacionais. Também está em andamento trabalho para implementar o suporte a Threads POSIX.
  • É possível usar a palavra-chave _Thread_local para usar armazenamento separado para cada thread (TLS, Thread-Local Storage). Por padrão, o tempo de execução C inicializa o TLS para o thread principal, o que fez com que o tamanho mínimo do executável aumentasse de 12 KB para 16 KB.
  • O suporte para os parâmetros “--ftrace” e “--strace” foi adicionado aos arquivos executáveis ​​para gerar informações sobre todas as chamadas de função e chamadas de sistema para stderr.
  • Adicionado suporte para a chamada de sistema closefrom(), compatível com Linux 5.9+, FreeBSD 8+ e OpenBSD.
  • Na plataforma Linux, o desempenho das chamadas clock_gettime e gettimeofday foi aumentado em até 10 vezes usando o mecanismo vDSO (virtual dynamic shared object), que permite mover o manipulador de chamadas do sistema para o espaço do usuário e evitar mudanças de contexto.
  • Funções matemáticas para trabalhar com números complexos foram movidas da biblioteca Musl. O trabalho de muitas funções matemáticas foi acelerado.
  • A função nointernet() foi proposta para desativar os recursos da rede.
  • Adicionadas novas funções para anexar strings de forma eficiente:pendend,appendf,appendr,appends,appendw,appendz,kappendf,kvappendf e vappendf.
  • Adicionada uma versão protegida da família de funções kprintf(), projetada para funcionar com privilégios elevados.
  • Desempenho significativamente melhorado de implementações SSL, SHA, curve25519 e RSA.

Fonte: opennet.ru

Adicionar um comentário