26 Nov 2020
qemu can emulate all kind of architectures and processors, including x86 and x86_64, it has presets for a long list of CPUs ([1], 486, pentium, Haswell, etc.)
I've tried this using qemu 4.2.1 on Ubuntu 20.04, latest is 5.1.0.
qemu does full-system emulation AND user-mode emulation. While the former allows to run a wide range of operating systems on any supported architecture [2], the later runs programs for another Linux or BSD target.
Full-system User-mode +---------------------+ +---------------------+ | Userspace emulation | | Userspace emulation | +----------+----------+ +----------+----------+ | | +---------+--------+ +-------+-------+ | Kernel emulation | | Kernel native | +---------+--------+ +-------+-------+ | | +----------+---------+ +--------+--------+ | Hardware emulation | | Hardware native | +--------------------+ +-----------------+
Let's compile the following simple program (hello.c
):
#include <stdio.h> int main() { printf("hello world %p\n", main); return 0; }And link statically to be self-contained; qemu can handle dynamically linked executables just fine as well.
To compile and link for 32-bit ARM [3]: arm-linux-gnueabihf-gcc -static -o hello-arm hello.c
For 64-bit x86: gcc -static -o hello-x86_x64 hello.c
Let's check:
$ file hello-arm
hello-arm: ELF 32-bit LSB executable, ARM, EABI5 version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, not stripped$ file hello-x86_x64
hello-x86_x64: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, not stripped
On Ubuntu, we need qemu-user [4], and can then execute both binaries:
$ qemu-arm -- ./hello-arm
hello world 0x10425$ qemu-x86_64 -- ./hello-x86_64
hello world 0x401ce5
qemu translates the input binary to run on the native CPU, also in
case the architectures match. It uses internal micro ops (some intermediate representation), these can be observed before and after
optimization:
qemu-x86_64 -d op -- ./hello-x86_64
qemu-x86_64 -d op_opt -- ./hello-x86_64
For example:
mov_i64 tmp0,r13 mov_i64 tmp1,r13 and_i64 cc_dst,tmp0,tmp1 discard cc_src discard loc10
Also the input and output assembler code can be seen:
qemu-x86_64 -d in_asm -- ./hello-x86_x64
qemu-x86_64 -d out_asm -- ./hello-x86_x64
qemu -cpu help
apt install gcc-arm-linux-gnueabihf
apt install qemu-user
qemu-x86_64 -d help
posted at: 23:45 | path: /programming | permanent link