[patch] Fix MIPS pipe, brk

Joseph S. Myers joseph at codesourcery.com
Tue Jan 3 02:58:57 UTC 2006


The MIPS implementation of the pipe syscall has various problems, fixed by 
this patch:

* The asm isn't marked as modifying res2 ($3), so allowing the compiler to 
move the assignment fd[1] = res2; above the asm (and giving a compilation 
warning that res2 may be used uninitialized).  This rather completely 
breaks pipe() and so causes pthread_create to hang.

* Errors are not detected; the function always returns 0 even when the 
syscall indicates an error.

* The list of clobbers for the asm is incomplete; the proper list to use 
for all syscalls is that used in bits/syscalls.h.  The brk implementation 
has this issue as well, so this patch fixes it for brk as well as pipe.

Index: libc/sysdeps/linux/mips/brk.c
===================================================================
--- libc/sysdeps/linux/mips/brk.c	(revision 13035)
+++ libc/sysdeps/linux/mips/brk.c	(working copy)
@@ -34,7 +34,8 @@
 	 "syscall"		/* Perform the system call.  */
 	 : "=r" (res)
 	 : "0" (__NR_brk), "r" (addr)
-	 : "$4", "$7");
+	 : "$1", "$3", "$4", "$7", "$8", "$9", "$10", "$11",
+	   "$12", "$13", "$14", "$15", "$24", "$25", "memory");
     newbrk = (void *) res;
   }
   __curbrk = newbrk;
Index: libc/sysdeps/linux/mips/pipe.c
===================================================================
--- libc/sysdeps/linux/mips/pipe.c	(revision 13035)
+++ libc/sysdeps/linux/mips/pipe.c	(working copy)
@@ -10,15 +10,21 @@
 {
     register long int res __asm__ ("$2"); // v0
     register long int res2 __asm__ ("$3"); // v1
+    register long int err __asm__ ("$7"); // a3
 
-    asm ("move\t$4,%2\n\t"		// $4 = a0
+    asm ("move\t$4,%4\n\t"		// $4 = a0
 	 "syscall"		/* Perform the system call.  */
-	 : "=r" (res)
+	 : "=r" (res), "=r" (res2), "=r" (err)
 	 : "0" (__NR_pipe), "r" (fd)
-	 : "$4", "$7");
-
-	fd[0] = res;
-	fd[1] = res2;
-	return(0);
+	 : "$1", "$4", "$8", "$9", "$10", "$11",
+	   "$12", "$13", "$14", "$15", "$24", "$25", "memory");
+    if (err) {
+	long e = res;
+	__set_errno (e);
+	return(-1);
+    }
+    fd[0] = res;
+    fd[1] = res2;
+    return(0);
 }
 strong_alias(__pipe,pipe)


-- 
Joseph S. Myers
joseph at codesourcery.com



More information about the uClibc mailing list