在Raspberry Pi上运行简单的ELLCC生成的ELF二进制文件时的非法指令

时间:2015-05-14 16:39:32

标签: arm raspberry-pi cross-compiling raspbian ellcc

我在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-engx86_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

1 个答案:

答案 0 :(得分:3)

我猜它在movw的0x0001018c处窒息。可以处理完整16位立即值的movw / movt编码首先出现在架构的ARMv6T2版本中 - 原始Pi模型中的ARM1176早于此,仅支持原始ARMv6 *

你需要告诉编译器生成适合你正在运行的东西的代码 - 我不知道ELLCC,但我从中猜测它是相当现代的最新的,因此默认为像ARMv6T2或ARMv7更新的东西。否则,它类似于为奔腾生成代码并希望它在80486上运行 - 你可能很幸运,你可能不会。也就是说,首先应该选择编码是没有充分理由的 - 它并不像在经典的“经典”编码中那样编码0。 mov指令......

然而,颓废的选择是将这个作为用Pi 2替换Pi的完美借口 - Cortex-A7s是功能强大的ARMv7内核;)

*为了清晰起见。我认为1176可能实际上是v6K,但这与此无关。我不确定是否有任何实际存在的普通ARMv6,并且所有各种架构扩展都是坦率的混乱