C 库与 glibc 的历史

最后更新: 2023-11-22 04:35:36 +0800 +0800
tags: History | Libc | Linux | Glibc
原文以英文撰写。您正在阅读AI翻译版本。

Linux 应用程序依赖两个不同的接口:内核系统调用 ABI 和 C 库。ABI 定义了在特定架构上进入内核的方式。C 库实现程序编译所依赖的 ISO C 和 POSIX 接口,并添加进程启动代码、动态加载器、名称服务查询、线程支持、区域设置处理,以及许多无法映射到单个系统调用的接口。因此,内核并不提供完整的 C 运行时。

GNU libc 的起源与发行版本 #

Richard Stallman 于 1983 年 9 月 27 日宣布了 GNU 项目。GNU libc 的开发在 20 世纪 80 年代后期继续进行;Roland McGrath 是最早公开贡献者之一。1988 年的 GNU Bulletin 报道称,大多数库已经完成。

早期发行资料必须谨慎对待。GNU FTP 存档保留了历史 glibc 补丁和发行存档,但存档覆盖范围并不是完整的发行数据库。例如,glibc 1.x 时代的发行版本和补丁采用了不同的可用性与日期记录惯例。与回溯整理的版本列表或软件包元数据相比,存档是更有力的证据。

glibc 2.0 于 1997 年 1 月发布,2.x 系列随后成为 GNU libc 持续发展的 ABI 系列。当前源代码、发行资料和手册由项目在 sourceware.org 以及 glibc 源代码仓库中维护。“glibc 2.x”描述的是一个源代码和 ABI 家族;对受支持的旧接口的兼容性通过 ABI 规则管理,而不是在每次发行时更改主库文件名。

从 Linux libc 到 glibc #

早期 Linux 系统采用了 GNU libc 的代码,之后 Linux 开发者维护了一个特定于 Linux 的分支,而上游 glibc 则独立开发。这个分支通常称为 Linux libc。其共享库世代包括 libc4 和 libc5:

  1. libc4 及更早版本支持历史 a.out 可执行文件环境中的程序。
  2. libc5 伴随 Linux 向 ELF 共享对象的过渡,使发行版能够采用现代动态链接模型。
  3. 此后,各发行版迁移到 GNU libc 2.x。Debian 派生软件包名称(例如 libc6)标识 glibc 2.x 共享库 ABI 世代,并不表示“glibc 版本 6”。

kernel.org 的 libc5 存档保存了后期的源代码快照。它是研究源代码历史的适当起点;关于某个具体分支点、发行日期或维护者的说法,应当与相应的存档代码树或发行公告进行核对。目录重组和代码导入使得声称存在单一源代码谱系会产生误导。

为什么 libc 迁移属于 ABI 迁移 #

替换 libc 不仅需要重新编译可执行文件,因为该库参与了进程 ABI:

  • 启动对象负责安排进入 main 以及进程终止;
  • 动态加载器查找共享对象并解析符号;
  • 导出的结构体、调用约定和版本化符号决定旧二进制文件能否继续加载;
  • 解析器和名称服务切换(NSS)模块实现服务查询;以及
  • POSIX 线程协调用户空间状态与内核同步原语。

因此,升级必须保持加载器、开发头文件、共享库、NSS 模块、软件包管理器和恢复工具之间的一致性。针对某个 libc 构建的二进制文件,如果需要不可用的符号版本,或者其 ELF PT_INTERP 段中记录的解释器无法找到,则可能在进入 main 之前失败。glibc 的 ABI 列表记录了受支持架构所公开的符号集合和版本基线各不相同。

Linux C 库的选择 #

glibc 并不是唯一实现 Linux 系统调用 ABI 的 C 库:

  • musl强调紧凑、面向标准的设计,常用于静态链接系统和最小化系统。
  • uClibc-ng面向具有可配置功能的嵌入式 Linux 系统。
  • Android 的 Bionic针对 Android 平台进行了定制。

源代码兼容性并不意味着二进制兼容性。即使程序的源代码看起来具有可移植性,glibc 扩展、符号版本、动态加载器行为、NSS 模块和 ABI 细节仍可能使其特定于 glibc。关于当前行为,应使用项目维护的最新手册;调查历史二进制文件时,应使用发行存档、原始头文件、目标架构 ABI 以及匹配的内核版本。

阅读历史文档 #

当前的手册页记录当前接口,并且可能说明某种行为何时出现或发生变化。历史源代码和二进制文件必须结合原始头文件、C 库、架构 ABI 以及内核行为进行解释。存档资料可以为 libc5 到 glibc 的迁移提供背景,但当前构建应遵循所选 C 库和发行版维护的文档。

评论

在 GitHub 上阅读或评论(发表评论需要登录)