How to single step ARM assembly in GDB on QEMU?

前端 未结 4 1742
死守一世寂寞
死守一世寂寞 2020-11-30 11:47

I\'m trying to learn about ARM assembler programming using the GNU assembler. I\'ve setup my PC with QEmu and have a Debian ARM-HF chroot environment.

If I assemble

4条回答
  •  挽巷
    挽巷 (楼主)
    2020-11-30 12:21

    Minimal working QEMU user mode example

    I was missing the -fno-pie -no-pie options:

    sudo apt-get install gdb-multiarch gcc-arm-linux-gnueabihf qemu-user
    printf '
    #include 
    #include 
    
    int main() {
        puts("hello world");
        return EXIT_SUCCESS;
    }
    ' >  hello_world.c
    arm-linux-gnueabihf-gcc -fno-pie -ggdb3 -no-pie -o hello_world hello_world.c
    qemu-arm -L /usr/arm-linux-gnueabihf -g 1234 ./hello_world
    

    On another terminal:

    gdb-multiarch -q --nh \
      -ex 'set architecture arm' \
      -ex 'set sysroot /usr/arm-linux-gnueabihf' \
      -ex 'file hello_world' \
      -ex 'target remote localhost:1234' \
      -ex 'break main' \
      -ex continue \
      -ex 'layout split'
    ;
    

    This leaves us at main, in a split code / disassembly view due to layout split. You will also interested in:

    layout regs
    

    which shows the registers.

    At the end of the day however, GDB Dashboard is more flexible and reliable: gdb split view with code

    -fno-pie -no-pie is required because the packaged Ubuntu GCC uses -fpie -pie by default, and those fail due to a QEMU bug: How to GDB step debug a dynamically linked executable in QEMU user mode?

    There was no gdbserver --multi-like functionality for the QEMU GDB stub on QEMU 2.11: How to restart QEMU user mode programs from the GDB stub as in gdbserver --multi?

    For those learning ARM assembly, I am starting some runnable examples with assertions and using the C standard library for IO at: https://github.com/cirosantilli/arm-assembly-cheat

    Tested on Ubuntu 18.04, gdb-multiarch 8.1, gcc-arm-linux-gnueabihf 7.3.0, qemu-user 2.11.

    Freestanding QEMU user mode example

    This analogous procedure also works on an ARM freestanding (no standard library) example:

    printf '
    .data
        msg:
            .ascii "hello world\\n"
        len = . - msg
    .text
    .global _start
    _start:
        /* write syscall */
        mov r0, #1     /* stdout */
        ldr r1, =msg   /* buffer */
        ldr r2, =len   /* len */
        mov r7, #4     /* Syscall ID. */
        swi #0
    
        /* exit syscall */
        mov r0, #0 /* Status. */
        mov r7, #1 /* Syscall ID. */
        swi #0
    ' >  hello_world.S
    arm-linux-gnueabihf-gcc -ggdb3 -nostdlib -o hello_world -static hello_world.S
    qemu-arm -g 1234 ./hello_world
    

    On another terminal:

    gdb-multiarch -q --nh \
      -ex 'set architecture arm' \
      -ex 'file hello_world' \
      -ex 'target remote localhost:1234' \
      -ex 'layout split' \
    ;
    

    We are now left at the first instruction of the program.

    QEMU full system examples

    • Linux kernel: How to debug the Linux kernel with GDB and QEMU?
    • Bare metal: https://github.com/cirosantilli/newlib-examples/tree/f70f8a33f8b727422bd6f0b2975c4455d0b33efa#gdb

提交回复
热议问题