microsoft / WSL

Issues found on WSL
https://docs.microsoft.com/windows/wsl
MIT License
17.26k stars 812 forks source link

I wonder if WSL will support the i386 (32 bit) program running later? #2468

Closed erikaemma closed 4 years ago

erikaemma commented 7 years ago

I just want to run arm-linux-gcc 4.4.3 :}

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

sudo apt-get install g++-multilib
sudo apt-get install libncurses5:i386
sudo apt-get install libc6:i386 libgcc1:i386 gcc-4.8-base:i386 libstdc++5:i386 libstdc++6:i386
sudo apt-get install lib32z1 lib32ncurses5 lib32ncursesw5 lib32ncursesw5-dev 
therealkenc commented 7 years ago

The User Voice was opened back up. If the embedded people were as organised as university students taking Machine Learning courses it would have a better chance.

poizan42 commented 7 years ago

@plgkm6 That is quite an old gcc, do you need it for binary compatibility? Can't you just use 4.4.7? It is my understanding that gcc never breaks binary compatibility in minor releases. I believe you can just install the amd64 versions of the cross compiler from an older ubuntu version - you can find the softfloat version here and hardfloat version here. Select the amd64 built, you'll need the gcc-..._base_..., cpp-... and gcc-... packages at least.

For c++ support you will also need the g++-... and libstdc++6-4.4-dev-... packages.

If you really need gcc 4.4.3 then you could build a version for a 64-bit host yourself, there are plenty of guides on how to build gcc cross compilers.

therealkenc commented 7 years ago

I was going to mention using the amd64 cross; but didn't because it isn't the root of (some of) the embedded guys' difficulty. The problem is many of their platform's supported build toolchains are stuck on 32-bit. Most notably Android, but also other embedded scenarios. Ref #1687, #1771, et al

MikeGitb commented 7 years ago

Disclaimer: I'm a x64 zealot and I'm programming embedded systems down to 8bit microcontroller, but have almost no experience with Android development.

My hope would be that without 32 support, the tool vendors get more pressure to update their toolchains and I'd much rather see some progress on their side than resources being wasted on backwards compatibility on the WSL side.

therealkenc commented 7 years ago

I'm a x64 zealot

Yeah, me too a little. That said, you'd think Microsoft would be more sympathetic. My Visual Studio 2017 (August preview) is 32-bit, almost 15 years after Opteron was released. If the implication here is that Microsoft should encourage tool vendors like say Google to update, an obvious retort would be: "Whatever dude. You first."

Funny story if you are a 64-bit zealot.... The new ARM-powered Windows 10 laptops that are supposedly coming this Christmas have a 32-bit x86 emulator only. The laptops won't run amd64 apps. On a 64-bit Snapdragon. [I understand the reason; I just think it is funny.]

No word yet on whether they'll support WSL. 😉

fpqc commented 7 years ago

@therealkenc I sorta wonder if they could actually leverage what they already have with WSL to ARM64. If I remember correctly, ADSS was originally designed to emulate Android on Windows phone (running on an ARM). Ubuntu has an ARM port, and that kind of userspace would be a natural thing to use in a WSL for ARM64. I guess I'm saying that it's interesting since part of the work seems like it's already done!

therealkenc commented 7 years ago

@fpqc - [Squarely in discussion tag territory] Yeah I yanked Ben's chain on that in #1769 (message). It would be fun to see for the amusement value, but my (sometimes flawed) powers of deductive reasoning say "nah". Ubuntu userland isn't the problem. The kernel is technically feasible. The problem is the target platform is the cheapest of cheap laptops. Not exactly a 'development use case scenario'. There's only 7-8 people on the team, and they need another target platform to support like they need a bullet in the head. Maybe I am jaded by the fact that I have seen this show before, and the ending is always the same. No not Windows 10 RT. I am old enough to have seen Windows NT 3.1 on MIPS. "This too will pass". Or, maybe I'm wrong. Maybe someone upstairs will tell the team different. Carry the OneCore torch and all that. Or maybe they'll do it for the amusement value. Or... maybe developers will run out in droves to buy Snapdraggon powered laptops this Christmas.

poizan42 commented 7 years ago

32-bit support could be fixed for probably 99% of programs by making a custom glibc, which anyone who feels up for it could do:

You can in fact run 32-bit code in WSL land. If you do a far jump to segment 0x23 then you are executing code in compatibility mode (i.e. 32-bit mode) - do a far jump to 0x33 to get back in 64-bit land. The problem is that WSL only supports 64-bit syscalls, so 32-bit code attempting to make syscalls won't work (and you can't trap them either, see #1655). I have a small demonstration that this is possible here: https://gist.github.com/poizan42/8ff01d3df80b1663afef775ca812b699

So if someone feel up for it then it should be possible to port glibc to "lol64" (Linux on Linux 64) that jumps to 64-bit mode to perform all the syscalls, and it should work for everything except fully static binaries and the rare stuff that makes syscalls without going through glibc (some emulation software possibly)

therealkenc commented 7 years ago

rare stuff that makes syscalls without going through glibc (some emulation software possibly)

Rare stuff, like gdb. Very cool hack though. #1655 was a good bug report by the way. I hope it gets addressed on the merits, nevermind the use case. Maybe ping a name-drop over there at some point. Good issue posts get lost/forgotten sometimes in all the noise.

MikeGitb commented 7 years ago

[I understand the reason;

Actually I don't - That is, I can speculate, but if you have any actual information on this I would be thankful if you could share

therealkenc commented 7 years ago

Well since you qualified the question, nope. I do not work at Microsoft, and even if I did, I couldn't share actual information like that. But I understand the reason.

MikeGitb commented 7 years ago

@therealkenc: Just to be clear, with "actual" information I didn't mean "official" information, but more like "knowledge / reasonable assumptions I gathered from other posts or experience".

As I said, I myself can only speculate that it has to do with performance or reuse of code, but that is not even an educated guess, because I have no knowledge about where the pain points are when trying to run x86 or x64 code on an arm system or how Microsoft does it.

therealkenc commented 7 years ago

There is never a single reason a company makes a decision. But my guess, for the price you've paid for it, is that it has at least partially to do with not running amok of instruction set patents with their emulator. 32-bit x86 is a smaller surface for Intel’s lawyers to attack, because most if not all of the juicy 32-bit x86 patents have expired. This makes the MSFT lawyer's jobs easier, and since these are low end battery optimised 4GB notebooks anyway, there is not a strong reason to make their lawyer’s jobs harder. It doesn't matter whether Intel has a legal leg to stand on, or not, of course. It would cost more for the in-house legal analysis, let alone risk a fight, than the entire engineering effort of the port.

My basis for this hypothesis is that Microsoft, Qualcomm, Lenovo, and the rest don't want to have to advertise the 32-bit limitation any more than you want to hear it. Whatever the technical challenges of doing an amd64 emulator, which I suspect are marginal in the scheme, they are not high enough to justify having to explain to customers and all the Arstechnicas and Engadgets of the world that the machines don't run x64/amd64 binaries. Thus, I think the reasons are at least in part non-technical.

I could be wrong, IANAL, and all that.....

Froosh commented 6 years ago

Based on some tinkering I was doing with qemu for some ARM dev, I think I may have found a technique to allow general 32-bit support in WSL. Hat-tip to @therealkenc for the concept 😁

Edit: requires "Fall Creators Update", 1709, build 16299 or newer (I think)

Presuming a fresh Ubuntu WSL instance, you'll need to install the qemu-user-static package, add the i386 binfmt, enable the i386 architecture, update your package lists, and install some i386 packages:

Install qemu and binfmt

sudo apt update
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'

[Edit: whoops, need to update package lists, added sudo apt update]

This will activate i386 support by causing them to be executed through qemu-i386-static, and drop a config file into /var/lib/binfmts/ for future reactivation.

You will need to reactivate this every time you restart WSL and want i386 support:

sudo service binfmt-support start

Enable i386 architecture and 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

Proof

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
therealkenc commented 6 years ago

What does the binfmt_misc flags look like? I noticed your service binfmt-support start worked unimpeded in this instance. Still trying to figure out what is going on there. [edit] nvm I missed that you added it manually per #2620 in the quick skim. Not sure what the implications for multilib are going to be, but this is definitely cool. Still a little surprised no one did this sooner. I had left #2620 in a "whatever people, need-repro" since October. It was only after you posted that I even looked.

therealkenc commented 6 years ago

I had to chase some generic apt borkage. After the dpkg --add-architecture and apt update, the apt install gcc:i386 gave me:

The following packages have unmet dependencies:
 gcc:i386 : Depends: cpp:i386 (>= 4:5.3.1-1ubuntu1) but it is not going to be installed
            Depends: gcc-5:i386 (>= 5.3.1-3~) but it is not going to be installed
E: Unable to correct problems, you have held broken packages.

Installing cpp-5:i386 and binutils:i386 harder eventually got me there. Pretty "normal" disarray for apt though. Could be just me.

Performance seems great so far in cursory tests. Which, of course it is; why wouldn't it be. The i386 code is being JIT compiled into x86-64. [One could even imagine hypothetical scenarios where it was faster on long long heavy code with lots of register pressure, though that's probably mostly wishful thinking.]

Nicely played Froosh. Adding the coveted workaround-available tag.

fcying commented 6 years ago

@Froosh sudo apt install gcc:i386 have some problem:

 gcc:i386 : Depends: cpp:i386 (>= 4:5.3.1-1ubuntu1) but it is not going to be installed
            Depends: gcc-5:i386 (>= 5.3.1-3~) but it is not going to be installed
E: Unable to correct problems, you have held broken packages.

I use sudo apt install -y libc6:i386 libncurses5:i386 libstdc++6:i386 zlib1g:i386 zlib1g-dev:i386 instead of it. Now it can run 32bit program , thanks very mush~~~~

therealkenc commented 6 years ago

E: Unable to correct problems, you have held broken packages.

If anyone feels competent enough at dpkg and apt to make a definitive statement (that's not me) about how to add an i386 target to a pure amd64 Debian derived system after the fact it would be worth having on the books. Seems to me dpkg --add-architecture i386 ought to be enough, but that doesn't seem to be the case in practice. I only had to add cpp-5:i386 and binutils:i386, which managed to drag in the rest of the dependencies automatically (the most notable of which is of course libc6:i386). The "held broken packages" error is incorrect and/or spurious; there aren't any held packages, broken or otherwise. Maybe someone motivated could ask what's going on there in the Ubuntu forums. I suspect there is some baseline that is expected to exist for a MultiArch install, but really I just don't know.

vsxd commented 6 years ago

Thank you very much, Froosh. I had run a 32bit binary file in Ubuntu WSL. But, if I want to use gdb to debug the binary file, some error info displayed:

dong@Yoga-900:/mnt/d/bomblab$ gdb ./bomb
qemu: Unsupported syscall: 355
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
...

And, if I want to continue:

...
(gdb) start
Temporary breakpoint 1 at 0x804894b: file bomb.c, line 37.
Starting program: /mnt/d/bomblab/bomb
qemu: Unsupported syscall: 26
Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!

I am a new Linux user, and this is my first time using gdb, I hope I didn't ask a wrong question

lygstate commented 6 years ago

Thanks a lot, works for me.

therealkenc commented 6 years ago

qemu: Unsupported syscall: 355

this

qemu: Unsupported syscall: 26

and this

elahia commented 6 years ago

Hi

First, I installed ubuntu 16.04 via WSL. by default python 2.7.9 (64 bit) is installed then I installed ROS lunar but to import one package i needed to download python 32 bit, which i used @froosh tutorial but meanwhile, i saw that Lunar is removing!!!

so when installation of python 2.7 32 bit finished i tried to reinstall ros lunar but this time i saw python 32 bit is removing!!!!

So how can i keep both of them beside each other????

untitled

Xinmudotmoe commented 6 years ago

@elahia Hey,Boy. English is not my native language, so there may be some semantic or grammatical errors. I think you are trying to make Python27 32bit and Python27 64bit coexist. But what happens when you execute /usr/bin/python27? I think you should choose a more important version, which is installed by apt. Another relatively less important version is placed ~/ under.By recompiling or Chroot. Like This image

elahia commented 6 years ago

@zhang1813023404 , thank you for your reply, my linux is 16.04 which support Lunar that published only in 64 bit! the best solution i found is trying to install ubuntu 14.04 and then indigo 32 bit and python2.7 in 32 bit version.

actually, it is not at all important for me to have python 64 bit! unless my packages work with 64 bit...

therealkenc commented 6 years ago

then I installed ROS lunar but to import one package i needed to download python 32 bit [...] actually, it is not at all important for me to have python 64 bit!

No your fast-path here is to track down and eliminate the 32-bit dependency. I surmise the package involved is this (right?). But whatever the problem it isn't related to WSL proper, and this would be a package nightmare under a pure 64-bit Real Linux too. You'll probably get better answers in a ROS Lunar group were they might better understand where the 32-bit dependency is coming from (I don't). When framing your question, make clear that you want/need a 64-bit clean install (contrast: "I'm trying to get this to run on WSL"). End-to-end CLI repro steps for what you are actually doing would be a good start too. Bonne chance.

elahia commented 6 years ago

@therealkenc apparently i didn't explain my problem clearly, so let me try again!

first of all, I need to run ROS on my windows 10, to this end i installed WSL. second*, i need to import a package which needs python2.7 32bit

Regards to my windows version, Ubuntu 16,04 is the default allowed linux for me. on the other hand, the default version of ROS for Ubuntu 16 is Lunar, which published only in 64bit!

sofar i have: linux64, ros 64 and python64 (these are all by default and i have no other option)


now i need to import the package (refer to second* ). so at first i have to install python2.7:i386, i done it by Froosh solution. but meanwhile Lunar removed. at first, i taught when the installation of python32bit finished i will reinstall the Lunar. but when i tried for reinstalling Lunar i saw that the python 32 bit is removing this time!!! so it seems they are not compatible!

the ros answer is that they will not publish any new ros pack in 32 bit regards to lack of use!!! and if i need a 32 bit version of ROS i have to downgrade my linux, for example to ubuntu14.04.

Now i found WSL-Distribution-Switcher which enables you to install different versions of ubuntu on WSL. however, i got some error...

I hope now i explained it clearly!

markusschaber commented 6 years ago

@elahia I think that @therealkenc is correct - you need to track down that dependency which requires 32 bit, and try to get a 64 bit version of it.

Xinmudotmoe commented 6 years ago

@elahia emmmm,I don't know if you can accept this method. If not special instructions, the default PWD is ~/. Executor is root. In any case, please do not put it in /mnt. wget http://releases.ubuntu.com/trusty/ubuntu-14.04.5-desktop-i386.iso The desktop version must be downloaded , because 1404 of the server version is distributed .deb . 7z x ubuntu-14.04.5-desktop-i386.iso In WSL, mount -o loop is almost impossible to use. unsquashfs -d ub14 casper/filesystem.squashfs Extract system files.

Refer to the code here https://github.com/Microsoft/WSL/issues/2468#issuecomment-374904520 apt install qemu-user-static

Refer to the code here https://github.com/Microsoft/WSL/issues/2620#issuecomment-374490404 cp /usr/bin/qemu-i386-static ub14/usr/bin/ cp -afL /etc/resolv.conf ub14/etc

The following code remembers to save as a script. Refer to the code here https://github.com/Microsoft/WSL/issues/2468#issuecomment-374904520 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' service binfmt-support start

Refer to the code here https://github.com/Microsoft/WSL/issues/2620#issuecomment-374116698 mount --bind /dev ub14/dev mount --bind /dev/pts ub14/dev/pts mount --bind /proc ub14/proc mount --bind /sys ub14/sys mount --bind /proc/sys/fs/binfmt_misc ub14/proc/sys/fs/binfmt_misc

Next, execute chroot. chroot ub14 /bin/bash Now an i386 architecture of Ubuntu 14.04 should be available.

But please note that this system is not complete, it is slower than WSL and has functional flaws. And all programs running inside this system will be considered qemu-i386-static in Windows.

They will take up a lot of space on the C drive, in fact if you really want to do this you should install WSL on other disks.

elahia commented 6 years ago

@markusschaber regard to this (take a look at linux section please) I'm not sure if i can do any downgrade ...

@zhang1813023404 Thank you so much for providing this suggestion,

actually, i found another solution but i encounter a new error! the solution is using WSL-Distribution-Switcher, now i have ubuntu 14.04 installed on my WSL! so generally, it should be able to install indigo 32 bit.

but the problem is that i cant set the ubuntu14.04 as the default os of my WSL! untitled

and on my WSL i have: untitled2

So i think trying to solve this problem is more easily than others! but i really stuck in it!

markusschaber commented 6 years ago

Hmm, the screenshot on http://doc.aldebaran.com/2-5/dev/community_software.html#retrieving-software shows linux 64 bit.

so maybe they have a 64 bit version, and the doc is just outdated?

did you try to contact their support?

elahia commented 6 years ago

@markusschaber yes i tried for it already and i got this troubleshooting

at first the problem was ImportError: No module named naoqi but after installing it i got the second error:

ImportError: ./_inaoqi.so: wrong ELF class: ELFCLASS32

Do you know how can i set ubuntu 14.04 as my default os on WSL! I think it can solve my problem!

markusschaber commented 6 years ago

Hmm - will both modules need to run in the same process? If yes, you won't have any chance, because using 32 bit Python will kick out ROS..

elahia commented 6 years ago

@markusschaber Yes i need ROS to run my code which imports naoqi (depends on python 32)!

but if i could install indigo(which is able in 32 bit) i can have both of them and for installing indigo i need ubuntu 14 which i installed! the last step is setting ubuntu 14 as the default one in WSL!

elahia commented 6 years ago

@zhang1813023404 thank you so much, i tried for your suggestion and ubuntu 14.04 is now installed. but i have a question, if i log out and then login which ubuntu would be active? and how can i set ubuntu 14.04 as the default one?

Xinmudotmoe commented 6 years ago

@elahia
In recent versions of Windows, background processes running in WSL will continue to run when you exit bash. This rule is completely feasible after chroot.

And the active system, both. The default login is still 64Bit system.

This is almost impossible for you to try to make this Chroot system the default system. I recommend that you install OpenSSH-Server in Ubuntu 14.04 and make it occupy other ports. Control this system via ssh. Then say ssh -p port rootlocalhost is saved as ub14.cmd in %SYSTEMROOT%/System32. This will connect to the target system.

If you think that the above solution is not feasible, you can try another option. Then say ubuntu run sh ~/ub14.sh is saved as ub14.cmd in %SYSTEMROOT%/System32. Similarly, you can only enter the Ubuntu 14.04 system through this command, and you cannot directly run the specified program in Ubuntu 14.04.

elahia commented 6 years ago

@zhang1813023404 your previous suggestion was really helpful for me, but i get into a new error which i think would be solved by installing ubuntu 14.04 64 bit! i tried to update your solution by downloading the 64 bit version of 14.04. but it made some errors, so would you please let me know how can i install 64 bit version of ubuntu 14.04? thanks for your consideration

ComingNine commented 6 years ago

@Froosh The helloworld.c compiled by gcc works with your method. However, similar helloworld.dpr compiled by CrossKylix (https://crosskylix.untergrund.net/) does not work and gives Segmentation fault (core dumped). Could you help to comment possible reason ?

Xinmudotmoe commented 6 years ago

@elahia Can you tell me what kind of mistake he is, I don't think this is an external system version issue. Because my WSL system is Ubuntu 18.04. And Chroot does not depend on a particular operating system.

If you are trying to install Ubuntu 14.04 64Bit, try using https://github.com/DDoSolitary/LxRunOffline.

elahia commented 6 years ago

@zhang1813023404 Dear Zhang, thank you so much for replying, i switched to other packages which are compatible with 16, so i don't need ubuntu 14.04 anymore!

Regards,

Zypp commented 6 years ago

Based on some tinkering I was doing with qemu for some ARM dev, I think I may have found a technique to allow general 32-bit support in WSL. Hat-tip to @therealkenc for the concept 😁

Edit: requires "Fall Creators Update", 1709, build 16299 or newer (I think)

Presuming a fresh Ubuntu WSL instance, you'll need to install the qemu-user-static package, add the i386 binfmt, enable the i386 architecture, update your package lists, and install some i386 packages:

Install qemu and binfmt

sudo apt update
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'

[Edit: whoops, need to update package lists, added sudo apt update]

This will activate i386 support by causing them to be executed through qemu-i386-static, and drop a config file into /var/lib/binfmts/ for future reactivation.

You will need to reactivate this every time you restart WSL and want i386 support:

sudo service binfmt-support start

Enable i386 architecture and 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

Proof

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

This works like a charm, until I try to run my 32 bit executables in valgrind. My question already got shot down on stackoverflow for not being about programming. When I run valgrind I get qemu: uncaught target signal 11 (Segmentation fault) - core dumped. Is there a fix or alternative method? My valgrind supports 32 bit, I verified this like in the answers here.

drolevar commented 5 years ago

I'm trying to launch java from openjdk-8-jre, and the java laucher cannot stat("/usr/lib/jvm/java-8-openjdk-i386/jre/lib/i386/server/libjvm.so"), which doesn't return 0. But the file itself exists. I guess it has something to do with qemu, but so far I had no luck figuring it out.

ad-on-is commented 5 years ago

I'm trying to use an ARM-crosscompiler. Unfortunatelly, I get these errors:

/d/Projects/SamsungTV/arm/bin/arm-v7a8v4r3-linux-gnueabi-gcc AmbiLight.c hook.c -fPIC -O2 -std=gnu99 -I../include -ldl -shared -Wl,-soname,/d/Projects/SamsungTV/libAmbiLight/out-/libAmbiLight.so -o /d/Projects/SamsungTV/libAmbiLight/out-/libAmbiLight.so
/d/Projects/SamsungTV/arm/bin/../lib/gcc/arm-v7a8v4r3-linux-gnueabi/4.7.4/../../../../arm-v7a8v4r3-linux-gnueabi/bin/ld:/d/Projects/SamsungTV/arm/bin/../arm-v7a8v4r3-linux-gnueabi/sys-root/usr/lib/libdl.so: file format not recognized; treating as linker script
/d/Projects/SamsungTV/arm/bin/../lib/gcc/arm-v7a8v4r3-linux-gnueabi/4.7.4/../../../../arm-v7a8v4r3-linux-gnueabi/bin/ld:/d/Projects/SamsungTV/arm/bin/../arm-v7a8v4r3-linux-gnueabi/sys-root/usr/lib/libdl.so:1: syntax error
collect2: error: ld returned 1 exit status
Makefile:15: recipe for target '/d/Projects/SamsungTV/libAmbiLight/out-/libAmbiLight.so' failed
make: *** [/d/Projects/SamsungTV/libAmbiLight/out-/libAmbiLight.so] Error 1

EDIT: Nevermind, this was caused due to the fact that I migrated from macOS to Windows, which messed up the symlinks. After downloading and extracting the toolchain in WSL, everything worked fine ;-)

yanygm commented 5 years ago

基于一些修补,我正在使用qemu为一些ARM开发,我想我可能已经找到了一种技术来允许WSL中的一般32位支持。帽子提示@therealkenc的概念

编辑:需要“Fall Creators Update”,1709,build 16299或更新版(我认为)

假设一个新的Ubuntu WSL实例,您需要安装qemu-user-static软件包,添加i386 binfmt,启用i386架构,更新软件包列表,以及安装一些i386软件包:

安装qemu和binfmt

sudo apt update
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'

[编辑:哎呀,需要更新包列表,添加sudo apt update]

这将激活i386支持,使其通过qemu-i386-static执行,并删除配置文件/var/lib/binfmts/以备将来重新激活。

每次重新启动WSL并希望获得i386支持时,您都需要重新激活它:

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

I hope to get 32-bit support on CentOS, what should I do? image

Xinmudotmoe commented 5 years ago

@yanygm

~中文~

update-binfmts本质是调用了Linux内核,而binfmt_misc属于Linux内核功能。

你可以在centos上编译binfmt-support,或者使用向/proc/sys/fs/binfmt_misc/register写入数据获得与update-binfmts相似的功能。

$ mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc 
 # 如果上一行执行后显示错误信息为already mounted,别管就行了。
$ echo :i386:M::'\x7fELF\x01\x01\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x03\x00\x01\x00\x00\x00':'\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xf8\xff\xff\xff\xff\xff\xff\xff':/usr/bin/qemu-i386-static: > /proc/sys/fs/binfmt_misc/register
 # 按照:name:type:offset:magic:mask:interpreter:flags的格式写入到/proc/sys/fs/binfmt_misc/register即可完成增加你想增加的binfmt_misc功能
$ echo 1 > /proc/sys/fs/binfmt_misc/status
 # 开启binfmt_misc功能(无论是否开启)
 # 现在 尝试运行32位程序应该没什么问题了

English translation

The essence of update-binfmts is to call the Linux kernel, and binfmt_misc is a Linux kernel feature.

You can compile binfmt-support on centos, or use the ability to write data to /proc/sys/fs/binfmt_misc/register to get similar functionality to update-binfmts.

$ mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc 
 # If the error message is displayed as always `mounted after` the previous line is executed, ignore it.
$ echo :i386:M::'\x7fELF\x01\x01\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x03\x00\x01\x00\x00\x00':'\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xf8\xff\xff\xff\xff\xff\xff\xff':/usr/bin/qemu-i386-static: > /proc/sys/fs/binfmt_misc/register
 # Write to /proc/sys/fs/binfmt_misc/register in the format:name:type:offset:magic:mask:interpreter:flags to increase the binfmt_misc feature you want to add.
$ echo 1 > /proc/sys/fs/binfmt_misc/status
 # Turn on the binfmt_misc function (whether or not it is enabled)
 # Now it’s okay to try to run a 32-Bit elf program.

image

Reference: Kernel Support for miscellaneous (your favourite) Binary Formats v1.1 — The Linux Kernel documentation Reference: #2468 (comment)

Biswa96 commented 5 years ago

@zhang1813023404 Does it retain after restarting WSL?

Xinmudotmoe commented 5 years ago

@Biswa96 When you reboot the operating system, or restart WSL, the configuration will be invalidated. If you want to maintain state, you may need to configure the $HOME/.bashrc file.

Biswa96 commented 5 years ago

@zhang1813023404 Thanks for the confirmation. I'm wondering that why MS devs. don't add the 32bit ELF binary support in binfmt_misc through init process, just like PE binary.

Xinmudotmoe commented 5 years ago

@Biswa96 No, here is just an alternative. The correct solution for 64-bit Kernel running 32-bit programs is not binfmt_misc. Binfmt_misc may be more convenient to run programs that Kernel does not support. In fact, on 64-bit Linux you rarely need to install a 32-bit compatible program. At the same time, the performance of QEMU in WSL is very worrying.

upsampled commented 5 years ago

Not getting the same results for GCC-7

$ sudo apt update
$ 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'
$ sudo service binfmt-support start
$ sudo dpkg --add-architecture i386
$ sudo apt update
$ sudo apt install cpp-5:i386 binutils:i386
$ sudo apt install gcc:i386

...
$ file /usr/bin/gcc-7
/usr/bin/gcc-7: symbolic link to i686-linux-gnu-gcc-7

$ readlink -f  /usr/bin/gcc-7
/usr/bin/i686-linux-gnu-gcc-7

$ file /usr/bin//i686-linux-gnu-gcc-7
/usr/bin//i686-linux-gnu-gcc-7: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=8d0e813ee35f322165b86b37d523b9f9b432e37e, stripped

$ /usr/bin/gcc-7 --version
gcc-7 (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0
Copyright (C) 2017 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 ./hello.c -o ./hello
/usr/lib/gcc/i686-linux-gnu/7/../../../../i686-linux-gnu/bin/ld: /usr/lib/gcc/i686-linux-gnu/7/liblto_plugin.so: error loading plugin: /usr/lib/gcc/i686-linux-gnu/7/liblto_plugin.so: wrong ELF class: ELFCLASS32
collect2: error: ld returned 1 exit status
d1tto commented 5 years ago

But when I use gdb to debug a program, I can't make a breakpoint in address . Beacuse the gdb is configured as "x86_64-linux-gnu" . How can I debug without changing the version of gdb ? image