Katoptriss
Katoptriss

Reputation: 107

Issue debugging a 32-bits assembly Hello world with GDB on a Raspberry Pi running a 64 bit version of Linux

I am trying to setup my Raspberry Pi so I can start learning ARM, and have issues debugging 32-bits ARM files. First, some informations maybe useful to my problem:

$ uname -a
Linux raspberrypi 5.15.32-v8+ #1538 SMP PREEMPT Thu Mar 31 19:40:39 BST 2022 aarch64 GNU/Linux

$ cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
NAME="Debian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=debian

I can write a hello world program (in assembly) for ARM64, compile it using as and ld, then execute it and debug it with gdb without any issue. For 32 bits ARM, after installing the package binutils-arm-linux-gnueabihf, I can compile my files using arm-linux-gnueabihf-as/ld and execute them without issue. However, I have problems debugging them with gdb.

My version of gdb is :

$ gdb -v
GNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git

and I am using the GEF extension. The file command for the 32-bits file gives:

$ file helloworld
helloworld: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped

After typing gdb helloworld, I can run it using the r command and it does print Hello world, but I can't debug it step by step: setting a breakpoint to the entry point (in my case, 0x10074 - obtained with info file -, which does not seem standard) makes the program run indefinitely, as if it was in an infinite loop, and stopping it with CTRL+C gives me:

$sp  : 0x798fdfb4
$lr  : 0xc6ac9670
$pc  : 0x20      
$cpsr: [negative ZERO CARRY OVERFLOW INTERRUPT FAST thumb]
────────────────────────────────────────────────────────────────────────────────────────── stack ────
[!] Unmapped address: '0x55798fdfb4'
─────────────────────────────────────────────────────────────────────────────────── code:arm:ARM ────
[!] Cannot disassemble from $PC
[!] Cannot access memory at address 0x20
──────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "helloworld", stopped 0x20 in ?? (), reason: SIGINT

I am not sure what is going on. The address in Unmapped address: '0x55798fdfb4' looks like a standard .text address under PIE + ASLR, but I don't know why there would be mapping issues. How could I fix this ?

Upvotes: 0

Views: 1145

Answers (1)

Frant
Frant

Reputation: 5895

This answer is more an answer to the question: "How can I learn 32 bit assembly language on my raspberry Pi" than a direct answer to yours:

If your goal is to learn Aarch32 T32 or A32 assembly language on your raspberry Pi, I would strongly suggest to do so on a 32 bit distribution - I am not sure at this stage that you can debug a user mode Aarch32 program on an Aarch64 Linux system using an Aarch64 multiarch GDB or an Aarch32 version of GDB, my own attempts having been unsuccessful, and having not found to this day examples of how exactly to do this. Another pro of this approach is that you will be able to concentrate on learning 32 bit Arm, and not asking yourself if your programs are not working because of a bug, or because off a potential problem/bug in the tools you are running on your Aarch64 system - my two cents.

If you have a spare 8GiB micro-SD card, you can install a 32 bit version of Ubuntu Server 22.04 from here.

One installed, here is what I am getting on my system:

cat /sys/firmware/devicetree/base/model
Raspberry Pi 3 Model B Rev 1.2
uname -a
Linux ubuntu 5.15.0-1005-raspi #5-Ubuntu SMP PREEMPT Mon Apr 4 12:25:49 UTC 2022 armv7l armv7l armv7l GNU/Linux

Install gcc and gdb:

sudo-apt -get install gcc gdb

Create hello-world.s, adapted from this example:

        .arch armv7a
        .file   "hello-world.s"
        .text
        .global main
        .syntax unified
        .thumb
        .thumb_func
        .type   main, %function
main:
         mov r0, #1                      @ 1 = stdout
         ldr r1, =hello_world            @ str pointer
         mov r2, #13                     @ str len
         mov r7, #4                      @ linux write syscall
         svc 0                           @ software interrupt call write
exit:
         mov r0, #0                      @ return code
         mov r7, #1                      @ linux exit syscall
         svc 0                           @ software interrupt call exit
        .data
hello_world:
        .ascii "Hello World!\n"
        .end

as -g -o hello-world.o hello-world.s
gcc  -g -o hello-world hello-world.o

./hello-world
Hello World!

GDB debug session:

gdb ./hello-world
GNU gdb (Ubuntu 12.0.90-0ubuntu1) 12.0.90
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "arm-linux-gnueabihf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./hello-world...
(gdb) b main
Breakpoint 1 at 0x4e0: file hello-world.s, line 10.
(gdb) run
Starting program: /home/ubuntu/hello-world
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".

Breakpoint 1, main () at hello-world.s:10
10               mov r0, #1                      @ 1 = stdout
(gdb) step
11               ldr r1, =hello_world            @ str pointer
(gdb)
12               mov r2, #13                     @ str len
(gdb)
13               mov r7, #4                      @ linux write syscall
(gdb)
14               svc 0                           @ software interrupt call write
(gdb)
Hello World!
exit () at hello-world.s:16
16               mov r0, #0                      @ return code
(gdb)
17               mov r7, #1                      @ linux exit syscall
(gdb)
18               svc 0                           @ software interrupt call exit
(gdb)
[Inferior 1 (process 3043) exited normally]
(gdb) quit

Upvotes: 1

Related Questions