【发布时间】:2017-11-29 11:39:22
【问题描述】:
据我所知,Linux ABI for ARM 声明系统调用返回值是通过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 的否定性的理由是什么?
附:如果我遗漏了什么或只是我的分析不正确 - 任何 cmet 表示赞赏。
【问题讨论】:
-
根据特定的系统调用,其他负值可能不是错误。
标签: assembly linux-kernel arm system-calls libc