[MIPS] syscall() segv on mips1

Atsushi Nemoto anemo at mba.ocn.ne.jp
Wed Oct 22 17:08:44 UTC 2008


On Tue, 21 Oct 2008 23:31:58 +0200, Bernhard Reutner-Fischer <rep.dot.nop at gmail.com> wrote:
> >> uclibc trunk on mips1 platform, a failed syscall() crashes later in
> >> __syscall_error() from incorrect t9 value.
> >>
> >> syscall() has .noreorder, so I guess this explicit 'nop' is needed.
> >
> >I think the set .noreorder should be complemented by set .reorder
> >after the syscall is made. Do we need the instructions in same order
> >for whole function ?
> 
> I would think that we can turn on reordering again after the syscall,
> yes. Can you try that?

Just turning on reordering just after the syscall insn is wrong.  The
SP adjustment insn must be executed on both success/failure path.

Also, I suppose J and JR instruction in error patch should be followed
by NOP.

Well, I think noreorder is not needed at all in this function.  So
here is my proposal fix.  Unfortunately I have not enough time to test
it by myself.  Could anybody try this?


diff -u uClibc-0.9.30-rc2/libc/sysdeps/linux/mips/syscall.S uClibc/libc/sysdeps/linux/mips/syscall.S
--- uClibc-0.9.30-rc2/libc/sysdeps/linux/mips/syscall.S	2007-09-15 16:25:54.000000000 +0900
+++ uClibc/libc/sysdeps/linux/mips/syscall.S	2008-10-23 01:53:28.000000000 +0900
@@ -32,7 +32,6 @@
 #ifdef __PIC__
 	SETUP_GP
 #endif
-	.set noreorder
 	move	v0, a0		/* Load system call number from first arg.  */
 	move	a0, a1		/* Move the next three args up a register.  */
 	move	a1, a2
@@ -59,12 +58,12 @@
 	lw	v0,7*4(sp)	/* for system call restarts */
 #endif
 	syscall			/* Do the system call.  */
-	bnez	a3, 1f
 #ifdef __mips64
 	daddiu	sp,sp,16
 #else
 	addiu	sp,sp,32
 #endif
+	bnez	a3, 1f
      	j ra			/* Return to caller.  */
 1:
 	move	a0,v0		/* Pass return val to C function. */



More information about the uClibc mailing list