From patchwork Wed Apr 22 16:09:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 38838 Return-Path: X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x1042.google.com (mail-pj1-x1042.google.com [IPv6:2607:f8b0:4864:20::1042]) by sourceware.org (Postfix) with ESMTPS id 083493948828 for ; Wed, 22 Apr 2020 16:09:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 083493948828 Received: by mail-pj1-x1042.google.com with SMTP id ms17so1194582pjb.0 for ; Wed, 22 Apr 2020 09:09:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:content-transfer-encoding :in-reply-to; bh=noau5oS1gNxcrHDLE1X3Yd17PXivffVpWJEw4sm2RMI=; b=haV8bK7vi51V9D2zGG2eY3t1FtMyEMV4k+6o7pVuDqc3mTZCw7EsM7rPeCywkQuvzO cOvqdDhPbSmQ+j+mvUh5wFRxCVfJ5TKqAo3eSn858wmB43xbHbg6EKhEl7OZRsHGcuEj 41DxGPFxwvzY+KN2nUOXFUid2U7QbiQIQiDeGL4B2HtSQgyS5aeJrsip0NUxl592hP3x C+vC+XRRDOd3AbrO4f4kyQiXuYlBZb0BVgIUHj6gaTL7FTKe/RS4MHfGmi45VjFSLtmv HO7Zqym73x/1csl5ccAlQSRBV451Sd/pc027H3WJI284LJmmfVJpu9hyolZujyD9c4sg TkXw== X-Gm-Message-State: AGi0Pua8zeiC8Skn4ETTSxr/JBTVwMiNSwqM1z5g733Asy1CTEf6K62s +sODhaajR+1AYobKjky8BoMOR8EU X-Google-Smtp-Source: APiQypIPwLYxX1D++OgxijQgvOKvLhDts2O7E1OzO4uuw4A+qVrYPAMttLgzRCpITQ1joONboA5Hpg== X-Received: by 2002:a17:90a:25ea:: with SMTP id k97mr12901559pje.122.1587571788698; Wed, 22 Apr 2020 09:09:48 -0700 (PDT) Received: from gnu-cfl-2.localdomain (c-69-181-90-243.hsd1.ca.comcast.net. [69.181.90.243]) by smtp.gmail.com with ESMTPSA id d5sm5501798pfa.59.2020.04.22.09.09.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Apr 2020 09:09:48 -0700 (PDT) Received: by gnu-cfl-2.localdomain (Postfix, from userid 1000) id 03198C0453; Wed, 22 Apr 2020 09:09:46 -0700 (PDT) Date: Wed, 22 Apr 2020 09:09:46 -0700 From: "H.J. Lu" To: Florian Weimer Cc: "H.J. Lu via Libc-alpha" Subject: V3 [PATCH 1/2] Add SYSCALL_ULONG_ARG_[12] to pass long to syscall [BZ #25810] Message-ID: <20200422160946.GB342519@gmail.com> References: <20200413175117.170042-1-hjl.tools@gmail.com> <20200413175117.170042-2-hjl.tools@gmail.com> <878sinls2q.fsf@mid.deneb.enyo.de> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <878sinls2q.fsf@mid.deneb.enyo.de> X-Spam-Status: No, score=-24.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 22 Apr 2020 16:09:53 -0000 On Wed, Apr 22, 2020 at 12:42:37PM +0200, 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) Fixed. > > > # 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” Fixed. > > > + 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 Fixed. > > And maybe guard it with a case match, so that performance does not > suffer too much. I didn't notice any significant build timing change. > > In any case, there should be an error check that covers the more > than-two-Us case. > Fixed. > > > # 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. I updated comments of SYSCALL_ULONG_ARG_1 and SYSCALL_ULONG_ARG_2 in syscall-template.S. > > > 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” Fixed. > > > 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.) Fixed. > > > 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.? I updated readlink and readlinkat. read/write are implemented as inlined SYSCALLs. > > > 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. This comment is C specific. I added /* Zero-extend 32-bit unsigned long int arguments to 64 bits. */ to the newly added ZERO_EXTEND_X micros. Here is the updated patch. OK for master? Thanks. H.J. --- X32 has 32-bit long and pointer with 64-bit off_t. Since x32 psABI requires that pointers passed in registers must be zero-extended to 64bit, x32 can share many syscall interfaces with LP64. When a LP64 syscall with long and unsigned long int arguments is used for x32, these arguments must be properly extended to 64-bit. Otherwise if the upper 32 bits of the register have undefined value, such a syscall will be rejected by kernel. For syscalls implemented in assembly codes, 'U' is added to syscall signature key letters for unsigned long, which is zero-extended to 64-bit types. SYSCALL_ULONG_ARG_1 and SYSCALL_ULONG_ARG_2 are passed to syscall-template.S for the first and the second unsigned long int arguments if PSEUDOS_HAVE_ULONG_INDICES is defined. They are used by x32 to zero-extend 32-bit arguments to 64 bits. Tested on i386, x86-64 and x32 as well as with build-many-glibcs.py. --- sysdeps/unix/make-syscalls.sh | 24 +++++++ sysdeps/unix/syscall-template.S | 49 +++++++++++++- sysdeps/unix/syscalls.list | 8 +-- sysdeps/unix/sysv/linux/syscalls.list | 16 ++--- sysdeps/unix/sysv/linux/x86_64/sysdep.h | 71 +++++++++++++++++---- sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h | 21 +++++- 6 files changed, 159 insertions(+), 30 deletions(-) diff --git a/sysdeps/unix/make-syscalls.sh b/sysdeps/unix/make-syscalls.sh index c07626677f..4f6c3490a2 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 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,27 @@ while read file srcfile caller syscall args strong weak; do ?:?????????) nargs=9;; esac + # Derive the unsigned long int arguments from the argument signature + ulong_arg_1=0 + ulong_arg_2=0 + ulong_count=0 + for U in $(echo $args | sed -e "s/.*:/:/" | grep -ob U) + do + ulong_count=$(expr $ulong_count + 1) + ulong_arg=$(echo $U | sed -e "s/:U//") + case $ulong_count in + 1) + ulong_arg_1=$ulong_arg + ;; + 2) + ulong_arg_2=$ulong_arg + ;; + *) + echo >&2 "$0: Too many unsigned long int arguments for syscall ($strong $weak)" + exit 2 + esac + done + # Make sure only the first syscall rule is used, if multiple dirs # define the same syscall. echo '' @@ -245,6 +267,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..f807a8603f 100644 --- a/sysdeps/unix/syscall-template.S +++ b/sysdeps/unix/syscall-template.S @@ -25,6 +25,12 @@ defining a few macros: SYSCALL_NAME syscall name SYSCALL_NARGS number of arguments this call takes + SYSCALL_ULONG_ARG_1 the first unsigned long int argument this + call takes. 0 means that there are no + unsigned long int arguments. + SYSCALL_ULONG_ARG_2 the second unsigned long int argument this + call takes. 0 means that there is at most + one unsigned long int argument. 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 +50,31 @@ /* 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_ULONG_INDICES is defined, PSEUDO and T_PSEUDO macros + have 2 extra arguments for unsigned long int arguments: + Extra argument 1: Position of the first unsigned long int argument. + Extra argument 2: Position of the second unsigned long int argument. + */ +#ifndef PSEUDOS_HAVE_ULONG_INDICES +# 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 +84,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 +99,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 +113,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..0cf290076d 100644 --- a/sysdeps/unix/syscalls.list +++ b/sysdeps/unix/syscalls.list @@ -37,16 +37,16 @@ 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 read - read Ci:ibn __libc_read __read read -readlink - readlink i:spi __readlink readlink +readlink - readlink i:spU __readlink readlink readv - readv Ci:ipi __readv readv reboot - reboot i:i reboot recv - recv Ci:ibni __libc_recv recv diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index e40f993495..1b1010d4c8 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 @@ -71,7 +71,7 @@ chown - chown i:sii __libc_chown __chown chown fchownat - fchownat i:isiii fchownat linkat - linkat i:isisi linkat mkdirat - mkdirat i:isi mkdirat -readlinkat - readlinkat i:issi readlinkat +readlinkat - readlinkat i:issU readlinkat symlinkat - symlinkat i:sis symlinkat unlinkat - unlinkat i:isi unlinkat diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h index 85f8f94820..bf36875477 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h +++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h @@ -57,13 +57,31 @@ # define SYSCALL_ERROR_LABEL syscall_error # endif +/* PSEUDO and T_PSEUDO macros have 2 extra arguments for unsigned long + int arguments. */ +# define PSEUDOS_HAVE_ULONG_INDICES 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 +89,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 +108,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 +192,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 +207,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..62e6f8fe11 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h +++ b/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h @@ -26,7 +26,26 @@ #undef LO_HI_LONG #define LO_HI_LONG(val) (val) -#ifndef __ASSEMBLER__ +#ifdef __ASSEMBLER__ +/* Zero-extend 32-bit unsigned long int arguments to 64 bits. */ +# 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