Exec 格式错误 32 位可执行 Windows 子系统 for Linux?

Posted

技术标签:

【中文标题】Exec 格式错误 32 位可执行 Windows 子系统 for Linux?【英文标题】:Exec format error 32-bit executable Windows Subsystem for Linux? 【发布时间】:2017-06-26 12:46:32 【问题描述】:

当我尝试在 适用于 Linux 的 Windows 子系统上执行使用 gcc -m32 main.c -o main 编译的 32 位文件时,我收到以下错误:bash: ./main: cannot execute binary file: Exec format error

如果我编译它没有 -m32 它运行。

在 WSL 上运行 32 位可执行文件的任何解决方案?

【问题讨论】:

.c.s 是源代码文件。它们不能直接执行,它们通常不是 C 编译器或汇编程序的输出。 我知道,我的意思是我编译一个 main.c 文件并执行 32 位可执行文件 ./main 我对此不够肯定,无法将其发布为答案,但我相信 WSL 本身就是一个 64 位进程。您不能在 64 位进程中运行 32 位可执行文件(或加载 32 位库)。 相关:WSL 不支持 64 位可执行文件中的 32 位 int 0x80 系统调用,因此除非您还使用正确的 syscall 系统,否则将 asm 构建为 64 位并没有帮助打电话给 ABI。 What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code? 【参考方案1】:

QEMU 和 binfmt 支持点亮方式:)

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

在阅读了 WSL 和 Windows 进程之间的 WSLInterop 使用 binfmt 之后,我正在修补 QEMU 以尝试一些 ARM 开发,并且偶然发现了如何使 32 位支持工作。

编辑:需要“秋季创作者更新”、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'

每次启动 WSL 时都需要重新激活 binfmt 支持:

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

【讨论】:

为我工作,WIN10 1803,WSL,ubuntu 18.04 LTS linux g++-8 效果很好,谢谢! Windows 10 v1803 WSL Ubuntu 16.04 如果我安装了64bit 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/…) 对于 WSL OpenSuse,将 qemu-i386-binfmt(来自 'qemu-linux-user' 包)放在 update-binfmts 行中,而不是 qemu-i386-static 非常适合我使用 -m32 编译器标志在使用 g++ v7.40 构建的 WSL Ubuntu 18.04 LTS 上执行 32 位二进制文​​件。本质上,运行 32 位二进制文​​件只需要apt install qemu-user-staticupdate-binfmts --install i386 ...service binfmt-support start。 gcc:i386 不是必需的,因为您可以使用 gcc-multilib 交叉编译 x86【参考方案2】:

WSL(目前)不提供 32 位 ELF 支持。自从 UserVoice 提出以来似乎没有任何进展 - 你运气不好。

参见UserVoice: Please add 32 bit ELF support to the kernel 和Support for 32-bit i386 ELF binaries。

如果可能,切换到真正的 Linux ;-)


自从最初发布以来,WSL2 上就提供了支持,它确实支持real Linux kernel!所以这应该是首选方式。

如链接的github issue 中所述,如果仍使用 WSL1,也可以使用 qemu-user

【讨论】:

这个答案似乎已经过时了。 另请参阅Does WSL 2 really support 32 bit program? re:如何真正确保您的 WSL 是 WSL2。显然有些人认为他们有 WSL2,但 32 位可执行文件仍然无法工作,因为它实际上是 WSL1。【参考方案3】:

WSL2 runs in a real virtual machine 使用real Linux kernel,因此实际上可以执行 Linux VM 可以执行的任何操作,包括运行 32 位代码。只需通过运行安装 32 位库

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

更多信息请阅读

Announcing WSL 2 WSL 2 FAQ

【讨论】:

您可能还需要sudo apt-get install gcc-multilib g++-multilib libc6:i386,根据smlnj.org/dist/working/110.95/install.html#install-64 没错,没有安装行不行。

以上是关于Exec 格式错误 32 位可执行 Windows 子系统 for Linux?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 cx_Freeze 在 64 位 Debian Linux 上运行时使 32 位可执行?

PE结构

在 Open Suse Leap 15.1 上对 32 位可执行文件的 iconv_open 支持

cmake 创建解决方案时未链接 64 位可执行文件

C ++ 32位与64位可执行符号[关闭]

有任何工具可用于将 32 位/64 位可执行文件打包在一起吗? [关闭]