Invalid instruction when running a simple ELLCC-generated ELF binary on a Raspberry Pi
I have an empty program in LLVM IR:
define i32 @main(i32 %argc, i8** %argv) nounwind {
entry:
ret i32 0
}
I am cross-compiling it on Intel x86-64 Windows for ARM Linux using ELLCC, with the following command:
ecc++ hw.ll -o hw.o -target arm-linux-engeabihf
It exits without error and generates an ELF binary.
When I take the binary into the Raspberry Pi B + model (works on Raspbian) I only get the following error:
Illegal instruction
I don't know how to tell what is wrong from the parsed code . I tried other ARM Linux targets but the behavior was the same. What's wrong?
The exact same file builds, links and works fine for other purposes like i386-linux-eng
, x86_64-w64-mingw32
etc. (which I can test) using the ELLCC toolchain again.
Assuming the library and startup code are not to blame, here's what the disassembly itself looks like 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
source to share
I am assuming it is choking off movw
at 0x0001018c. The movw
/ encodings movt
, which can handle full 16-bit instantaneous values, first appeared in the ARMv6T2 architecture version - ARM1176 in the original Pi models predates what only the original ARMv6 * supports .
You need to tell the compiler to generate code that matches the one you are working on - I don't know ELLCC, but I would assume it is quite modern and modern and thus newer, like ARMv6T2 or ARMv7. Otherwise, it is akin to code generation for the Pentium and hopes it runs on 80486 - you might get lucky, you might not. However, there is no compelling reason why he should have chosen this encoding in the first place - it is not as if 0 could not be encoded in a "classic" instruction mov
...
The decadent option, however, would have considered it a great excuse to replace the Pi with a Pi 2 - Cortex-A7, which has good ARMv7 cores;)
* False for clarity. I think 1176 might indeed be v6K, but that doesn't matter here. I'm not sure if anything really exists as simple ARMv6, and all the various architecture extensions are an openly disgusting mess.
source to share