git-syscalls5-7-unbound-stack
authorGNU Libc Maintainers <debian-glibc@lists.debian.org>
Fri, 26 Jan 2018 22:35:29 +0000 (22:35 +0000)
committerAurelien Jarno <aurel32@debian.org>
Fri, 26 Jan 2018 22:35:29 +0000 (22:35 +0000)
2017-08-29  Adhemerval Zanella  <adhemerval.zanella@linaro.org>
    Aurelien Jarno  <aurelien@aurel32.net>
    Maciej W. Rozycki  <macro@imgtec.com>

[BZ #21956]
* sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile
[subdir = misc] (sysdep_routines): Remove `mips16-syscall5',
`mips16-syscall6' and `mips16-syscall7'.
(CFLAGS-mips16-syscall5.c, CFLAGS-mips16-syscall6.c)
(CFLAGS-mips16-syscall7.c): Remove.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions (libc):
Remove `__mips16_syscall5', `__mips16_syscall6' and
`__mips16_syscall7'.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c
(__mips16_syscall0): Rename `__mips16_syscall_return' to
`__mips_syscall_return'.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c
(__mips16_syscall1): Likewise.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c
(__mips16_syscall2): Likewise.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c
(__mips16_syscall3): Likewise.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c
(__mips16_syscall4): Likewise.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c:
Remove.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c:
Remove.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c:
Remove.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h
(__mips16_syscall5): Expand to `__mips_syscall5' rather than
`__mips16_syscall5'.  Remove prototype.
(__mips16_syscall6): Expand to `__mips_syscall6' rather than
`__mips16_syscall6'.  Remove prototype.
(__mips16_syscall7): Expand to `__mips_syscall7' rather than
`__mips16_syscall7'.  Remove prototype.
(__nomips16, __mips16_syscall_return): Move to...
* sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
(__nomips16, __mips_syscall_return): ... here.
[__mips16] (INTERNAL_SYSCALL_NCS): Rename
`__mips16_syscall_return' to `__mips_syscall_return'.
[__mips16] (INTERNAL_SYSCALL_MIPS16): Pass `number' to
`internal_syscall##nr'.
[!__mips16] (INTERNAL_SYSCALL): Pass `SYS_ify (name)' to
`internal_syscall##nr'.
(FORCE_FRAME_POINTER): Remove.
(__mips_syscall5): New prototype.
(internal_syscall5): Rewrite to call `__mips_syscall5'.
(__mips_syscall6): New prototype.
(internal_syscall6): Rewrite to call `__mips_syscall6'.
(__mips_syscall7): New prototype.
(internal_syscall7): Rewrite to call `__mips_syscall7'.
* sysdeps/unix/sysv/linux/mips/mips32/mips-syscall5.S: New file.
* sysdeps/unix/sysv/linux/mips/mips32/mips-syscall6.S: New file.
* sysdeps/unix/sysv/linux/mips/mips32/mips-syscall7.S: New file.
* sysdeps/unix/sysv/linux/mips/mips32/Makefile [subdir = misc]
(sysdep_routines): Add libc-do-syscall.
* sysdeps/unix/sysv/linux/mips/mips32/Versions (libc): Add
`__mips_syscall5', `__mips_syscall6' and `__mips_syscall7'.

Gbp-Pq: Topic mips
Gbp-Pq: Name git-syscalls5-7-unbound-stack.diff

17 files changed:
sysdeps/unix/sysv/linux/mips/mips32/Makefile
sysdeps/unix/sysv/linux/mips/mips32/Versions
sysdeps/unix/sysv/linux/mips/mips32/mips-syscall5.S [new file with mode: 0644]
sysdeps/unix/sysv/linux/mips/mips32/mips-syscall6.S [new file with mode: 0644]
sysdeps/unix/sysv/linux/mips/mips32/mips-syscall7.S [new file with mode: 0644]
sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile
sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c [deleted file]
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c [deleted file]
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c [deleted file]
sysdeps/unix/sysv/linux/mips/mips32/sysdep.h

index 33b461500ca78f67cbe01f9651ec3c69b2fa3f52..05c0d6474337be40c01697bbd03794589918d686 100644 (file)
@@ -1,3 +1,6 @@
+ifeq ($(subdir),misc)
+sysdep_routines += mips-syscall5 mips-syscall6 mips-syscall7
+endif
 ifeq ($(subdir),conform)
 # For bugs 17786 and 21278.
 conformtest-xfail-conds += mips-o32-linux
index 9621fb5cae80dc4fc7c8ad244aea5891651938ad..9337f8fe3df832ce4e0431dcf3e9a485d020449a 100644 (file)
@@ -3,4 +3,7 @@ libc {
     getrlimit64;
     setrlimit64;
   }
+  GLIBC_PRIVATE {
+    __mips_syscall5; __mips_syscall6; __mips_syscall7;
+  }
 }
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall5.S b/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall5.S
new file mode 100644 (file)
index 0000000..9f33167
--- /dev/null
@@ -0,0 +1,35 @@
+/* MIPS syscall wrappers.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+       .text
+       .set    nomips16
+
+/* long long __mips_syscall5 (long arg1, long arg2, long arg3, long arg4,
+                             long arg5,
+                             long number)  */
+
+ENTRY(__mips_syscall5)
+       lw      v0, 20(sp)
+       syscall
+       move    v1, a3
+       jr      ra
+END(__mips_syscall5)
+libc_hidden_def (__mips_syscall5)
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall6.S b/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall6.S
new file mode 100644 (file)
index 0000000..0836660
--- /dev/null
@@ -0,0 +1,35 @@
+/* MIPS syscall wrappers.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+       .text
+       .set    nomips16
+
+/* long long __mips_syscall6 (long arg1, long arg2, long arg3, long arg4,
+                             long arg5, long arg6,
+                             long number)  */
+
+ENTRY(__mips_syscall6)
+       lw      v0, 24(sp)
+       syscall
+       move    v1, a3
+       jr      ra
+END(__mips_syscall6)
+libc_hidden_def (__mips_syscall6)
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall7.S b/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall7.S
new file mode 100644 (file)
index 0000000..f7e742c
--- /dev/null
@@ -0,0 +1,35 @@
+/* MIPS syscall wrappers.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+       .text
+       .set    nomips16
+
+/* long long __mips_syscall7 (long arg1, long arg2, long arg3, long arg4,
+                             long arg5, long arg6, long arg7,
+                             long number)  */
+
+ENTRY(__mips_syscall7)
+       lw      v0, 28(sp)
+       syscall
+       move    v1, a3
+       jr      ra
+END(__mips_syscall7)
+libc_hidden_def (__mips_syscall7)
index fa9fcb7e6f2e7009e58abb938942a4f3a12d770f..6869bf4f7c50bc18a7ea771a6bba68934014574a 100644 (file)
@@ -1,13 +1,9 @@
 ifeq ($(subdir),misc)
 sysdep_routines += mips16-syscall0 mips16-syscall1 mips16-syscall2
-sysdep_routines += mips16-syscall3 mips16-syscall4 mips16-syscall5
-sysdep_routines += mips16-syscall6 mips16-syscall7
+sysdep_routines += mips16-syscall3 mips16-syscall4
 CFLAGS-mips16-syscall0.c += -fexceptions
 CFLAGS-mips16-syscall1.c += -fexceptions
 CFLAGS-mips16-syscall2.c += -fexceptions
 CFLAGS-mips16-syscall3.c += -fexceptions
 CFLAGS-mips16-syscall4.c += -fexceptions
-CFLAGS-mips16-syscall5.c += -fexceptions
-CFLAGS-mips16-syscall6.c += -fexceptions
-CFLAGS-mips16-syscall7.c += -fexceptions
 endif
index 73bcfb566c9d370dc031ec91dfb6bcf553afecea..bb21747f4455334363c68aa0e66d7963fdaebe12 100644 (file)
@@ -1,6 +1,6 @@
 libc {
   GLIBC_PRIVATE {
     __mips16_syscall0; __mips16_syscall1; __mips16_syscall2; __mips16_syscall3;
-    __mips16_syscall4; __mips16_syscall5; __mips16_syscall6; __mips16_syscall7;
+    __mips16_syscall4;
   }
 }
index 880e9908e8759fc8b879caf7697e4e3c99848bf1..2ade219c6e79ae6f98ad881d084fd913683e4a5f 100644 (file)
 #ifndef MIPS16_SYSCALL_H
 #define MIPS16_SYSCALL_H 1
 
-#define __nomips16 __attribute__ ((nomips16))
-
-union __mips16_syscall_return
-  {
-    long long val;
-    struct
-      {
-       long v0;
-       long v1;
-      }
-    reg;
-  };
-
 long long __nomips16 __mips16_syscall0 (long number);
 #define __mips16_syscall0(dummy, number)                               \
        __mips16_syscall0 ((long) (number))
@@ -61,29 +48,22 @@ long long __nomips16 __mips16_syscall4 (long a0, long a1, long a2, long a3,
                           (long) (a3),                                 \
                           (long) (number))
 
-long long __nomips16 __mips16_syscall5 (long a0, long a1, long a2, long a3,
-                                       long a4,
-                                       long number);
+/* The remaining ones use regular MIPS wrappers.  */
+
 #define __mips16_syscall5(a0, a1, a2, a3, a4, number)                  \
-       __mips16_syscall5 ((long) (a0), (long) (a1), (long) (a2),       \
-                          (long) (a3), (long) (a4),                    \
-                          (long) (number))
+       __mips_syscall5 ((long) (a0), (long) (a1), (long) (a2),         \
+                        (long) (a3), (long) (a4),                      \
+                        (long) (number))
 
-long long __nomips16 __mips16_syscall6 (long a0, long a1, long a2, long a3,
-                                       long a4, long a5,
-                                       long number);
 #define __mips16_syscall6(a0, a1, a2, a3, a4, a5, number)              \
-       __mips16_syscall6 ((long) (a0), (long) (a1), (long) (a2),       \
-                          (long) (a3), (long) (a4), (long) (a5),       \
-                          (long) (number))
+       __mips_syscall6 ((long) (a0), (long) (a1), (long) (a2),         \
+                        (long) (a3), (long) (a4), (long) (a5),         \
+                        (long) (number))
 
-long long __nomips16 __mips16_syscall7 (long a0, long a1, long a2, long a3,
-                                       long a4, long a5, long a6,
-                                       long number);
 #define __mips16_syscall7(a0, a1, a2, a3, a4, a5, a6, number)          \
-       __mips16_syscall7 ((long) (a0), (long) (a1), (long) (a2),       \
-                          (long) (a3), (long) (a4), (long) (a5),       \
-                          (long) (a6),                                 \
-                          (long) (number))
+       __mips_syscall7 ((long) (a0), (long) (a1), (long) (a2),         \
+                        (long) (a3), (long) (a4), (long) (a5),         \
+                        (long) (a6),                                   \
+                        (long) (number))
 
 #endif
index 490245b34ec1bc448f24de097ff497376280a10a..51d946928227bb6cb9a5b104d8b62d9f3348fa33 100644 (file)
    <http://www.gnu.org/licenses/>.  */
 
 #include <sysdep.h>
-#include <mips16-syscall.h>
 
 #undef __mips16_syscall0
 
 long long __nomips16
 __mips16_syscall0 (long number)
 {
-  union __mips16_syscall_return ret;
+  union __mips_syscall_return ret;
   ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 0);
   return ret.val;
 }
index 3061e8accb76ac4124ba840ddc23cecc4d45b901..13d57a78aa92b9ea46816ccfe431dbb03e2b484d 100644 (file)
@@ -17,7 +17,6 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <sysdep.h>
-#include <mips16-syscall.h>
 
 #undef __mips16_syscall1
 
@@ -25,7 +24,7 @@ long long __nomips16
 __mips16_syscall1 (long a0,
                   long number)
 {
-  union __mips16_syscall_return ret;
+  union __mips_syscall_return ret;
   ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 1,
                                        a0);
   return ret.val;
index 440a4ed285903773fc105e03f84498d460d62737..6e0e8d5bb5bfb04210d7865a231ad454087476da 100644 (file)
@@ -17,7 +17,6 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <sysdep.h>
-#include <mips16-syscall.h>
 
 #undef __mips16_syscall2
 
@@ -25,7 +24,7 @@ long long __nomips16
 __mips16_syscall2 (long a0, long a1,
                   long number)
 {
-  union __mips16_syscall_return ret;
+  union __mips_syscall_return ret;
   ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 2,
                                        a0, a1);
   return ret.val;
index c3f83fc1f69b4d210ebd55cd521a4d086d6ca74e..6bd6b8222bed3dcc2ba22d7bfaad47dd1fa86c4d 100644 (file)
@@ -17,7 +17,6 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <sysdep.h>
-#include <mips16-syscall.h>
 
 #undef __mips16_syscall3
 
@@ -25,7 +24,7 @@ long long __nomips16
 __mips16_syscall3 (long a0, long a1, long a2,
                   long number)
 {
-  union __mips16_syscall_return ret;
+  union __mips_syscall_return ret;
   ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 3,
                                        a0, a1, a2);
   return ret.val;
index 496297d296a7409db8ac74100c010771d0b99c6e..3847e4bc25d660d893f66b70a878b31a09881602 100644 (file)
@@ -17,7 +17,6 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <sysdep.h>
-#include <mips16-syscall.h>
 
 #undef __mips16_syscall4
 
@@ -25,7 +24,7 @@ long long __nomips16
 __mips16_syscall4 (long a0, long a1, long a2, long a3,
                   long number)
 {
-  union __mips16_syscall_return ret;
+  union __mips_syscall_return ret;
   ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 4,
                                        a0, a1, a2, a3);
   return ret.val;
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c
deleted file mode 100644 (file)
index ad265d8..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* MIPS16 syscall wrappers.
-   Copyright (C) 2013-2017 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <mips16-syscall.h>
-
-#undef __mips16_syscall5
-
-long long __nomips16
-__mips16_syscall5 (long a0, long a1, long a2, long a3,
-                  long a4,
-                  long number)
-{
-  union __mips16_syscall_return ret;
-  ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 5,
-                                       a0, a1, a2, a3, a4);
-  return ret.val;
-}
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c
deleted file mode 100644 (file)
index bfbd395..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* MIPS16 syscall wrappers.
-   Copyright (C) 2013-2017 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <mips16-syscall.h>
-
-#undef __mips16_syscall6
-
-long long __nomips16
-__mips16_syscall6 (long a0, long a1, long a2, long a3,
-                  long a4, long a5,
-                  long number)
-{
-  union __mips16_syscall_return ret;
-  ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 6,
-                                       a0, a1, a2, a3, a4, a5);
-  return ret.val;
-}
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c
deleted file mode 100644 (file)
index e126761..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* MIPS16 syscall wrappers.
-   Copyright (C) 2013-2017 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <mips16-syscall.h>
-
-#undef __mips16_syscall7
-
-long long __nomips16
-__mips16_syscall7 (long a0, long a1, long a2, long a3,
-                  long a4, long a5, long a6,
-                  long number)
-{
-  union __mips16_syscall_return ret;
-  ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 7,
-                                       a0, a1, a2, a3, a4, a5, a6);
-  return ret.val;
-}
index e9e3ee7e82f9aee603d410cd8ab2edb785bc0b07..dadfa18de888e7bca41fefd58d58d142b7f23aa8 100644 (file)
 #undef INTERNAL_SYSCALL
 #undef INTERNAL_SYSCALL_NCS
 
+#define __nomips16 __attribute__ ((nomips16))
+
+union __mips_syscall_return
+  {
+    long long val;
+    struct
+      {
+       long v0;
+       long v1;
+      }
+    reg;
+  };
+
 #ifdef __mips16
 /* There's no MIPS16 syscall instruction, so we go through out-of-line
    standard MIPS wrappers.  These do use inline snippets below though,
 
 # define INTERNAL_SYSCALL_NCS(number, err, nr, args...)                        \
 ({                                                                     \
-       union __mips16_syscall_return _sc_ret;                          \
+       union __mips_syscall_return _sc_ret;                            \
        _sc_ret.val = __mips16_syscall##nr (args, number);              \
        err = _sc_ret.reg.v1;                                           \
        _sc_ret.reg.v0;                                                 \
 # define INTERNAL_SYSCALL_MIPS16(number, err, nr, args...)             \
        internal_syscall##nr ("lw\t%0, %2\n\t",                         \
                              "R" (number),                             \
-                             0, err, args)
+                             number, err, args)
 
 #else /* !__mips16 */
 # define INTERNAL_SYSCALL(name, err, nr, args...)                      \
        internal_syscall##nr ("li\t%0, %2\t\t\t# " #name "\n\t",        \
                              "IK" (SYS_ify (name)),                    \
-                             0, err, args)
+                             SYS_ify (name), err, args)
 
 # define INTERNAL_SYSCALL_NCS(number, err, nr, args...)                        \
        internal_syscall##nr (MOVE32 "\t%0, %2\n\t",                    \
        _sys_result;                                                    \
 })
 
-/* 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
-   of GCC 4.7, this is sufficient.  */
-#define FORCE_FRAME_POINTER                                            \
-  void *volatile __fp_force __attribute__ ((unused)) = alloca (4)
+/* Standalone MIPS wrappers used for 5, 6, and 7 argument syscalls,
+   which require stack arguments.  We rely on the compiler arranging
+   wrapper's arguments according to the MIPS o32 function calling
+   convention, which is reused by syscalls, except for the syscall
+   number passed and the error flag returned (taken care of in the
+   wrapper called).  This relieves us from relying on non-guaranteed
+   compiler specifics required for the stack arguments to be pushed,
+   which would be the case if these syscalls were inlined.  */
+
+long long __nomips16 __mips_syscall5 (long arg1, long arg2, long arg3,
+                                     long arg4, long arg5,
+                                     long number);
+libc_hidden_proto (__mips_syscall5, nomips16)
 
 #define internal_syscall5(v0_init, input, number, err,                 \
                          arg1, arg2, arg3, arg4, arg5)                 \
 ({                                                                     \
-       long _sys_result;                                               \
-                                                                       \
-       FORCE_FRAME_POINTER;                                            \
-       {                                                               \
-       register long __s0 asm ("$16") __attribute__ ((unused))         \
-         = (number);                                                   \
-       register long __v0 asm ("$2");                                  \
-       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);                  \
-       __asm__ volatile (                                              \
-       ".set\tnoreorder\n\t"                                           \
-       "subu\t$29, 32\n\t"                                             \
-       "sw\t%6, 16($29)\n\t"                                           \
-       v0_init                                                         \
-       "syscall\n\t"                                                   \
-       "addiu\t$29, 32\n\t"                                            \
-       ".set\treorder"                                                 \
-       : "=r" (__v0), "+r" (__a3)                                      \
-       : input, "r" (__a0), "r" (__a1), "r" (__a2),                    \
-         "r" ((long) (arg5))                                           \
-       : __SYSCALL_CLOBBERS);                                          \
-       err = __a3;                                                     \
-       _sys_result = __v0;                                             \
-       }                                                               \
-       _sys_result;                                                    \
+       union __mips_syscall_return _sc_ret;                            \
+       _sc_ret.val = __mips_syscall5 ((long) (arg1),                   \
+                                      (long) (arg2),                   \
+                                      (long) (arg3),                   \
+                                      (long) (arg4),                   \
+                                      (long) (arg5),                   \
+                                      (long) (number));                \
+       err = _sc_ret.reg.v1;                                           \
+       _sc_ret.reg.v0;                                                 \
 })
 
+long long __nomips16 __mips_syscall6 (long arg1, long arg2, long arg3,
+                                     long arg4, long arg5, long arg6,
+                                     long number);
+libc_hidden_proto (__mips_syscall6, nomips16)
+
 #define internal_syscall6(v0_init, input, number, err,                 \
                          arg1, arg2, arg3, arg4, arg5, arg6)           \
 ({                                                                     \
-       long _sys_result;                                               \
-                                                                       \
-       FORCE_FRAME_POINTER;                                            \
-       {                                                               \
-       register long __s0 asm ("$16") __attribute__ ((unused))         \
-         = (number);                                                   \
-       register long __v0 asm ("$2");                                  \
-       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);                  \
-       __asm__ volatile (                                              \
-       ".set\tnoreorder\n\t"                                           \
-       "subu\t$29, 32\n\t"                                             \
-       "sw\t%6, 16($29)\n\t"                                           \
-       "sw\t%7, 20($29)\n\t"                                           \
-       v0_init                                                         \
-       "syscall\n\t"                                                   \
-       "addiu\t$29, 32\n\t"                                            \
-       ".set\treorder"                                                 \
-       : "=r" (__v0), "+r" (__a3)                                      \
-       : input, "r" (__a0), "r" (__a1), "r" (__a2),                    \
-         "r" ((long) (arg5)), "r" ((long) (arg6))                      \
-       : __SYSCALL_CLOBBERS);                                          \
-       err = __a3;                                                     \
-       _sys_result = __v0;                                             \
-       }                                                               \
-       _sys_result;                                                    \
+       union __mips_syscall_return _sc_ret;                            \
+       _sc_ret.val = __mips_syscall6 ((long) (arg1),                   \
+                                      (long) (arg2),                   \
+                                      (long) (arg3),                   \
+                                      (long) (arg4),                   \
+                                      (long) (arg5),                   \
+                                      (long) (arg6),                   \
+                                      (long) (number));                \
+       err = _sc_ret.reg.v1;                                           \
+       _sc_ret.reg.v0;                                                 \
 })
 
+long long __nomips16 __mips_syscall7 (long arg1, long arg2, long arg3,
+                                     long arg4, long arg5, long arg6,
+                                     long arg7,
+                                     long number);
+libc_hidden_proto (__mips_syscall7, nomips16)
+
 #define internal_syscall7(v0_init, input, number, err,                 \
                          arg1, arg2, arg3, arg4, arg5, arg6, arg7)     \
 ({                                                                     \
-       long _sys_result;                                               \
-                                                                       \
-       FORCE_FRAME_POINTER;                                            \
-       {                                                               \
-       register long __s0 asm ("$16") __attribute__ ((unused))         \
-         = (number);                                                   \
-       register long __v0 asm ("$2");                                  \
-       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);                  \
-       __asm__ volatile (                                              \
-       ".set\tnoreorder\n\t"                                           \
-       "subu\t$29, 32\n\t"                                             \
-       "sw\t%6, 16($29)\n\t"                                           \
-       "sw\t%7, 20($29)\n\t"                                           \
-       "sw\t%8, 24($29)\n\t"                                           \
-       v0_init                                                         \
-       "syscall\n\t"                                                   \
-       "addiu\t$29, 32\n\t"                                            \
-       ".set\treorder"                                                 \
-       : "=r" (__v0), "+r" (__a3)                                      \
-       : input, "r" (__a0), "r" (__a1), "r" (__a2),                    \
-         "r" ((long) (arg5)), "r" ((long) (arg6)), "r" ((long) (arg7)) \
-       : __SYSCALL_CLOBBERS);                                          \
-       err = __a3;                                                     \
-       _sys_result = __v0;                                             \
-       }                                                               \
-       _sys_result;                                                    \
+       union __mips_syscall_return _sc_ret;                            \
+       _sc_ret.val = __mips_syscall7 ((long) (arg1),                   \
+                                      (long) (arg2),                   \
+                                      (long) (arg3),                   \
+                                      (long) (arg4),                   \
+                                      (long) (arg5),                   \
+                                      (long) (arg6),                   \
+                                      (long) (arg7),                   \
+                                      (long) (number));                \
+       err = _sc_ret.reg.v1;                                           \
+       _sc_ret.reg.v0;                                                 \
 })
 
 #define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \