Message ID | 20200413175117.170042-2-hjl.tools@gmail.com |
---|---|
State | New |
Headers | show |
Series | V2 [PATCH 1/2] Add SYSCALL_ULONG_ARG_[12] to pass long to syscall [BZ #25810] | expand |
* H. J. Lu via Libc-alpha: > diff --git a/sysdeps/unix/make-syscalls.sh b/sysdeps/unix/make-syscalls.sh > index c07626677f..4a28badea6 100644 > --- a/sysdeps/unix/make-syscalls.sh > +++ b/sysdeps/unix/make-syscalls.sh > @@ -30,6 +30,7 @@ > # P: optionally-NULL pointer to typed object (e.g., 3rd argument to sigaction) > # s: non-NULL string (e.g., 1st arg to open) > # S: optionally-NULL string (e.g., 1st arg to acct) > +# U: unsigned long Maybe this? # U: unsigned long int (32-bit types are zero-extended to 64-bit types) > # v: vararg scalar (e.g., optional 3rd arg to open) > # V: byte-per-page vector (3rd arg to mincore) > # W: wait status, optionally-NULL pointer to int (e.g., 2nd arg of wait4) > @@ -184,6 +185,91 @@ while read file srcfile caller syscall args strong weak; do > ?:?????????) nargs=9;; > esac > > + # Derive the unsigned long arguments from the argument signature “unsigned long int” > + ulong_arg_1=0 > + ulong_arg_2=0 > + case $args in > + ?:U*) > + ulong_arg_1=1 > + case $args in > + ?:UU*) ulong_arg_2=2;; > + ?:U?U*) ulong_arg_2=3;; > + ?:U??U*) ulong_arg_2=4;; > + ?:U???U*) ulong_arg_2=5;; > + ?:U????U*) ulong_arg_2=6;; > + ?:U?????U*) ulong_arg_2=7;; > + ?:U??????U*) ulong_arg_2=8;; > + ?:U???????U) ulong_arg_2=9;; > + esac > + ;; > + ?:????????U) > + ulong_arg_1=9 > + ;; > + esac > + I must say that I find this really, really ugly. We should rewrite this in Python as soon as possible (in a separate patch). You could try this instead: $ echo U1U | grep -ob U 0:U 2:U And maybe guard it with a case match, so that performance does not suffer too much. In any case, there should be an error check that covers the more than-two-Us case. > # Make sure only the first syscall rule is used, if multiple dirs > # define the same syscall. > echo '' > @@ -245,6 +331,8 @@ while read file srcfile caller syscall args strong weak; do > \$(make-target-directory) > (echo '#define SYSCALL_NAME $syscall'; \\ > echo '#define SYSCALL_NARGS $nargs'; \\ > + echo '#define SYSCALL_ULONG_ARG_1 $ulong_arg_1'; \\ > + echo '#define SYSCALL_ULONG_ARG_2 $ulong_arg_2'; \\ Should this be conditional on whether $ulong_arg_1 and $ulong_arg_2 are empty? I think that might be less confusing. Otherwise, the comment at the beginning should mention the special value zero. > echo '#define SYSCALL_SYMBOL $strong'; \\ > echo '#define SYSCALL_NOERRNO $noerrno'; \\ > echo '#define SYSCALL_ERRVAL $errval'; \\ > diff --git a/sysdeps/unix/syscall-template.S b/sysdeps/unix/syscall-template.S > index cf6c7a58fb..0824a3c61e 100644 > --- a/sysdeps/unix/syscall-template.S > +++ b/sysdeps/unix/syscall-template.S > @@ -25,6 +25,10 @@ > defining a few macros: > SYSCALL_NAME syscall name > SYSCALL_NARGS number of arguments this call takes > + SYSCALL_ULONG_ARG_1 the first unsigned long argument this > + call takes > + SYSCALL_ULONG_ARG_2 the second unsigned long argument this > + call takes “unsigned long int” > SYSCALL_SYMBOL primary symbol name > SYSCALL_NOERRNO 1 to define a no-errno version (see below) > SYSCALL_ERRVAL 1 to define an error-value version (see below) > @@ -44,9 +48,27 @@ > /* This indirection is needed so that SYMBOL gets macro-expanded. */ > #define syscall_hidden_def(SYMBOL) hidden_def (SYMBOL) > > -#define T_PSEUDO(SYMBOL, NAME, N) PSEUDO (SYMBOL, NAME, N) > -#define T_PSEUDO_NOERRNO(SYMBOL, NAME, N) PSEUDO_NOERRNO (SYMBOL, NAME, N) > -#define T_PSEUDO_ERRVAL(SYMBOL, NAME, N) PSEUDO_ERRVAL (SYMBOL, NAME, N) > +/* If PSEUDOS_HAVE_4_ARGS is defined, PSEUDO macros have 4 arguments. */ > +#ifndef PSEUDOS_HAVE_4_ARGS > +# undef SYSCALL_ULONG_ARG_1 > +# define SYSCALL_ULONG_ARG_1 0 > +#endif PSEUDOS_HAVE_4_ARGS should be PSEUDOS_HAVE_ULONG_INDICES or something like that. And a comment that briefly explains all the macro arguments. (Not sure if T_PSEUDO is documented somewhere else already.) > diff --git a/sysdeps/unix/syscalls.list b/sysdeps/unix/syscalls.list > index 01c4a0e6b1..e63a8b9d23 100644 > --- a/sysdeps/unix/syscalls.list > +++ b/sysdeps/unix/syscalls.list > @@ -37,11 +37,11 @@ kill - kill i:ii __kill kill > link - link i:ss __link link > listen - listen i:ii __listen listen > lseek - lseek i:iii __libc_lseek __lseek lseek > -madvise - madvise i:pii __madvise madvise > +madvise - madvise i:pUi __madvise madvise > mkdir - mkdir i:si __mkdir mkdir > mmap - mmap b:aniiii __mmap mmap > -mprotect - mprotect i:aii __mprotect mprotect > -munmap - munmap i:ai __munmap munmap > +mprotect - mprotect i:aUi __mprotect mprotect > +munmap - munmap i:aU __munmap munmap > open - open Ci:siv __libc_open __open open > profil - profil i:piii __profil profil > ptrace - ptrace i:iiii ptrace What about read, readlink, write, etc.? > diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h > index a37d520f86..b8a74ad2c2 100644 > --- a/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h > +++ b/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h > @@ -26,7 +26,25 @@ > #undef LO_HI_LONG > #define LO_HI_LONG(val) (val) > > -#ifndef __ASSEMBLER__ > +#ifdef __ASSEMBLER__ > +# undef ZERO_EXTEND_1 > +# define ZERO_EXTEND_1 movl %edi, %edi; > +# undef ZERO_EXTEND_2 > +# define ZERO_EXTEND_2 movl %esi, %esi; > +# undef ZERO_EXTEND_3 > +# define ZERO_EXTEND_3 movl %edx, %edx; > +# if SYSCALL_ULONG_ARG_1 == 4 || SYSCALL_ULONG_ARG_2 == 4 > +# undef DOARGS_4 > +# define DOARGS_4 movl %ecx, %r10d; > +# else > +# undef ZERO_EXTEND_4 > +# define ZERO_EXTEND_4 movl %r10d, %r10d; > +# endif > +# undef ZERO_EXTEND_5 > +# define ZERO_EXTEND_5 movl %r8d, %r8d; > +# undef ZERO_EXTEND_6 > +# define ZERO_EXTEND_6 movl %r9d, %r9d; > +#else /* !__ASSEMBLER__ */ > # undef ARGIFY > /* Enforce zero-extension for pointers and array system call arguments. > For integer types, extend to int64_t (the full register) using a The comment should come before the newly added changes, I think.
On 22/04/2020 07:42, Florian Weimer wrote: > * H. J. Lu via Libc-alpha: > >> diff --git a/sysdeps/unix/make-syscalls.sh b/sysdeps/unix/make-syscalls.sh >> index c07626677f..4a28badea6 100644 >> --- a/sysdeps/unix/make-syscalls.sh >> +++ b/sysdeps/unix/make-syscalls.sh >> @@ -30,6 +30,7 @@ >> # P: optionally-NULL pointer to typed object (e.g., 3rd argument to sigaction) >> # s: non-NULL string (e.g., 1st arg to open) >> # S: optionally-NULL string (e.g., 1st arg to acct) >> +# U: unsigned long > > Maybe this? > > # U: unsigned long int (32-bit types are zero-extended to 64-bit types) > >> # v: vararg scalar (e.g., optional 3rd arg to open) >> # V: byte-per-page vector (3rd arg to mincore) >> # W: wait status, optionally-NULL pointer to int (e.g., 2nd arg of wait4) >> @@ -184,6 +185,91 @@ while read file srcfile caller syscall args strong weak; do >> ?:?????????) nargs=9;; >> esac >> >> + # Derive the unsigned long arguments from the argument signature > > “unsigned long int” > >> + ulong_arg_1=0 >> + ulong_arg_2=0 >> + case $args in >> + ?:U*) >> + ulong_arg_1=1 >> + case $args in >> + ?:UU*) ulong_arg_2=2;; >> + ?:U?U*) ulong_arg_2=3;; >> + ?:U??U*) ulong_arg_2=4;; >> + ?:U???U*) ulong_arg_2=5;; >> + ?:U????U*) ulong_arg_2=6;; >> + ?:U?????U*) ulong_arg_2=7;; >> + ?:U??????U*) ulong_arg_2=8;; >> + ?:U???????U) ulong_arg_2=9;; >> + esac >> + ;; > >> + ?:????????U) >> + ulong_arg_1=9 >> + ;; >> + esac >> + > > I must say that I find this really, really ugly. We should rewrite > this in Python as soon as possible (in a separate patch). And I think we should make long term gold to just get rid of this assembly macro and focus on automatic generation to a C code file as well. > > You could try this instead: > > $ echo U1U | grep -ob U > 0:U > 2:U > > And maybe guard it with a case match, so that performance does not > suffer too much. > > In any case, there should be an error check that covers the more > than-two-Us case. > > >> # Make sure only the first syscall rule is used, if multiple dirs >> # define the same syscall. >> echo '' >> @@ -245,6 +331,8 @@ while read file srcfile caller syscall args strong weak; do >> \$(make-target-directory) >> (echo '#define SYSCALL_NAME $syscall'; \\ >> echo '#define SYSCALL_NARGS $nargs'; \\ >> + echo '#define SYSCALL_ULONG_ARG_1 $ulong_arg_1'; \\ >> + echo '#define SYSCALL_ULONG_ARG_2 $ulong_arg_2'; \\ > > Should this be conditional on whether $ulong_arg_1 and $ulong_arg_2 > are empty? I think that might be less confusing. > > Otherwise, the comment at the beginning should mention the special > value zero. > >> echo '#define SYSCALL_SYMBOL $strong'; \\ >> echo '#define SYSCALL_NOERRNO $noerrno'; \\ >> echo '#define SYSCALL_ERRVAL $errval'; \\ >> diff --git a/sysdeps/unix/syscall-template.S b/sysdeps/unix/syscall-template.S >> index cf6c7a58fb..0824a3c61e 100644 >> --- a/sysdeps/unix/syscall-template.S >> +++ b/sysdeps/unix/syscall-template.S >> @@ -25,6 +25,10 @@ >> defining a few macros: >> SYSCALL_NAME syscall name >> SYSCALL_NARGS number of arguments this call takes >> + SYSCALL_ULONG_ARG_1 the first unsigned long argument this >> + call takes >> + SYSCALL_ULONG_ARG_2 the second unsigned long argument this >> + call takes > > “unsigned long int” > >> SYSCALL_SYMBOL primary symbol name >> SYSCALL_NOERRNO 1 to define a no-errno version (see below) >> SYSCALL_ERRVAL 1 to define an error-value version (see below) >> @@ -44,9 +48,27 @@ >> /* This indirection is needed so that SYMBOL gets macro-expanded. */ >> #define syscall_hidden_def(SYMBOL) hidden_def (SYMBOL) >> >> -#define T_PSEUDO(SYMBOL, NAME, N) PSEUDO (SYMBOL, NAME, N) >> -#define T_PSEUDO_NOERRNO(SYMBOL, NAME, N) PSEUDO_NOERRNO (SYMBOL, NAME, N) >> -#define T_PSEUDO_ERRVAL(SYMBOL, NAME, N) PSEUDO_ERRVAL (SYMBOL, NAME, N) >> +/* If PSEUDOS_HAVE_4_ARGS is defined, PSEUDO macros have 4 arguments. */ >> +#ifndef PSEUDOS_HAVE_4_ARGS >> +# undef SYSCALL_ULONG_ARG_1 >> +# define SYSCALL_ULONG_ARG_1 0 >> +#endif > > PSEUDOS_HAVE_4_ARGS should be PSEUDOS_HAVE_ULONG_INDICES or something > like that. And a comment that briefly explains all the macro > arguments. (Not sure if T_PSEUDO is documented somewhere else > already.) > >> diff --git a/sysdeps/unix/syscalls.list b/sysdeps/unix/syscalls.list >> index 01c4a0e6b1..e63a8b9d23 100644 >> --- a/sysdeps/unix/syscalls.list >> +++ b/sysdeps/unix/syscalls.list >> @@ -37,11 +37,11 @@ kill - kill i:ii __kill kill >> link - link i:ss __link link >> listen - listen i:ii __listen listen >> lseek - lseek i:iii __libc_lseek __lseek lseek >> -madvise - madvise i:pii __madvise madvise >> +madvise - madvise i:pUi __madvise madvise >> mkdir - mkdir i:si __mkdir mkdir >> mmap - mmap b:aniiii __mmap mmap >> -mprotect - mprotect i:aii __mprotect mprotect >> -munmap - munmap i:ai __munmap munmap >> +mprotect - mprotect i:aUi __mprotect mprotect >> +munmap - munmap i:aU __munmap munmap >> open - open Ci:siv __libc_open __open open >> profil - profil i:piii __profil profil >> ptrace - ptrace i:iiii ptrace > > What about read, readlink, write, etc.? > >> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h >> index a37d520f86..b8a74ad2c2 100644 >> --- a/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h >> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h >> @@ -26,7 +26,25 @@ >> #undef LO_HI_LONG >> #define LO_HI_LONG(val) (val) >> >> -#ifndef __ASSEMBLER__ >> +#ifdef __ASSEMBLER__ >> +# undef ZERO_EXTEND_1 >> +# define ZERO_EXTEND_1 movl %edi, %edi; >> +# undef ZERO_EXTEND_2 >> +# define ZERO_EXTEND_2 movl %esi, %esi; >> +# undef ZERO_EXTEND_3 >> +# define ZERO_EXTEND_3 movl %edx, %edx; >> +# if SYSCALL_ULONG_ARG_1 == 4 || SYSCALL_ULONG_ARG_2 == 4 >> +# undef DOARGS_4 >> +# define DOARGS_4 movl %ecx, %r10d; >> +# else >> +# undef ZERO_EXTEND_4 >> +# define ZERO_EXTEND_4 movl %r10d, %r10d; >> +# endif >> +# undef ZERO_EXTEND_5 >> +# define ZERO_EXTEND_5 movl %r8d, %r8d; >> +# undef ZERO_EXTEND_6 >> +# define ZERO_EXTEND_6 movl %r9d, %r9d; >> +#else /* !__ASSEMBLER__ */ >> # undef ARGIFY >> /* Enforce zero-extension for pointers and array system call arguments. >> For integer types, extend to int64_t (the full register) using a > > The comment should come before the newly added changes, I think. >
On Wed, 22 Apr 2020, Adhemerval Zanella via Libc-alpha wrote: > > I must say that I find this really, really ugly. We should rewrite > > this in Python as soon as possible (in a separate patch). > > And I think we should make long term gold to just get rid of this > assembly macro and focus on automatic generation to a C code file > as well. There are a couple of possible improvements in this area that might be in tension here: * Simplifying how the syscall arguments are specified. The reason there are so many different letters is not because of anything relevant to assembly code generation now, it's because of the old support for bounded pointers (removed from GCC in 2002, actual substantive uses in the glibc syscall generation code removed in <https://sourceware.org/legacy-ml/libc-alpha/2013-01/msg00919.html>). * Generating debug info for the automatically generated syscall implementations. For that, the C code should have actual meaningful argument types, not just a sequence of integers that has the right ABI (but may not even have the right number of arguments, in cases where a 64-bit argument uses two letters for syscall arguments in the 32-bit syscalls.list files). What this suggests to me is that automatically-generated C code should get actual argument types from the header files in some way, and in the cases where header file information isn't sufficient (including syscalls not declared in header files or with different arguments to the public C function, etc.), using some sort of internal header to give the types might be better than having complicated encodings in syscalls.list. Maybe syscalls.list doesn't need much more information than the conventions for return value / error handling and the *number* of arguments, if types can be extracted from C headers.
On 22/04/2020 19:01, Joseph Myers wrote: > On Wed, 22 Apr 2020, Adhemerval Zanella via Libc-alpha wrote: > >>> I must say that I find this really, really ugly. We should rewrite >>> this in Python as soon as possible (in a separate patch). >> >> And I think we should make long term gold to just get rid of this >> assembly macro and focus on automatic generation to a C code file >> as well. > > There are a couple of possible improvements in this area that might be in > tension here: > > * Simplifying how the syscall arguments are specified. The reason there > are so many different letters is not because of anything relevant to > assembly code generation now, it's because of the old support for bounded > pointers (removed from GCC in 2002, actual substantive uses in the glibc > syscall generation code removed in > <https://sourceware.org/legacy-ml/libc-alpha/2013-01/msg00919.html>). > > * Generating debug info for the automatically generated syscall > implementations. For that, the C code should have actual meaningful > argument types, not just a sequence of integers that has the right ABI > (but may not even have the right number of arguments, in cases where a > 64-bit argument uses two letters for syscall arguments in the 32-bit > syscalls.list files). > > What this suggests to me is that automatically-generated C code should get > actual argument types from the header files in some way, and in the cases > where header file information isn't sufficient (including syscalls not > declared in header files or with different arguments to the public C > function, etc.), using some sort of internal header to give the types > might be better than having complicated encodings in syscalls.list. Maybe > syscalls.list doesn't need much more information than the conventions for > return value / error handling and the *number* of arguments, if types can > be extracted from C headers. My initial approach would be to extend the syscall argument definition on syscall file description (syscalls.list) with all the required information to synthesize the C implementation. It increases the verbose required in the argument description, but I think it would simpler than try infer from the header itself (which would require to parse the it and the this information). Something like, using wordsize-64 fstatfs syscalls.list entry: fstatfs fstatfs [sys/statfs.h] [const char *, struct statfs64 *] [fstatfs64:w, __fstatfs64:w] which would translate to: #define fstatfs64 __redirect_fstatfs64 #define __fstatfs64 __redirect___fstatfs64 #include <sys/statfs.h> #undef fstatfs64 #undef __fstatfs64 int __fstatfs (int arg1, struct statfs *arg2) { return INLINE_SYSCALL_CALL (fstatfs, arg1, arg2); } weak_alias (__fstatfs, fstatfs) weak_alias (__fstatfs, __fstatfs64) weak_alias (__fstatfs, fstatfs64) The alias would require some pre-defined logic to handle the LFS alias for __OFF_T_MATCHES_OFF64_T (and I am not sure if this example would be better handled in a C implementation in fact), to handle internal hidden alias, and version.
diff --git a/sysdeps/unix/make-syscalls.sh b/sysdeps/unix/make-syscalls.sh index c07626677f..4a28badea6 100644 --- a/sysdeps/unix/make-syscalls.sh +++ b/sysdeps/unix/make-syscalls.sh @@ -30,6 +30,7 @@ # P: optionally-NULL pointer to typed object (e.g., 3rd argument to sigaction) # s: non-NULL string (e.g., 1st arg to open) # S: optionally-NULL string (e.g., 1st arg to acct) +# U: unsigned long # v: vararg scalar (e.g., optional 3rd arg to open) # V: byte-per-page vector (3rd arg to mincore) # W: wait status, optionally-NULL pointer to int (e.g., 2nd arg of wait4) @@ -184,6 +185,91 @@ while read file srcfile caller syscall args strong weak; do ?:?????????) nargs=9;; esac + # Derive the unsigned long arguments from the argument signature + ulong_arg_1=0 + ulong_arg_2=0 + case $args in + ?:U*) + ulong_arg_1=1 + case $args in + ?:UU*) ulong_arg_2=2;; + ?:U?U*) ulong_arg_2=3;; + ?:U??U*) ulong_arg_2=4;; + ?:U???U*) ulong_arg_2=5;; + ?:U????U*) ulong_arg_2=6;; + ?:U?????U*) ulong_arg_2=7;; + ?:U??????U*) ulong_arg_2=8;; + ?:U???????U) ulong_arg_2=9;; + esac + ;; + ?:?U*) + ulong_arg_1=2 + case $args in + ?:?UU*) ulong_arg_2=3;; + ?:?U?U*) ulong_arg_2=4;; + ?:?U??U*) ulong_arg_2=5;; + ?:?U???U*) ulong_arg_2=6;; + ?:?U????U*) ulong_arg_2=7;; + ?:?U?????U*) ulong_arg_2=8;; + ?:?U??????U) ulong_arg_2=9;; + esac + ;; + ?:??U*) + ulong_arg_1=3 + case $args in + ?:??UU*) ulong_arg_2=4;; + ?:??U?U*) ulong_arg_2=5;; + ?:??U??U*) ulong_arg_2=6;; + ?:??U???U*) ulong_arg_2=7;; + ?:??U????U*) ulong_arg_2=8;; + ?:??U?????U) ulong_arg_2=9;; + esac + ;; + ?:???U*) + ulong_arg_1=4 + case $args in + ?:???UU*) ulong_arg_2=5;; + ?:???U?U*) ulong_arg_2=6;; + ?:???U??U*) ulong_arg_2=7;; + ?:???U???U*) ulong_arg_2=8;; + ?:???U????U) ulong_arg_2=9;; + esac + ;; + ?:????U*) + ulong_arg_1=5 + case $args in + ?:????UU*) ulong_arg_2=6;; + ?:????U?U*) ulong_arg_2=7;; + ?:????U??U*) ulong_arg_2=8;; + ?:????U???U) ulong_arg_2=9;; + esac + ;; + ?:?????U*) + ulong_arg_1=6 + case $args in + ?:?????UU*) ulong_arg_2=7;; + ?:?????U?U*) ulong_arg_2=8;; + ?:?????U??U) ulong_arg_2=9;; + esac + ;; + ?:??????U*) + ulong_arg_1=7 + case $args in + ?:??????UU*) ulong_arg_2=8;; + ?:??????U?U) ulong_arg_2=9;; + esac + ;; + ?:???????U*) + ulong_arg_1=8 + case $args in + ?:??????UU) ulong_arg_2=9;; + esac + ;; + ?:????????U) + ulong_arg_1=9 + ;; + esac + # Make sure only the first syscall rule is used, if multiple dirs # define the same syscall. echo '' @@ -245,6 +331,8 @@ while read file srcfile caller syscall args strong weak; do \$(make-target-directory) (echo '#define SYSCALL_NAME $syscall'; \\ echo '#define SYSCALL_NARGS $nargs'; \\ + echo '#define SYSCALL_ULONG_ARG_1 $ulong_arg_1'; \\ + echo '#define SYSCALL_ULONG_ARG_2 $ulong_arg_2'; \\ echo '#define SYSCALL_SYMBOL $strong'; \\ echo '#define SYSCALL_NOERRNO $noerrno'; \\ echo '#define SYSCALL_ERRVAL $errval'; \\ diff --git a/sysdeps/unix/syscall-template.S b/sysdeps/unix/syscall-template.S index cf6c7a58fb..0824a3c61e 100644 --- a/sysdeps/unix/syscall-template.S +++ b/sysdeps/unix/syscall-template.S @@ -25,6 +25,10 @@ defining a few macros: SYSCALL_NAME syscall name SYSCALL_NARGS number of arguments this call takes + SYSCALL_ULONG_ARG_1 the first unsigned long argument this + call takes + SYSCALL_ULONG_ARG_2 the second unsigned long argument this + call takes SYSCALL_SYMBOL primary symbol name SYSCALL_NOERRNO 1 to define a no-errno version (see below) SYSCALL_ERRVAL 1 to define an error-value version (see below) @@ -44,9 +48,27 @@ /* This indirection is needed so that SYMBOL gets macro-expanded. */ #define syscall_hidden_def(SYMBOL) hidden_def (SYMBOL) -#define T_PSEUDO(SYMBOL, NAME, N) PSEUDO (SYMBOL, NAME, N) -#define T_PSEUDO_NOERRNO(SYMBOL, NAME, N) PSEUDO_NOERRNO (SYMBOL, NAME, N) -#define T_PSEUDO_ERRVAL(SYMBOL, NAME, N) PSEUDO_ERRVAL (SYMBOL, NAME, N) +/* If PSEUDOS_HAVE_4_ARGS is defined, PSEUDO macros have 4 arguments. */ +#ifndef PSEUDOS_HAVE_4_ARGS +# undef SYSCALL_ULONG_ARG_1 +# define SYSCALL_ULONG_ARG_1 0 +#endif + +#if SYSCALL_ULONG_ARG_1 +# define T_PSEUDO(SYMBOL, NAME, N, U1, U2) \ + PSEUDO (SYMBOL, NAME, N, U1, U2) +# define T_PSEUDO_NOERRNO(SYMBOL, NAME, N, U1, U2) \ + PSEUDO_NOERRNO (SYMBOL, NAME, N, U1, U2) +# define T_PSEUDO_ERRVAL(SYMBOL, NAME, N, U1, U2) \ + PSEUDO_ERRVAL (SYMBOL, NAME, N, U1, U2) +#else +# define T_PSEUDO(SYMBOL, NAME, N) \ + PSEUDO (SYMBOL, NAME, N) +# define T_PSEUDO_NOERRNO(SYMBOL, NAME, N) \ + PSEUDO_NOERRNO (SYMBOL, NAME, N) +# define T_PSEUDO_ERRVAL(SYMBOL, NAME, N) \ + PSEUDO_ERRVAL (SYMBOL, NAME, N) +#endif #define T_PSEUDO_END(SYMBOL) PSEUDO_END (SYMBOL) #define T_PSEUDO_END_NOERRNO(SYMBOL) PSEUDO_END_NOERRNO (SYMBOL) #define T_PSEUDO_END_ERRVAL(SYMBOL) PSEUDO_END_ERRVAL (SYMBOL) @@ -56,7 +78,12 @@ /* This kind of system call stub never returns an error. We return the return value register to the caller unexamined. */ +# if SYSCALL_ULONG_ARG_1 +T_PSEUDO_NOERRNO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS, + SYSCALL_ULONG_ARG_1, SYSCALL_ULONG_ARG_2) +# else T_PSEUDO_NOERRNO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS) +# endif ret_NOERRNO T_PSEUDO_END_NOERRNO (SYSCALL_SYMBOL) @@ -66,7 +93,12 @@ T_PSEUDO_END_NOERRNO (SYSCALL_SYMBOL) value, or zero for success. We may massage the kernel's return value to meet that ABI, but we never set errno here. */ +# if SYSCALL_ULONG_ARG_1 +T_PSEUDO_ERRVAL (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS, + SYSCALL_ULONG_ARG_1, SYSCALL_ULONG_ARG_2) +# else T_PSEUDO_ERRVAL (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS) +# endif ret_ERRVAL T_PSEUDO_END_ERRVAL (SYSCALL_SYMBOL) @@ -75,7 +107,12 @@ T_PSEUDO_END_ERRVAL (SYSCALL_SYMBOL) /* This is a "normal" system call stub: if there is an error, it returns -1 and sets errno. */ +# if SYSCALL_ULONG_ARG_1 +T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS, + SYSCALL_ULONG_ARG_1, SYSCALL_ULONG_ARG_2) +# else T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS) +# endif ret T_PSEUDO_END (SYSCALL_SYMBOL) diff --git a/sysdeps/unix/syscalls.list b/sysdeps/unix/syscalls.list index 01c4a0e6b1..e63a8b9d23 100644 --- a/sysdeps/unix/syscalls.list +++ b/sysdeps/unix/syscalls.list @@ -37,11 +37,11 @@ kill - kill i:ii __kill kill link - link i:ss __link link listen - listen i:ii __listen listen lseek - lseek i:iii __libc_lseek __lseek lseek -madvise - madvise i:pii __madvise madvise +madvise - madvise i:pUi __madvise madvise mkdir - mkdir i:si __mkdir mkdir mmap - mmap b:aniiii __mmap mmap -mprotect - mprotect i:aii __mprotect mprotect -munmap - munmap i:ai __munmap munmap +mprotect - mprotect i:aUi __mprotect mprotect +munmap - munmap i:aU __munmap munmap open - open Ci:siv __libc_open __open open profil - profil i:piii __profil profil ptrace - ptrace i:iiii ptrace diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index e40f993495..4d4af84f9f 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -32,12 +32,12 @@ ioperm - ioperm i:iii ioperm iopl - iopl i:i iopl klogctl EXTRA syslog i:isi klogctl lchown - lchown i:sii __lchown lchown -mincore - mincore i:anV mincore -mlock - mlock i:bn mlock +mincore - mincore i:aUV mincore +mlock - mlock i:bU mlock mlockall - mlockall i:i mlockall -mount EXTRA mount i:sssip __mount mount -mremap EXTRA mremap b:ainip __mremap mremap -munlock - munlock i:ai munlock +mount EXTRA mount i:sssUp __mount mount +mremap EXTRA mremap b:aUUip __mremap mremap +munlock - munlock i:aU munlock munlockall - munlockall i: munlockall nfsservctl EXTRA nfsservctl i:ipp __compat_nfsservctl nfsservctl@GLIBC_2.0:GLIBC_2.28 pipe - pipe i:f __pipe pipe @@ -46,7 +46,7 @@ pivot_root EXTRA pivot_root i:ss pivot_root prctl EXTRA prctl i:iiiii __prctl prctl query_module EXTRA query_module i:sipip __compat_query_module query_module@GLIBC_2.0:GLIBC_2.23 quotactl EXTRA quotactl i:isip quotactl -remap_file_pages - remap_file_pages i:piiii __remap_file_pages remap_file_pages +remap_file_pages - remap_file_pages i:pUiUi __remap_file_pages remap_file_pages sched_getp - sched_getparam i:ip __sched_getparam sched_getparam sched_gets - sched_getscheduler i:i __sched_getscheduler sched_getscheduler sched_primax - sched_get_priority_max i:i __sched_get_priority_max sched_get_priority_max @@ -54,7 +54,7 @@ sched_primin - sched_get_priority_min i:i __sched_get_priority_min sched_get_pri sched_setp - sched_setparam i:ip __sched_setparam sched_setparam sched_sets - sched_setscheduler i:iip __sched_setscheduler sched_setscheduler sched_yield - sched_yield i: __sched_yield sched_yield -sendfile - sendfile i:iipi sendfile +sendfile - sendfile i:iipU sendfile sendfile64 - sendfile64 i:iipi sendfile64 setfsgid EXTRA setfsgid i:i setfsgid setfsuid EXTRA setfsuid i:i setfsuid diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h index 85f8f94820..3596273c94 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h +++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h @@ -57,13 +57,30 @@ # define SYSCALL_ERROR_LABEL syscall_error # endif +/* PSEUDO macros have 4 arguments. */ +# define PSEUDOS_HAVE_4_ARGS 1 + +# ifndef SYSCALL_ULONG_ARG_1 +# define SYSCALL_ULONG_ARG_1 0 +# define SYSCALL_ULONG_ARG_2 0 +# endif + # undef PSEUDO -# define PSEUDO(name, syscall_name, args) \ - .text; \ - ENTRY (name) \ - DO_CALL (syscall_name, args); \ - cmpq $-4095, %rax; \ +# if SYSCALL_ULONG_ARG_1 +# define PSEUDO(name, syscall_name, args, ulong_arg_1, ulong_arg_2) \ + .text; \ + ENTRY (name) \ + DO_CALL (syscall_name, args, ulong_arg_1, ulong_arg_2); \ + cmpq $-4095, %rax; \ jae SYSCALL_ERROR_LABEL +# else +# define PSEUDO(name, syscall_name, args) \ + .text; \ + ENTRY (name) \ + DO_CALL (syscall_name, args, 0, 0); \ + cmpq $-4095, %rax; \ + jae SYSCALL_ERROR_LABEL +# endif # undef PSEUDO_END # define PSEUDO_END(name) \ @@ -71,10 +88,17 @@ END (name) # undef PSEUDO_NOERRNO -# define PSEUDO_NOERRNO(name, syscall_name, args) \ - .text; \ - ENTRY (name) \ - DO_CALL (syscall_name, args) +# if SYSCALL_ULONG_ARG_1 +# define PSEUDO_NOERRNO(name, syscall_name, args, ulong_arg_1, ulong_arg_2) \ + .text; \ + ENTRY (name) \ + DO_CALL (syscall_name, args, ulong_arg_1, ulong_arg_2) +# else +# define PSEUDO_NOERRNO(name, syscall_name, args) \ + .text; \ + ENTRY (name) \ + DO_CALL (syscall_name, args, 0, 0) +# endif # undef PSEUDO_END_NOERRNO # define PSEUDO_END_NOERRNO(name) \ @@ -83,11 +107,19 @@ # define ret_NOERRNO ret # undef PSEUDO_ERRVAL -# define PSEUDO_ERRVAL(name, syscall_name, args) \ - .text; \ - ENTRY (name) \ - DO_CALL (syscall_name, args); \ +# if SYSCALL_ULONG_ARG_1 +# define PSEUDO_ERRVAL(name, syscall_name, args, ulong_arg_1, ulong_arg_2) \ + .text; \ + ENTRY (name) \ + DO_CALL (syscall_name, args, ulong_arg_1, ulong_arg_2); \ + negq %rax +# else +# define PSEUDO_ERRVAL(name, syscall_name, args) \ + .text; \ + ENTRY (name) \ + DO_CALL (syscall_name, args, 0, 0); \ negq %rax +# endif # undef PSEUDO_END_ERRVAL # define PSEUDO_END_ERRVAL(name) \ @@ -159,8 +191,10 @@ Syscalls of more than 6 arguments are not supported. */ # undef DO_CALL -# define DO_CALL(syscall_name, args) \ +# define DO_CALL(syscall_name, args, ulong_arg_1, ulong_arg_2) \ DOARGS_##args \ + ZERO_EXTEND_##ulong_arg_1 \ + ZERO_EXTEND_##ulong_arg_2 \ movl $SYS_ify (syscall_name), %eax; \ syscall; @@ -172,6 +206,14 @@ # define DOARGS_5 DOARGS_4 # define DOARGS_6 DOARGS_5 +# define ZERO_EXTEND_0 /* nothing */ +# define ZERO_EXTEND_1 /* nothing */ +# define ZERO_EXTEND_2 /* nothing */ +# define ZERO_EXTEND_3 /* nothing */ +# define ZERO_EXTEND_4 /* nothing */ +# define ZERO_EXTEND_5 /* nothing */ +# define ZERO_EXTEND_6 /* nothing */ + #else /* !__ASSEMBLER__ */ /* Registers clobbered by syscall. */ diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h index a37d520f86..b8a74ad2c2 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h +++ b/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h @@ -26,7 +26,25 @@ #undef LO_HI_LONG #define LO_HI_LONG(val) (val) -#ifndef __ASSEMBLER__ +#ifdef __ASSEMBLER__ +# undef ZERO_EXTEND_1 +# define ZERO_EXTEND_1 movl %edi, %edi; +# undef ZERO_EXTEND_2 +# define ZERO_EXTEND_2 movl %esi, %esi; +# undef ZERO_EXTEND_3 +# define ZERO_EXTEND_3 movl %edx, %edx; +# if SYSCALL_ULONG_ARG_1 == 4 || SYSCALL_ULONG_ARG_2 == 4 +# undef DOARGS_4 +# define DOARGS_4 movl %ecx, %r10d; +# else +# undef ZERO_EXTEND_4 +# define ZERO_EXTEND_4 movl %r10d, %r10d; +# endif +# undef ZERO_EXTEND_5 +# define ZERO_EXTEND_5 movl %r8d, %r8d; +# undef ZERO_EXTEND_6 +# define ZERO_EXTEND_6 movl %r9d, %r9d; +#else /* !__ASSEMBLER__ */ # undef ARGIFY /* Enforce zero-extension for pointers and array system call arguments. For integer types, extend to int64_t (the full register) using a