3

I wanted to use the cross-compiler for some testing on an or1200 design in which I used to perform some benchmarks on another machine. The other machine had the binaries of the or32-uclinux- tool chain and I coppied those to my Ubuntu 20.04 machine.

The binaries seem to work fine, but when I tried to compile my assembly code with

or32-uclinux-gcc -c custom.S -o assembly_code_obj.o 

It gave me a bunch of errors like

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'

What would be the problem here?

Debug Info

[A] On my Ubuntu machine

The output of the 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] On the original machine

The output of the 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
ex1led
  • 427
  • 5
  • 21
  • Does `or32-uclinux-gcc -S` use syntax that looks anything like your hand-written code? Possibly GAS for that target uses a different syntax than you're expecting. – Peter Cordes Dec 11 '20 at 22:39
  • Also make sure your cross-gcc knows to run the cross-assembler. For testing, just run `or32-uclinux-as` (or whatever it is called) directly. Do you get an error for every instruction or are there some that are accepted? – Jester Dec 11 '20 at 22:44
  • @PeterCordes yes, of course. Exactly the same code works perfectly fine on the original machine that I've taken the binaries from. – ex1led Dec 11 '20 at 22:58
  • @Jester or32-uclinux-as runs. I mean, if I run ```or32-uclinux-as --help``` I get prompted the help info :( Also, every instruction is erroneous – ex1led Dec 11 '20 at 22:59
  • But does that print error if you do `or32-uclinux-as custom.S -o assembly_code_obj.o` (assuming your `.S` doesn't really need preprocessor, otherwise run it through cpp first). – Jester Dec 11 '20 at 23:08
  • It runs and it generates the object file appropriately @Jester. The problem comes with gcc. And I need gcc in my flow. – ex1led Dec 11 '20 at 23:24
  • So that means your gcc invokes the wrong assembler. – Jester Dec 11 '20 at 23:25
  • @Jester true, but this is really peculiar. How could this be. I mean, I simply took the binaries over I did not ```./configure``` and ```make``` them. So, this is really weird. – ex1led Dec 11 '20 at 23:26
  • That may mean on the working system `as` (or whatever `gcc` invokes) is symlinked or is otherwise redirected to the correct one. Add `-v` option to your `gcc` command to see what it is doing. – Jester Dec 11 '20 at 23:32
  • I am updating the question with the verbosed output of the compiler – ex1led Dec 11 '20 at 23:34
  • 1
    Yes so it just runs `as`. You need to make sure that refers to the cross assembler. – Jester Dec 11 '20 at 23:37
  • @Jester uhm, any suggestions on how to do that? ^^ – ex1led Dec 11 '20 at 23:43
  • On my system `/usr/bin/as` is a symlink. You could update that to point to `or32-uclinux-as`. You could also put a new symlink in a directory that you put earlier in `PATH` and make sure `gcc` is invoked with that `PATH` set. – Jester Dec 11 '20 at 23:46
  • @Jester but if I change it like that, wouldn't that be an issue for the rest of gcc's? – ex1led Dec 11 '20 at 23:48
  • If you use the second option, and only set that `PATH` while running the cross-gcc then that should have no effect on other architecture. You can also check the original machine you copied from. Look at `/usr/bin/as` and `which as` and `as --version`. – Jester Dec 11 '20 at 23:49
  • @Jester Its the OS assembler, meaning the ```x86_64-suse-linux```. But in that machine the toolchain works fine with no complications – ex1led Dec 11 '20 at 23:50
  • And what does adding `-v` to `gcc` on that machine say? – Jester Dec 11 '20 at 23:59
  • @Jester added it to the question. It locates the appropriate assembler – ex1led Dec 12 '20 at 00:07
  • Compare the `specs` files. – Jester Dec 12 '20 at 00:22
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/225847/discussion-between-broxigar-and-jester). – ex1led Dec 12 '20 at 00:30
  • You could try `GCC_EXEC_PREFIX=/somewhere or32-uclinux-gcc` or `COMPILER_PATH=/somewhere or32-uclinux-gcc`, where `/somewhere` is a dir that has an `as` entry that's a symlink to the cross-assembler. I think GCC uses that to find `as`, not just internal GCC components like `cc1` and `cc1plus`. Or if you're configuring your cross-GCC yourself, just set that. – Peter Cordes Dec 12 '20 at 01:16
  • GCC expects that the or32 assembler and other or32 build tools are installed in `/home/broxigar/utilities/or32/bin` but apparently can't find it there or a few other places it looks so falls back on whatever version of `as` happens to be in the PATH. – Ross Ridge Dec 12 '20 at 01:29

1 Answers1

2

The cause for the errors is that gcc is running the native assembler instead of the or1200 one. Turns out the executable binary of the assembler was on a big file system with 64 bit inodes and happened to get one which was outside of the 32 bit integer range. gcc uses the stat C library function to locate the helper programs which in this case failed with EOVERFLOW. Unfortunately, the system call succeeds so looking in strace does not give a hint as to why the presence of the file is not detected:

stat64("/home/<snip>/or32-uclinux/bin/as", {..}) = 0 

ltrace at least tells us that it fails:

__xstat(3, "/home/<snip>/or32-uclinux/bin/as", 0xffed1f00) = -1 

But we actually had to debug using gdb to check errno.

If rebuilding gcc is not an option, then a workaround is to use a smaller file system.

Jester
  • 56,577
  • 4
  • 81
  • 125