我发现ptrace将使用__ptrace及其__ptrace.S代码,如下所示:
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在这里做了什么?
谢谢你的任何提示。
发布于 2013-05-29 13:51:38
它正在执行系统调用。当您运行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()。较慢的旧版本Linux 使用swi #__NR_ptrace向内核发送函数号。swi指令是also known as svc。根据ARM documentation on svc,此指令切换到监控模式,并在地址 or 处执行软件中断异常。处理这个问题的特定Linux代码在中。目前还不完全清楚它为什么要保留r4。函数号被发送到寄存器r7中的EABI Linux,该寄存器对syscall() Linux入口点的表进行索引。其他熟悉的例程有read()、write()等。
https://stackoverflow.com/questions/16806276
复制相似问题