【发布时间】:2012-09-28 09:15:42
【问题描述】:
如果用户应用程序进行系统调用,则会触发软件中断/异常。如何查看产生软件中断的源代码?
【问题讨论】:
-
您可能应该查看库源代码(例如 libc,GNU libc 或 uClibc)而不是内核源代码。
标签: linux linux-kernel system-calls
如果用户应用程序进行系统调用,则会触发软件中断/异常。如何查看产生软件中断的源代码?
【问题讨论】:
标签: linux linux-kernel system-calls
可以使用 Intel x86 汇编指令int n 触发软件中断,其中n 是中断号。系统调用是软件中断的一种特殊情况;在您可以通过
mov eax, m
int 0x80
其中m 应替换为中断号。以下是链接到每个函数的联机手册页的 32-bit syscall numbers 和 64-bit syscall numbers 列表。您还需要通过其他寄存器(ebx、ecx 等)将参数传递给系统调用,您可以阅读更多关于 here 的信息。
这是进行系统调用的最通用方式,因为它独立于外部库,如 libc,如果需要,可以使用内联汇编在 C/C++ 中实现。
很久以前,有一个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
【讨论】:
在Linux Assembly Howto 中有解释。你应该阅读维基百科syscall 页面(以及关于VDSO),以及intro(2) 和syscalls(2) 手册页。另请参阅this 答案和this 之一。还可以查看 Gnu Libc 和 musl-libc 源代码。还学习使用strace 找出给定命令或进程进行了哪些系统调用。
另请参阅calling conventions 和与您的系统相关的应用程序二进制接口规范。对于 x86-64,它是 here。
【讨论】:
int 0x80 而不是系统调用。
exit(n) 是 eax=60 edi=n syscall 而不是 eax=1 ebx=n int0x80。