Linaro ARM toolchain prebuild binaries in 64 bit OS - linux

I have an Ubuntu 14.04 Trusty 64 bit machine. My OS and kernel are all 64 bit
uname -a
Linux --- 3.13.0-43-generic #72-Ubuntu SMP Mon Dec 8 19:35:06 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
I downloaded the pre-built tool-chain binaries from Linaro as I’m working on something with Raspberry Pi, but I’m unable to compile my code because the binaries that I had downloaded were 32 bit, it is not getting recognized on my 64 bit machine.
Could anyone give me some pointers? (if i can find a 64bit pre-built tool-chain from Linaro) or any other solution that I can deploy on my Ubuntu to workaround the problem
My error as below
some#somemachine:~/tools/compilers/linaro/gcc-linaro-arm-none-eabi-4.9-2014.09_linux/bin$ file ./arm-none-eabi-gcc-4.9.2
./arm-none-eabi-gcc-4.9.2: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, stripped
The file (yeap! its there in the directory)
some#somemachine:~/tools/compilers/linaro/gcc-linaro-arm-none-eabi-4.9-2014.09_linux/bin$ arm-none-eabi-gcc -v
bash: /home/some/tools/compilers/linaro/gcc-linaro-arm-none-eabi-4.9-2014.09_linux/bin/arm-none-eabi-gcc: No such file or directory

i found the problem. I had to do little bit of googling.
sudo apt-get install lib32z1 lib32ncurses5 lib32bz2-1.0
will fix the problem. This will enable 32 bit applications run normally on 64 bit machines + might have to install other *.i386 libraries

AFAICT, Linaro now provides native 64-bit versions of the tool-chain.
For example, the 14.11 release for the bare-metal ABI:
http://releases.linaro.org/14.11/components/toolchain/binaries/arm-none-eabi
http://releases.linaro.org/14.11/components/toolchain/binaries/arm-none-eabi/gcc-linaro-4.9-2014.11-x86_64_arm-eabi.tar.xz

Related

-bash: ./ex1: cannot execute binary file: Exec format error [duplicate]

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?
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

Raspberry Pi 3: Running arm32 programs on an arm64 system

I run my program perfectly on my Raspberry Pi 3 when I run 32bit Raspibian. It is a Linux 5.10.33-v7+ #1 armv7l system. The programs were compiled on this system, in C++. If I copy the executables to another card with that system, it works.
However, these same executables do not run when I use Debian 4.19.181-1 aarch64 Linux 4.19.0.16-arm64 (I copy the compiled file and paste it on the other system ).
When trying to run, it returns:
-bash: ./Myprogram: No such file or directory.
If I try to run with bash Myprogram, it returns:
Myprogram: cannot execute binary file
From what I've researched, this is an incompatible architectural error.
I've already tried changing permissions with chmod.
I think 32bit files should work on a 64bit system.
The "file" command returns:
ELF 32-bit LSB executable, ARM, EABI5 version 1 (GNU/Linux),
dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for
GNU/Linux 3.2.0,
BuildID[sha1]=ad484c860b63e0d8735c2b7aa5c69f2e49caaf29, with
debug_info, not stripped
Thank you so much
I understand the problem is the architecture. But why can the same processor (same raspbery) run an armv7l OS and also an arm64 OS? How does compatibility work?
Why does raspberry run both arm64 OS and armv7l OS but not programs?
it's not just a 32 or 64 bit problem .
you are two differents architectures, for your program to work you have no choice, you must recompile it for this architecture.
If you want to make portability you can use systems like "Make".

Running 32-bit ARM binary on aarch64 not working despite CONFIG_COMPAT

I've got a 64-bit ARM machine that I'd like to run 32-bit ARM binaries on. As a test case I've built a small hello world for 32-bit ARM using the arm-linux-gnueabihf-gcc toolchain. file shows it as:
root#ubuntu:/home/ubuntu# file hello
hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=61ffe5e22117a6d4c2ae37a1f4c76617d3e5facc, not stripped
But trying to run it produces:
root#ubuntu:/home/ubuntu# ./hello
bash: ./hello: cannot execute binary file: Exec format error
Based on a prior question, I checked whether the kernel was built with the CONFIG_COMPAT option, and it was:
root#ubuntu:/home/ubuntu# grep CONFIG_COMPAT= /boot/config-$(uname -r)
CONFIG_COMPAT=y
I also verified that the armhf architecture has been added and that the armhf version of the loader is present. Note that the loader itself doesn't run either:
root#ubuntu:/home/ubuntu# dpkg --print-foreign-architectures
armhf
root#ubuntu:/home/ubuntu# dpkg -l libc6:armhf
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==============-=============-============-=================================
ii libc6:armhf 2.30-0ubuntu2 armhf GNU C Library: Shared libraries
root#ubuntu:/home/ubuntu# file /lib/arm-linux-gnueabihf/ld-2.30.so
/lib/arm-linux-gnueabihf/ld-2.30.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=dff2b536287d61ddca68f3e001e14b7c235bbf68, stripped
root#ubuntu:/home/ubuntu# /lib/arm-linux-gnueabihf/ld-2.30.so
bash: /lib/arm-linux-gnueabihf/ld-2.30.so: cannot execute binary file: Exec format error
Other relevant system info:
root#ubuntu:/home/ubuntu# cat /proc/cpuinfo
processor : 0
BogoMIPS : 400.00
Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics cpuid asimdrdm
CPU implementer : 0x43
CPU architecture: 8
CPU variant : 0x1
CPU part : 0x0af
CPU revision : 2
root#ubuntu:/home/ubuntu# uname -a
Linux ubuntu 5.3.0-24-generic #26-Ubuntu SMP Thu Nov 14 01:14:25 UTC 2019 aarch64 aarch64 aarch64 GNU/Linux
I'm running out of things to try at this point. Any idea how to get the kernel to recognize these binaries and run them?
Ok, it looks like the underlying problem here is not in software, unfortunately. The CPU we're using, the Cavium ThunderX2, is one of the few 64-bit ARM chips that does not have aarch32 support. Quoting from WikiChip:
Only the 64-bit AArch64 execution state is support. No 32-bit AArch32 support.
So, this explains why it's not able to run 32-bit ARM binaries. I'm still fairly sure that other 64-bit ARM chips, like the Cortex-A57, are able to do this.
Update: older 32-bit ARM binaries do indeed work on aarch64 with a CPU that supports it, as shown below on an AWS ARM a1.metal instance:
ubuntu#ip-172-31-12-156:~$ cat /proc/cpuinfo | tail
processor : 15
BogoMIPS : 166.66
Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid
CPU implementer : 0x41
CPU architecture: 8
CPU variant : 0x0
CPU part : 0xd08
CPU revision : 3
ubuntu#ip-172-31-12-156:~$ uname -a
Linux ip-172-31-12-156 4.15.0-1054-aws #56-Ubuntu SMP Thu Nov 7 16:18:50 UTC 2019 aarch64 aarch64 aarch64 GNU/Linux
ubuntu#ip-172-31-12-156:~$ dpkg --print-foreign-architectures
armhf
ubuntu#ip-172-31-12-156:~$ file hello_hf
hello_hf: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 3.2.0, BuildID[sha1]=c95f0c46dfab925db53506751d7677156e334e5c, not stripped
ubuntu#ip-172-31-12-156:~$ ./hello_hf
hello, world!
This question has become more relevant as 32bit ARM chips are being phased out.
Me, I like to see old 32 bit binaries supported on new 64 bit hardware. Not so important, but convenient.
I took out my old Raspberry Pi Zero (32 bit) and Raspberry Pi 3B+ (64 bit) and for the first time installed a 64 bit OS on the 3B+ despite warnings of bugs and such and did some compiling.
No special make parameters. Just plain ordinary 32 bit compiling.
Runs fine on 32 bit and 64 bit.
Controllers and VMs will be running 32 bit architecture for many more years.
4GB memory limit is a pain yes. But for small apps its not a problem.

Specify the expected Linux version of the output binary of GCC

I'm helping others doing a lab experiment of the "operating systems concepts" course. The experiment task is to compile Linux 2.6.26 and run it in QEMU.
After compiling the Linux kernel, we're told to write a smallest program to serve as the init program. The example we're presented (and we followed) is:
#include <stdio.h>
int main() {
while (1) {
puts("Hello!");
sleep(2);
}
}
The compilation command is:
root#ubuntu:/home/vmware/oslab# gcc --version
gcc (Ubuntu 4.8.4-2ubuntu1~14.04.4) 4.8.4
Copyright (C) 2013 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.
root#ubuntu:/home/vmware/oslab# gcc -static -o init hello.c
The host environment should be a freshly-installed Ubuntu 14.04.6 (i386).
The problem is, one of my fellow students followed the instruction carefully, and the init program failed to execute. I asked him for his whole initrd.img, and noticed how his init program looks different:
vmware#ubuntu:~/oslab$ file mnt/init
mnt/init: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=7365ac494ef1d924c171899c169dbd3195d2d209, not stripped
To me, that's clearly not something that can run on Linux 2.6.26. With GCC 4.8 provided in the Ubuntu APT repository (trusty), how can I get GCC to output something that runs on Linux 2.6.26?
FYI: On my own testing VM (also Ubuntu 14.04.6, Linux 4.4, same latest GCC version from Ubuntu APT repo as of April 2, 2019), the compiled program shows Linux 2.6.24 in file output. Also, his binary runs perfectly well in QEMU with my freshly compiled 2.6.32.37 kernel.
Specify the expected Linux version of the output binary of GCC
in your question you speak about the version of libc C but that can also concerns a lot of other libs, and may be you want also produce 32b and/or 64b executable(s).
For me the most secure way is to use pbuilder, I use it to produce BoUML debs for Ubuntu Cosmic (18.10) Bionic (18.04), Artful (17.10) Zesty (17.04) Yakkety (16.10) Xenial (16.04) Trusty (14.04) and Precise (12.04) and that in both 32b and 64b, and I do all of that from my Ubuntu Xenial 64b just doing the appropriate sequence of pbuilder commands (without any reboot to go in each Linux release)
That needs time to generate a version but because this is made in the corresponding Linux version you are sure of the result.
The provided lab environment was Ubuntu 14.04, where the package libc6 has version 2.19-0ubuntu6.14.
The lab instruction provided by the teaching assistants contained an instruction to change the APT source by editing /etc/apt/sources.list manually, which had a SERIOUS disaster in it: The "version" string in the edited example was xenial instead of trusty, which, if followed, would factually update your system to Xenial (Ubuntu 16.04). The new version of libc6 was 2.23-0ubuntu11, which would cause as and ld (from binutils, not related to GCC) to output ELF with a minimum Linux version of 2.6.32.
With glibc version 2.19, the output ELF is compatible with Linux 2.6.24, but with glibc 2.23, the output is only compatible with Linux 2.6.32.
I tested and verified this by compiling a test program under Ubuntu 14.04 and checking the ELF information, then replaced all trusty with xenial, did apt-get update and only updated binutils and its dependencies (which includes libc6), and compiled the program and checked it again.

Cannot execute binary file error when running bibtex2html

I'm working on a project for a friend on a machine I'm not familiar with and I've run into some errors.
I'm running a program called bibtex2html, which is used to generate an HTML reference page. When I run the program, it gives me a "Cannot execute binary file" error.
From my preliminary research, it seems there are a number of causes to this problem, and I'm not really sure to begin.
What I've done so far:
uname -a ->
Linux baseline 2.6.38-15-generic-pae #60-Ubuntu SMP Tue May 22 11:48:17 UTC 2012 i686 i686 i386 GNU/Linux
file ~/bibtex2html/bibtex2html -> ~/bibtex2html/bibtex2html: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, stripped
You did all the research correctly, now you just need to interpret it. It's a 64-bit executable (x86-64), and you're on a 32-bit kernel (i686). You'll need to find or compile a 32-bit version of bibtex2html.

Resources