From patchwork Fri Aug 18 17:44:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aurelien Jarno X-Patchwork-Id: 22225 Received: (qmail 123290 invoked by alias); 18 Aug 2017 17:45:09 -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 123215 invoked by uid 89); 18 Aug 2017 17:45:04 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-23.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD, UNSUBSCRIBE_BODY autolearn=ham version=3.3.2 spammy= X-HELO: hall.aurel32.net Date: Fri, 18 Aug 2017 19:44:51 +0200 From: Aurelien Jarno To: "Maciej W. Rozycki" Cc: Adhemerval Zanella , Joseph Myers , libc-alpha@sourceware.org Subject: Re: [PATCH] mips/o32: fix internal_syscall5/6/7 Message-ID: <20170818174451.hhdfihr266nvpwqs@aurel32.net> Mail-Followup-To: "Maciej W. Rozycki" , Adhemerval Zanella , Joseph Myers , libc-alpha@sourceware.org References: <39ca6099-2a86-f5f4-30fe-e86bb4cd736b@linaro.org> <20170817212022.nz6wv6d55xlvubez@aurel32.net> <20170818071616.vk4i25nd2fkkk5ij@aurel32.net> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: NeoMutt/20170609 (1.8.3) 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 Aurelien Jarno [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 + . */ + +#include +#include + + .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 - . */ - -#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 - . */ - -#include -#include - -#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 - . */ - -#include -#include - -#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 - . */ - -#include -#include - -#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 - . */ - -#include -#include - -#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 - . */ - -#include -#include - -#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 - . */ - -#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; -} 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 - . */ - -#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; -} 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 - . */ - -#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; -} 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 +# 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", \