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:
Olivier Houchard 2006-10-21 00:46:56 +00:00
parent 010b65f54a
commit 06e28eec94

View File

@ -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;