Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ARM Linux executable mysteriously runs on x86_64

I'm using the Docker container (thewtex/cross-compiler-linux-armv7) to cross-compile a simple "Hello World" Linux user space C program on an x86_64 system. The target system is a ARMv7 embedded system (in particular a Kobo Aura HD e-reader with stock firmware).

The source code of the program (hello_world.c) is as follows

#include <stdio.h>

int main(int argc, char *argv[]) {
    printf("Hello World!\n");
    return 0;
}

Unexpectedly, I can execute the resulting executable on the host system:

andreas@andreas-pc:~/tmp/test$ uname -a && ./hello 
Linux andreas-pc 4.5.5-201.fc23.x86_64 #1 SMP Sat May 21 15:29:49 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
Hello World!

as well as on the target device

[root@(none) onboard]# uname -a && ./hello 
Linux (none) 2.6.35.3-850-gbc67621+ #1038 PREEMPT Thu Apr 25 15:48:22 CST 2013 armv7l GNU/Linux
Hello World!

Is there any explanation for this?


For reference, I invoke the compiler using the following set of commands

docker run thewtex/cross-compiler-linux-armv7 > ./dockcross.sh
chmod +x dockcross.sh

For some reason the generated shell script is buggy, I manually have to replace /cross-compiler-base/cross-compiler-linux-armv7/ and /:build/:build:z/ in dockcross.sh. Now I run

./dockcross.sh arm-linux-gnueabihf-cc hello_world.c -static -o hello

file returns the following information about the resulting hello executable

hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=317a9ea164931f614b24e98dec743050e2d7f900, not stripped
like image 688
Andreas Stöckel Avatar asked Jun 19 '16 22:06

Andreas Stöckel


People also ask

Can Arm64 run x86?

The WOW64 layer of Windows allows x86 code to run on the Arm64 version of Windows. x86 emulation works by compiling blocks of x86 instructions into Arm64 instructions with optimizations to improve performance.

Can linux for ARM run x86 apps?

Yes you can run x86-64 binaries on arm64.

Can QEMU emulate x86 on ARM?

QEMU can (slowly) emulate any architecture on any other architecture. In this case, they're using QEMU to emulate x86-64 on ARM64. No nesting or Rosetta is needed.

Can Ubuntu ARM run x86 apps?

Natively, ARM instructions do NOT run on an x86, and equally so, x86 instructions don't run on an ARM. However, there are emulators in both directions that allow programs compiled for one to run on the other platform in certain circumstances.


1 Answers

There is a mechanism in the Linux kernel called binfmt_misc that can be used to associate arbitrary interpreters with executables. This association can either be based on a magic byte sequence at the beginning of the executable itself, or its file extension (e.g., wine automatically registers itself for *.exe files). Interpreters are registered in the kernel by writing to the /proc/sys/fs/binfmt_misc/ sysfs.

On Fedora, the systemd-binfmt service is responsible for the interpreter registration. It reads a set of configuration files from the /usr/lib/binfmt.d directory and performs the necessary writes to the sysfs. In the context of the above question, installation of the qemu emulator-suite will place the corresponding configuration files in this directory. For ARM this file is called qemu-arm and has the following content:

enabled
interpreter /usr/bin/qemu-arm
flags: 
offset 0
magic 7f454c4601010100000000000000000002002800
mask ffffffffffffff00fffffffffffffffffeffffff

This allows to transparently execute statically linked ARM executables on Linux. Thanks to Mark Plotnick for pointing this mechanism out.

like image 106
Andreas Stöckel Avatar answered Sep 29 '22 01:09

Andreas Stöckel