-
Notifications
You must be signed in to change notification settings - Fork 0
Description
现象
同一套 Nix flake 生成的交叉工具链,在 Linux 上可以正常链接;在 macOS(Darwin)上使用 h8300-elf-gcc 链接时,vfprintf/vfiprintf 触发的 64 位无符号除法 helper 未定义:
.../newlib/libc/stdio/vfprintf.c:1348:(.text+0xcc3): undefined reference to __umoddi3' .../newlib/libc/stdio/vfprintf.c:1369:(.text+0xcfb): undefined reference to __udivdi3'
环境
Host A(Linux):链接成功
Host B(macOS / Darwin):链接失败
binutils(target):h8300-elf-2.44
GCC(target):h8300-elf-14.3.0
newlib:4.5.0.20241231
两端链接行均由 h8300-elf-gcc 驱动生成,顺序包含 -lgcc -lc -lgcc;两端实际使用的 libgcc.a 路径一致:
/nix/store/c777lnv6977yqk4pd3wcw6y694d3zasn-gcc-h8300-elf-14.3.0/lib/gcc/h8300-elf/14.3.0/libgcc.a
复现步骤(最小化)
使用上述版本的 h8300-elf 工具链与 newlib(sysroot 指向 newlib)。
编译并链接包含 printf("%llu\n", 0ULL); 的最小程序(或任何会触发 vfprintf 处理 long long 的用例)。
在 Linux 主机:链接通过。
在 macOS 主机:出现 __udivdi3/__umoddi3 未定义。
期望结果
两端行为一致;在 macOS 上也应成功解析并链接到 libgcc 中的 64 位除法 helper。
实际结果
Linux:OK。
macOS:undefined reference to __udivdi3/__umoddi3。
已做排查
确认链接顺序:对象在前,随后 -lgcc -lc -lgcc,与 Linux 侧一致。
确认库一致:两端均指向同一 libgcc.a 绝对路径(见上)。
确认符号存在:在 macOS 上用交叉版 h8300-elf-nm -g $(h8300-elf-gcc -print-libgcc-file-name) 能看到 __udivdi3/__umoddi3 导出(苹果自带 nm 对 GNU archive 有误报,但不作为依据)。
与 LTO 无关:禁用 LTO 亦可复现;不依赖 -plugin 的结果相同。
可能原因(供参考)
macOS 与 Linux 的 ld.bfd 在静态归档扫描/重扫时存在行为差异;vfprintf.o 在 -lc 内引入未定义后,macOS 侧未在随后的扫描中匹配到 libgcc.a 中的 helper,导致未定义残留。(Linux 侧则能命中。)
附:一次失败的链接行(节选)
collect2 --sysroot=... -m h8300helf
.../crt0.o .../crti.o .../crtbegin.o
-L.../h8300-elf/14.3.0 -L.../newlib-h8300-elf-4.5.0.20241231/h8300-elf/lib
-lgcc -lc -lgcc
.../crtend.o .../crtn.o
影响程度
低(目前可绕过或暂不依赖 %lld/%llu 打印);报告此差异供维护者评估。