Недопустимая инструкция при запуске простого ELLCC-сгенерированного двоичного файла ELF на Raspberry Pi

У меня есть пустая программа в LLVM IR:

define i32 @main(i32 %argc, i8** %argv) nounwind {
entry:
    ret i32 0
}

Я кросс-компилирую его на Intel x86-64 Windows для ARM Linux, используя ELLCC, с помощью следующей команды:

ecc++ hw.ll -o hw.o -target arm-linux-engeabihf

Он завершается без ошибок и генерирует двоичный файл ELF.

Когда я беру двоичный файл в Raspberry Pi Model B+ (работает Raspbian), я получаю только следующую ошибку:

Illegal instruction

Я не знаю, как сказать, что не так из разобранного кода. Я пробовал другие цели 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

1 ответ

Решение

Я предполагаю, что это задыхается от movw в 0x0001018c. movw / movt кодировки, которые могут обрабатывать полные 16-битные непосредственные значения, впервые появились в версии архитектуры ARMv6T2 - ARM1176 в оригинальных моделях Pi предшествовал этому, поддерживая только оригинальную ARMv6 *.

Вы должны сказать компилятору генерировать код, соответствующий тому, на чем вы работаете - я не знаю ELLCC, но я предполагаю, что он довольно современный и современный и, следовательно, по умолчанию использует что-то более новое, например ARMv6T2. или ARMv7. В противном случае это сродни генерации кода для Pentium и надежде, что он будет работать на 80486 - вам может повезти, а может и нет. Тем не менее, нет веской причины, по которой он должен был выбрать это кодирование в первую очередь - это не так, как если бы 0 не могло быть закодировано в "классическом" mov инструкция...

Декадентским вариантом, однако, было бы считать это идеальным оправданием для замены Pi на Pi 2 - Cortex-A7s в том, что это хорошие ядра ARMv7;)

* Ложь для ясности. Я думаю, что 1176 на самом деле может быть v6K, но это не имеет значения здесь. Я не уверен, существует ли что-нибудь на самом деле как простой ARMv6, и все различные расширения архитектуры откровенно отвратительны

Другие вопросы по тегам