qemu-system-aarch64: semihosting does not respect runtime-configurable endianness

Host environment

  • Operating system: macOS 15.7.3
  • OS/kernel version: Darwin Kernel Version 24.6.0
  • Architecture: AArch64
  • QEMU flavor: qemu-system-aarch64
  • QEMU version: 10.2.50 (v10.2.0-283-g0fc482b73d)
  • QEMU command line:
    ./build/qemu-system-aarch64-unsigned \
        -M raspi3b -display none -semihosting \
        -kernel ../semihosting/target/aarch64_be-unknown-none-softfloat/debug/no-std-test

Emulated/Virtualized environment

  • Operating system: Bare-metal, the semihosting Rust crate for the aarch64_be-unknown-none-softfloat target.
  • OS/kernel version: 0.1.21
  • Architecture: AArch64

Description of problem

semihosting::process::exit(0) running on a QEMU-emulated AArch64 CPU in big-endian mode on a little-endian host results in the QEMU process exiting with 1 instead of 0. Potentially more tests are broken.

This is due to QEMU not respecting AArch64's runtime-configurable endianness. On semihosting::process::exit(0), in QEMU's semihosting/arm-compat-semi.c#L768, arg0 is 0x2600020000000000 and compared with ADP_Stopped_ApplicationExit, which is 0x20026. Swapping the byte order in these cases resolves the issue.

Steps to reproduce

  1. Build QEMU with --target-list=aarch64-softmmu.
  2. Clone github.com/taiki-e/semihosting.
  3. Apply the following patch:
    --- a/tools/no-std.sh
    +++ b/tools/no-std.sh
    @@ -188,15 +188,6 @@ run() {
     
       local test_dir=tests/no-std
       case "${target}" in
    -    aarch64_be*)
    -      case "${runner}" in
    -        qemu-system)
    -          # TODO: QEMU exit with 1
    -          info "QEMU bug on aarch64_be (${target}) with system-mode (skipped)"
    -          return 0
    -          ;;
    -      esac
    -      ;;
         aarch64* | arm64* | riscv*)
           case "${runner}" in
             qemu-system)
    --- a/tools/qemu-system-runner.sh
    +++ b/tools/qemu-system-runner.sh
    @@ -56,7 +56,7 @@ qemu_system() {
       qemu_arch="$1"
       shift
     
    -  "qemu-system-${qemu_arch}" "$@" "${args[@]}"
    +  "/path-to-qemu/build/qemu-system-aarch64-unsigned" "$@" "${args[@]}"
     }
     
     export QEMU_AUDIO_DRV=none
  4. ./tools/no-std.sh +nightly aarch64-unknown-none-softfloat aarch64_be-unknown-none-softfloat

Additional information

I'll post a patch to resolve this issue shortly but wanted to file an issue regardless, in case my patches are not the way to go.

Edited Jan 06, 2026 by Martin Kröning
Assignee Loading
Time tracking Loading