【问题标题】:System calls Implementation系统调用实现
【发布时间】:2012-09-28 09:15:42
【问题描述】:

如果用户应用程序进行系统调用,则会触发软件中断/异常。如何查看产生软件中断的源代码?

【问题讨论】:

  • 您可能应该查看库源代码(例如 libc,GNU libc 或 uClibc)而不是内核源代码。

标签: linux linux-kernel system-calls


【解决方案1】:

可以使用 Intel x86 汇编指令int n 触发软件中断,其中n 是中断号。系统调用是软件中断的一种特殊情况;在您可以通过

手动进行系统调用
mov eax, m
int 0x80

其中m 应替换为中断号。以下是链接到每个函数的联机手册页的 32-bit syscall numbers64-bit syscall numbers 列表。您还需要通过其他寄存器(ebxecx 等)将参数传递给系统调用,您可以阅读更多关于 here 的信息。

这是进行系统调用的最通用方式,因为它独立于外部库,如 libc,如果需要,可以使用内联汇编在 C/C++ 中实现。

【讨论】:

  • 这是针对一般问题的特定于实现的答案。
  • 链接已损坏。直接引用内核源代码可能会更好:32 bit64 bit
【解决方案2】:

很久以前,有一个int 0x80 陷阱可以进入内核,但现在sysenter 是首选。

您可以通过转储vsyscall 部分来获取代码,该部分由内核自动映射到每个进程。

$ cat /proc/self/maps 
blah blah blah
...
blah blah blah
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

更多信息请查看this article

【讨论】:

    【解决方案3】:

    Linux Assembly Howto 中有解释。你应该阅读维基百科syscall 页面(以及关于VDSO),以及intro(2)syscalls(2) 手册页。另请参阅this 答案和this 之一。还可以查看 Gnu Libcmusl-libc 源代码。还学习使用strace 找出给定命令或进程进行了哪些系统调用。

    另请参阅calling conventions 和与您的系统相关的应用程序二进制接口规范。对于 x86-64,它是 here

    【讨论】:

    • 现在Linux Assembly Howto 仍然解释了已弃用的int 0x80 而不是系统调用。
    • @ceving:是的。随意贡献到那个Assembly HowTo来改进它。但我相信现在很少有人关心汇编,因为编译器提供的代码比人类编写的更好,而且因为 VDSO...
    • 完全一样。只有数字和寄存器不同。 exit(n)eax=60 edi=n syscall 而不是 eax=1 ebx=n int0x80
    猜你喜欢
    • 2016-05-25
    • 2018-04-04
    • 2016-01-18
    • 2017-02-14
    • 2012-08-22
    • 1970-01-01
    • 1970-01-01
    • 2012-09-19
    • 2017-07-27
    相关资源
    最近更新 更多