Movatterモバイル変換


[0]ホーム

URL:


This is the mail archive of thelibc-alpha@sourceware.orgmailing list for theglibc project.


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

Re: [PATCH v5] [BZ #21956] MIPS/o32: Fix internal_syscall5/6/7


On 24/08/2017 10:26, Maciej W. Rozycki wrote:> From: Adhemerval Zanella <adhemerval.zanella@linaro.org>> > Fix a commit cc25c8b4c119 ("New pthread rwlock that is more scalable.") > regression and prevent uncontrolled stack space usage from happening > when a 5-, 6- or 7-argument syscall wrapper is placed in a loop.> > The cause of the problem is the use of `alloca' in regular MIPS/Linux > wrappers to force the use of the frame pointer register in any function > using one or more of these wrappers.  Using the frame pointer register > is required so as not to break frame unwinding as the the stack pointer > is lowered within the inline asm used by these wrappers to make room for > the stack arguments, which 5-, 6- and 7-argument syscalls use with the > o32 ABI.> > The regular MIPS/Linux wrappers are macros however, expanded inline, and > stack allocations made with `alloca' are not discarded until the return > of the function they are made in.  Consequently if called in a loop, > then virtual memory is wasted, and if the loop goes through enough > iterations, then ultimately available memory can get exhausted causing > the program to crash.> > Address the issue by replacing the inline code with standalone assembly > functions, which rely on the compiler arranging syscall arguments > according to the o32 function calling convention, which MIPS/Linux > syscalls also use, except for the syscall number passed and the error > flag returned.  This way there is no need to fiddle with the stack > pointer anymore and all that has to be handled in the new standalone > functions is the special handling of the syscall number and the error > flag.> > Redirect 5-, 6- or 7-argument MIPS16/Linux syscall wrappers to these new > functions as well, so as to avoid an unnecessary double call the > existing wrappers would cause with the new arrangement.> > 2017-08-24  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'.Patch LGTM, thanks for following this up.> > ---> On Mon, 21 Aug 2017, Adhemerval Zanella wrote:> >>> 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.> >  Thanks for the hint.  Actually that does not cause code duplication.> >  I actually considered making hidden aliases available for use within > libc.so as a possible future improvement, but didn't realise it would be > as simple to arrange with the symbols defined in standalone assembly > code rather than C.  This results in 61 BAL instructions replacing JALR > ones in my regular MIPS libc.so build.Nice improvement.> >>> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall5.S>>> ===================================================================>>> --- /dev/null1970-01-01 00:00:00.000000000 +0000>>> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall5.S2017-08-20 03:02:13.583854495 +0100>>> @@ -0,0 +1,33 @@>>>> One line comment to describe this file.> >  I pinched the terse comment used across the existing MIPS16 wrappers > (with s/MIPS16/MIPS/ applied); I hope this is good enough as otherwise the > code should be self-explanatory.I think it is good enough.> >>> @@ -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.> >  Good point, let me know if what I came up with is comprehensive enough.> >  This update has passed regular MIPS and MIPS16 o32 regression testing, > with no regressions.  OK to apply?Ok from my side.> >  NB while looking at it I've noticed we do not pass any `-O' optimisation > flag to the GCC driver while building .S files.  That in turn means no GAS > branch optimisation is enabled and consequently branch delay slots are not > scheduled in `reorder' code by the assembler (the MIPS/GCC `asm' spec has > this `%{noasmopt:-O0; O0|fno-delayed-branch:-O1; O*:-O2; :-O1}'), causing > delay slots wasted with a NOP where a preceding instruction could be moved > instead and save some code space.  It can be easily observed by comparing > code in the compiler-generated MIPS16 wrappers vs the new standalone > assembly regular MIPS (and microMIPS) wrappers.> >  Was this a deliberate choice made sometime to have greater control over > code produced or just an accidental oversight?I am not sure if it was deliberate, but my guess it is not really an issuefor most architectures since afaik any '-O' optimization flag along with.S files usually does not turn any extra flags (SUBTARGET_ASM_SPEC seemsto be define only in a handful architectures on gcc).For MIPS I think we can set ASFLAGS to O1 since it should enable therequired optimization, unless there is an specific gas option to enableit (which I couldn't find). Another option would be to filter out CFLAGSand extract the optimization level used for ASFLAGS, but I think for thisspecific issue it should extra non required complexity.Another thing I noticed is another possible optimization for size wouldto use ".set push", ".set noreorder", and ".set pop" instead of currentcode as below.Using GCC 6.2.1 and binutils 2.27 I noted building for mips16 (usinga strip libc.so for both):- base:sectionsize.text966480.eh_frame_hdr8764.eh_frame36628.pdr97568- patched:sectionsize.text966160.eh_frame_hdr8732.eh_frame36492.pdr97440Not that much, but still a gain. Using O1 (as below) shows some moreslight gains:sectionsize.text966096.eh_frame_hdr8732.eh_frame36492.pdr97440---diff --git a/sysdeps/mips/Makefile b/sysdeps/mips/Makefileindex 7c1d779..1130015 100644--- a/sysdeps/mips/Makefile+++ b/sysdeps/mips/Makefile@@ -83,3 +83,9 @@ $(objpfx)tst-mode-switch-2: $(shared-thread-library) endif endif endif++# Enable delay branch optimization+ASFLAGS-.o += -O1+ASFLAGS-.os += -O1+ASFLAGS-.op += -O1+ASFLAGS-.oS += -O2---diff --git a/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips32/sysdep.hindex dadfa18..96867de 100644--- a/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h+++ b/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h@@ -159,10 +159,11 @@ union __mips_syscall_return        register long __v0 asm ("$2");                                  \        register long __a3 asm ("$7");                                  \        __asm__ volatile (                                              \-       ".set\tnoreorder\n\t"                                           \+       ".set push\n\t"                                                 \+       ".set noreorder\n\t"                                            \        v0_init                                                         \        "syscall\n\t"                                                   \-       ".set reorder"                                                  \+       ".set pop"                                                      \        : "=r" (__v0), "=r" (__a3)                                      \        : input                                                         \        : __SYSCALL_CLOBBERS);                                          \@@ -183,10 +184,11 @@ union __mips_syscall_return        register long __a0 asm ("$4") = (long) (arg1);                  \        register long __a3 asm ("$7");                                  \        __asm__ volatile (                                              \-       ".set\tnoreorder\n\t"                                           \+       ".set push\n\t"                                                 \+       ".set noreorder\n\t"                                            \        v0_init                                                         \        "syscall\n\t"                                                   \-       ".set reorder"                                                  \+       ".set pop"                                                      \        : "=r" (__v0), "=r" (__a3)                                      \        : input, "r" (__a0)                                             \        : __SYSCALL_CLOBBERS);                                          \@@ -208,10 +210,11 @@ union __mips_syscall_return        register long __a1 asm ("$5") = (long) (arg2);                  \        register long __a3 asm ("$7");                                  \        __asm__ volatile (                                              \-       ".set\tnoreorder\n\t"                                           \+       ".set push\n\t"                                                 \+       ".set noreorder\n\t"                                            \        v0_init                                                         \        "syscall\n\t"                                                   \-       ".set\treorder"                                                 \+       ".set pop"                                                      \        : "=r" (__v0), "=r" (__a3)                                      \        : input, "r" (__a0), "r" (__a1)                                 \        : __SYSCALL_CLOBBERS);                                          \@@ -235,10 +238,11 @@ union __mips_syscall_return        register long __a2 asm ("$6") = (long) (arg3);                  \        register long __a3 asm ("$7");                                  \        __asm__ volatile (                                              \-       ".set\tnoreorder\n\t"                                           \+       ".set push\n\t"                                                 \+       ".set noreorder\n\t"                                            \        v0_init                                                         \        "syscall\n\t"                                                   \-       ".set\treorder"                                                 \+       ".set pop"                                                      \        : "=r" (__v0), "=r" (__a3)                                      \        : input, "r" (__a0), "r" (__a1), "r" (__a2)                     \        : __SYSCALL_CLOBBERS);                                          \@@ -262,10 +266,11 @@ union __mips_syscall_return        register long __a2 asm ("$6") = (long) (arg3);                  \        register long __a3 asm ("$7") = (long) (arg4);                  \        __asm__ volatile (                                              \-       ".set\tnoreorder\n\t"                                           \+       ".set push\n\t"                                                 \+       ".set noreorder\n\t"                                            \        v0_init                                                         \        "syscall\n\t"                                                   \-       ".set\treorder"                                                 \+       ".set pop"                                                      \        : "=r" (__v0), "+r" (__a3)                                      \        : input, "r" (__a0), "r" (__a1), "r" (__a2)                     \        : __SYSCALL_CLOBBERS);                                          \> >   Maciej> > --->  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          |   35 ++>  sysdeps/unix/sysv/linux/mips/mips32/mips-syscall6.S          |   35 ++>  sysdeps/unix/sysv/linux/mips/mips32/mips-syscall7.S          |   35 ++>  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                 |  163 ++++------->  17 files changed, 201 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/Makefile2017-08-20 21:30:35.093821957 +0100> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/Makefile2017-08-22 20:33:16.504589387 +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/Versions2017-08-20 21:30:35.142707136 +0100> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/Versions2017-08-22 20:33:16.571894966 +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/null1970-01-01 00:00:00.000000000 +0000> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall5.S2017-08-22 20:47:54.745857965 +0100> @@ -0,0 +1,35 @@> +/* MIPS syscall wrappers.> +   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> +.setnomips16> +> +/* long long __mips_syscall5 (long arg1, long arg2, long arg3, long arg4,> +      long arg5,> +      long number)  */> +> +ENTRY(__mips_syscall5)> +lwv0, 20(sp)> +syscall> +movev1, a3> +jrra> +END(__mips_syscall5)> +libc_hidden_def (__mips_syscall5)> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall6.S> ===================================================================> --- /dev/null1970-01-01 00:00:00.000000000 +0000> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall6.S2017-08-22 20:47:47.596264940 +0100> @@ -0,0 +1,35 @@> +/* MIPS syscall wrappers.> +   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> +.setnomips16> +> +/* long long __mips_syscall6 (long arg1, long arg2, long arg3, long arg4,> +      long arg5, long arg6,> +      long number)  */> +> +ENTRY(__mips_syscall6)> +lwv0, 24(sp)> +syscall> +movev1, a3> +jrra> +END(__mips_syscall6)> +libc_hidden_def (__mips_syscall6)> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall7.S> ===================================================================> --- /dev/null1970-01-01 00:00:00.000000000 +0000> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall7.S2017-08-22 20:47:25.781928113 +0100> @@ -0,0 +1,35 @@> +/* MIPS syscall wrappers.> +   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> +.setnomips16> +> +/* long long __mips_syscall7 (long arg1, long arg2, long arg3, long arg4,> +      long arg5, long arg6, long arg7,> +      long number)  */> +> +ENTRY(__mips_syscall7)> +lwv0, 28(sp)> +syscall> +movev1, a3> +jrra> +END(__mips_syscall7)> +libc_hidden_def (__mips_syscall7)> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile> ===================================================================> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile2017-08-20 21:30:35.448096086 +0100> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile2017-08-22 20:33:16.687468562 +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/Versions2017-08-20 21:30:35.487709423 +0100> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions2017-08-22 20:33:16.719930829 +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.h2017-08-20 21:30:35.540283348 +0100> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h2017-08-22 20:33:16.732035716 +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.c2017-08-20 21:30:35.557630985 +0100> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c2017-08-22 20:33:16.741195496 +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.c2017-08-20 21:30:35.658293922 +0100> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c2017-08-22 20:33:16.758455153 +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.c2017-08-20 21:30:35.769000365 +0100> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c2017-08-22 20:33:16.768703866 +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.c2017-08-20 21:30:35.796726756 +0100> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c2017-08-22 20:33:16.779819073 +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.c2017-08-20 21:30:35.819263979 +0100> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c2017-08-22 20:33:16.794914009 +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.c2017-08-20 21:30:35.822296212 +0100> +++ /dev/null1970-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.c2017-08-20 21:30:35.838512882 +0100> +++ /dev/null1970-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.c2017-08-20 21:30:35.846816836 +0100> +++ /dev/null1970-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.h2017-08-20 21:30:35.944796826 +0100> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h2017-08-22 23:13:25.010701782 +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,74 @@>  _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)> +/* Standalone MIPS wrappers used for 5, 6, and 7 argument syscalls,> +   which require stack arguments.  We rely on the compiler arranging> +   wrapper's arguments according to the MIPS o32 function calling> +   convention, which is reused by syscalls, except for the syscall> +   number passed and the error flag returned (taken care of in the> +   wrapper called).  This relieves us from relying on non-guaranteed> +   compiler specifics required for the stack arguments to be pushed,> +   which would be the case if these syscalls were inlined.  */> +> +long long __nomips16 __mips_syscall5 (long arg1, long arg2, long arg3,> +      long arg4, long arg5,> +      long number);> +libc_hidden_proto (__mips_syscall5, nomips16)>  >  #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);> +libc_hidden_proto (__mips_syscall6, nomips16)> +>  #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);> +libc_hidden_proto (__mips_syscall7, nomips16)> +>  #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", \>

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

[8]ページ先頭

©2009-2026 Movatter.jp