Run aarch64 program through qemu

這篇的目的是利用 qemu & gdb 觀看 aarch64 program 的行為。

最近會有一直看 & 執行 assembly code 的需求,但是也不是很想一直看 x86-64 的 assembly code XD。剛好最近在 aarch64 的東西,索性以 aarch64 為目標。

aarch64 的 compiler 並不難找,可以使用 Linaro GCC,以後如果沒有什麼意外應該 會自己 build 一個 FSF GCC,以後如果有機會看 GCC 內部行為的時候會比較方便。

aarch64 的 qemu 的話,其實我對 qemu 不熟,我在 Ubuntu 16.04 用 sudo apt search qemu 好像找不到 aarch64 的支援,我也不是很確定,但是自己 build 一個 qemu 來用並不困難,所以我選擇自己 build 一個 qemu。

Build qemu for arm and aarch64

mkdir -p /home/yen3/tools/qemu/src
cd /home/yen3/tools/qemu/src
wget http://wiki.qemu-project.org/download/qemu-2.8.0.tar.bz2
tar xf qemu-2.8.0.tar.bz2
mkdir -p build_qemu
cd build_qemu
../qemu-2.8.0/configure --prefix=$HOME/tools/qemu  \
    --target-list=arm-linux-user,aarch64-linux-user,arm-softmmu,aarch64-softmmu
    --enable-linux-user
make
make install

Observe aarch64 through gdb and qemu

  1. 環境說明
    • 假設 aarch64 compiler 在 /home/yen3/tools/xc/gcc621/bin/aarch64-linux-gnu-gcc
    • 假設 qemu 在 /home/yen3/tools/qemu/bin/qemu-aarch64
  2. 編譯 main.c 變成 main.out (for aarch64)

    /home/yen3/tools/xc/gcc621/bin/aarch64-linux-gnu-gcc -g -O0 main.c -o main.out
    
  3. 利用 qemu 執行該程式 - 這邊需注意一點,需要透過 -L 設定 sysroot,如果是 抓 linaro gcc 的話,記得連 sysroot 的 tarball 也一並下載,如果是自己編的 話,應該會知道 sysroot 在那裡。

    /home/yen3/tools/qemu/bin/qemu-aarch64 \
      -L /home/yen3/tools/xc/gcc621 \
      -g 1234 \
      ./main.out
    
  4. 利用 aarch64-linux-gnu-gdb 連到 gdb server 上

    /home/yen3/tools/xc/gcc621/bin/aarch64-linux-gnu-gdb -x test.gdb
    
    • test.gdb 內容如下
      target remote localhost:1234
      file ./main.out
      tui enable
      layout split
      b main
      c
      set sysroot /home/yen3/tools/xc/gcc630/aarch64-linux-gnu
      

2017/01/26 Update

這幾天嘗試自己 build 了一個 debuggable aarch64-linux-gcc 出來,我把全部的 指令寫成一個 Makefile。

CC       = /home/yen3/tools/xc/gcc630/bin/aarch64-linux-gnu-gcc
GDB      = /home/yen3/tools/xc/gcc621/bin/aarch64-linux-gnu-gdb
QEMU_BIN = /home/yen3/tools/qemu/bin/qemu-aarch64
SYSROOT  = /home/yen3/tools/xc/gcc630/aarch64-linux-gnu

CFLAGS   = -ggdb -O0 -fno-builtin-printf
SRC      = main.c
BIN      = main.out

all:
        $(CC) $(CFLAGS) ${SRC} -o ${BIN}
run:
        QEMU_LD_PREFIX=$(SYSROOT) $(QEMU_BIN) ./${BIN}
gdb:
        QEMU_LD_PREFIX=$(SYSROOT) $(QEMU_BIN) -g 1234 ./${BIN} &
        $(GDB) -x test.gdb
clean:
        rm ${BIN}

也順便把 test.gdb 更新了一下,直接更新在上面。

不過忘了 build gdb,也無妨,現在是用 linaro gcc 的 gdb,過幾天有空再自己 build 一個。

Comments

Comments powered by Disqus