linux – Assembly中系统调用的返回值是什么?
作者:互联网
当我尝试研究内核的系统调用的返回值时,我找到了描述它们的表,以及我需要将它放在不同的寄存器中以使它们工作.但是,我没有找到任何文档说明我从系统调用获得的返回值是什么.我只是在不同的地方找到我收到的东西将在EAX寄存器中.
The result is usually returned in the EAX register.
汇编语言循序渐进:Jeff Duntemann编写的Linux书籍在他的程序中多次说明:
Look at sys_read’s return value in EAX
Copy sys_read return value for safe keeping
我没有解释任何有关此返回值的网站.有没有互联网资源?或者有人能解释我这个价值观吗?
解决方法:
另见this excellent LWN article about system calls,它假定为C知识.
另外:The Definitive Guide to Linux System Calls (on x86),及相关:What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?
C是Unix系统编程的语言,所以所有文档都是用C语言编写的.然后是文档,说明任何给定平台上C接口和asm之间的细微差别,通常在手册页的Notes部分.
sys_read表示原始系统调用(与libc包装函数相对). read系统调用的内核实现是一个名为sys_read()的内核函数.你不能用调用指令调用它,因为它在内核中,而不是库中.但人们仍然在谈论“调用sys_read”以区别于libc函数调用.但是,即使您的意思是原始系统调用(特别是当libc包装器没有做任何特殊操作时),也可以说读取,就像我在这个答案中所做的那样.
另请注意,syscall.h使用实际系统调用号定义SYS_read等常量. (在int 0x80或syscall指令之前放入EAX的值).
Linux系统调用返回值(在x86上的EAX / RAX中)是成功的非负值,或a negative error code.如果传递无效指针,则为-EFAULT.
此行为记录在syscalls(2)
手册页中.
实际上,-1到-4095意味着错误,其他任何意味着成功. glibc的generic syscall(2)
wrapper使用了这个序列:cmp rax,-4095 / jae SYSCALL_ERROR_LABEL,对于所有Linux系统调用显然是guaranteed to be future-proof.有趣的案例包括有效地址为can have the sign bit set, but must be page aligned的mmap,以及内核ABI将-20..19返回值范围映射到1..40的getpriority,以及libc对其进行解码.更多细节在a related answer about decoding syscall error return values.
更新,是的,所有系统调用肯定都保证-4095 .. -1是Linux运行的所有体系结构上的错误范围.有关详细信息,请参阅AOSP non-obvious syscall() implementation. (将来,不同的体系结构可以为MAX_ERRNO使用不同的值,但是像x86-64这样的现有arches的值保证与Linux保持内核ABI稳定的非破坏用户空间策略的一部分相同. )
要查找特定平台的常量的实际数值,您需要找到它们是#defined的C头文件.有关详细信息,请参见my answer on a question about that.
每个sys调用的返回值的含义记录在第2节手册页中,如read(2)
.(sys_read是原始系统调用,glibc read()函数是一个非常薄的包装器.)大多数手册页都有一个完整的部分为了返回值.例如
RETURN VALUE
On success, the number of bytes read is returned (zero indicates
end of file), and the file position is advanced by this number. It
is not an error if this number is smaller than the number of bytes
requested; this may happen for example because fewer bytes are
actually available right now (maybe because we were close to end-of-
file, or because we are reading from a pipe, or from a terminal), or
because read() was interrupted by a signal. See also NOTES.On error, -1 is returned, and errno is set appropriately. In this
case, it is left unspecified whether the file position (if any)
changes.
请注意,最后一段描述了glibc包装器如何解码值,如果原始系统调用的返回值为负,则描述sets errno到-EAX,因此errno = EFAULT,如果原始系统调用返回-EFAULT,则返回-1.
还有一个完整的部分列出了read()允许返回的所有可能的错误代码,以及它们对read()的具体含义. (POSIX标准化了大多数此行为.)
我不确定glibc在哪里解码mmap(2)
的返回值,其中返回值不是有符号类型.它可能使用与通用系统调用包装器相同的方法(检查无符号值> -4096UL),但每个系统调用的特定包装器没有实际调整寄存器之间的args并调用该函数的开销.
我没有看到它in the glibc source tree;据推测,它被埋藏在某些宏层之下.例如in the x86-64 macro
标签:linux,assembly,return-value,nasm,system-calls 来源: https://codeday.me/bug/20190925/1816566.html