23

我想检查在 glibc 中执行系统调用的代码。我发现了这样的东西。

ENTRY (syscall)
    movq %rdi, %rax     /* Syscall number -> rax.  */
    movq %rsi, %rdi     /* shift arg1 - arg5.  */
    movq %rdx, %rsi
    movq %rcx, %rdx
    movq %r8, %r10
    movq %r9, %r8
    movq 8(%rsp),%r9    /* arg6 is on the stack.  */
    syscall         /* Do the system call.  */
    cmpq $-4095, %rax   /* Check %rax for error.  */
    jae SYSCALL_ERROR_LABEL /* Jump to error handler if error.  */
L(pseudo_end):
    ret         /* Return to caller.  */

现在我的问题是系统调用(在cmpq指令之前)是否是指令?其次,如果是指令,ENTRY(syscall)是什么意思?ENTRY(我不知道 ENTRY 是什么)和指令的名称相同?其次,什么是L(pseudo_end)?

4

2 回答 2

31

syscall是 x86-64 中的一条指令,用作进行系统调用的 ABI 的一部分。(32 位 ABI 使用int 80hor sysenter,并且在 64 位模式下也可用,但在 64 位代码中使用 32 位 ABI 是个坏主意,尤其是对于带有指针参数的调用。)

但是还有一个名为 的 C 库函数syscall(2),它是系统调用 ABI 的通用包装器。您的代码显示了该函数的转储,包括将返回值解码为errno-setting。ENTRY(syscall)只是意味着该功能从那里开始。

L()并且ENTRY()是 CPP 宏。

L(pseudo_end)只是一个可以作为跳转目标的标签。也许代码会SYSCALL_ERROR_LABEL跳回到那里,尽管对于那个代码块来说它会更有效ret,所以它可能是以前版本的遗物,或者用于其他东西。

于 2012-05-14T13:14:11.573 回答
6

是的,syscall是关于 x86-64 的指令。sysenter在 i686 上有类似的指令。

ENTRY(syscall)将是一个宏。可能会扩展到符号定义,您必须为此使用 grep。

于 2012-05-14T13:09:50.490 回答