ARM Linux 可执行文件神秘地在 x86_64 上运行 [英] ARM Linux executable mysteriously runs on x86_64

查看:61
本文介绍了ARM Linux 可执行文件神秘地在 x86_64 上运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Docker 容器 (thewtex/cross-compiler-linux-armv7) 在 x86_64<上交叉编译一个简单的Hello World"Linux 用户空间 C 程序系统.目标系统为 ARMv7 嵌入式系统(特别是带有库存固件的 Kobo Aura HD 电子阅读器).

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).

程序源码(hello_world.c)如下

#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!

以及在目标设备上

[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!

对此有什么解释吗?

作为参考,我使用以下命令集调用编译器

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

由于某种原因生成的shell脚本有问题,我必须手动替换/cross-compiler-base/cross-compiler-linux-armv7//:build/:builddockcross.sh 中的:z/.现在我跑

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 返回有关生成的 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

推荐答案

Linux 内核中有一个机制叫做 binfmt_misc 可用于将任意解释器与可执行文件相关联.这种关联既可以基于可执行文件本身开头的魔术字节序列,也可以基于其文件扩展名(例如,wine 自动为 *.exe 文件注册自己).解释器通过写入 /proc/sys/fs/binfmt_misc/ sysfs 在内核中注册.

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.

在 Fedora 上,systemd-binfmt 服务负责解释器注册.它从 /usr/lib/binfmt.d 目录中读取一组配置文件,并对 sysfs 执行必要的写入.在上述问题的上下文中,qemu emulator-suite 的安装会将相应的配置文件放在此目录中.对于 ARM,此文件称为 qemu-arm 并具有以下内容:

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

这允许在 Linux 上透明地执行静态链接的 ARM 可执行文件.感谢 Mark Plotnick 指出这个机制.

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

这篇关于ARM Linux 可执行文件神秘地在 x86_64 上运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆