On 20 January 2014 09:37, Waldemar Brodkorb <[email protected]> wrote: > Hi, > > any news/comment about this? > > thx > Waldemar > > Waldemar Brodkorb wrote, > >> fork() is broken for MIPS64 N64 ABI. You can check it with a simple >> C program statically linked with qemu-mips64 user emulation. >> Internally fork() is using the clone system call (at least with NPTL) >> with 5 arguments. See ./libpthread/nptl/sysdeps/unix/sysv/linux/i386/fork.c. >> The calling conventions for MIPS N32 and N64 allow to use up to 8 registers >> for that. See http://en.wikipedia.org/wiki/Calling_convention#MIPS >> This is correctly implemented in libc/sysdeps/linux/mips/bits/syscalls.h, >> but not in libc/sysdeps/linux/mips/sysdep.h. fork.c uses the later one. >> It seems that fork() works fine for MIPS64 N32 with just using the stack like >> with the O32 case. There is a user of INLINE_SYSCALL with 7 arguments in >> libc/sysdeps/linux/common/sync_file_range.c for MIPS64 N32, so I decided to >> only use the macros for the MIPS64 N64 case. With this patch my uClibc based >> Linux system boots up fine in qemu-system-mips64.
The mips sysdeps looks highly repetitive, it would be nice to massage it to use something like the i386 variant. Maybe you want to do that? I am applying the below for now though, thanks! cheers, >> >> Signed-off-by: Waldemar Brodkorb <[email protected]> >> --- >> libc/sysdeps/linux/mips/sysdep.h | 63 >> ++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 63 insertions(+) >> >> diff --git a/libc/sysdeps/linux/mips/sysdep.h >> b/libc/sysdeps/linux/mips/sysdep.h >> index 6dba1fb..46b6c53 100644 >> --- a/libc/sysdeps/linux/mips/sysdep.h >> +++ b/libc/sysdeps/linux/mips/sysdep.h >> @@ -279,6 +279,8 @@ L(syse1): >> _sys_result; \ >> }) >> >> +#if _MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIN32 >> + >> /* We need to use a frame pointer for the functions in which we >> adjust $sp around the syscall, or debug information and unwind >> information will be $sp relative and thus wrong during the syscall. As >> @@ -382,6 +384,67 @@ L(syse1): >> #define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", >> "$13", \ >> "$14", "$15", "$24", "$25", "memory" >> >> +#else /* N64 */ >> + >> +#undef internal_syscall5 >> +#define internal_syscall5(ncs_init, cs_init, input, err, arg1, arg2, arg3, >> arg4, arg5) \ >> +({ \ >> + long _sys_result; \ >> + \ >> + { \ >> + register long __v0 __asm__("$2") ncs_init; \ >> + register long __a0 __asm__("$4") = (long) arg1; \ >> + register long __a1 __asm__("$5") = (long) arg2; \ >> + register long __a2 __asm__("$6") = (long) arg3; \ >> + register long __a3 __asm__("$7") = (long) arg4; \ >> + register long __a4 __asm__("$8") = (long) arg5; \ >> + __asm__ __volatile__ ( \ >> + ".set\tnoreorder\n\t" \ >> + cs_init \ >> + "syscall\n\t" \ >> + ".set\treorder" \ >> + : "=r" (__v0), "+r" (__a3) \ >> + : input, "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a4) \ >> + : __SYSCALL_CLOBBERS); \ >> + err = __a3; \ >> + _sys_result = __v0; \ >> + } \ >> + _sys_result; \ >> +}) >> + >> +#undef internal_syscall6 >> +#define internal_syscall6(ncs_init, cs_init, input, err, arg1, arg2, arg3, >> arg4, arg5, arg6) \ >> +({ \ >> + long _sys_result; \ >> + \ >> + { \ >> + register long __v0 __asm__("$2") ncs_init; \ >> + register long __a0 __asm__("$4") = (long) arg1; \ >> + register long __a1 __asm__("$5") = (long) arg2; \ >> + register long __a2 __asm__("$6") = (long) arg3; \ >> + register long __a3 __asm__("$7") = (long) arg4; \ >> + register long __a4 __asm__("$8") = (long) arg5; \ >> + register long __a5 __asm__("$9") = (long) arg6; \ >> + __asm__ __volatile__ ( \ >> + ".set\tnoreorder\n\t" \ >> + cs_init \ >> + "syscall\n\t" \ >> + ".set\treorder" \ >> + : "=r" (__v0), "+r" (__a3) \ >> + : input, "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a4), \ >> + "r" (__a5) \ >> + : __SYSCALL_CLOBBERS); \ >> + err = __a3; \ >> + _sys_result = __v0; \ >> + } \ >> + _sys_result; \ >> +}) >> + >> +#define __SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", \ >> + "$14", "$15", "$24", "$25", "hi", "lo", "memory" >> + >> +#endif >> + >> /* Pointer mangling is not yet supported for MIPS. */ >> #define PTR_MANGLE(var) (void) (var) >> #define PTR_DEMANGLE(var) (void) (var) >> -- >> 1.7.10.4 >> >> _______________________________________________ >> uClibc mailing list >> [email protected] >> http://lists.busybox.net/mailman/listinfo/uclibc >> > _______________________________________________ > uClibc mailing list > [email protected] > http://lists.busybox.net/mailman/listinfo/uclibc _______________________________________________ uClibc mailing list [email protected] http://lists.busybox.net/mailman/listinfo/uclibc
