Move SV_ABI_ERRNO translation into linux-specific code, to simplify
the syscall path and declutter it a bit. No functional changes intended. Reviewed by: kib (earlier version) MFC after: 2 weeks Sponsored by: DARPA Differential Revision: https://reviews.freebsd.org/D26378
This commit is contained in:
parent
160ea95362
commit
c26391f4dd
@ -543,7 +543,7 @@ cpu_set_syscall_retval(struct thread *td, int error)
|
||||
break;
|
||||
|
||||
default:
|
||||
frame->tf_rax = SV_ABI_ERRNO(td->td_proc, error);
|
||||
frame->tf_rax = error;
|
||||
frame->tf_rflags |= PSL_C;
|
||||
break;
|
||||
}
|
||||
|
@ -219,6 +219,11 @@ linux_set_syscall_retval(struct thread *td, int error)
|
||||
|
||||
cpu_set_syscall_retval(td, error);
|
||||
|
||||
if (__predict_false(error != 0)) {
|
||||
if (error != ERESTART && error != EJUSTRETURN)
|
||||
frame->tf_rax = SV_ABI_ERRNO(td->td_proc, error);
|
||||
}
|
||||
|
||||
/* Restore all registers. */
|
||||
set_pcb_flags(td->td_pcb, PCB_FULL_IRET);
|
||||
}
|
||||
|
@ -112,6 +112,7 @@ static void linux32_fixlimit(struct rlimit *rl, int which);
|
||||
static bool linux32_trans_osrel(const Elf_Note *note, int32_t *osrel);
|
||||
static void linux_vdso_install(void *param);
|
||||
static void linux_vdso_deinstall(void *param);
|
||||
static void linux32_set_syscall_retval(struct thread *td, int error);
|
||||
|
||||
#define LINUX_T_UNKNOWN 255
|
||||
static int _bsd_to_linux_trapcode[] = {
|
||||
@ -669,6 +670,19 @@ linux32_fetch_syscall_args(struct thread *td)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
linux32_set_syscall_retval(struct thread *td, int error)
|
||||
{
|
||||
struct trapframe *frame = td->td_frame;
|
||||
|
||||
cpu_set_syscall_retval(td, error);
|
||||
|
||||
if (__predict_false(error != 0)) {
|
||||
if (error != ERESTART && error != EJUSTRETURN)
|
||||
frame->tf_rax = SV_ABI_ERRNO(td->td_proc, error);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear registers on exec
|
||||
* XXX copied from ia32_signal.c.
|
||||
@ -906,7 +920,7 @@ struct sysentvec elf_linux_sysvec = {
|
||||
.sv_fixlimit = linux32_fixlimit,
|
||||
.sv_maxssiz = &linux32_maxssiz,
|
||||
.sv_flags = SV_ABI_LINUX | SV_ILP32 | SV_IA32 | SV_SHP,
|
||||
.sv_set_syscall_retval = cpu_set_syscall_retval,
|
||||
.sv_set_syscall_retval = linux32_set_syscall_retval,
|
||||
.sv_fetch_syscall_args = linux32_fetch_syscall_args,
|
||||
.sv_syscallnames = NULL,
|
||||
.sv_shared_page_base = LINUX32_SHAREDPAGE,
|
||||
|
@ -219,7 +219,7 @@ cpu_set_syscall_retval(struct thread *td, int error)
|
||||
/* nothing to do */
|
||||
break;
|
||||
default:
|
||||
frame->tf_r0 = SV_ABI_ERRNO(td->td_proc, error);
|
||||
frame->tf_r0 = error;
|
||||
frame->tf_spsr |= PSR_C; /* carry bit */
|
||||
break;
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ cpu_set_syscall_retval(struct thread *td, int error)
|
||||
break;
|
||||
default:
|
||||
frame->tf_spsr |= PSR_C; /* carry bit */
|
||||
frame->tf_x[0] = SV_ABI_ERRNO(td->td_proc, error);
|
||||
frame->tf_x[0] = error;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -141,6 +141,13 @@ linux_set_syscall_retval(struct thread *td, int error)
|
||||
|
||||
td->td_retval[1] = td->td_frame->tf_x[1];
|
||||
cpu_set_syscall_retval(td, error);
|
||||
|
||||
if (__predict_false(error != 0)) {
|
||||
if (error != ERESTART && error != EJUSTRETURN) {
|
||||
td->td_frame->tf_x[0] =
|
||||
SV_ABI_ERRNO(td->td_proc, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -407,7 +407,7 @@ cpu_set_syscall_retval(struct thread *td, int error)
|
||||
break;
|
||||
|
||||
default:
|
||||
td->td_frame->tf_eax = SV_ABI_ERRNO(td->td_proc, error);
|
||||
td->td_frame->tf_eax = error;
|
||||
td->td_frame->tf_eflags |= PSL_C;
|
||||
break;
|
||||
}
|
||||
|
@ -792,6 +792,19 @@ linux_fetch_syscall_args(struct thread *td)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
linux_set_syscall_retval(struct thread *td, int error)
|
||||
{
|
||||
struct trapframe *frame = td->td_frame;
|
||||
|
||||
cpu_set_syscall_retval(td, error);
|
||||
|
||||
if (__predict_false(error != 0)) {
|
||||
if (error != ERESTART && error != EJUSTRETURN)
|
||||
frame->tf_eax = SV_ABI_ERRNO(td->td_proc, error);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* exec_setregs may initialize some registers differently than Linux
|
||||
* does, thus potentially confusing Linux binaries. If necessary, we
|
||||
@ -855,7 +868,7 @@ struct sysentvec linux_sysvec = {
|
||||
.sv_fixlimit = NULL,
|
||||
.sv_maxssiz = NULL,
|
||||
.sv_flags = SV_ABI_LINUX | SV_AOUT | SV_IA32 | SV_ILP32,
|
||||
.sv_set_syscall_retval = cpu_set_syscall_retval,
|
||||
.sv_set_syscall_retval = linux_set_syscall_retval,
|
||||
.sv_fetch_syscall_args = linux_fetch_syscall_args,
|
||||
.sv_syscallnames = NULL,
|
||||
.sv_shared_page_base = LINUX_SHAREDPAGE,
|
||||
@ -891,7 +904,7 @@ struct sysentvec elf_linux_sysvec = {
|
||||
.sv_fixlimit = NULL,
|
||||
.sv_maxssiz = NULL,
|
||||
.sv_flags = SV_ABI_LINUX | SV_IA32 | SV_ILP32 | SV_SHP,
|
||||
.sv_set_syscall_retval = cpu_set_syscall_retval,
|
||||
.sv_set_syscall_retval = linux_set_syscall_retval,
|
||||
.sv_fetch_syscall_args = linux_fetch_syscall_args,
|
||||
.sv_syscallnames = NULL,
|
||||
.sv_shared_page_base = LINUX_SHAREDPAGE,
|
||||
|
@ -955,7 +955,7 @@ cpu_set_syscall_retval(struct thread *td, int error)
|
||||
tf->srr0 -= 4;
|
||||
break;
|
||||
default:
|
||||
tf->fixreg[FIRSTARG] = SV_ABI_ERRNO(p, error);
|
||||
tf->fixreg[FIRSTARG] = error;
|
||||
tf->cr |= 0x10000000; /* Set summary overflow */
|
||||
break;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user