Or32-uclinux-gcc выдает сообщения ассемблера: нет такой инструкции

Я хотел использовать кросс-компилятор для тестирования дизайна 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'

В чем тут может быть проблема?

Отладочная информация

[A] На моем компьютере с Ubuntu

Вывод 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'

[B] На оригинальной машине

Вывод 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

Использует ли or32-uclinux-gcc -S синтаксис, похожий на ваш код, написанный от руки? Возможно, GAS для этой цели использует другой синтаксис, чем вы ожидаете.

Peter Cordes 11.12.2020 23:39

Также убедитесь, что ваш кросс-gcc умеет запускать кросс-ассемблер. Для тестирования просто запустите or32-uclinux-as (или как там это называется) напрямую. Вы получаете ошибку для каждой инструкции или есть некоторые, которые принимаются?

Jester 11.12.2020 23:44

@PeterCordes да, конечно. Точно такой же код прекрасно работает на исходной машине, с которой я взял двоичные файлы.

ex1led 11.12.2020 23:58

@Jester или 32-uclinux-as работает. Я имею в виду, что если я запускаю or32-uclinux-as --help, мне подсказывают справочную информацию :( Кроме того, каждая инструкция ошибочна

ex1led 11.12.2020 23:59

Но будет ли эта ошибка печати, если вы это сделаете or32-uclinux-as custom.S -o assembly_code_obj.o (при условии, что вашему .S действительно не нужен препроцессор, иначе сначала запустите его через cpp).

Jester 12.12.2020 00:08

Он запускается и генерирует объектный файл соответствующим образом @Jester. Проблема связана с gcc. И мне нужен gcc в моем потоке.

ex1led 12.12.2020 00:24

Значит, ваш gcc вызывает не тот ассемблер.

Jester 12.12.2020 00:25

@Jester правда, но это действительно странно. Как это могло произойти. Я имею в виду, что я просто взял бинарники, а не ./configure и make их. Итак, это действительно странно.

ex1led 12.12.2020 00:26

Это может означать, что в рабочей системе as (или что-то еще, что вызывает gcc) есть символическая ссылка или иное перенаправление на правильную. Добавьте опцию -v к вашей команде gcc, чтобы увидеть, что она делает.

Jester 12.12.2020 00:32

Я обновляю вопрос с подробным выводом компилятора

ex1led 12.12.2020 00:34

Да так он просто работает as. Нужно убедиться, что это относится к кросс-ассемблеру.

Jester 12.12.2020 00:37

@Jester хм, есть предложения, как это сделать? ^^

ex1led 12.12.2020 00:43

В моей системе /usr/bin/as — это символическая ссылка. Вы можете обновить это, чтобы указать на or32-uclinux-as. Вы также можете поместить новую символическую ссылку в каталог, который вы ранее поместили в PATH, и убедиться, что gcc вызывается с этим набором PATH.

Jester 12.12.2020 00:46

@Jester, но если я изменю это так, не будет ли это проблемой для остальных gcc?

ex1led 12.12.2020 00:48

Если вы используете второй вариант и устанавливаете этот PATH только при запуске кросс-gcc, это не должно влиять на другую архитектуру. Вы также можете проверить исходную машину, с которой вы скопировали. Посмотрите на /usr/bin/as и which as и as --version.

Jester 12.12.2020 00:49

@Jester Это ассемблер ОС, то есть x86_64-suse-linux. Но на этой машине тулчейн работает без проблем.

ex1led 12.12.2020 00:50

И что говорит добавление -v к gcc на этой машине?

Jester 12.12.2020 00:59

@Jester добавил это к вопросу. Он находит соответствующий ассемблер

ex1led 12.12.2020 01:07

Сравните файлы specs.

Jester 12.12.2020 01:22

Давайте продолжим обсуждение в чате.

ex1led 12.12.2020 01:30

Вы можете попробовать GCC_EXEC_PREFIX=/somewhere or32-uclinux-gcc или COMPILER_PATH=/somewhere or32-uclinux-gcc, где /somewhere — это каталог с записью as, которая является символической ссылкой на кросс-ассемблер. Я думаю, что GCC использует это для поиска as, а не только внутренних компонентов GCC, таких как cc1 и cc1plus. Или, если вы настраиваете кросс-GCC самостоятельно, просто установите это.

Peter Cordes 12.12.2020 02:16

GCC ожидает, что ассемблер or32 и другие инструменты сборки or32 установлены в /home/broxigar/utilities/or32/bin, но, по-видимому, не может найти его там или в нескольких других местах, поэтому возвращается к любой версии as, оказавшейся в PATH.

Ross Ridge 12.12.2020 02:29
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
22
152
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Причина ошибок в том, что 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 невозможна, можно использовать файловую систему меньшего размера.

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