从Linux交叉编译ARM64汇编到Mac时的执行格式错误排查
x86-64 Linux交叉编译ARM64 macOS Hello World 执行格式错误排查与解决
在x86-64 Linux环境下交叉编译ARM64汇编版Hello World,运行生成的linuxbuild.out时出现exec format error: ./linuxbuild.out(错误码126)。对比objdump输出发现生成文件缺少__mh_execute_header符号,尝试过给链接器加-F参数和使用懒加载库均无效。
操作详情
汇编代码 hello.s
.global _main .align 2 _main: mov X0, #1 adr X1, hello mov X2, #13 mov X16, #4 svc 0 mov X0, #0 mov X16, #1 svc 0 hello: .ascii "Hello\n"
编译命令
clang hello.s --target=arm64-apple-macosx12.5.0 -c -o h.o ld64.lld h.o -arch arm64 -platform_version macos 12 5 -v -dylib -o linuxbuild.out
编译输出
LLD 14.0.6 Library search paths: /usr/lib /usr/local/lib Framework search paths: ld64.lld: warning: h.o has version 12.5.0, which is newer than target minimum of 12
objdump对比结果
% /opt/homebrew/opt/binutils/bin/objdump -x a.out linuxbuild.out a.out: file format mach-o-arm64 a.out architecture: aarch64, flags 0x00000012: EXEC_P, HAS_SYMS start address 0x0000000100003f90 MACH-O header: magic: 0xfeedfacf cputype: 0x100000c (ARM64) cpusubtype: 0 (ARM64_ALL) filetype: 0x2 ncmds: 0x10 sizeocmds: 0x2e8 flags: 0x200085 version: 2 Sections: Idx Name Size VMA LMA File off Algn 0 .text 00000026 0000000100003f90 0000000100003f90 00003f90 2**2 CONTENTS, ALLOC, LOAD, CODE 1 __TEXT.__unwind_info 00000048 0000000100003fb8 0000000100003fb8 00003fb8 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE SYMBOL TABLE: 0000000100003fb0 l 0e SECT 01 0000 [.text] hello 0000000100000000 g 0f SECT 01 0010 [.text] __mh_execute_header 0000000100003f90 g 0f SECT 01 0000 [.text] _main linuxbuild.out: file format mach-o-arm64 linuxbuild.out architecture: aarch64, flags 0x00000050: HAS_SYMS, DYNAMIC start address 0x0000000000000000 MACH-O header: magic: 0xfeedfacf cputype: 0x100000c (ARM64) cpusubtype: 0 (ARM64_ALL) filetype: 0x6 ncmds: 0xb sizeocmds: 0x208 flags: 0x100085 version: 2 Sections: Idx Name Size VMA LMA File off Algn 0 .text 00000026 0000000000000248 0000000000000248 00000248 2**2 CONTENTS, ALLOC, LOAD, CODE SYMBOL TABLE: 0000000000000268 l 0e SECT 01 0000 [.text] hello 0000000000000248 g 0f SECT 01 0000 [.text] _main
问题根源与解决方法
核心问题
链接时使用了-dylib参数,生成的是动态库(filetype 0x6)而非可执行文件(filetype 0x2)。动态库无法直接执行,导致exec format error;同时动态库不会生成__mh_execute_header符号,该符号是Mach-O可执行文件的入口标识。修复步骤
替换链接器参数,去掉-dylib,添加-e _main指定入口函数,生成可执行文件:ld64.lld h.o -arch arm64 -platform_version macos 12 5 -v -e _main -o linuxbuild.out重新编译后,通过
objdump验证:文件类型应为EXEC_P,符号表中会出现__mh_execute_header。额外说明
汇编代码使用的是macOS系统调用规则(X16存放系统调用号,svc 0触发),生成的可执行文件仅能在ARM64 macOS环境运行,无法直接在Linux(包括ARM64 Linux)上执行——两者系统调用机制不同。若需在Linux运行,需修改为ARM64 Linux的系统调用方式(X8存放系统调用号,svc #0触发)。
内容的提问来源于stack exchange,提问作者Stan
相关产品推荐
相关产品推荐

