1

So I'm new trying asm and I want to compile a little program that just exits with i386 instructions instead of x86-64 ones. I have a x86-64 Ubuntu which compile and run x86-64 one perfectly but I don't get it how to assemble and link the i386 version on the same x86-64 machine (I have installed i386 compat).

I know there are similar questions answered already, But none of them use as and ld to do it so I don't know exactly how could I translate those solutions to my problem.

For the x86-64 I use as and ld as follows:

#       Assemble: as exit.s -o exit.o
#        Linking: ld exit.o -o exit

The x86-32 version of the program:

.section .data
.section .text
.globl _start
_start:
    movl $1, %eax
    movl $0, %ebx
    int $0x80

Now.. I've been searching how to do it and found about the --32 in as and the -m {arg} in ld but every time I get to compile it without arch errors it gives me the "File in wrong format" error.

I've tried doing ld with elf_i386 and i386linux like this:

as --32 exit.s -o exit.o
ld -m elf_i386 exit.o -o exit
#Error: -bash: ./exit: cannot execute binary file: File in wrong format
ld -m i386linux exit.o -o exit
#Error: -bash: ./exit: cannot execute binary file: File in wrong format

I want to add that for compatibility I've installed these packages listed in the Ubuntu help forum:

sudo dpkg --add-architecture i386
sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386
sudo apt-get install multiarch-support
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Ricardo
  • 337
  • 5
  • 16
  • 2
    Post the exact commands you used along with the errors. `as --32` and `ld -melf_i386` should work. – Jester Nov 02 '18 at 11:41
  • Hi @Jester tried and got the error posted above. – Ricardo Nov 02 '18 at 11:47
  • Looks like your kernel was built without `CONFIG_COMPAT_BINFMT_ELF` [List of executable formats on Linux](https://stackoverflow.com/q/23311306), so it doesn't recognize 32-bit ELF static executables as executable. (and BTW, x32 is something very different: it's 32-bit pointers in 64-bit mode https://en.wikipedia.org/wiki/X32_ABI. Also, x64 is Windows-only terminology, Linux uses x86-64). – Peter Cordes Nov 02 '18 at 12:37
  • Ok, thanks for pointing it out. – Ricardo Nov 02 '18 at 12:51

1 Answers1

2

Those are the correct commands for assembling and linking a 32-bit static executable. (Assembling 32-bit binaries on a 64-bit system (GNU toolchain))

Looks like your kernel was built without CONFIG_COMPAT_BINFMT_ELF List of executable formats on Linux, so it doesn't recognize 32-bit ELF static executables as executable. (I think that's the relevant Linux kernel config option.)


Or you're using the Windows Subsystem version 1 for Linux, which also doesn't support 32-bit executable.

WSL v1 doesn't support the 32-bit int 0x80 ABI from 64-bit processes, either, so that also won't work. (What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?). It's like a Linux kernel without CONFIG_IA32_EMULATION.

See Does WSL 2 really support 32 bit program? for how to make sure you're really using WSL2, which is a real Linux kernel in a VM, and thus allows 32-bit user-space.


libc packages are irrelevant for this. You're making a static executable which doesn't depend on any other files to run.

After running your build commands on my Arch Linux system, I get:

$ as --32 exit.s -o exit.o
$ ld -m elf_i386 exit.o -o exit
$ file exit
exit: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, not stripped
$ ./exit ; echo $?
0

So it works fine, your system is just broken somehow. It's either not real Ubuntu, or you have a custom kernel.

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