This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] mips/o32: fix internal_syscall5/6/7


On 2017-08-18 10:32, Maciej W. Rozycki wrote:
> On Fri, 18 Aug 2017, Aurelien Jarno wrote:
> 
> > >  If it's a regression, then it probably is.  What compiler version?  The 
> > > fix for missing trailing label annotation went in r242424, for GCC 7.  If 
> > > it's in handcoded assembly OTOH, then the offending code has to be fixed.
> > 
> > I am using GCC 6, so if the fix went in GCC 7, that's normal the issue
> > is present.
> 
>  OK then; you can use the workaround I suggested to verify MIPS16 
> compilation then.

The workaround didn't work. That said building with GCC 7 fixes the
issue.

> > >  Perhaps we could have separate `__libc_do_syscall5', `__libc_do_syscall6' 
> > > and `__libc_do_syscall7' stubs even, really minimal, with the only code 
> > > required being to load $v0 from the last argument, i.e.:
> > > 
> > > ENTRY(__libc_do_syscall5)
> > > 	lw	v0, 16(sp)
> > > 	syscall
> > > 	move	v1, a3
> > > 	jr	ra
> > > END(__libc_do_syscall5)
> > > 
> > > (and then $sp offsets of 20 and 24 for the other two)?  I'd withdraw any 
> > > concerns about code complication I might have had so far then. :)
> > 
> > That's an interesting idea. If we use a different stub depending on the
> > number of arguments, we can actually pass the syscall number last, which
> > is probably more readable. Could also be used for mips16 in all cases?
> 
>  MIPS16 wrappers do that already, which is also why there is an individual 
> one for each syscall argument count.

Please find below a new patch implementing that. It started to be
complicated to get the MIPS16 related defines used to build the 
equivalent code through GCC to work, so I decided to also implement
__libc_do_syscall0 to __libc_do_syscall4 in libc-do-syscall.S. I looked
at the original code generated by GCC, it's very similar to what I used,
sometimes just a bit longer (sometimes GCC saves the syscall number to
the stack to reload it just after).

I have compiled and tested it on mips O32 little and big endian and found
no regression. Of course it fixes nptl/tst-rwlock15. I have also compiled
it on mips16 O32 little endian, but I haven't tested it besides running
ld.so and libc.so under QEMU.

Changelog:

2017-08-18  Adhemerval Zanella  <adhemerval.zanella@linaro.org>
	    Aurelien Jarno <aurelien@aurel32.net>

	[BZ #21956]
	* sysdeps/unix/sysv/linux/mips/mips32/Makefile [subdir = crypt]
	(libcrypt-sysdep_routines): Add libc-do-syscall.
	[subdir = elf] (sysdep-dl-routines): Likewise.
	[subdir = io] (sysdep_routines): Likewise.
	[subdir = nptl] (libpthread-sysdep_routines): Likewise.
	[subdir = nptl] (libpthread-shared-only-routines): Likewise.
	[subdir = nscd] (nscd-modules): Likewise.
	[subdir = nss] (libnss_db-sysdep_routines): Likewise.
	[subdir = nss] (libnss_db-shared-only-routines): Likewise.
	[subdir = resolv] (libanl-sysdep_routines): Likewise.
	[subdir = resolv] (libanl-shared-only-routines): Likewise.
	[subdir = rt] (librt-sysdep_routines): Likewise.
	[subdir = rt] (librt-shared-only-routines): Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/libc-do-syscall.S: New file.
	* sysdeps/unix/sysv/linux/mips/mips32/sysdep.h: [!__mips16]
	(INTERNAL_SYSCALL): Make code unconditional.
	[!__mips16] (INTERNAL_SYSCALL_NCS): Likewise.
	[__mips16] (INTERNAL_SYSCALL): Remove.
	[__mips16] (INTERNAL_SYSCALL_NCS): Likewise.
	(__nomips16): Define.
	(__libc_do_syscall_return): Likewise.
	[__mips16] (__libc_do_syscall0): Declare.
	[__mips16] (internal_syscall0): Define.
	[__mips16] (__libc_do_syscall1): Declare.
	[__mips16] (internal_syscall1): Define.
	[__mips16] (__libc_do_syscall2): Declare.
	[__mips16] (internal_syscall2): Define.
	[__mips16] (__libc_do_syscall3): Declare.
	[__mips16] (internal_syscall3): Define.
	[__mips16] (__libc_do_syscall4): Declare.
	[__mips16] (internal_syscall4): Define.
	(internal_syscall0): Guard with !__mips16.
	(internal_syscall1): Guard with !__mips16.
	(internal_syscall2): Guard with !__mips16.
	(internal_syscall3): Guard with !__mips16.
	(internal_syscall4): Guard with !__mips16.
	(FORCE_FRAME_POINTER): Remove.
	(internal_syscall5): Rewrite to call __libc_do_syscall5.
	(internal_syscall6): Rewrite to call __libc_do_syscall6.
	(internal_syscall7): Rewrite to call __libc_do_syscall7.
	* sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile: Remove file.
	* sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h:
	  Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c:
	  Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c:
	  Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c:
	  Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c:
	  Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c:
	  Likewise
	* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c:
	  Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c:
	  Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c:
	  Likewise.


diff --git a/sysdeps/unix/sysv/linux/mips/mips32/Makefile b/sysdeps/unix/sysv/linux/mips/mips32/Makefile
index 33b461500c..d0bb1fc200 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/Makefile
+++ b/sysdeps/unix/sysv/linux/mips/mips32/Makefile
@@ -1,8 +1,44 @@
+ifeq ($(subdir),crypt)
+libcrypt-sysdep_routines += libc-do-syscall
+endif
+
+ifeq ($(subdir),elf)
+sysdep-dl-routines += libc-do-syscall
+endif
+
 ifeq ($(subdir),conform)
 # For bugs 17786 and 21278.
 conformtest-xfail-conds += mips-o32-linux
 endif
 
+ifeq ($(subdir),io)
+sysdep_routines += libc-do-syscall
+endif
+
+ifeq ($(subdir),nptl)
+libpthread-sysdep_routines += libc-do-syscall
+libpthread-shared-only-routines += libc-do-syscall
+endif
+
+ifeq ($(subdir),nscd)
+nscd-modules += libc-do-syscall
+endif
+
+ifeq ($(subdir),nss)
+libnss_db-sysdep_routines += libc-do-syscall
+libnss_db-shared-only-routines += libc-do-syscall
+endif
+
+ifeq ($(subdir),resolv)
+libanl-sysdep_routines += libc-do-syscall
+libanl-shared-only-routines += libc-do-syscall
+endif
+
+ifeq ($(subdir),rt)
+librt-sysdep_routines += libc-do-syscall
+librt-shared-only-routines += libc-do-syscall
+endif
+
 ifeq ($(subdir),stdlib)
 tests += bug-getcontext-mips-gp
 endif
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/libc-do-syscall.S b/sysdeps/unix/sysv/linux/mips/mips32/libc-do-syscall.S
new file mode 100644
index 0000000000..e6777f6967
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/mips32/libc-do-syscall.S
@@ -0,0 +1,105 @@
+/* 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
+
+#ifdef __mips16
+
+/* long long __libc_do_syscall0 (long arg1, long number)  */
+	.hidden __libc_do_syscall0
+ENTRY(__libc_do_syscall0)
+        move    v0, a0
+        syscall
+        move    v1, a3
+        jr      ra
+END(__libc_do_syscall0)
+
+
+/* long long __libc_do_syscall1 (long arg1, long number)  */
+	.hidden __libc_do_syscall1
+ENTRY(__libc_do_syscall1)
+        move    v0, a1
+        syscall
+        move    v1, a3
+        jr      ra
+END(__libc_do_syscall1)
+
+/* long long __libc_do_syscall2 (long arg1, long arg2, long number)  */
+	.hidden __libc_do_syscall2
+ENTRY(__libc_do_syscall2)
+        move    v0, a2
+        syscall
+        move    v1, a3
+        jr      ra
+END(__libc_do_syscall2)
+
+/* long long __libc_do_syscall3 (long arg1, long arg2, long arg3,
+				 long number)  */
+	.hidden __libc_do_syscall3
+ENTRY(__libc_do_syscall3)
+        move    v0, a3
+        syscall
+        move    v1, a3
+        jr      ra
+END(__libc_do_syscall3)
+
+/* long long __libc_do_syscall4 (long arg1, long arg2, long arg3, long arg4,
+				 long number)  */
+	.hidden __libc_do_syscall4
+ENTRY(__libc_do_syscall4)
+        lw      v0, 16(sp)
+        syscall
+        move    v1, a3
+        jr      ra
+END(__libc_do_syscall4)
+
+#endif /* !__mips16 */
+
+/* long long __libc_do_syscall5 (long arg1, long arg2, long arg3, long arg4,
+				 long arg5, long number)  */
+	.hidden __libc_do_syscall5
+ENTRY(__libc_do_syscall5)
+        lw      v0, 20(sp)
+        syscall
+        move    v1, a3
+        jr      ra
+END(__libc_do_syscall5)
+
+/* long long __libc_do_syscall6 (long arg1, long arg2, long arg3, long arg4,
+				 long arg5, long arg6, long number)  */
+	.hidden __libc_do_syscall6
+ENTRY(__libc_do_syscall6)
+        lw      v0, 24(sp)
+        syscall
+        move    v1, a3
+        jr      ra
+END(__libc_do_syscall6)
+
+/* long long __libc_do_syscall7 (long arg1, long arg2, long arg3, long arg4,
+				 long arg5, long arg6, long arg7,
+				 long number)  */
+	.hidden __libc_do_syscall7
+ENTRY(__libc_do_syscall7)
+        lw      v0, 28(sp)
+        syscall
+        move    v1, a3
+        jr      ra
+END(__libc_do_syscall7)
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile b/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile
deleted file mode 100644
index fa9fcb7e6f..0000000000
--- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-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
-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
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions b/sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions
deleted file mode 100644
index 73bcfb566c..0000000000
--- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions
+++ /dev/null
@@ -1,6 +0,0 @@
-libc {
-  GLIBC_PRIVATE {
-    __mips16_syscall0; __mips16_syscall1; __mips16_syscall2; __mips16_syscall3;
-    __mips16_syscall4; __mips16_syscall5; __mips16_syscall6; __mips16_syscall7;
-  }
-}
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h
deleted file mode 100644
index 880e9908e8..0000000000
--- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h
+++ /dev/null
@@ -1,89 +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/>.  */
-
-#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))
-
-long long __nomips16 __mips16_syscall1 (long a0,
-					long number);
-#define __mips16_syscall1(a0, number)					\
-	__mips16_syscall1 ((long) (a0),					\
-			   (long) (number))
-
-long long __nomips16 __mips16_syscall2 (long a0, long a1,
-					long number);
-#define __mips16_syscall2(a0, a1, number)				\
-	__mips16_syscall2 ((long) (a0), (long) (a1),			\
-			   (long) (number))
-
-long long __nomips16 __mips16_syscall3 (long a0, long a1, long a2,
-					long number);
-#define __mips16_syscall3(a0, a1, a2, number)				\
-	__mips16_syscall3 ((long) (a0), (long) (a1), (long) (a2),	\
-			   (long) (number))
-
-long long __nomips16 __mips16_syscall4 (long a0, long a1, long a2, long a3,
-					long number);
-#define __mips16_syscall4(a0, a1, a2, a3, number)			\
-	__mips16_syscall4 ((long) (a0), (long) (a1), (long) (a2),	\
-			   (long) (a3),					\
-			   (long) (number))
-
-long long __nomips16 __mips16_syscall5 (long a0, long a1, long a2, long a3,
-					long a4,
-					long number);
-#define __mips16_syscall5(a0, a1, a2, a3, a4, number)			\
-	__mips16_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))
-
-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))
-
-#endif
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c
deleted file mode 100644
index 490245b34e..0000000000
--- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c
+++ /dev/null
@@ -1,30 +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_syscall0
-
-long long __nomips16
-__mips16_syscall0 (long number)
-{
-  union __mips16_syscall_return ret;
-  ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 0);
-  return ret.val;
-}
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c
deleted file mode 100644
index 3061e8accb..0000000000
--- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c
+++ /dev/null
@@ -1,32 +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_syscall1
-
-long long __nomips16
-__mips16_syscall1 (long a0,
-		   long number)
-{
-  union __mips16_syscall_return ret;
-  ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 1,
-					a0);
-  return ret.val;
-}
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c
deleted file mode 100644
index 440a4ed285..0000000000
--- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c
+++ /dev/null
@@ -1,32 +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_syscall2
-
-long long __nomips16
-__mips16_syscall2 (long a0, long a1,
-		   long number)
-{
-  union __mips16_syscall_return ret;
-  ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 2,
-					a0, a1);
-  return ret.val;
-}
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c
deleted file mode 100644
index c3f83fc1f6..0000000000
--- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c
+++ /dev/null
@@ -1,32 +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_syscall3
-
-long long __nomips16
-__mips16_syscall3 (long a0, long a1, long a2,
-		   long number)
-{
-  union __mips16_syscall_return ret;
-  ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 3,
-					a0, a1, a2);
-  return ret.val;
-}
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c
deleted file mode 100644
index 496297d296..0000000000
--- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c
+++ /dev/null
@@ -1,32 +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_syscall4
-
-long long __nomips16
-__mips16_syscall4 (long a0, long a1, long a2, long a3,
-		   long number)
-{
-  union __mips16_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
index ad265d88e2..0000000000
--- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c
+++ /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
index bfbd395ed3..0000000000
--- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c
+++ /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
index e1267616dc..0000000000
--- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c
+++ /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;
-}
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
index e9e3ee7e82..31d70c0189 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
+++ b/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
@@ -98,45 +98,100 @@
 #undef INTERNAL_SYSCALL
 #undef INTERNAL_SYSCALL_NCS
 
+#define INTERNAL_SYSCALL(name, err, nr, args...)			\
+	internal_syscall##nr ("li\t%0, %2\t\t\t# " #name "\n\t",	\
+			      "IK" (SYS_ify (name)),			\
+			      SYS_ify(name), err, args)
+
+#define INTERNAL_SYSCALL_NCS(number, err, nr, args...)			\
+	internal_syscall##nr (MOVE32 "\t%0, %2\n\t",			\
+			      "r" (__s0),				\
+			      number, err, args)
+
+#define __nomips16 __attribute__ ((nomips16))
+
+union __libc_do_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,
-   through INTERNAL_SYSCALL_MIPS16.  Spilling the syscall number to
-   memory gives the best code in that case, avoiding the need to save
-   and restore a static register.  */
+/* There's no MIPS16 syscall instruction, so we always need to go through
+   out-of-line standard MIPS wrappers.  */
+
+long long __nomips16 __libc_do_syscall0 (long number);
 
-# include <mips16-syscall.h>
+# define internal_syscall0(v0_init, input, number, err, dummy)		\
+({									\
+	union __libc_do_syscall_return _sys_result;			\
+	_sys_result.val = __libc_do_syscall0 (number);			\
+	err = _sys_result.reg.v1;					\
+	_sys_result.reg.v0;						\
+})
 
-# define INTERNAL_SYSCALL(name, err, nr, args...)			\
-	INTERNAL_SYSCALL_NCS (SYS_ify (name), err, nr, args)
+long long __nomips16 __libc_do_syscall1 (long arg1, long number);
 
-# define INTERNAL_SYSCALL_NCS(number, err, nr, args...)			\
+# define internal_syscall1(v0_init, input, number, err, arg1)		\
 ({									\
-	union __mips16_syscall_return _sc_ret;				\
-	_sc_ret.val = __mips16_syscall##nr (args, number);		\
-	err = _sc_ret.reg.v1;						\
-	_sc_ret.reg.v0;							\
+	union __libc_do_syscall_return _sys_result;			\
+	_sys_result.val = __libc_do_syscall1 ((long) (arg1),		\
+					      number);			\
+	err = _sys_result.reg.v1;					\
+	_sys_result.reg.v0;						\
 })
 
-# define INTERNAL_SYSCALL_MIPS16(number, err, nr, args...)		\
-	internal_syscall##nr ("lw\t%0, %2\n\t",				\
-			      "R" (number),				\
-			      0, err, args)
+long long __nomips16 __libc_do_syscall2 (long arg1, long arg2, long number);
 
-#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)
+# define internal_syscall2(v0_init, input, number, err, arg1, arg2)	\
+({									\
+	union __libc_do_syscall_return _sys_result;			\
+	_sys_result.val = __libc_do_syscall2 ((long) (arg1),		\
+					      (long) (arg2),		\
+					      number);			\
+	err = _sys_result.reg.v1;					\
+	_sys_result.reg.v0;						\
+})
 
-# define INTERNAL_SYSCALL_NCS(number, err, nr, args...)			\
-	internal_syscall##nr (MOVE32 "\t%0, %2\n\t",			\
-			      "r" (__s0),				\
-			      number, err, args)
+long long __nomips16 __libc_do_syscall3 (long arg1, long arg2, long arg3,
+					 long number);
 
-#endif /* !__mips16 */
+# define internal_syscall3(v0_init, input, number, err,			\
+			   arg1, arg2, arg3)				\
+({									\
+	union __libc_do_syscall_return _sys_result;			\
+	_sys_result.val = __libc_do_syscall3 ((long) (arg1),		\
+					      (long) (arg2),		\
+					      (long) (arg3),		\
+					      number);			\
+	err = _sys_result.reg.v1;					\
+	_sys_result.reg.v0;						\
+})
+
+long long __nomips16 __libc_do_syscall4 (long arg1, long arg2, long arg3,
+					 long arg4, long number);
 
-#define internal_syscall0(v0_init, input, number, err, dummy...)	\
+# define internal_syscall4(v0_init, input, number, err,			\
+			   arg1, arg2, arg3, arg4)			\
+({									\
+	union __libc_do_syscall_return _sys_result;			\
+	_sys_result.val = __libc_do_syscall4 ((long) (arg1),		\
+					      (long) (arg2),		\
+					      (long) (arg3),		\
+					      (long) (arg4),		\
+					      number);			\
+	err = _sys_result.reg.v1;					\
+	_sys_result.reg.v0;						\
+})
+
+#else /* !__mips16 */
+
+# define internal_syscall0(v0_init, input, number, err, dummy...)	\
 ({									\
 	long _sys_result;						\
 									\
@@ -159,7 +214,7 @@
 	_sys_result;							\
 })
 
-#define internal_syscall1(v0_init, input, number, err, arg1)		\
+# define internal_syscall1(v0_init, input, number, err, arg1)		\
 ({									\
 	long _sys_result;						\
 									\
@@ -183,7 +238,7 @@
 	_sys_result;							\
 })
 
-#define internal_syscall2(v0_init, input, number, err, arg1, arg2)	\
+# define internal_syscall2(v0_init, input, number, err, arg1, arg2)	\
 ({									\
 	long _sys_result;						\
 									\
@@ -208,8 +263,8 @@
 	_sys_result;							\
 })
 
-#define internal_syscall3(v0_init, input, number, err,			\
-			  arg1, arg2, arg3)				\
+# define internal_syscall3(v0_init, input, number, err,			\
+			   arg1, arg2, arg3)				\
 ({									\
 	long _sys_result;						\
 									\
@@ -235,8 +290,8 @@
 	_sys_result;							\
 })
 
-#define internal_syscall4(v0_init, input, number, err,			\
-			  arg1, arg2, arg3, arg4)			\
+# define internal_syscall4(v0_init, input, number, err,			\
+			   arg1, arg2, arg3, arg4)			\
 ({									\
 	long _sys_result;						\
 									\
@@ -262,110 +317,65 @@
 	_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)
+#endif /* !__mips16 */
+
+/* Out-of-line standard MIPS wrappers used for 5, 6, and 7 argument syscall
+   which requires arguments in stack.  */
+
+long long __nomips16 __libc_do_syscall5 (long arg1, long arg2, long arg3,
+					 long arg4, long arg5, long number);
 
 #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 __libc_do_syscall_return _sys_result;			\
+	_sys_result.val = __libc_do_syscall5 ((long) (arg1),		\
+					      (long) (arg2),		\
+					      (long) (arg3),		\
+					      (long) (arg4),		\
+					      (long) (arg5),		\
+					      number);			\
+	err = _sys_result.reg.v1;					\
+	_sys_result.reg.v0;						\
 })
 
+long long __nomips16 __libc_do_syscall6 (long arg1, long arg2, long arg3,
+					 long arg4, long arg5, long arg6,
+					 long number);
+
 #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 __libc_do_syscall_return _sys_result;			\
+	_sys_result.val = __libc_do_syscall6 ((long) (arg1),		\
+					      (long) (arg2),		\
+					      (long) (arg3),		\
+					      (long) (arg4),		\
+					      (long) (arg5),		\
+					      (long) (arg6),		\
+					      number);			\
+	err = _sys_result.reg.v1;					\
+	_sys_result.reg.v0;						\
 })
 
+long long __nomips16 __libc_do_syscall7 (long arg1, long arg2, long arg3,
+					 long arg4, long arg5, long arg6,
+					 long arg7, long number);
+
 #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 __libc_do_syscall_return _sys_result;			\
+	_sys_result.val = __libc_do_syscall7 ((long) (arg1),		\
+					      (long) (arg2),		\
+					      (long) (arg3),		\
+					      (long) (arg4),		\
+					      (long) (arg5),		\
+					      (long) (arg6),		\
+					      (long) (arg7),		\
+					      number);			\
+	err = _sys_result.reg.v1;					\
+	_sys_result.reg.v0;						\
 })
 
 #define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \

-- 
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
aurelien@aurel32.net                 http://www.aurel32.net


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]