使用标志 _FILE_OFFSET_BITS=64 和 _TIME_BITS=64 构建 glibc 失败

问题描述 投票:0回答:1

我想做的是在 glibc 中修复 Y2038 问题。 我在 Ubuntu 18.04 VM 中使用 buildroot 2022.02.2 来交叉编译 32 位 ARM CPU。 我读到添加额外的标志 _FILE_OFFSET_BITS=64 和 _TIME_BITS=64 应该可以做到这一点,但我得到这样的构建错误

/tmp/cclzLgs6.s:汇编器消息: /tmp/cclzLgs6.s:138:错误:符号“__sigtimedwait64”是 已经定义了

2.34 中是否提供对 Y2038 问题的支持,还是正在进行中? 或者也许我做错了什么,比如缺少一些标志?

谢谢你, 卡塔林

arm glibc buildroot
1个回答
2
投票

您可以执行以下操作来获取 Y2038 安全 buildroot 32 位 ARM 系统:

  1. 使用预编译的 ARM 工具链:https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads。版本 11.2-2022.02 由 GCC 11.2 和 glibc 2.34 组成。 (glibc 2.34 中引入了 _TIME_BITS=64 选项。)
  2. 使用版本 >= 5.1 的 Linux 内核。 https://sourceware.org/pipermail/libc-alpha/2021-August/129718.html 表示需要 5.1 才能完全支持 64 位时间。
  3. 曾尝试在https://github.com/buildroot/buildroot/commit/6e33e5908086a511294296f317f6e6f86fa84b1d中的buildroot中启用系统范围的_TIME_BITS=64,但后来在https://github.com/buildroot/中恢复buildroot/commit/dd170f0cbad729dba4193b2b20e3de0a7010d485 由于无法构建某些软件包。你还应该做的是根据第一个补丁添加_TIME_BITS=64。
  4. 对于某些未定义 _FILE_OFFSET_BITS 的包,特别是 zlib 包以及在代码中嵌入 zlib 的包,您可能会遇到构建错误。这里的一个简单修复是修改这些包中的代码,以便每当 _FILE_OFFSET_BITS 未定义时也取消定义 _TIME_BITS。这似乎在我看过的所有情况下都有效,因为受影响的编译单元无论如何都不使用任何时间函数。

例如,将此补丁作为 0002-time-bits.patch 放在 buildroot/package/libzlib/ 中:

--- a/gzguts.h
+++ b/gzguts.h
@@ -9,6 +9,7 @@
 #  endif
 #  ifdef _FILE_OFFSET_BITS
 #    undef _FILE_OFFSET_BITS
+#    undef _TIME_BITS
 #  endif
 #endif
 

这是必需的,因为 glibc 标头中有一个断言,当 _TIME_BITS 为 64 但 _FILE_OFFSET_BITS 不是 64 时会出错。

更新:

新发布的 zlib 1.3 版本包含上述补丁(https://github.com/madler/zlib/commit/a566e156b3fa07b566ddbf6801b517a9dba04fa3)。

我注意到的一件事是,可以从其网站下载的预编译 ARM 工具链与内核 v4.20.13 的 Linux 内核头文件捆绑在一起。在某些情况下,这些旧标头与 _TIME_BITS=64 不兼容,例如 SO_TIMESTAMP/SCM_TIMESTAMP 的使用,因为这些旧标头定义了不正确的(旧)整数。我在运行 btmon 记录器时通过看到损坏的时间戳注意到了这一点。我决定使用更新的 Linux 内核标头构建自己的工具链,目标是我实际使用的 Linux 内核版本。

幸运的是,由于自动构建脚本和 ARM 工具链每个版本提供的说明,从头开始构建工具链相对简单,可以通过单击相关下载部分底部的“版本说明”链接找到这些说明。这些说明可在“使用 Linaro 的 ABE 从源构建 Linux 托管工具链”下找到。该示例适用于

arm-gnu-toolchain-aarch64-none-elf
,但相应的说明也适用于
arm-gnu-toolchain-arm-none-linux-gnueabihf

在下载的manifest文件中,我将

linux_revision=v4.20.13
更改为
linux_revision=v6.3
(这是我的目标内核版本)并删除了
linux_md5sum
行(我懒得找出校验和)。由于一些非常奇怪的原因,示例清单中的
gcc_stage2_flags
与预编译发布的二进制文件中使用的明显不同。值得注意的是,由于示例清单文件中的
--disable-libatomic
,libatomic 未包含在内。但许多 buildroot 包都需要 libatomic,例如需要对大于 8 字节的对象执行“原子操作”,或者恰好链接到 libatomic.so 的包。为了更好地与二进制版本保持一致,我从 --disable-libatomic --without-cloog --without-isl --disable-libgomp --disable-libquadmath 中删除了
gcc_stage2_flags
(但没有触及
gcc_stage1_flags
)。
用这个新工具链替换预编译的工具链后,btmon 现在显示正确的时间戳。

再次更新:

Buildroot 终于正式添加了 _TIME_BITS=64 标志,您可以通过配置选项

BR2_TIME_BITS_64

轻松启用该标志。请注意,您仍然应该确保您拥有使用适当的 Linux 标头构建的工具链,如上所述。

© www.soinside.com 2019 - 2024. All rights reserved.