OSDN Git Service

Atsushi Nemoto writes:
authorEric Andersen <andersen@codepoet.org>
Tue, 26 Oct 2004 20:48:18 +0000 (20:48 -0000)
committerEric Andersen <andersen@codepoet.org>
Tue, 26 Oct 2004 20:48:18 +0000 (20:48 -0000)
>>>>> On Tue, 19 Oct 2004 13:28:34 -0600, Erik Andersen <andersen@codepoet.org> said:
>> BTW, top of uClibc TODO list is "Fix syscall() on mips".  What is a
>> problem?

andersen> It appears that uClibc's syscall() for mips works ok for
andersen> syscalls with a few arguments.  But as I recall, it does not
andersen> work properly with _syscall5, _syscall6, _syscall7, etc.
andersen> Perhaps there is some mistake in its assumptions about the
andersen> mips/linux ABI regarding which syscall arguments are passed
andersen> via register vs which syscall arguments are passed on the
andersen> stack.

Hmm... I found a old fix in uClibc ML archive.

http://www.uclibc.org/lists/uclibc/2002-September/004459.html

But it seems somewhat broken.  How about this fix instead?  I tested
mmap with syscall() in mips.  mips64 is not tested.

libc/sysdeps/linux/mips/syscall.S

index b270e31..ce2f129 100644 (file)
@@ -33,23 +33,33 @@ syscall:
        move    a0, a1          /* Move the next three args up a register.  */
        move    a1, a2
        move    a2, a3
-       /* Load the remaining possible args (up to 11) from the stack.  */
+       /* Load the remaining possible args (up to 7) from the stack.  */
 #ifdef __mips64
-       ld      t0,4*8(sp)
-       ld      t1,5*8(sp)
-       ld      t2,6*8(sp)
-       ld      t3,7*8(sp)
-       ld      t4,8*8(sp)
-       ld      t5,9*8(sp)
-       ld      t6,10*8(sp)
+       move    a3, a4
+       move    a4, a5
+       move    a5, a6
+       move    a6, a7
+       daddiu  sp,sp,-16
+       sd      v0,0*8(sp)
+       ld      v0,0*8(sp)      /* for system call restarts */
 #else
-       lw      t0,4*4(sp)
-       lw      t1,5*4(sp)
-       lw      t2,6*4(sp)
-       lw      t3,7*4(sp)
-       lw      t4,8*4(sp)
-       lw      t5,9*4(sp)
-       lw      t6,10*4(sp)
+       lw      a3,4*4(sp)
+       lw      t0,5*4(sp)
+       lw      t1,6*4(sp)
+       lw      t2,7*4(sp)
+       addiu   sp,sp,-32
+       sw      t0,4*4(sp)
+       sw      t1,5*4(sp)
+       sw      t2,6*4(sp)
+       sw      v0,7*4(sp)
+       lw      v0,7*4(sp)      /* for system call restarts */
 #endif
        syscall                 /* Do the system call.  */
+#ifdef __mips64
+       daddiu  sp,sp,16
+#else
+       addiu   sp,sp,32
+#endif
        j ra                    /* Return to caller.  */
+.end    syscall
+.size   syscall,.-syscall