common-user: Adjust system call return on FreeBSD
FreeBSD system calls return positive errno. On the 4 hosts for which we have support, error is indicated by the C bit set or clear. Reviewed-by: Warner Losh <imp@bsdimp.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
bbf15aaf7c
commit
5bfd125ec8
@ -60,17 +60,29 @@ safe_syscall_start:
|
|||||||
cbnz w10, 2f
|
cbnz w10, 2f
|
||||||
svc 0x0
|
svc 0x0
|
||||||
safe_syscall_end:
|
safe_syscall_end:
|
||||||
|
|
||||||
/* code path for having successfully executed the syscall */
|
/* code path for having successfully executed the syscall */
|
||||||
|
#if defined(__linux__)
|
||||||
|
/* Linux kernel returns (small) negative errno. */
|
||||||
cmp x0, #-4096
|
cmp x0, #-4096
|
||||||
b.hi 0f
|
b.hi 0f
|
||||||
|
#elif defined(__FreeBSD__)
|
||||||
|
/* FreeBSD kernel returns positive errno and C bit set. */
|
||||||
|
b.cs 1f
|
||||||
|
#else
|
||||||
|
#error "unsupported os"
|
||||||
|
#endif
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
#if defined(__linux__)
|
||||||
/* code path setting errno */
|
/* code path setting errno */
|
||||||
0: neg w0, w0
|
0: neg w0, w0
|
||||||
b safe_syscall_set_errno_tail
|
b safe_syscall_set_errno_tail
|
||||||
|
#endif
|
||||||
|
|
||||||
/* code path when we didn't execute the syscall */
|
/* code path when we didn't execute the syscall */
|
||||||
2: mov w0, #QEMU_ERESTARTSYS
|
2: mov w0, #QEMU_ERESTARTSYS
|
||||||
b safe_syscall_set_errno_tail
|
1: b safe_syscall_set_errno_tail
|
||||||
|
|
||||||
.cfi_endproc
|
.cfi_endproc
|
||||||
.size safe_syscall_base, .-safe_syscall_base
|
.size safe_syscall_base, .-safe_syscall_base
|
||||||
|
@ -74,10 +74,19 @@ safe_syscall_start:
|
|||||||
bne 2f
|
bne 2f
|
||||||
swi 0
|
swi 0
|
||||||
safe_syscall_end:
|
safe_syscall_end:
|
||||||
|
|
||||||
/* code path for having successfully executed the syscall */
|
/* code path for having successfully executed the syscall */
|
||||||
|
#if defined(__linux__)
|
||||||
|
/* Linux kernel returns (small) negative errno. */
|
||||||
cmp r0, #-4096
|
cmp r0, #-4096
|
||||||
neghi r0, r0
|
neghi r0, r0
|
||||||
bhi 1f
|
bhi 1f
|
||||||
|
#elif defined(__FreeBSD__)
|
||||||
|
/* FreeBSD kernel returns positive errno and C bit set. */
|
||||||
|
bcs 1f
|
||||||
|
#else
|
||||||
|
#error "unsupported os"
|
||||||
|
#endif
|
||||||
pop { r4, r5, r6, r7, r8, pc }
|
pop { r4, r5, r6, r7, r8, pc }
|
||||||
|
|
||||||
/* code path when we didn't execute the syscall */
|
/* code path when we didn't execute the syscall */
|
||||||
|
@ -71,9 +71,18 @@ safe_syscall_start:
|
|||||||
mov 8+16(%esp), %eax /* syscall number */
|
mov 8+16(%esp), %eax /* syscall number */
|
||||||
int $0x80
|
int $0x80
|
||||||
safe_syscall_end:
|
safe_syscall_end:
|
||||||
|
|
||||||
/* code path for having successfully executed the syscall */
|
/* code path for having successfully executed the syscall */
|
||||||
|
#if defined(__linux__)
|
||||||
|
/* Linux kernel returns (small) negative errno. */
|
||||||
cmp $-4095, %eax
|
cmp $-4095, %eax
|
||||||
jae 0f
|
jae 0f
|
||||||
|
#elif defined(__FreeBSD__)
|
||||||
|
/* FreeBSD kernel returns positive errno and C bit set. */
|
||||||
|
jc 1f
|
||||||
|
#else
|
||||||
|
#error "unsupported os"
|
||||||
|
#endif
|
||||||
pop %ebx
|
pop %ebx
|
||||||
.cfi_remember_state
|
.cfi_remember_state
|
||||||
.cfi_adjust_cfa_offset -4
|
.cfi_adjust_cfa_offset -4
|
||||||
@ -90,8 +99,10 @@ safe_syscall_end:
|
|||||||
ret
|
ret
|
||||||
.cfi_restore_state
|
.cfi_restore_state
|
||||||
|
|
||||||
|
#if defined(__linux__)
|
||||||
0: neg %eax
|
0: neg %eax
|
||||||
jmp 1f
|
jmp 1f
|
||||||
|
#endif
|
||||||
|
|
||||||
/* code path when we didn't execute the syscall */
|
/* code path when we didn't execute the syscall */
|
||||||
2: mov $QEMU_ERESTARTSYS, %eax
|
2: mov $QEMU_ERESTARTSYS, %eax
|
||||||
|
@ -68,9 +68,18 @@ safe_syscall_start:
|
|||||||
jnz 2f
|
jnz 2f
|
||||||
syscall
|
syscall
|
||||||
safe_syscall_end:
|
safe_syscall_end:
|
||||||
|
|
||||||
/* code path for having successfully executed the syscall */
|
/* code path for having successfully executed the syscall */
|
||||||
|
#if defined(__linux__)
|
||||||
|
/* Linux kernel returns (small) negative errno. */
|
||||||
cmp $-4095, %rax
|
cmp $-4095, %rax
|
||||||
jae 0f
|
jae 0f
|
||||||
|
#elif defined(__FreeBSD__)
|
||||||
|
/* FreeBSD kernel returns positive errno and C bit set. */
|
||||||
|
jc 1f
|
||||||
|
#else
|
||||||
|
#error "unsupported os"
|
||||||
|
#endif
|
||||||
pop %rbp
|
pop %rbp
|
||||||
.cfi_remember_state
|
.cfi_remember_state
|
||||||
.cfi_def_cfa_offset 8
|
.cfi_def_cfa_offset 8
|
||||||
@ -78,8 +87,10 @@ safe_syscall_end:
|
|||||||
ret
|
ret
|
||||||
.cfi_restore_state
|
.cfi_restore_state
|
||||||
|
|
||||||
|
#if defined(__linux__)
|
||||||
0: neg %eax
|
0: neg %eax
|
||||||
jmp 1f
|
jmp 1f
|
||||||
|
#endif
|
||||||
|
|
||||||
/* code path when we didn't execute the syscall */
|
/* code path when we didn't execute the syscall */
|
||||||
2: mov $QEMU_ERESTARTSYS, %eax
|
2: mov $QEMU_ERESTARTSYS, %eax
|
||||||
|
Loading…
Reference in New Issue
Block a user