0

I am running a Kali Linux distribution on an arm cpu (aarch64).

I have successfully install x86_64-linux-gnux32-gcc and x86_64-linux-gnu-gcc.

I have wrote a basic c program:

#include <stdio.h>

void main()
{
   printf("Hello world\n");
}

I have compiled 2 versions:

x86_64-linux-gnu-gcc test1.c -o test1_64
x86_64-linux-gnux32-gcc test1.c -o test1_32

The first binary (64 bits) works fine when i run it with this command:

qemu-x86_64-static ./test1_64

But i have an error with the second binary (32 bits):

qemu-x86_64-static ./test1_32 
qemu-x86_64-static: ./test1_32: Invalid ELF image for this architecture

I have tried to force a 32 bits cpu with this command:

qemu-x86_64-static -cpu qemu32 ./test1_32

I have also tried to compile the binary with -static option. I got the same result.

How can i run my 32 bits executable ?

Thanks a lot

Bob5421
  • 7,757
  • 14
  • 81
  • 175
  • Maybe there is a `qemu-x86-static` version of QEMU that only emulates x86-32? – Martin Rosenau Jul 30 '22 at 12:55
  • I am very surprised about that because an x86_64 cpu is always compatible with x86 32. And as you can see i have tried to pass qemu32 cpu argument to qemu. I think this is a library issue but i have also tried to compile binary in static mode. So i am lost ! – Bob5421 Jul 30 '22 at 14:58
  • By the way, never `void main`, always `int main`. https://stackoverflow.com/questions/204476/what-should-main-return-in-c-and-c – Nate Eldredge Jul 30 '22 at 16:10
  • qemu-i386-static library can be used to run 32bit architecture ref: https://github.com/multiarch/qemu-user-static/releases – ras Jul 30 '22 at 16:16
  • `file ./test1_32` should show you that you've still made an x86-64 executable, not i386, with a compiler for the x32 ABI as Nate noticed. Unfortunately the `file` output says "*ELF 32-bit LSB executable, x86-64, version 1 (SYSV)*, ..." so the 32-bit part could be misleading. – Peter Cordes Jul 30 '22 at 19:20

2 Answers2

1

x86_64-linux-gnux32-gcc is not what you want for building 32-bit programs. This is actually a 64-bit compiler that targets the x32 ABI, a scheme to have 64-bit code that needs only 32 bits for pointers. It never really caught on and is fairly obscure these days, so I'm not surprised that qemu wouldn't support it.

The x86_64 target of gcc supports building 32-bit programs as well, using the -m32 option. So you ought to be able to build your 32-bit Hello World with

x86_64-linux-gnu-gcc test1.c -o test1_32 -m32

(You might have to separately install 32-bit x86 libraries to successfully cross compile.)

Then to run it, use qemu-i386 instead of qemu-x86_64.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
  • It does not work, i get this error when compiling: /usr/lib/gcc-cross/x86_64-linux-gnu/11/../../../../x86_64-linux-gnu/bin/ld: skipping incompatible /usr/lib/gcc-cross/x86_64-linux-gnu/11/libgcc.a when searching for -lgcc – Bob5421 Jul 30 '22 at 19:24
  • @Bob5421: Like this answer says: *(You might have to separately install 32-bit x86 libraries to successfully cross compile.)* x86-64 libraries can't be linked with an i386 executable you're making with `gcc -m32`. This is the right answer. – Peter Cordes Jul 30 '22 at 19:26
  • Thanks but I have install libc6-dev-i386. The files are in /usr/lib32/ but there is no libgcc.a... – Bob5421 Jul 30 '22 at 19:29
0

file ./test1_32 should show you that you've still made an x86-64 executable, not i386, with a compiler for the x32 ABI as Nate noticed.

Unfortunately the file output says "ELF 32-bit LSB executable, x86-64, version 1 (SYSV), ..." so the 32-bit part could be misleading.

An actual 32-bit build has "ELF 32-bit LSB executable, Intel 80386,".

A single install of GCC/GAS can build for 32 or 64-bit x86, unlike for ARM32 vs. AArch64 where you need different builds of GCC, so I expect that was part of the confusion. GCC treats i386 and x86-64 as flavours of the same architecture, while AArch64 is treated as a totally separate architecture from ARM. (IDK if GCC did that because x86-64 machine code is similar to 32-bit, so the same assembler can pretty easily handle both. But AArch64 uses a totally different machine code format from ARM32, no point in trying to share code in the assembler between the two architectures.)

So you were probably expecting to need a GCC with 32 in its name to make 32-bit x86 executables. That is not the case.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847