C是Unix系统编程的语言,因此所有文档均以C表示。然后,在任何给定平台上都有C接口与asm之间细微差异的文档,通常在手册页的Notes部分中。
sys_read表示原始系统调用(与libc包装器函数相对)。
read系统调用的内核实现是称为的内核函数
sys_read()。您不能使用
call指令来调用它,因为它在内核中,而不是库中。但是人们仍然在谈论“调用
sys_read”以区别于libc函数调用。但是,
read即使您指的是原始系统调用(特别是当libc包装器没有执行任何特殊操作时),也可以说出来,就像我在此答案中所做的那样。
还要注意,
syscall.h定义常量时应
SYS_read使用实际的系统调用号码。(您在EAX
int0x80或
syscall指令前输入的值)。
Linux系统调用的返回值(在
EAX/
RAXx86上)或者是成功的非负值,或一个负的错误代码。例如,
-EFAULT如果您传递了无效的指针。
syscalls(2)手册页中记录了此行为。
实际上, -1到-4095表示错误,其他表示成功。glibc的通用
syscall(2)包装器使用以下序列:
cmp rax, -4095/
jaeSYSCALL_ERROR_LABEL,显然可以保证所有Linux系统调用都符合未来的要求。有趣的情况包括:
mmap有效地址[可以设置符号位,但必须进行页面对齐];
getpriority内核ABI将-20..19返回值范围映射到1..40,然后libc对其进行解码。有关解码系统调用错误返回值的相关答案中的更多详细信息。
更新,是的,对于所有的系统调用,都可以保证在Linux运行的所有体系结构上的错误范围都是
-4095..
-1有关更多详细信息,请参见[AOSP非显而易见的syscall()实现。(将来,不同的体系结构可能会为MAX_ERRNO使用不同的值,但可以保证现有拱门(如x86-64)的值与Linux保持内核ABI稳定的不中断用户空间策略的一部分相同。
要查找特定平台常数的实际数值,您需要在
#defined所在的位置找到C头文件。有关详细信息,
每个sys调用的返回值的含义在第2节的手册页中都有介绍,例如
read(2)。(
sys_read这是glibc
read()函数非常薄的包装程序的原始系统调用。)大多数手册页都有用于返回值的整个部分。例如
返回值
成功后,将返回读取的字节数(零表示文件末尾),并且文件位置以该数字前移。如果此数目小于请求的字节数,这不是错误;例如,这可能是因为当前
实际可用的字节较少(可能是因为我们接近
文件末尾,或者因为我们正在从管道或终端
读取),或者因为read()被a中断了。信号。另请参阅注释。如果出错,则返回-1,并正确设置errno。在这种情况下,未指定文件位置(如果有)是否
更改。
需要注意的是最后一段描述glibc的包装如何解码值,并设置errno到
-EAX如果原始系统调用的返回值是负的,所以
errno=EFAULT和返回
-1如果原始系统调用返回
-EFAULT。
整个章节列出了所有可能
read()返回的错误代码,以及它们的特殊含义
read()。(POSIX标准化了大多数这种行为。)
我不确定glibc到底在哪里解码的返回值
mmap(2),而返回值不是带符号的类型。它可能使用与通用syscall包装器相同的方法(检查unsigned value
> -4096UL),但是每个系统调用的特定包装器没有实际在寄存器之间对arg进行改组并调用该函数的开销。
我在glibc源代码树中没有看到它;大概它埋在某些宏层下。



