发布标准 C 库 Cosmopolitan 2.0,专为可移植可执行文件而开发

Cosmopolitan 2.0项目的版本已经发布,开发了标准C库和通用可执行文件格式,可用于为不同操作系统分发程序,而无需使用解释器和虚拟机。 在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 引导扇区' exec 7 $(命令 -v $0) printf '\177ELF...LINKER-ENCODED-FREEBSD-HEADER' >&7 exec "$0" "$@" exec qemu-x86_64 "$0" "$ @" 退出 1 实模式... ELF 段... OpenBSD 注意... MACHO 标头... 代码和数据... ZIP 目录...

在文件的开头,标有“MZqFpD”标签,该标签被视为 Windows PE 格式标头。 该序列也在指令“pop %r10;”中被解码。 jno 0x4a; jo 0x4a”,以及指令“jg 177x0”的“\47ELF”行,用于转发到入口点。 Unix 系统运行使用 exec 命令的 shell 代码,通过无名管道传递可执行代码。 所提出方法的局限性是只能使用支持 Thompson Shell 兼容模式的 shell 在类 Unix 操作系统上运行。

qemu-x86_64 调用提供了额外的可移植性,并允许为 x86_64 架构编译的代码在非 x86 平台上运行,例如 Raspberry Pi 板和配备 ARM 处理器的 Apple 设备。 该项目还可用于创建无需操作系统(裸机)即可运行的独立应用程序。 在此类应用中,引导加载程序附加到可执行文件,并且该程序充当可引导操作系统。

该项目开发的标准C库libc提供了2024个函数(在第一个版本中约有1400个函数)。 在性能方面,Cosmopolitan 的运行速度与 glibc 一样快,并且明显领先于 Musl 和 Newlib,尽管 Cosmopolitan 的代码大小比 glibc 小一个数量级,并且大致相当于 Musl 和 Newlib。 为了优化memcpy和strlen等频繁调用的函数,还使用了“滴流性能”技术,其中使用宏绑定来调用函数,其中编译器被告知代码执行中涉及的CPU寄存器进程,它允许在保存 CPU 状态时通过仅保存可更改的寄存器来节省资源。

新版本的变化包括:

  • 访问 zip 文件内的内部资源的方案已更改(打开文件时,现在使用通常的 /zip/... 路径,而不是使用 zip:.. 前缀)。 同样,要访问 Windows 中的磁盘,可以使用“/c/...”等路径而不是“C:/...”。
  • 提出了一种新的 APE(Actually Portable Executable)加载器,它定义了通用可执行文件的格式。 新的加载程序使用 mmap 将程序放入内存中,不再动态更改内容。 如有必要,通用可执行文件可以转换为与各个平台绑定的常规可执行文件。
  • 在Linux平台上,可以使用binfmt_misc内核模块来运行APE程序。 值得注意的是,使用 binfmt_misc 是最快的启动方法。
  • 对于Linux,已经提出了由OpenBSD 项目开发的pledge() 和unvell() 系统调用功能的实现。 提供了一个API,用于在C、C++、Python 和Redbean 程序中使用这些调用,以及用于隔离任意进程的pledge.com 实用程序。
  • 该构建使用 Landlock Make 实用程序 - GNU Make 的一个版本,具有更严格的依赖性检查,并使用 Landlock 系统调用将程序与系统的其余部分隔离并提高缓存效率。 作为一个选项,保留了使用常规 GNU Make 进行构建的能力。
  • 多线程函数已实现 - _spawn() 和 _join(),它们是特定于不同操作系统的 API 的通用绑定。 实现 POSIX 线程支持的工作也在进行中。
  • 可以使用 _Thread_local 关键字为每个线程使用单独的存储(TLS,线程本地存储)。 默认情况下,C 运行时为主线程初始化 TLS,这导致最小可执行文件大小从 12 KB 增加到 16 KB。
  • 可执行文件中添加了对“--ftrace”和“--strace”参数的支持,以将有关所有函数调用和系统调用的信息输出到 stderr。
  • 添加了对 closefrom() 系统调用的支持,在 Linux 5.9+、FreeBSD 8+ 和 OpenBSD 上受支持。
  • 在Linux平台上,通过使用vDSO(虚拟动态共享对象)机制,clock_gettime和gettimeofday调用的性能最高提高了10倍,这使得将系统调用处理程序移至用户空间并避免上下文切换成为可能。
  • 用于处理复数的数学函数已从 Musl 库中移出。 许多数学函数的工作都得到了加速。
  • nointernet() 函数已被提议用于禁用网络功能。
  • 添加了用于高效附加字符串的新函数:append、appendf、appendr、appends、appendw、appendz、kappendf、kvappendf 和 vappendf。
  • 添加了 kprintf() 系列函数的受保护版本,旨在使用提升的权限。
  • 显着提高了 SSL、SHA、curve25519 和 RSA 实施的性能。

来源: opennet.ru

添加评论