Ошибка формата Exec 32-разрядная исполняемая подсистема Windows для Linux?

Когда я пытаюсь выполнить 32-битный файл, скомпилированный с gcc -m32 main.c -o main в подсистеме Windows для Linux, я получаю следующую ошибку: bash: ./main: cannot execute binary file: Exec format error.

Если я скомпилирую его без -m32, он запустится.

Любое решение для запуска 32-разрядного исполняемого файла на WSL?


person Ford1892    schedule 08.02.2017    source источник
comment
.c и .s - файлы исходного кода. Они не могут быть выполнены напрямую и обычно не являются результатом работы компилятора C или программы на ассемблере.   -  person too honest for this site    schedule 08.02.2017
comment
Я знаю, я имел в виду, что я компилирую файл main.c и выполняю 32-битный исполняемый файл ./main   -  person Ford1892    schedule 08.02.2017
comment
Я не уверен в этом достаточно, чтобы опубликовать его в качестве ответа, но я верю, что WSL сам по себе является 64-битным процессом. Вы не можете запустить 32-битный исполняемый файл (или загрузить 32-битную библиотеку) в 64-битном процессе.   -  person David W    schedule 08.02.2017
comment
Связано: WSL не поддерживает 32-битные int 0x80 системные вызовы в 64-битных исполняемых файлах, поэтому сборка asm как 64-битной не поможет, если вы также не используете правильный syscall системный вызов ABI. Что произойдет, если вы используете 32-битный int 0x80 Linux ABI в 64-битном коде?   -  person Peter Cordes    schedule 04.02.2021


Ответы (3)


Поддержка 32-битного ELF в WSL (пока) не предусмотрена. Похоже, что с тех пор, как был поднят UserVoice, никакого прогресса нет - вам не повезло.

См. UserVoice: добавьте поддержку 32-битного ELF в ядро ​​ и Поддержка 32-битных двоичных файлов i386 ELF.

Если возможно, переключитесь на настоящий Linux ;-)


Поскольку это было изначально опубликовано, поддержка была доступна на WSL2, который поддерживает настоящее ядро ​​Linux! Так что это должно быть предпочтительным способом.

Как указано в связанной проблеме github, есть qemu-user, которая может быть используется, если WSL1 все еще используется.

person P.P    schedule 08.02.2017
comment
Этот ответ кажется устаревшим. - person Nate Eldredge; 25.05.2021

Поддержка QEMU и binfmt освещает путь :)

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

Прочитав, что WSLInterop между процессами WSL и Windows использует binfmt, я возился с QEMU, чтобы попробовать некоторые разработки ARM, и случайно обнаружил, как заставить работать 32-битную поддержку.

Изменить: требуется "Fall Creators Update", 1709, сборка 16299 или новее.

Установите конфигурацию qemu и binfmt:

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'

Вам нужно будет повторно активировать поддержку binfmt каждый раз, когда вы запускаете WSL:

sudo service binfmt-support start

Включите пакеты архитектуры i386:

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

Попробуйте:

$ 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

И чтобы доказать, что это действительно работает, отключите поддержку i386 и попробуйте еще раз:

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

$ ./helloworld
-bash: ./helloworld: cannot execute binary file: Exec format error
person Froosh    schedule 21.03.2018
comment
у меня работает, WIN10 1803, WSL, ubuntu 18.04 LTS linux g ++ - 8 - person zhaorufei; 02.08.2018
comment
Отлично работает, спасибо! Windows 10 v1803 WSL Ubuntu 16.04 - person Octa9on; 15.01.2019
comment
Если я установил 64-битный gcc, то когда я запустил sudo apt install gcc:i386, он дал мне следующие ошибки: The following packages have unmet dependencies: gcc:i386 : Depends: cpp:i386 (>= 4:7.3.0-3ubuntu2.1) but it is not going to be installed Depends: gcc-7:i386 (>= 7.3.0-27~) but it is not going to be installed E: Unable to correct problems, you have held broken packages Я попытаюсь использовать метод, упомянутый здесь (askubuntu.com/questions/510269/) - person Donghua Liu; 16.01.2019
comment
Я не очень хорош в решении проблем с подходящей установкой, поэтому я держу несколько установок WSL для разных нужд (например, i386 против x64 и т. Д.). Как вы уже упоминали, отдельные chroot / контейнеры тоже должны выполнять эту работу. - person Froosh; 18.01.2019
comment
Для WSL OpenSuse поместите qemu-i386-binfmt (из пакета 'qemu-linux-user') вместо qemu-i386-static в строке update-binfmts. - person Nathan Mills; 02.04.2019
comment
Мне нужно удалить 64-битную версию gcc, а затем установить 32-битную. - person Donghua Liu; 03.04.2019
comment
У меня отлично работает для выполнения 32-битных двоичных файлов на WSL Ubuntu 18.04 LTS, созданных с помощью g ++ v7.40 с использованием флага компилятора -m32. По сути, все, что требуется для запуска 32-битных двоичных файлов, - это apt install qemu-user-static, update-binfmts --install i386 ... и service binfmt-support start. gcc: i386 не требуется, так как вы можете кросс-компиляцию для x86 с помощью gcc-Multilib - person Francois B; 22.10.2019
comment
Это работает без шага sudo apt install gcc: i386. Я попытался установить gcc: i386, и он хотел удалить все мои 64-битные пакеты компилятора и заменить их 32-битными. Нет, спасибо. - person teadotjay; 08.11.2019

WSL2 работает в реальная виртуальная машина с использованием реального ядра Linux , поэтому на самом деле можно делать все, что может делать виртуальная машина Linux, в том числе запускать 32-битный код. Просто установите 32-битные библиотеки, запустив

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

Для получения дополнительной информации прочтите

person phuclv    schedule 21.11.2019
comment
Вам также может понадобиться sudo apt-get install gcc-multilib g++-multilib libc6:i386 согласно smlnj.org/dist/ рабочий / 110.95 / install.html # install-64 - person iono; 26.01.2021
comment
Правильно, без строки установки не работает. - person Leila; 07.04.2021