Ok I am an idiot. On 32 bits big-endian systems, it is needed to handle the
syscalls using __syscall but only actually returning 32bits, such as mmap(), specially : they set the return value in td->td_retval[0], but the userland functions will expect this in r1, and not in r0 as it is normally done, as it is the LSB. So add a special case for all these syscalls (all except lseek, which truly returns 64bits). Many thanks to Peter Grehan for his patience while explaining me the issue.
This commit is contained in:
parent
010b65f54a
commit
06e28eec94
@ -940,8 +940,23 @@ syscall(struct thread *td, trapframe_t *frame, u_int32_t insn)
|
||||
}
|
||||
switch (error) {
|
||||
case 0:
|
||||
frame->tf_r0 = td->td_retval[0];
|
||||
frame->tf_r1 = td->td_retval[1];
|
||||
#ifdef __ARMEB__
|
||||
if ((insn & 0x000fffff) == SYS___syscall &&
|
||||
(code != SYS_lseek)) {
|
||||
/*
|
||||
* 64-bit return, 32-bit syscall. Fixup byte order
|
||||
*/
|
||||
frame->tf_r0 = 0;
|
||||
frame->tf_r1 = td->td_retval[0];
|
||||
} else {
|
||||
frame->tf_r0 = td->td_retval[0];
|
||||
frame->tf_r1 = td->td_retval[1];
|
||||
}
|
||||
#else
|
||||
frame->tf_r0 = td->td_retval[0];
|
||||
frame->tf_r1 = td->td_retval[1];
|
||||
#endif
|
||||
|
||||
frame->tf_spsr &= ~PSR_C_bit; /* carry bit */
|
||||
break;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user