Linux 裸系统调用,不是 glibc

Linux bare system calls, not glibc

我正在阅读一篇解释如何在不通过 glibc 的情况下调用裸系统调用的文章。要调用 chmodexit,请使用:

#include <linux/unistd.h>
_syscall2(int,chmod,char*,f,int,m)
_syscall1(int,exit,int,r)

我的 gcc 抱怨他们。它们有什么用,它们是如何工作的?

$ gcc --version
gcc (Ubuntu 7.4.0-1ubuntu1~18.04) 7.4.0
$ gcc e.c 
e.c:2:15: error: unknown type name ‘setresuid’; did you mean ‘__NR_setresuid’?
 _syscall3(int,setresuid,int,r,int,e,int,s)
               ^~~~~~~~~
               __NR_setresuid
e.c:2:29: error: unknown type name ‘r’
 _syscall3(int,setresuid,int,r,int,e,int,s)
                             ^
e.c:2:35: error: unknown type name ‘e’
 _syscall3(int,setresuid,int,r,int,e,int,s)
                                   ^
e.c:2:41: error: unknown type name ‘s’
 _syscall3(int,setresuid,int,r,int,e,int,s)
                                         ^

您的文章可能已过时。

如果您使用 C 编写代码,则没有理由避免使用 syscalls(2) (notice the plural) as documented. Be also aware of the vdso(7). You could use some other C standard library than the glibc (e.g. musl-libc, dietlibc,等等...)并且您可能(但不建议这样做)静态 link 它。

您可以使用 syscall(2) (notice the singular) instead. I see no reason to do that, e.g. use read(2) or mmap(2) 而没有 syscall

Assembly HowTo 可能是一本有趣的读物(注意,它可能过于以 32 位为中心,当今大多数 Linux PC 都是 64 位 x86-64)。

另见 osdev.org

顺便说一句,一些旧的 Unixes(例如 Solaris)有一个 libsys 提供 只是 系统调用,并且它们的 libc linked 到它。我也想要一个libsys!但是在当前的 Linux 系统上,这并不重要,因为几乎每个进程(运行 一些 dynamically linked ELF executable) is mmap(2)-ing, after ld-linux.so(8), several segments and sections of your libc.so.6; for details, read Drepper's How to write a shared library (since it also explains in details how shared libraries actually work). Use also pmap(1) 在一些 运行 进程(例如 shell 中的 pmap $$)。

一些罕见的系统调用(例如userfaultfd(2) today 2Q2019) are not known by the glibc. They are an exception, because most system calls are wrapped by your libc (the wrapping usually just deals with errno(3) setting on failure). Be aware of strace(1)

你还应该阅读 Operating Systems: Three Easy Pieces(这是一本可免费下载的书,解释了系统调用的作用和原因)