Stream of Consciousness

Share this post

QEMU and Dynamic Linking on Ubuntu

www.alexrp.com

QEMU and Dynamic Linking on Ubuntu

Installing foreign-architecture shared libraries.

Alex Rønne Petersen
Apr 18, 2023
Share

As part of my adventures in cross-compilation using Zig, I've been using QEMU extensively to test cross-compiled binaries. One issue I ran into is this:

$ zig cc -target aarch64-linux-gnu main.c
$ wsl qemu-aarch64 ./a.out
/lib/ld-linux-aarch64.so.1: No such file or directory

This stems from the fact that a.out is a dynamically-linked executable (note the -gnu rather than -musl). It cannot be loaded without the dynamic linker for aarch64 being present.

It turns out that it's possible to install the dynamic linker (or, to be precise, the glibc) for other architectures. The process is not documented very well, unfortunately. I'll describe the steps I followed below.


First, run the following:

# dpkg --add-architecture arm64

You'll need to modify your /etc/apt/sources.list (or files in /etc/apt/sources.list.d depending on how you've organized things). In my case, it looked like this:

deb http://archive.ubuntu.com/ubuntu groovy main multiverse restricted universe
deb http://archive.ubuntu.com/ubuntu groovy-backports main multiverse restricted universe
deb http://archive.ubuntu.com/ubuntu groovy-updates main multiverse restricted universe
deb http://security.ubuntu.com/ubuntu groovy-security main multiverse restricted universe

These repositories don't actually have an arm64 port. So you'll need to decorate them like so:

deb [arch=amd64] http://archive.ubuntu.com/ubuntu groovy main multiverse restricted universe
deb [arch=amd64] http://archive.ubuntu.com/ubuntu groovy-backports main multiverse restricted universe
deb [arch=amd64] http://archive.ubuntu.com/ubuntu groovy-updates main multiverse restricted universe
deb [arch=amd64] http://security.ubuntu.com/ubuntu groovy-security main multiverse restricted universe

This informs apt not to fetch from these repositories for architectures other than amd64.

Before saving, you'll also need to add the actual arm64 repositories to the file:

deb [arch=arm64] http://ports.ubuntu.com groovy main multiverse restricted universe
deb [arch=arm64] http://ports.ubuntu.com groovy-backports main multiverse restricted universe
deb [arch=arm64] http://ports.ubuntu.com groovy-updates main multiverse restricted universe

Make sure everything's updated:

# apt update && apt full-upgrade

You can now install glibc:

# apt install libc6:arm64

Finally, run the foreign executable:

$ wsl qemu-aarch64 ./a.out
Hello World

Note: If you're like me and also care about armhf, you can change the [arch=arm64] to [arch=arm64,armhf] in your /etc/apt/sources.list and repeat all the other steps, replacing arm64 with armhf. The same is true for ppc64el, riscv64, and s390x.

Share
Comments
Top
New

No posts

Ready for more?

© 2023 Alex Rønne Petersen
Privacy ∙ Terms ∙ Collection notice
Start WritingGet the app
Substack is the home for great writing