From a9540a2624182be37c28ec48fd338ab16448400a Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Thu, 6 Feb 2014 20:26:36 +0000 Subject: [PATCH] Fix __syscall on armeb EABI. As it returns a 64-bit value it needs to place 32-bit data in r1, not r0. 64-bit data is already packed correctly. --- sys/arm/arm/vm_machdep.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c index 58cb1945ecf..fdfeca481cf 100644 --- a/sys/arm/arm/vm_machdep.c +++ b/sys/arm/arm/vm_machdep.c @@ -298,15 +298,25 @@ cpu_set_syscall_retval(struct thread *td, int error) struct trapframe *frame; int fixup; #ifdef __ARMEB__ - uint32_t insn; + u_int call; #endif frame = td->td_frame; fixup = 0; #ifdef __ARMEB__ - insn = *(u_int32_t *)(frame->tf_pc - INSN_SIZE); - if ((insn & 0x000fffff) == SYS___syscall) { + /* + * __syscall returns an off_t while most other syscalls return an + * int. As an off_t is 64-bits and an int is 32-bits we need to + * place the returned data into r1. As the lseek and frerebsd6_lseek + * syscalls also return an off_t they do not need this fixup. + */ +#ifdef __ARM_EABI__ + call = frame->tf_r7; +#else + call = *(u_int32_t *)(frame->tf_pc - INSN_SIZE) & 0x000fffff; +#endif + if (call == SYS___syscall) { register_t *ap = &frame->tf_r0; register_t code = ap[_QUAD_LOWWORD]; if (td->td_proc->p_sysent->sv_mask)