- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
据我所知,ARM 的 Linux ABI 声明系统调用返回值是通过 r0
传递的如果它是负数,它应该被线程化为 errno 值被否定。即系统调用以一些错误结束。AOSP does this check以某种奇特的方式:
ENTRY(syscall)
mov ip, sp
stmfd sp!, {r4, r5, r6, r7}
.cfi_def_cfa_offset 16
.cfi_rel_offset r4, 0
.cfi_rel_offset r5, 4
.cfi_rel_offset r6, 8
.cfi_rel_offset r7, 12
mov r7, r0
mov r0, r1
mov r1, r2
mov r2, r3
ldmfd ip, {r3, r4, r5, r6}
swi #0
ldmfd sp!, {r4, r5, r6, r7}
.cfi_def_cfa_offset 0
cmn r0, #(MAX_ERRNO + 1) /* Set C flag if r0 is between -4095 and -1, set Z flag if r0 == -4096 */
bxls lr /* return if Z is set or C is clear */
neg r0, r0
b __set_errno_internal
END(syscall)
看起来这个函数不会威胁r0 < -4096
作为错误条件。虽然它应该。当然是真的errno
将适合允许的间隙,但无论如何以这种方式执行检查而不是仅仅测试的理由是什么 r0
消极情绪?
附言如果我遗漏了什么或者只是我的分析不正确 - 欢迎提出任何意见。
最佳答案
这就是 Linux 的系统调用 ABI/API 的设计方式,仅限 -errno
的有限范围值是允许的,以避免为一小组错误代码使用可能返回值范围的一半。 (没有人需要超过 4095 个 errno 代码?)
正如@Timothy 指出的那样,mmap
是一个很好的例子:它需要返回一个指针。 mmap
的返回值始终是页面对齐的,因此在具有 4k 页或更大页面(即几乎(?)所有内容)的系统上,-4095
是您可以使用的最大幅度负数,但也不是有效的页面地址。
-4095
= 2^32 - 4095
在 32 位 2 的补码系统中。最高页面起始地址是2^32-4096
。这就是选择恰好这个范围作为表示“错误”的范围的明显动机。
(但请注意,您仍然无法映射虚拟地址空间的最高页面 even for a 32-bit process under a 64-bit kernel,即使 -4096UL
将是 mmap
的非错误返回。内核在内部 对指针使用相同的带内 -errno
代码机制,而不仅仅是系统调用 ABI,因此它保留首页以防止拥有同时也是错误代码的有效指针。这也避免了以下可能性极端情况,例如指向数组的尾数为 0(NULL)的指针。)
意味着错误的值范围在理论上取决于平台并且是系统调用 ABI 的一部分,但 AFAIK Linux 使用 [-4095..-1]
在它支持的每个平台上。 MUSL libc 实现硬编码 -4096UL
在非 x86 或特定于 ARM 的 C 源文件中: /src/internal/syscall_ret.c
.
正如@Tsyvarev 指出的那样,Linux 定义了 MAX_ERRNO
至 4095 in include/linux/err.h
,而不是特定于架构的 header 。 (一条评论指出,如果需要的话,它可以成为特定于体系结构的,并且它是由于内核指针的工作方式而被特别选择的。)
x86-64 System V ABI 也有一个关于 Linux 系统调用的信息性(非规范性)部分,其中 -4095
至 -1
范围被指定。 (Search for -4095
)。 (其他使用 x86-64 System V 的平台可以改变它们的系统调用 ABI,例如 FreeBSD 或 MacOS)
有趣的事实:这意味着 sys_getpriority
无法返回 nice
直接水平。相反 it returns 20-nice
, which maps the -20..19
range of nice values to 40..1
. libc 包装函数必须在通用 retval > -4096UL
之后解码 nice 值检查检测到非错误返回值。
有趣的事实 #2:某些 Linux 平台(例如 MIPS 和 PowerPC)上的系统调用 ABI 返回 -1
在返回值和 errno 代码在一个单独的寄存器中。来源:本评论syscall inline-asm wrapper library . (看起来是一个不错的库;避免了诸如缺少 "memory"
某些系统调用包装器 header 所具有的破坏之类的问题。)
相关:
关于assembly - AOSP 非显而易见的 syscall() 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47551940/
谁能找出这个东西的语法错误? UPDATE `inventory` LEFT JOIN `manufacturers` ON ( `man_id` = `manufacturers`.`id` )
我是一名优秀的程序员,十分优秀!