Reputation: 107
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
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