我在LLVM IR中有一个空程序:
define i32 @main(i32 %argc, i8** %argv) nounwind {
entry:
ret i32 0
}
我使用ELLCC在Intel x86-64 Windows for ARM Linux上交叉编译,使用以下命令:
ecc++ hw.ll -o hw.o -target arm-linux-engeabihf
完成没有错误并生成ELF二进制文件。
当我将二进制文件带到Raspberry Pi Model B +(运行Raspbian)时,我只得到以下错误:
Illegal instruction
我不知道怎么告诉我the disassembled code的错误。我尝试了其他ARM Linux目标,但行为是一样的。怎么了?
完全相同的文件构建,链接并且可以运行其他目标,例如i386-linux-eng
,x86_64-w64-mingw32
等(我可以测试),再次使用ELLCC工具链。
假设库和启动代码没有错,这就是main
本身的反汇编:
.text:00010188 e24dd008 sub sp, sp, #8
.text:0001018c e3002000 movw r2, #0
.text:00010190 e58d0004 str r0, [sp, #4]
.text:00010194 e1a00002 mov r0, r2
.text:00010198 e58d1000 str r1, [sp]
.text:0001019c e28dd008 add sp, sp, #8
.text:000101a0 e12fff1e bx lr
答案 0 :(得分:3)
我猜它在movw
的0x0001018c处窒息。可以处理完整16位立即值的movw
/ movt
编码首先出现在架构的ARMv6T2版本中 - 原始Pi模型中的ARM1176早于此,仅支持原始ARMv6 *
你需要告诉编译器生成适合你正在运行的东西的代码 - 我不知道ELLCC,但我从中猜测它是相当现代的最新的,因此默认为像ARMv6T2或ARMv7更新的东西。否则,它类似于为奔腾生成代码并希望它在80486上运行 - 你可能很幸运,你可能不会。也就是说,首先应该选择编码是没有充分理由的 - 它并不像在经典的“经典”编码中那样编码0。 mov
指令......
*为了清晰起见。我认为1176可能实际上是v6K,但这与此无关。我不确定是否有任何实际存在的普通ARMv6,并且所有各种架构扩展都是坦率的混乱