0

我发现 ptrace 将在 __ptrace.S 中使用 __ptrace 及其代码,如下所示:

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)

我不知道该过程如何在 swi #0 处继续,以及 r7 在这里做什么?

感谢您的任何提示。

4

1 回答 1

6

它正在执行系统调用。当您运行时swi #0,控制权会交还给 Linux 内核,在该内核中处理 ptrace 请求。

快速谷歌发现 Linux 内核实现位于linux/kernel/ptrace.c中。

在 ARM EABI 调用约定中,r0-r3 是暂存寄存器,可以用作临时寄存器。如果您需要使用任何其他寄存器,则必须保存它们。在这种情况下, r7 用于保存系统调用号__NR_ptrace。要在不违反约定的情况下使用 r7,需要保存并在完成后恢复。

在代码中,这是通过以下方式完成的:

...
stmfd   sp!, {r4, r7} /* Save */
ldr     r7, =__NR_ptrace /* Use */
...
ldmfd   sp!, {r4, r7} /* Restore */
...

这个特定的代码是一个EABI内核syscall()。较慢的旧OABI用于swi #__NR_ptrace向Linux 内核发送函数号。swi指令也称为svc. 根据ARM 上的文档svc,该指令切换到超级用户模式并执行软件中断异常;在地址0xffff00080x00000008。处理此问题的特定 Linux 代码位于entry-armv.S中。目前尚不完全清楚为什么要保存r4. 功能编号被发送到EABILinux in register r7,它索引syscall()Linux 入口点表。其他熟悉的例程是read(),write()等。

于 2013-05-29T05:51:38.327 回答