This post describes userspace tracing with QEMU. The example binary computes the hash of an input string. Source available here (compile with -static).
wget https://download.qemu.org/qemu-8.2.2.tar.xz
tar -xvf qemu-8.2.2.tar.xz && cd qemu-8.2.2
./configure --enable-trace-backends=simple
make -j$(nproc)
export QEMU=$(pwd)/build/qemu-aarch64
$QEMU -d cpu,nochain -D /tmp/trace sha256sum "Hello World"
head /tmp/trace
PC=00000000004005c0 X00=0000000000000000 X01=0000000000000000
X02=0000000000000000 X03=0000000000000000 X04=0000000000000000
X05=0000000000000000 X06=0000000000000000 X07=0000000000000000
X08=0000000000000000 X09=0000000000000000 X10=0000000000000000
X11=0000000000000000 X12=0000000000000000 X13=0000000000000000
X14=0000000000000000 X15=0000000000000000 X16=0000000000000000
X17=0000000000000000 X18=0000000000000000 X19=0000000000000000
X20=0000000000000000 X21=0000000000000000 X22=0000000000000000
X23=0000000000000000 X24=0000000000000000 X25=0000000000000000
X26=0000000000000000 X27=0000000000000000 X28=0000000000000000
du -h /tmp/trace
31.0M /tmp/trace
nm -S sha256sum | grep sha256
00000000004009d4 00000000000007b0 T sha256
$QEMU -d cpu,nochain -D /tmp/trace -dfilter 0x4009d4..0x401184 sha256sum "Hello World"
du -h /tmp/trace
436K /tmp/trace
grep PC /tmp/trace | cut -d " " -f 2 | cut -d "=" -f 2 | sort | uniq -c
1 00000000004009d4
1 0000000000400a60
1 0000000000400a64
1 0000000000400a7c
2 0000000000400a84
1 0000000000400af0
1 0000000000400afc
2 0000000000400b08
48 0000000000400b28
48 0000000000400b4c
48 0000000000400b94
48 0000000000400bb8
1 0000000000400c40
1 0000000000400c4c
2 0000000000400c94
64 0000000000400ca0
64 0000000000400cb0
64 0000000000400cc0
64 0000000000400d38
64 0000000000400d48
64 0000000000400d58
1 0000000000400df4
1 0000000000400e00
1 0000000000400e80
2 0000000000400e8c
1 0000000000400e94
1 0000000000401000
1 0000000000401184