From patchwork Mon Aug 21 10:48:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Maciej W. Rozycki" X-Patchwork-Id: 22253 Received: (qmail 45892 invoked by alias); 21 Aug 2017 10:49:26 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 45776 invoked by uid 89); 21 Aug 2017 10:49:19 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-8.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, RP_MATCHES_RCVD, SPF_PASS, UNSUBSCRIBE_BODY autolearn=ham version=3.3.2 spammy= X-HELO: mailapp01.imgtec.com Date: Mon, 21 Aug 2017 11:48:58 +0100 From: "Maciej W. Rozycki" To: Aurelien Jarno CC: Adhemerval Zanella , Joseph Myers , Subject: Re: [PATCH] mips/o32: fix internal_syscall5/6/7 In-Reply-To: <20170819124445.bwtvapy6w3dghucd@aurel32.net> Message-ID: References: <39ca6099-2a86-f5f4-30fe-e86bb4cd736b@linaro.org> <20170817212022.nz6wv6d55xlvubez@aurel32.net> <20170818071616.vk4i25nd2fkkk5ij@aurel32.net> <20170818174451.hhdfihr266nvpwqs@aurel32.net> <20170819124445.bwtvapy6w3dghucd@aurel32.net> User-Agent: Alpine 2.00 (DEB 1167 2008-08-23) MIME-Version: 1.0 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'. 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. 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. 4. I wrapped `number' in parentheses in `internal_syscall5', `internal_syscall6' and `internal_syscall7', and cast it to `long'. 5. I have adjusted some comments. 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 Aurelien Jarno Maciej W. Rozycki [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 @@ +/* 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 + . */ + +#include +#include + + .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 @@ +/* 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 + . */ + +#include +#include + + .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 @@ +/* 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 + . */ + +#include +#include + + .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 @@ . */ #include -#include #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 @@ . */ #include -#include #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 @@ . */ #include -#include #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 @@ . */ #include -#include #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 @@ . */ #include -#include #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 - . */ - -#include -#include - -#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 - . */ - -#include -#include - -#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 - . */ - -#include -#include - -#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. */ + +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", \