在macOS上用ld转arm64二进制为Mach-O时遇_start符号缺失问题
问题分析与解决方案
问题根源
你通过ld -r -sectcreate将output.bin打包进了__TEXT/_start段,但没有为该段的起始地址绑定_start符号。链接器在第三步需要找到_start符号作为入口点,但当前output.o中仅存在段数据,无对应符号定义,因此报错。
解决方法
方法一:直接在链接时添加符号
修改第二步的ld命令,通过-addsym参数手动将_start符号绑定到__TEXT/_start段的起始位置:
ld -r -o output.o stub.o -sectcreate __TEXT _start output.bin -addsym _start:0:__TEXT,_start
-addsym格式说明:符号名:偏移量:段名,段子名,这里偏移量设为0,因为你的机器码从段的起始位置开始。
执行完该命令后,运行nm output.o应该能看到:
0000000000000000 T _start
此时再执行第三步的链接命令即可成功生成可执行文件。
方法二:用汇编文件定义符号(更直观)
创建一个汇编文件start.s,通过.incbin导入你的机器码并显式定义_start符号:
.global _start _start: .incbin "output.bin"
编译该汇编文件:
as -o start.o start.s -arch arm64
将其与空存根对象合并(若不需要stub.o可直接跳过此步):
ld -r -o output.o start.o stub.o
最后执行第三步的链接命令即可。
额外说明
空stub.o的作用仅为让链接器生成合法的Mach-O结构,若你的BF编译代码已包含所有必要的系统调用依赖,也可直接用汇编生成的start.o进行链接,无需stub.o。
内容的提问来源于stack exchange,提问作者Joseph
相关产品推荐
相关产品推荐

