• Uncategorized

About gcc : Exec-format-error-32-bit-executable-Windows-Subsystem-for-Linux

Question Detail

When I try to execute a 32-bit file compiled with gcc -m32 main.c -o main on Windows Subsystem for Linux, I get the following error: bash: ./main: cannot execute binary file: Exec format error.

If I compile it without -m32 it runs.

Any solution for running 32-bit executable on WSL?

Question Answer

QEMU and binfmt support light the way 🙂

https://github.com/microsoft/wsl/issues/2468#issuecomment-374904520

After reading that the WSLInterop between WSL and Windows processes used binfmt, I was tinkering with QEMU to try some ARM development, and incidentally discovered how to get 32-bit support working.

Edit: requires “Fall Creators Update”, 1709, build 16299 or newer

Install qemu and binfmt config:

sudo apt install qemu-user-static
sudo update-binfmts --install i386 /usr/bin/qemu-i386-static --magic '\x7fELF\x01\x01\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x03\x00\x01\x00\x00\x00' --mask '\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xf8\xff\xff\xff\xff\xff\xff\xff'

You’ll need to reactivate binfmt support every time you start WSL:

sudo service binfmt-support start

Enable i386 architecture packages:

sudo dpkg --add-architecture i386
sudo apt update
sudo apt install gcc:i386

Try it out:

$ file /usr/bin/gcc-5
/usr/bin/gcc-5: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=2637bb7cb85f8f12b40f03cd015d404930c3c790, stripped

$ /usr/bin/gcc-5 --version
gcc-5 (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ gcc helloworld.c -o helloworld

$ ./helloworld
Hello, world!

$ file helloworld
helloworld: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=3a0c7be5c6a8d45613e4ef2b7b3474df6224a5da, not stripped

And to prove it really was working, disable i386 support and try again:

$ sudo service binfmt-support stop
 * Disabling additional executable binary formats binfmt-support [ OK ]

$ ./helloworld
-bash: ./helloworld: cannot execute binary file: Exec format error

32-bit ELF support isn’t provided by WSL (yet). There doesn’t seem to be any progress since the UserVoice was raised – you are out luck.

See UserVoice: Please add 32 bit ELF support to the kernel and Support for 32-bit i386 ELF binaries.

If possible, switch to a real Linux 😉


Since this was originally posted, the support has been available on WSL2 which does support real Linux kernel! So that should be the preferred way.

As noted in the linked github issue, there’s also qemu-user which can be used if WSL1 is still used.

WSL2 runs in a real virtual machine using a real Linux kernel, therefore it’s actually possible to do anything a Linux VM can do, including running 32-bit code. Just install 32-bit libs by running

sudo dpkg --add-architecture i386
sudo apt-get update

For more information read

  • Announcing WSL 2
  • WSL 2 FAQ

You may also like...

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.