Я хотел использовать кросс-компилятор для тестирования дизайна or1200
, в котором я выполнял некоторые тесты на другой машине. На другой машине были двоичные файлы цепочки инструментов or32-uclinux-
, и я скопировал их на свою машину с Ubuntu 20.04.
Двоичные файлы работают нормально, но когда я попытался скомпилировать свой ассемблерный код с помощью
or32-uclinux-gcc -c custom.S -o assembly_code_obj.o
Это дало мне кучу ошибок, таких как
custom.S: Assembler messages:
custom.S:19: Error: no such instruction: `l.nop 0x0'
custom.S:20: Error: no such instruction: `l.nop 0x0'
custom.S:23: Error: no such instruction: `l.movhi r3,hi(_simple_test_asm)'
custom.S:24: Error: no such instruction: `l.ori r3,r3,lo(_simple_test_asm)'
custom.S:25: Error: no such instruction: `l.jr r3'
custom.S:33: Error: no such instruction: `l.addi r1,r0,0xff'
custom.S:34: Error: no such instruction: `l.addi r2,r0,0x06'
custom.S:35: Error: no such instruction: `l.nop'
custom.S:36: Error: no such instruction: `l.nop'
custom.S:37: Error: no such instruction: `l.nop'
custom.S:38: Error: no such instruction: `l.nop'
custom.S:39: Error: no such instruction: `l.nop'
custom.S:40: Error: no such instruction: `l.div r3,r1,r2'
custom.S:42: Error: no such instruction: `l.nop 0x0001'
В чем тут может быть проблема?
Вывод or32-uclinux-gcc -c custom.S -o custom.o -v
or32-uclinux-gcc -c custom.S -o custom.o -v
Reading specs from /home/broxigar/utilities/or32/bin/../lib/gcc-lib/or32-uclinux/3.2.3/specs
Configured with: ./configure --target=or32-uclinux --prefix=/opt/or32-uclinux --local-prefix=/opt/or32-uclinux/or32-uclinux --with-gnu-as --with-gnu-ld --verbose --enable-languages=c : (reconfigured) ./configure --host=i686-pc-linux --target=arm-elf --prefix=/usr/local -v --with-newlib : (reconfigured) ./configure --target=or32-uclinux --prefix=/opt/or32-uclinux --local-prefix=/opt/or32-uclinux/or32-uclinux --with-gnu-as --with-gnu-ld --verbose --enable-languages=c : (reconfigured) ./configure --target=or32-uclinux --prefix=/opt/or32-uclinux --local-prefix=/opt/or32-uclinux/or32-uclinux --with-gnu-as --with-gnu-ld --verbose --enable-languages=c
Thread model: single
gcc version 3.2.3
/home/broxigar/utilities/or32/bin/../lib/gcc-lib/or32-uclinux/3.2.3/cpp0 -lang-asm -v -iprefix /home/broxigar/utilities/or32/bin/../lib/gcc-lib/or32-uclinux/3.2.3/ -D__GNUC__=3 -D__GNUC_MINOR__=2 -D__GNUC_PATCHLEVEL__=3 -D__GXX_ABI_VERSION=102 -Dunix -Dlinux -D__ELF__ -DOR1K -Dor1k -D__or1k__ -D__OR1K__ -D__unix__ -D__linux__ -D__ELF__ -D__OR1K__ -D__or1k__ -D__or1k__ -D__OR1K__ -D__unix -D__linux -D__OR1K -D__or1k -Asystem=unix -Asystem=posix -D__NO_INLINE__ -D__STDC_HOSTED__=1 custom.S -o /tmp/ccmryjef.s
GNU CPP version 3.2.3 (cpplib) (OR32 GNU/Linux with ELF)
ignoring nonexistent directory "/home/broxigar/utilities/or32/lib/gcc-lib/or32-uclinux/../../../or32-uclinux/sys-include"
ignoring nonexistent directory "/home/broxigar/utilities/or32/lib/gcc-lib/or32-uclinux/../../../or32-uclinux/include"
ignoring nonexistent directory "/opt/or32-uclinux/include"
ignoring nonexistent directory "/opt/or32-uclinux/lib/gcc-lib/or32-uclinux/3.2.3/include"
ignoring nonexistent directory "/opt/or32-uclinux/lib/gcc-lib/or32-uclinux/3.2.3/../../../../or32-uclinux/sys-include"
ignoring nonexistent directory "/opt/or32-uclinux/lib/gcc-lib/or32-uclinux/3.2.3/../../../../or32-uclinux/include"
#include "..." search starts here:
#include <...> search starts here:
/home/broxigar/utilities/or32/lib/gcc-lib/or32-uclinux/3.2.3/include
End of search list.
as --traditional-format -o custom.o /tmp/ccmryjef.s // <====== Invoking the wrong assembler for the x86 architecture
custom.S: Assembler messages:
custom.S:19: Error: no such instruction: `l.nop 0x0'
custom.S:20: Error: no such instruction: `l.nop 0x0'
custom.S:23: Error: no such instruction: `l.movhi r3,hi(_simple_test_asm)'
custom.S:24: Error: no such instruction: `l.ori r3,r3,lo(_simple_test_asm)'
custom.S:25: Error: no such instruction: `l.jr r3'
custom.S:33: Error: no such instruction: `l.addi r1,r0,0xff'
custom.S:34: Error: no such instruction: `l.addi r2,r0,0x06'
custom.S:35: Error: no such instruction: `l.nop'
custom.S:36: Error: no such instruction: `l.nop'
custom.S:37: Error: no such instruction: `l.nop'
custom.S:38: Error: no such instruction: `l.nop'
custom.S:39: Error: no such instruction: `l.nop'
custom.S:40: Error: no such instruction: `l.div r3,r1,r2'
custom.S:42: Error: no such instruction: `l.nop 0x0001'
Вывод or32-uclinux-gcc -c custom.S -o custom.o -v
Reading specs from /software/or32-uclinux/bin/../lib/gcc-lib/or32-uclinux/3.2.3/specs
Configured with: ./configure --target=or32-uclinux --prefix=/opt/or32-uclinux --local-prefix=/opt/or32-uclinux/or32-uclinux --with-gnu-as --with-gnu-ld --verbose --enable-languages=c : (reconfigured) ./configure --host=i686-pc-linux --target=arm-elf --prefix=/usr/local -v --with-newlib : (reconfigured) ./configure --target=or32-uclinux --prefix=/opt/or32-uclinux --local-prefix=/opt/or32-uclinux/or32-uclinux --with-gnu-as --with-gnu-ld --verbose --enable-languages=c : (reconfigured) ./configure --target=or32-uclinux --prefix=/opt/or32-uclinux --local-prefix=/opt/or32-uclinux/or32-uclinux --with-gnu-as --with-gnu-ld --verbose --enable-languages=c
Thread model: single
gcc version 3.2.3
/software/or32-uclinux/bin/../lib/gcc-lib/or32-uclinux/3.2.3/cpp0 -lang-asm -v -iprefix /software/or32-uclinux/bin/../lib/gcc-lib/or32-uclinux/3.2.3/ -D__GNUC__=3 -D__GNUC_MINOR__=2 -D__GNUC_PATCHLEVEL__=3 -D__GXX_ABI_VERSION=102 -Dunix -Dlinux -D__ELF__ -DOR1K -Dor1k -D__or1k__ -D__OR1K__ -D__unix__ -D__linux__ -D__ELF__ -D__OR1K__ -D__or1k__ -D__or1k__ -D__OR1K__ -D__unix -D__linux -D__OR1K -D__or1k -Asystem=unix -Asystem=posix -D__NO_INLINE__ -D__STDC_HOSTED__=1 custom.S -o /tmp/ccUm7N9j.s
GNU CPP version 3.2.3 (cpplib) (OR32 GNU/Linux with ELF)
ignoring nonexistent directory "/software/or32-uclinux/or32-uclinux/sys-include"
ignoring nonexistent directory "/software/or32-uclinux/or32-uclinux/include"
ignoring nonexistent directory "/opt/or32-uclinux/include"
ignoring nonexistent directory "/opt/or32-uclinux/lib/gcc-lib/or32-uclinux/3.2.3/include"
ignoring nonexistent directory "/opt/or32-uclinux/lib/gcc-lib/or32-uclinux/3.2.3/../../../../or32-uclinux/sys-include"
ignoring nonexistent directory "/opt/or32-uclinux/lib/gcc-lib/or32-uclinux/3.2.3/../../../../or32-uclinux/include"
#include "..." search starts here:
#include <...> search starts here:
/software/or32-uclinux/lib/gcc-lib/or32-uclinux/3.2.3/include
End of search list.
/software/or32-uclinux/bin/../lib/gcc-lib/or32-uclinux/3.2.3/../../../../or32-uclinux/bin/as --traditional-format -o custom.o /tmp/ccUm7N9
Также убедитесь, что ваш кросс-gcc умеет запускать кросс-ассемблер. Для тестирования просто запустите or32-uclinux-as
(или как там это называется) напрямую. Вы получаете ошибку для каждой инструкции или есть некоторые, которые принимаются?
@PeterCordes да, конечно. Точно такой же код прекрасно работает на исходной машине, с которой я взял двоичные файлы.
@Jester или 32-uclinux-as работает. Я имею в виду, что если я запускаю or32-uclinux-as --help
, мне подсказывают справочную информацию :( Кроме того, каждая инструкция ошибочна
Но будет ли эта ошибка печати, если вы это сделаете or32-uclinux-as custom.S -o assembly_code_obj.o
(при условии, что вашему .S
действительно не нужен препроцессор, иначе сначала запустите его через cpp).
Он запускается и генерирует объектный файл соответствующим образом @Jester. Проблема связана с gcc. И мне нужен gcc в моем потоке.
Значит, ваш gcc вызывает не тот ассемблер.
@Jester правда, но это действительно странно. Как это могло произойти. Я имею в виду, что я просто взял бинарники, а не ./configure
и make
их. Итак, это действительно странно.
Это может означать, что в рабочей системе as
(или что-то еще, что вызывает gcc
) есть символическая ссылка или иное перенаправление на правильную. Добавьте опцию -v
к вашей команде gcc
, чтобы увидеть, что она делает.
Я обновляю вопрос с подробным выводом компилятора
Да так он просто работает as
. Нужно убедиться, что это относится к кросс-ассемблеру.
@Jester хм, есть предложения, как это сделать? ^^
В моей системе /usr/bin/as
— это символическая ссылка. Вы можете обновить это, чтобы указать на or32-uclinux-as
. Вы также можете поместить новую символическую ссылку в каталог, который вы ранее поместили в PATH
, и убедиться, что gcc
вызывается с этим набором PATH
.
@Jester, но если я изменю это так, не будет ли это проблемой для остальных gcc?
Если вы используете второй вариант и устанавливаете этот PATH
только при запуске кросс-gcc, это не должно влиять на другую архитектуру. Вы также можете проверить исходную машину, с которой вы скопировали. Посмотрите на /usr/bin/as
и which as
и as --version
.
@Jester Это ассемблер ОС, то есть x86_64-suse-linux
. Но на этой машине тулчейн работает без проблем.
И что говорит добавление -v
к gcc
на этой машине?
@Jester добавил это к вопросу. Он находит соответствующий ассемблер
Сравните файлы specs
.
Давайте продолжим обсуждение в чате.
Вы можете попробовать GCC_EXEC_PREFIX=/somewhere or32-uclinux-gcc
или COMPILER_PATH=/somewhere or32-uclinux-gcc
, где /somewhere
— это каталог с записью as
, которая является символической ссылкой на кросс-ассемблер. Я думаю, что GCC использует это для поиска as
, а не только внутренних компонентов GCC, таких как cc1
и cc1plus
. Или, если вы настраиваете кросс-GCC самостоятельно, просто установите это.
GCC ожидает, что ассемблер or32 и другие инструменты сборки or32 установлены в /home/broxigar/utilities/or32/bin
, но, по-видимому, не может найти его там или в нескольких других местах, поэтому возвращается к любой версии as
, оказавшейся в PATH.
Причина ошибок в том, что gcc
работает на родном ассемблере вместо or1200. Выяснилось, что исполняемый двоичный файл ассемблера находился в большой файловой системе с 64-битными индексными дескрипторами и случайно получил тот, который находился за пределами диапазона 32-битных целых чисел. gcc использует функцию stat
библиотеки C, чтобы найти вспомогательные программы, которые в данном случае завершились ошибкой с EOVERFLOW
. К сожалению, системный вызов выполняется успешно, поэтому поиск в strace
не дает подсказки, почему присутствие файла не обнаружено:
stat64("/home/<snip>/or32-uclinux/bin/as", {..}) = 0
ltrace
по крайней мере сообщает нам, что это не удается:
__xstat(3, "/home/<snip>/or32-uclinux/bin/as", 0xffed1f00) = -1
Но на самом деле нам пришлось отлаживать, используя gdb
, чтобы проверить errno
.
Если пересборка gcc невозможна, можно использовать файловую систему меньшего размера.
Использует ли
or32-uclinux-gcc -S
синтаксис, похожий на ваш код, написанный от руки? Возможно, GAS для этой цели использует другой синтаксис, чем вы ожидаете.