0

I found that ptrace will use __ptrace and its code in __ptrace.S like below:

ENTRY(__ptrace)
.save   {r4, r7}
stmfd   sp!, {r4, r7}
ldr     r7, =__NR_ptrace
swi     #0
ldmfd   sp!, {r4, r7}
movs    r0, r0
bxpl    lr
b       __set_syscall_errno
END(__ptrace)

what I don't know is how the process continue at swi #0 and what r7 is doing here?

Thanks for any hints.

user1921972
  • 5
  • 1
  • 4

1 Answers1

6

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.

Community
  • 1
  • 1
tangrs
  • 9,709
  • 1
  • 38
  • 53
  • thank you tangrs, so you mean the code to be executed is where __NR_ptrace pointed to? but how? – user1921972 May 29 '13 at 06:02
  • When control is handed back to the kernel, it will read r7 to determine which service the program requires. – tangrs May 29 '13 at 06:04
  • actually I copied that piece of code from android. it there any doc for "reading r7 to decide service #"? – user1921972 May 29 '13 at 06:14
  • also I read the doc for SWI, seems it has 2 ways to pass arguments and swi #0 will use r0 as service number however in this case, r0 should be the request of ret = __ptrace(request, pid, addr, &word); and it confused me very much – user1921972 May 29 '13 at 06:15
  • The system call convention will probably be different for different operating systems. The one I'm talking about is the Linux kernel specifically (which Android runs on). The code for getting the syscall number can be found at http://lxr.free-electrons.com/source/arch/arm/kernel/entry-common.S#L387 – tangrs May 29 '13 at 06:22
  • ah, the code piece is using EABI, which defines the usage of r7 as service number. thanks much tangrs! – user1921972 May 29 '13 at 06:36
  • I'm not sure it's actually specified by the EABI. I think it's Linux specific TBH - might have to check up on it. Also, don't forget to mark the answer as accepted if you're happy with it. – tangrs May 29 '13 at 10:22