This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
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