It is performing a system call. When you run swi #0
, control is handed back to the Linux kernel where it processes the request for ptrace.
A quick Google reveals the Linux kernel implementation is in linux/kernel/ptrace.c.
In the ARM EABI calling convention, r0-r3 are scratch registers and can be used as temporary registers. If you need to use any other register, you must save them. In this case, r7 is being used for holding the system call number __NR_ptrace
. To use r7 without breaking the convention, it needs to be saved and restored when done.
In the code, that's done by:
...
stmfd sp!, {r4, r7} /* Save */
ldr r7, =__NR_ptrace /* Use */
...
ldmfd sp!, {r4, r7} /* Restore */
...
This particular code is an EABI kernel syscall()
. The slower older OABI uses swi #__NR_ptrace
to signal the function number to the Linux kernel. The swi
instruction is also known as svc
. As per the ARM documentation on svc
, this instruction switches to supervisor mode and executes the software interrupt exception; at address 0xffff0008 or 0x00000008. The particular Linux code that handles this is in entry-armv.S. It is not entirely clear why it is preserving r4
. The function number is sent to an EABI Linux in register r7
, which indexes a table of syscall()
Linux entry points. Other familiar routines are read()
, write()
, etc.