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 21/08/2017 07:48, Maciej W. Rozycki wrote:
> On Sat, 19 Aug 2017, Aurelien Jarno wrote:
>
>>>> The workaround didn't work.
>>>
>>> Hmm, that means there's something wrong with binutils which needs fixing.
>>> Can you please send me the failing .s file and the command line used to
>>> assemble it (from `gcc -v')?
>>
>> Please find that attached.
>
> Thanks. There's indeed a bug in GAS, a MIPS16 path of execution has been
> missed in the handling of this option. I have a preliminary fix, however
> I yet have to prepare test suite cases (originally the option was
> mistakenly only covered by regular MIPS and microMIPS testing, which is
> clearly why the MIPS16 case has been missed). I expect this fix to be
> included in the upcoming 2.29.1 release, and also backported to 2.28
> (although no new 2.28 release is scheduled).
>
>>> The MIPS16 wrappers were split into individual files so that only ones
>>> that are actually used by `ld.so' are pulled. I think it would be good if
>>> we preserved that. I'll see if I can experiment with keeping the original
>>> MIPS16 0-3 wrappers.
>>
>> For what I have seen, ld.so already uses syscalls with 1 to 4 arguments.
>> It doesn't use any syscall without argument though. So it's only 4
>> instructions overhead.
>
> Why make things worse where they don't have to be and there's no benefit
> elsewhere that would balance the regression?
>
> Here's what I had in mind. The key was updating the macros appropriately
> in sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h. Beyond
> that I made a number of clean-ups:
>
> 1. I renamed `__libc_do_syscall?' to `__mips_syscall?', for consistency
> with `__mips16_syscall?', and consequently `__libc_do_syscall_return'
> to `__mips_syscall_return'.
Ok.
>
> 2. I exported `__mips_syscall?' wrappers from `libc.so' rather than making
> them hidden. This is also consistent with `__mips16_syscall?' wrappers
> and reduces code duplication of doubtful benefit -- it could be that
> some calls, if internal, could be subject to the JALR->BAL
> optimisation, however only those that are in range and only in regular
> MIPS code, for a minimal execution time saving on some processors only.
> Exporting these entries makes the maintenance effort much easier
> though, as we don't have to track and record their use in the
> individual subdirectories in Makefile.
In this case we can still have internal hidden calls for libc with the cost
of code duplication by using hiden alias with:
libc_hidden_proto (__mips_syscall{5,6,7}, nomips16)
And with the pairing
libc_hidden_def (__mips_syscall{5,6,7});
On implementation.
>
> 3. I renamed `_sys_result' to `_sc_ret' where it is declared as `union
> __mips_syscall_return', again for clarity and consistency with MIPS16
> INTERNAL_SYSCALL_NCS.
Ok.
>
> 4. I wrapped `number' in parentheses in `internal_syscall5',
> `internal_syscall6' and `internal_syscall7', and cast it to `long'.
Ok.
>
> 5. I have adjusted some comments.
I think it still worth to add some more explanation (see below).
>
> Please let me know if you have any questions or concerns about this
> update.
>
> This passes o32 regular MIPS regression testing, however my GCC 8 binary
> seems to miscompile support_test_main.c in the MIPS16 mode, causing all
> the relevant test cases to crash with SIGILL (in the `support_set_test_dir
> (test_dir)' invocation it's `test_dir' that is jumped to rather than
> `support_set_test_dir'; I'll file a bug separately). I'll find a way to
> run MIPS16 testing eventually, however meanwhile I will appreciate if you
> do it for me.
>
> Maciej
>
> 2017-08-21 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'.
>
> ---
> sysdeps/unix/sysv/linux/mips/mips32/Makefile | 4
> sysdeps/unix/sysv/linux/mips/mips32/Versions | 3
> sysdeps/unix/sysv/linux/mips/mips32/mips-syscall5.S | 33 ++
> sysdeps/unix/sysv/linux/mips/mips32/mips-syscall6.S | 33 ++
> sysdeps/unix/sysv/linux/mips/mips32/mips-syscall7.S | 33 ++
> sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile | 6
> sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions | 2
> sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h | 44 ---
> sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c | 3
> sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c | 3
> sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c | 3
> sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c | 3
> sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c | 3
> sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c | 33 --
> sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c | 33 --
> sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c | 33 --
> sysdeps/unix/sysv/linux/mips/mips32/sysdep.h | 154 ++++-------
> 17 files changed, 186 insertions(+), 240 deletions(-)
>
> glibc-aurelien-mips-o32-syscall.diff
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/Makefile
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/Makefile 2017-08-20 01:30:23.485088512 +0100
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/Makefile 2017-08-20 01:34:46.716443161 +0100
> @@ -3,6 +3,10 @@ ifeq ($(subdir),conform)
> conformtest-xfail-conds += mips-o32-linux
> endif
>
> +ifeq ($(subdir),misc)
> +sysdep_routines += mips-syscall5 mips-syscall6 mips-syscall7
> +endif
> +
> ifeq ($(subdir),stdlib)
> tests += bug-getcontext-mips-gp
> endif
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/Versions
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/Versions 2017-08-20 01:30:23.617089669 +0100
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/Versions 2017-08-20 01:34:46.740608292 +0100
> @@ -3,4 +3,7 @@ libc {
> getrlimit64;
> setrlimit64;
> }
> + GLIBC_PRIVATE {
> + __mips_syscall5; __mips_syscall6; __mips_syscall7;
> + }
> }
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall5.S
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall5.S 2017-08-20 03:02:13.583854495 +0100
> @@ -0,0 +1,33 @@
One line comment to describe this file.
> +/* 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)
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall6.S
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall6.S 2017-08-20 03:02:17.294755273 +0100
> @@ -0,0 +1,33 @@
Same as before.
> +/* 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)
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall7.S
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall7.S 2017-08-20 03:02:20.617120331 +0100
> @@ -0,0 +1,33 @@
Same as before.
> +/* 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)
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile 2017-08-20 01:30:23.490163141 +0100
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile 2017-08-20 01:34:46.819433661 +0100
> @@ -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: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions 2017-08-20 01:30:23.494195070 +0100
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions 2017-08-20 01:34:46.830600751 +0100
> @@ -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: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h 2017-08-20 01:30:23.505269052 +0100
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h 2017-08-20 01:34:46.845845282 +0100
> @@ -19,19 +19,6 @@
> #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) (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: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c 2017-08-20 01:30:23.564450375 +0100
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c 2017-08-20 01:34:46.849881768 +0100
> @@ -17,14 +17,13 @@
> <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: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c 2017-08-20 01:30:23.568506526 +0100
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c 2017-08-20 01:34:46.860061453 +0100
> @@ -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: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c 2017-08-20 01:30:23.578642154 +0100
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c 2017-08-20 01:34:46.865155941 +0100
> @@ -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: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c 2017-08-20 01:30:23.582725033 +0100
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c 2017-08-20 01:34:46.873273352 +0100
> @@ -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: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c 2017-08-20 01:30:23.591846747 +0100
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c 2017-08-20 01:34:46.894612901 +0100
> @@ -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;
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c 2017-08-20 01:30:23.522504662 +0100
> +++ /dev/null 1970-01-01 00:00:00.000000000 +0000
> @@ -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;
> -}
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c 2017-08-20 01:30:23.536931914 +0100
> +++ /dev/null 1970-01-01 00:00:00.000000000 +0000
> @@ -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;
> -}
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c 2017-08-20 01:30:23.546046859 +0100
> +++ /dev/null 1970-01-01 00:00:00.000000000 +0000
> @@ -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: glibc/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h 2017-08-20 01:30:23.602967356 +0100
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h 2017-08-20 14:15:03.369838111 +0100
> @@ -98,6 +98,19 @@
> #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,
> @@ -112,7 +125,7 @@
>
> # 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; \
> @@ -121,13 +134,13 @@
> # 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", \
> @@ -262,110 +275,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)
> +/* Out-of-line standard MIPS wrappers used for 5, 6, and 7 argument
> + syscalls, which require stack arguments. */
I think it is worth to add a comment why we are using out-of-line wrappers
for syscalls with 5, 6, and 7 arguments.
> +
> +long long __nomips16 __mips_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 __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);
> +
> #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);
> +
> #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", \
>