Foi publicada a versão do projeto Cosmopolitan 2.0, que desenvolve a biblioteca padrão C e um formato universal de arquivos executáveis que pode ser utilizado para distribuir programas para diferentes sistemas operacionais sem o uso de interpretadores e máquinas virtuais. O resultado obtido pela compilação no GCC e Clang é combinado em um arquivo executável universal estáticamente vinculado, que é adequado para execução em qualquer distribuição Linux, macOS, Windows, FreeBSD, OpenBSD, NetBSD e até chamado a partir da BIOS. O código do projeto é distribuído sob a licença ISC (versão simplificada do MIT/BSD).
O contêiner para a formação de arquivos executáveis universais é baseado na combinação de segmentos e cabeçalhos específicos para diferentes sistemas operacionais (PE, ELF, MACHO, OPENBSD) em um único arquivo, combinando vários formatos utilizados em Unix, Windows e macOS. Para garantir a execução de um único arquivo executável em sistemas Windows e Unix, é aplicada uma técnica relacionada à codificação de arquivos Windows PE na forma de um script shell, aproveitando o fato de que o Thompson Shell não usa o marcador de script "#!". Para criar programas que incluem vários arquivos (combinando todos os recursos em um único arquivo), é suportada a formação de um arquivo executável na forma de um arquivo ZIP especialmente formatado. O esquema do formato proposto (exemplo do aplicativo hello.com):
MZqFpD=’ SECTOR DE BOOT DA BIOS’ exec 7 $(command -v $0) printf ‘\177ELF…LINKER-ENCODED-FREEBSD-HEADER’ >&7 exec «$0» «$@» exec qemu-x86_64 «$0» «$@» exit 1 MODO REAL… SEGMENTOS ELF… NOTA OPENBSD… CABEÇALHOS MACHO… CÓDIGO E DADOS… DIRETÓRIO ZIP…
No início do arquivo é indicada a etiqueta "MZqFpD", que é interpretada como o cabeçalho do formato Windows PE. Esta sequência também é decodificada na instrução "pop %r10 ; jno 0x4a ; jo 0x4a", e a string "\177ELF" na instrução "jg 0x47", que são utilizadas para redirecionar para o ponto de entrada. Em sistemas Unix, o código shell é executado, utilizando o comando exec para passar o código executável através de um canal anônimo. A limitação do método proposto é que a execução em sistemas operacionais similares ao Unix só é possível utilizando shells que suportam o modo de compatibilidade com o Thompson Shell.
A chamada qemu-x86_64 é prevista para implementar portabilidade adicional e permite executar código compilado para a arquitetura x86_64 em plataformas diferentes de x86, como em placas Raspberry Pi e dispositivos Apple equipados com processadores ARM. O projeto também pode ser usado para criar aplicativos autossuficientes que funcionam sem um sistema operacional (bare metal). Nesses aplicativos, um carregador é anexado ao arquivo executável, e o programa atua como um sistema operacional carregável.
Na biblioteca padrão de C libc em desenvolvimento, foram propostas 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 supera significativamente o Musl e o Newlib, ao mesmo tempo em que o Cosmopolitan é um fator de dez menor em tamanho de código que o glibc e é aproximadamente equivalente ao Musl e Newlib. Para otimizar funções frequentemente chamadas, como memcpy e strlen, é utilizada uma técnica chamada 'trickle-down performance', na qual um macro é utilizado para chamar a função, informando o compilador sobre os registradores do CPU utilizados durante a execução do código, permitindo economia de recursos mantendo o estado do CPU ao salvar apenas os registradores modificáveis.
Entre as mudanças na nova versão:
- O esquema de acesso a recursos internos dentro de um arquivo zip foi alterado (ao abrir arquivos, agora são usadas rotas comuns /zip/... em vez de acessar pelo prefixo zip:..). De forma semelhante, para acesso a discos no Windows, agora é possível utilizar caminhos do tipo '/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 utiliza mmap para alocar o programa na memória e não altera mais o conteúdo em tempo real. Se necessário, o arquivo executável universal pode ser convertido em arquivos executáveis normais vinculados a plataformas específicas.
- Na plataforma Linux, foi implementada a possibilidade de usar o módulo do kernel binfmt_misc para executar programas APE. Observa-se que o uso do binfmt_misc é o método mais rápido para iniciar.
- Para Linux, foi proposta a implementação das funcionalidades das chamadas de sistema pledge() e unveil(), desenvolvidas pelo projeto OpenBSD. Uma API é fornecida para o uso dessas chamadas em programas nas linguagens C, C++, Python e Redbean, além de uma ferramenta pledge.com para isolar processos arbitrários.
- Para a montagem, foi utilizada a ferramenta Landlock Make — uma versão do GNU Make com verificação de dependências mais rigorosa e uso da chamada de sistema Landlock para isolar o programa do restante do sistema e aumentar a eficiência do cache. A capacidade de montagem também foi mantida com o GNU Make convencional.
- Foram implementadas funções para multithreading — _spawn() e _join(), que representam wrappers universais sobre APIs específicas de diferentes sistemas operacionais. Também está em andamento o trabalho para implementar suporte a POSIX Threads.
- Foi disponibilizada a utilização da palavra-chave _Thread_local para usar armazenamentos separados para cada thread (TLS, Thread-Local Storage). Por padrão, o runtime C inicializa o TLS para o thread principal, o que levou ao aumento do tamanho mínimo dos arquivos executáveis de 12 para 16 KB.
- Adicionada ao arquivo executável o suporte para os parâmetros ‘—ftrace’ e ‘—strace’ para gerar informações no stderr sobre todas as chamadas de funções e chamadas de sistema.
- Adicionado suporte à chamada de sistema closefrom(), suportada no Linux 5.9+, FreeBSD 8+ e OpenBSD.
- Na plataforma Linux, a performance das chamadas clock_gettime e gettimeofday foi aumentada em até 10 vezes através do uso do mecanismo vDSO (objeto compartilhado dinâmico virtual), que permite mover o manipulador da chamada de 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 transferidas da biblioteca Musl. A execução de muitas funções matemáticas foi acelerada.
- Foi proposta a função nointernet(), que desativa as capacidades de rede.
- Novas funções foram adicionadas para anexo eficiente de strings: appendd, appendf, appendr, appends, appendw, appendz, kappendf, kvappendf e vappendf.
- Uma versão segura da família de funções kprintf() foi adicionada, destinada ao uso com privilégios elevados.
- A performance das implementações foi significativamente aumentada SSL, SHA, curve25519 e RSA.
Fonte: opennet.ru
