From patchwork Fri Apr 10 21:22:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 38803 Return-Path: X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x1044.google.com (mail-pj1-x1044.google.com [IPv6:2607:f8b0:4864:20::1044]) by sourceware.org (Postfix) with ESMTPS id 920DF385B835 for ; Fri, 10 Apr 2020 21:22:56 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 920DF385B835 Received: by mail-pj1-x1044.google.com with SMTP id mn19so1190073pjb.0 for ; Fri, 10 Apr 2020 14:22:56 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=j2VntioHSkYbiZL065B/+EyvNRPeg1yoTSmkBmwDZgk=; b=Ir2yZEsmzsCVXHl2p/nsM8kEZ9M8S9TAJje9HZl70mSwu/HAvenFRVaB5yRtUmxgND hiv4j2YaytunwWLXpAiqSO+EPfJDAcaIMjv5/AnlfradQEm4FhPBWfKweE5/2u3qI/4Q iMIhyw8Bs5DPkuHLZQlgcLzWr/E7RszMkFq7WkOnC9qO7+P6AuLZnoZHjSbZAbXCtFeb NlV4blvx1ywb28+ARt0eTiiCSLlR2XHWr9y2u3ZYQhlLHJCWMEhcvMnlZZ2p0gwac4ft 0T06NqLqDXmgsPQuCvT3l3S42Rz8YS2H1Si/o81/LLeX2I9L8EI4bbMaoYQDwy64L+Ti D6KA== X-Gm-Message-State: AGi0PuYKxggAMi0sHKtI4oKc5hyYEzCL047nytPRW0jy50KdWwiiq4Hf tis3B5m0WkTYYTaBXhAeUdwW1JjJ X-Google-Smtp-Source: APiQypJG7kCnDnrOeS6o7CJQxr4MlDkfZjmfXCplJ6FenfEm3iSwKRd2FoIkknLGAYeFh7P1CzRqzA== X-Received: by 2002:a17:90a:1f07:: with SMTP id u7mr8004848pja.24.1586553774050; Fri, 10 Apr 2020 14:22:54 -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 202sm2264387pfx.109.2020.04.10.14.22.52 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Apr 2020 14:22:53 -0700 (PDT) Received: from gnu-cfl-2.localdomain (localhost [IPv6:::1]) by gnu-cfl-2.localdomain (Postfix) with ESMTP id 8474AC031D for ; Fri, 10 Apr 2020 14:22:50 -0700 (PDT) From: "H.J. Lu" To: libc-alpha@sourceware.org Subject: [PATCH] Add SYSCALL_LONG/SYSCALL_ULONG to pass long to syscall [BZ #25810] Date: Fri, 10 Apr 2020 14:22:49 -0700 Message-Id: <20200410212249.3529885-1-hjl.tools@gmail.com> X-Mailer: git-send-email 2.25.2 MIME-Version: 1.0 X-Spam-Status: No, score=-25.1 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, KAM_SHORT, 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: Fri, 10 Apr 2020 21:23:00 -0000 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 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 inline syscalls, SYSCALL_LONG and SYSCALL_ULONG are introduced as wrappers for long and unsigned long arguments. For syscalls implemented in assembly codes, 'U' is added to syscall signature key letters for unsigned long. SYSCALL_ULONG_ARG_1 and SYSCALL_ULONG_ARG_2 are passed to syscall-template.S for the first and the second unsigned long arguments. They are used by x32 to zero-extend 32-bit arguments to 64 bits. Tested on i386, x86-64 and 32 as well as with build-many-glibcs.py. --- misc/Makefile | 2 +- misc/tst-syscalls.c | 146 ++++++++++++++++++ sysdeps/unix/make-syscalls.sh | 88 +++++++++++ sysdeps/unix/syscall-template.S | 37 ++++- sysdeps/unix/sysv/linux/copy_file_range.c | 2 +- sysdeps/unix/sysv/linux/getcwd.c | 2 +- sysdeps/unix/sysv/linux/getdents.c | 3 +- sysdeps/unix/sysv/linux/getdents64.c | 6 +- sysdeps/unix/sysv/linux/getentropy.c | 4 +- sysdeps/unix/sysv/linux/getrandom.c | 3 +- sysdeps/unix/sysv/linux/mlock2.c | 8 +- sysdeps/unix/sysv/linux/mmap64.c | 7 +- sysdeps/unix/sysv/linux/mq_timedreceive.c | 12 +- sysdeps/unix/sysv/linux/mq_timedsend.c | 14 +- sysdeps/unix/sysv/linux/msgrcv.c | 7 +- sysdeps/unix/sysv/linux/msgsnd.c | 7 +- sysdeps/unix/sysv/linux/msync.c | 2 +- sysdeps/unix/sysv/linux/pkey_mprotect.c | 3 +- sysdeps/unix/sysv/linux/pread.c | 3 +- sysdeps/unix/sysv/linux/pread64.c | 3 +- sysdeps/unix/sysv/linux/pread64_nocancel.c | 3 +- sysdeps/unix/sysv/linux/pwrite.c | 3 +- sysdeps/unix/sysv/linux/pwrite64.c | 3 +- sysdeps/unix/sysv/linux/read.c | 2 +- sysdeps/unix/sysv/linux/read_nocancel.c | 2 +- sysdeps/unix/sysv/linux/readahead.c | 2 +- sysdeps/unix/sysv/linux/recv.c | 7 +- sysdeps/unix/sysv/linux/recvfrom.c | 8 +- sysdeps/unix/sysv/linux/sched_setaffinity.c | 3 +- sysdeps/unix/sysv/linux/semtimedop.c | 6 +- sysdeps/unix/sysv/linux/send.c | 7 +- sysdeps/unix/sysv/linux/sendto.c | 8 +- sysdeps/unix/sysv/linux/shmget.c | 6 +- sysdeps/unix/sysv/linux/splice.c | 3 +- sysdeps/unix/sysv/linux/sysdep.h | 5 + sysdeps/unix/sysv/linux/tee.c | 2 +- sysdeps/unix/sysv/linux/vmsplice.c | 2 +- sysdeps/unix/sysv/linux/write.c | 2 +- sysdeps/unix/sysv/linux/write_nocancel.c | 2 +- sysdeps/unix/sysv/linux/x86_64/sysdep.h | 57 +++++-- .../unix/sysv/linux/x86_64/x32/syscalls.list | 10 ++ sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h | 30 ++++ 42 files changed, 450 insertions(+), 82 deletions(-) create mode 100644 misc/tst-syscalls.c diff --git a/misc/Makefile b/misc/Makefile index b8fed5783d..67c5237f97 100644 --- a/misc/Makefile +++ b/misc/Makefile @@ -87,7 +87,7 @@ tests := tst-dirname tst-tsearch tst-fdset tst-mntent tst-hsearch \ tst-preadvwritev tst-preadvwritev64 tst-makedev tst-empty \ tst-preadvwritev2 tst-preadvwritev64v2 tst-warn-wide \ tst-ldbl-warn tst-ldbl-error tst-dbl-efgcvt tst-ldbl-efgcvt \ - tst-mntent-autofs + tst-mntent-autofs tst-syscalls # Tests which need libdl. ifeq (yes,$(build-shared)) diff --git a/misc/tst-syscalls.c b/misc/tst-syscalls.c new file mode 100644 index 0000000000..d07f03633b --- /dev/null +++ b/misc/tst-syscalls.c @@ -0,0 +1,146 @@ +/* Test for syscall interfaces. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include +#include + +struct Array +{ + size_t length; + void *ptr; +}; + +static int error_count; + +__attribute__ ((noclone, noinline)) +struct Array +allocate (size_t bytes) +{ + if (!bytes) + return __extension__ (struct Array) {0, 0}; + + void *p = mmap (0x0, bytes, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (p == MAP_FAILED) + return __extension__ (struct Array) {0, 0}; + + return __extension__ (struct Array) {bytes, p}; +} + +__attribute__ ((noclone, noinline)) +void +deallocate (struct Array b) +{ + if (b.length && munmap (b.ptr, b.length)) + { + printf ("munmap error: %m\n"); + error_count++; + } +} + +__attribute__ ((noclone, noinline)) +void * +do_mmap (void *addr, size_t length) +{ + return mmap (addr, length, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); +} + +__attribute__ ((noclone, noinline)) +void * +reallocate (struct Array b) +{ + if (b.length) + return do_mmap (b.ptr, b.length); + return NULL; +} + +__attribute__ ((noclone, noinline)) +void +protect (struct Array b) +{ + if (b.length) + { + if (mprotect (b.ptr, b.length, + PROT_READ | PROT_WRITE | PROT_EXEC)) + { + printf ("mprotect error: %m\n"); + error_count++; + } + } +} + +__attribute__ ((noclone, noinline)) +ssize_t +do_read (int fd, void *ptr, struct Array b) +{ + if (b.length) + return read (fd, ptr, b.length); + return 0; +} + +__attribute__ ((noclone, noinline)) +ssize_t +do_write (int fd, void *ptr, struct Array b) +{ + if (b.length) + return write (fd, ptr, b.length); + return 0; +} + +static int +do_test (void) +{ + struct Array array; + + array = allocate (1); + protect (array); + deallocate (array); + void *p = reallocate (array); + if (p == MAP_FAILED) + { + printf ("mmap error: %m\n"); + error_count++; + } + array.ptr = p; + protect (array); + deallocate (array); + + int fd = xopen ("/dev/null", O_RDWR, 0); + char buf[2]; + array.ptr = buf; + if (do_read (fd, array.ptr, array) == -1) + { + printf ("read error: %m\n"); + error_count++; + } + if (do_write (fd, array.ptr, array) == -1) + { + printf ("write error: %m\n"); + error_count++; + } + xclose (fd); + + return error_count ? EXIT_FAILURE : EXIT_SUCCESS; +} + +#include diff --git a/sysdeps/unix/make-syscalls.sh b/sysdeps/unix/make-syscalls.sh index c07626677f..52cf7e2f16 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 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..e8d6d59b15 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,21 @@ /* 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 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 +72,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 +87,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 +101,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/sysv/linux/copy_file_range.c b/sysdeps/unix/sysv/linux/copy_file_range.c index a73c89f079..50487df77c 100644 --- a/sysdeps/unix/sysv/linux/copy_file_range.c +++ b/sysdeps/unix/sysv/linux/copy_file_range.c @@ -26,5 +26,5 @@ copy_file_range (int infd, __off64_t *pinoff, size_t length, unsigned int flags) { return SYSCALL_CANCEL (copy_file_range, infd, pinoff, outfd, poutoff, - length, flags); + SYSCALL_ULONG (length), flags); } diff --git a/sysdeps/unix/sysv/linux/getcwd.c b/sysdeps/unix/sysv/linux/getcwd.c index fabc4bb8cc..d228467edf 100644 --- a/sysdeps/unix/sysv/linux/getcwd.c +++ b/sysdeps/unix/sysv/linux/getcwd.c @@ -75,7 +75,7 @@ __getcwd (char *buf, size_t size) int retval; - retval = INLINE_SYSCALL (getcwd, 2, path, alloc_size); + retval = INLINE_SYSCALL (getcwd, 2, path, SYSCALL_ULONG (alloc_size)); if (retval > 0 && path[0] == '/') { #ifndef NO_ALLOCATION diff --git a/sysdeps/unix/sysv/linux/getdents.c b/sysdeps/unix/sysv/linux/getdents.c index a76be2e5e7..fc8da0caae 100644 --- a/sysdeps/unix/sysv/linux/getdents.c +++ b/sysdeps/unix/sysv/linux/getdents.c @@ -53,7 +53,8 @@ __getdents (int fd, void *buf0, size_t nbytes) if (nbytes <= sizeof (struct dirent)) kbuf = (void*) kbuftmp; - retval = INLINE_SYSCALL_CALL (getdents64, fd, kbuf, kbytes); + retval = INLINE_SYSCALL_CALL (getdents64, fd, kbuf, + SYSCALL_ULONG (kbytes)); if (retval == -1) return -1; diff --git a/sysdeps/unix/sysv/linux/getdents64.c b/sysdeps/unix/sysv/linux/getdents64.c index 75892c2823..63c89c7d60 100644 --- a/sysdeps/unix/sysv/linux/getdents64.c +++ b/sysdeps/unix/sysv/linux/getdents64.c @@ -29,7 +29,8 @@ __getdents64 (int fd, void *buf, size_t nbytes) checks in the kernel use an int type. */ if (nbytes > INT_MAX) nbytes = INT_MAX; - return INLINE_SYSCALL_CALL (getdents64, fd, buf, nbytes); + return INLINE_SYSCALL_CALL (getdents64, fd, buf, + SYSCALL_ULONG (nbytes)); } libc_hidden_def (__getdents64) weak_alias (__getdents64, getdents64) @@ -74,7 +75,8 @@ __old_getdents64 (int fd, char *buf, size_t nbytes) <= __alignof__ (struct dirent64), "alignment of __old_dirent64 is larger than dirent64"); - ssize_t retval = INLINE_SYSCALL_CALL (getdents64, fd, buf, nbytes); + ssize_t retval = INLINE_SYSCALL_CALL (getdents64, fd, buf, + SYSCALL_ULONG (nbytes)); if (retval > 0) { /* This is the marker for the first entry. Offset 0 is reserved diff --git a/sysdeps/unix/sysv/linux/getentropy.c b/sysdeps/unix/sysv/linux/getentropy.c index 2f3a4e4692..f99d2783a1 100644 --- a/sysdeps/unix/sysv/linux/getentropy.c +++ b/sysdeps/unix/sysv/linux/getentropy.c @@ -41,7 +41,9 @@ getentropy (void *buffer, size_t length) while (buffer < end) { /* NB: No cancellation point. */ - ssize_t bytes = INLINE_SYSCALL_CALL (getrandom, buffer, end - buffer, 0); + ssize_t bytes = INLINE_SYSCALL_CALL (getrandom, buffer, + SYSCALL_ULONG (end - buffer), + 0); if (bytes < 0) { if (errno == EINTR) diff --git a/sysdeps/unix/sysv/linux/getrandom.c b/sysdeps/unix/sysv/linux/getrandom.c index 63b8d36bf4..8008890939 100644 --- a/sysdeps/unix/sysv/linux/getrandom.c +++ b/sysdeps/unix/sysv/linux/getrandom.c @@ -26,7 +26,8 @@ ssize_t __getrandom (void *buffer, size_t length, unsigned int flags) { - return SYSCALL_CANCEL (getrandom, buffer, length, flags); + return SYSCALL_CANCEL (getrandom, buffer, SYSCALL_ULONG (length), + flags); } libc_hidden_def (__getrandom) weak_alias (__getrandom, getrandom) diff --git a/sysdeps/unix/sysv/linux/mlock2.c b/sysdeps/unix/sysv/linux/mlock2.c index e52f43f35c..599ed5c351 100644 --- a/sysdeps/unix/sysv/linux/mlock2.c +++ b/sysdeps/unix/sysv/linux/mlock2.c @@ -23,11 +23,13 @@ int mlock2 (const void *addr, size_t length, unsigned int flags) { #ifdef __ASSUME_MLOCK2 - return INLINE_SYSCALL_CALL (mlock2, addr, length, flags); + return INLINE_SYSCALL_CALL (mlock2, addr, SYSCALL_ULONG (length), + flags); #else if (flags == 0) - return INLINE_SYSCALL_CALL (mlock, addr, length); - int ret = INLINE_SYSCALL_CALL (mlock2, addr, length, flags); + return INLINE_SYSCALL_CALL (mlock, addr, SYSCALL_ULONG (length)); + int ret = INLINE_SYSCALL_CALL (mlock2, addr, SYSCALL_ULONG (length), + flags); if (ret == 0 || errno != ENOSYS) return ret; /* Treat the missing system call as an invalid (non-zero) flag diff --git a/sysdeps/unix/sysv/linux/mmap64.c b/sysdeps/unix/sysv/linux/mmap64.c index 8074deb466..7efe7f171d 100644 --- a/sysdeps/unix/sysv/linux/mmap64.c +++ b/sysdeps/unix/sysv/linux/mmap64.c @@ -53,10 +53,11 @@ __mmap64 (void *addr, size_t len, int prot, int flags, int fd, off64_t offset) MMAP_PREPARE (addr, len, prot, flags, fd, offset); #ifdef __NR_mmap2 - return (void *) MMAP_CALL (mmap2, addr, len, prot, flags, fd, - (off_t) (offset / MMAP2_PAGE_UNIT)); + return (void *) MMAP_CALL (mmap2, addr, SYSCALL_ULONG (len), prot, flags, + fd, (off_t) (offset / MMAP2_PAGE_UNIT)); #else - return (void *) MMAP_CALL (mmap, addr, len, prot, flags, fd, offset); + return (void *) MMAP_CALL (mmap, addr, SYSCALL_ULONG (len), prot, flags, + fd, offset); #endif } weak_alias (__mmap64, mmap64) diff --git a/sysdeps/unix/sysv/linux/mq_timedreceive.c b/sysdeps/unix/sysv/linux/mq_timedreceive.c index 728a63d1ec..aae1443196 100644 --- a/sysdeps/unix/sysv/linux/mq_timedreceive.c +++ b/sysdeps/unix/sysv/linux/mq_timedreceive.c @@ -30,11 +30,12 @@ __mq_timedreceive_time64 (mqd_t mqdes, char *__restrict msg_ptr, size_t msg_len, # ifndef __NR_mq_timedreceive_time64 # define __NR_mq_timedreceive_time64 __NR_mq_timedreceive # endif - return SYSCALL_CANCEL (mq_timedreceive_time64, mqdes, msg_ptr, msg_len, - msg_prio, abs_timeout); + return SYSCALL_CANCEL (mq_timedreceive_time64, mqdes, msg_ptr, + SYSCALL_ULONG (msg_len), msg_prio, abs_timeout); #else - int ret = SYSCALL_CANCEL (mq_timedreceive_time64, mqdes, msg_ptr, msg_len, - msg_prio, abs_timeout); + int ret = SYSCALL_CANCEL (mq_timedreceive_time64, mqdes, msg_ptr, + SYSCALL_ULONG (msg_len), msg_prio, + abs_timeout); if (ret == 0 || errno != ENOSYS) return ret; @@ -50,7 +51,8 @@ __mq_timedreceive_time64 (mqd_t mqdes, char *__restrict msg_ptr, size_t msg_len, ts32 = valid_timespec64_to_timespec (*abs_timeout); } - return SYSCALL_CANCEL (mq_timedreceive, mqdes, msg_ptr, msg_len, msg_prio, + return SYSCALL_CANCEL (mq_timedreceive, mqdes, msg_ptr, + SYSCALL_ULONG (msg_len), msg_prio, abs_timeout != NULL ? &ts32 : NULL); #endif } diff --git a/sysdeps/unix/sysv/linux/mq_timedsend.c b/sysdeps/unix/sysv/linux/mq_timedsend.c index f2a43df300..7e174df888 100644 --- a/sysdeps/unix/sysv/linux/mq_timedsend.c +++ b/sysdeps/unix/sysv/linux/mq_timedsend.c @@ -30,11 +30,11 @@ __mq_timedsend_time64 (mqd_t mqdes, const char *msg_ptr, size_t msg_len, # ifndef __NR_mq_timedsend_time64 # define __NR_mq_timedsend_time64 __NR_mq_timedsend # endif - return SYSCALL_CANCEL (mq_timedsend_time64, mqdes, msg_ptr, msg_len, - msg_prio, abs_timeout); + return SYSCALL_CANCEL (mq_timedsend_time64, mqdes, msg_ptr, + SYSCALL_ULONG (msg_len), msg_prio, abs_timeout); #else - int ret = SYSCALL_CANCEL (mq_timedsend_time64, mqdes, msg_ptr, msg_len, - msg_prio, abs_timeout); + int ret = SYSCALL_CANCEL (mq_timedsend_time64, mqdes, msg_ptr, + SYSCALL_ULONG (msg_len), msg_prio, abs_timeout); if (ret == 0 || errno != ENOSYS) return ret; @@ -50,7 +50,8 @@ __mq_timedsend_time64 (mqd_t mqdes, const char *msg_ptr, size_t msg_len, ts32 = valid_timespec64_to_timespec (*abs_timeout); } - return SYSCALL_CANCEL (mq_timedsend, mqdes, msg_ptr, msg_len, msg_prio, + return SYSCALL_CANCEL (mq_timedsend, mqdes, msg_ptr, + SYSCALL_ULONG (msg_len), msg_prio, abs_timeout != NULL ? &ts32 : NULL); #endif } @@ -66,7 +67,8 @@ __mq_timedsend (mqd_t mqdes, const char *msg_ptr, size_t msg_len, if (abs_timeout != NULL) ts64 = valid_timespec_to_timespec64 (*abs_timeout); - return __mq_timedsend_time64 (mqdes, msg_ptr, msg_len, msg_prio, + return __mq_timedsend_time64 (mqdes, msg_ptr, + SYSCALL_ULONG (msg_len), msg_prio, abs_timeout != NULL ? &ts64 : NULL); } #endif diff --git a/sysdeps/unix/sysv/linux/msgrcv.c b/sysdeps/unix/sysv/linux/msgrcv.c index 95edc7a787..ecfa2df4fb 100644 --- a/sysdeps/unix/sysv/linux/msgrcv.c +++ b/sysdeps/unix/sysv/linux/msgrcv.c @@ -25,10 +25,11 @@ __libc_msgrcv (int msqid, void *msgp, size_t msgsz, long int msgtyp, int msgflg) { #ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS - return SYSCALL_CANCEL (msgrcv, msqid, msgp, msgsz, msgtyp, msgflg); + return SYSCALL_CANCEL (msgrcv, msqid, msgp, SYSCALL_ULONG (msgsz), + SYSCALL_LONG (msgtyp), msgflg); #else - return SYSCALL_CANCEL (ipc, IPCOP_msgrcv, msqid, msgsz, msgflg, - MSGRCV_ARGS (msgp, msgtyp)); + return SYSCALL_CANCEL (ipc, IPCOP_msgrcv, msqid, SYSCALL_ULONG (msgsz), + msgflg, MSGRCV_ARGS (msgp, SYSCALL_LONG (msgtyp))); #endif } weak_alias (__libc_msgrcv, msgrcv) diff --git a/sysdeps/unix/sysv/linux/msgsnd.c b/sysdeps/unix/sysv/linux/msgsnd.c index 554516f2ca..9e329d8e72 100644 --- a/sysdeps/unix/sysv/linux/msgsnd.c +++ b/sysdeps/unix/sysv/linux/msgsnd.c @@ -24,10 +24,11 @@ int __libc_msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg) { #ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS - return SYSCALL_CANCEL (msgsnd, msqid, msgp, msgsz, msgflg); + return SYSCALL_CANCEL (msgsnd, msqid, msgp, SYSCALL_ULONG (msgsz), + msgflg); #else - return SYSCALL_CANCEL (ipc, IPCOP_msgsnd, msqid, msgsz, msgflg, - msgp); + return SYSCALL_CANCEL (ipc, IPCOP_msgsnd, msqid, SYSCALL_ULONG (msgsz), + msgflg, msgp); #endif } weak_alias (__libc_msgsnd, msgsnd) diff --git a/sysdeps/unix/sysv/linux/msync.c b/sysdeps/unix/sysv/linux/msync.c index de1dd2ac5e..0ef48a1eaf 100644 --- a/sysdeps/unix/sysv/linux/msync.c +++ b/sysdeps/unix/sysv/linux/msync.c @@ -22,5 +22,5 @@ int msync (void *addr, size_t length, int flags) { - return SYSCALL_CANCEL (msync, addr, length, flags); + return SYSCALL_CANCEL (msync, addr, SYSCALL_ULONG (length), flags); } diff --git a/sysdeps/unix/sysv/linux/pkey_mprotect.c b/sysdeps/unix/sysv/linux/pkey_mprotect.c index 4ec1feba2e..9130bbdef6 100644 --- a/sysdeps/unix/sysv/linux/pkey_mprotect.c +++ b/sysdeps/unix/sysv/linux/pkey_mprotect.c @@ -28,5 +28,6 @@ pkey_mprotect (void *addr, size_t len, int prot, int pkey) /* If the key is -1, the system call is precisely equivalent to mprotect. */ return __mprotect (addr, len, prot); - return INLINE_SYSCALL_CALL (pkey_mprotect, addr, len, prot, pkey); + return INLINE_SYSCALL_CALL (pkey_mprotect, addr, SYSCALL_ULONG (len), + prot, pkey); } diff --git a/sysdeps/unix/sysv/linux/pread.c b/sysdeps/unix/sysv/linux/pread.c index 8dd87b3976..41d51d810c 100644 --- a/sysdeps/unix/sysv/linux/pread.c +++ b/sysdeps/unix/sysv/linux/pread.c @@ -24,7 +24,8 @@ ssize_t __libc_pread (int fd, void *buf, size_t count, off_t offset) { - return SYSCALL_CANCEL (pread64, fd, buf, count, SYSCALL_LL_PRW (offset)); + return SYSCALL_CANCEL (pread64, fd, buf, SYSCALL_ULONG (count), + SYSCALL_LL_PRW (offset)); } strong_alias (__libc_pread, __pread) diff --git a/sysdeps/unix/sysv/linux/pread64.c b/sysdeps/unix/sysv/linux/pread64.c index 3d4ffbafc1..7a7bf7076c 100644 --- a/sysdeps/unix/sysv/linux/pread64.c +++ b/sysdeps/unix/sysv/linux/pread64.c @@ -22,7 +22,8 @@ ssize_t __libc_pread64 (int fd, void *buf, size_t count, off64_t offset) { - return SYSCALL_CANCEL (pread64, fd, buf, count, SYSCALL_LL64_PRW (offset)); + return SYSCALL_CANCEL (pread64, fd, buf, SYSCALL_ULONG (count), + SYSCALL_LL64_PRW (offset)); } weak_alias (__libc_pread64, __pread64) diff --git a/sysdeps/unix/sysv/linux/pread64_nocancel.c b/sysdeps/unix/sysv/linux/pread64_nocancel.c index af33985959..ea9e3be552 100644 --- a/sysdeps/unix/sysv/linux/pread64_nocancel.c +++ b/sysdeps/unix/sysv/linux/pread64_nocancel.c @@ -23,6 +23,7 @@ ssize_t __pread64_nocancel (int fd, void *buf, size_t count, off64_t offset) { - return INLINE_SYSCALL_CALL (pread64, fd, buf, count, SYSCALL_LL64_PRW (offset)); + return INLINE_SYSCALL_CALL (pread64, fd, buf, SYSCALL_ULONG (count), + SYSCALL_LL64_PRW (offset)); } hidden_def (__pread64_nocancel) diff --git a/sysdeps/unix/sysv/linux/pwrite.c b/sysdeps/unix/sysv/linux/pwrite.c index 17964686e5..c1cddbfe81 100644 --- a/sysdeps/unix/sysv/linux/pwrite.c +++ b/sysdeps/unix/sysv/linux/pwrite.c @@ -24,7 +24,8 @@ ssize_t __libc_pwrite (int fd, const void *buf, size_t count, off_t offset) { - return SYSCALL_CANCEL (pwrite64, fd, buf, count, SYSCALL_LL_PRW (offset)); + return SYSCALL_CANCEL (pwrite64, fd, buf, SYSCALL_ULONG (count), + SYSCALL_LL_PRW (offset)); } strong_alias (__libc_pwrite, __pwrite) diff --git a/sysdeps/unix/sysv/linux/pwrite64.c b/sysdeps/unix/sysv/linux/pwrite64.c index 709775c207..a47c309144 100644 --- a/sysdeps/unix/sysv/linux/pwrite64.c +++ b/sysdeps/unix/sysv/linux/pwrite64.c @@ -22,7 +22,8 @@ ssize_t __libc_pwrite64 (int fd, const void *buf, size_t count, off64_t offset) { - return SYSCALL_CANCEL (pwrite64, fd, buf, count, SYSCALL_LL64_PRW (offset)); + return SYSCALL_CANCEL (pwrite64, fd, buf, SYSCALL_ULONG (count), + SYSCALL_LL64_PRW (offset)); } weak_alias (__libc_pwrite64, __pwrite64) diff --git a/sysdeps/unix/sysv/linux/read.c b/sysdeps/unix/sysv/linux/read.c index 64f558a587..6c37b4fba9 100644 --- a/sysdeps/unix/sysv/linux/read.c +++ b/sysdeps/unix/sysv/linux/read.c @@ -23,7 +23,7 @@ ssize_t __libc_read (int fd, void *buf, size_t nbytes) { - return SYSCALL_CANCEL (read, fd, buf, nbytes); + return SYSCALL_CANCEL (read, fd, buf, SYSCALL_ULONG (nbytes)); } libc_hidden_def (__libc_read) diff --git a/sysdeps/unix/sysv/linux/read_nocancel.c b/sysdeps/unix/sysv/linux/read_nocancel.c index f9d8a3b563..4a734e9d83 100644 --- a/sysdeps/unix/sysv/linux/read_nocancel.c +++ b/sysdeps/unix/sysv/linux/read_nocancel.c @@ -23,6 +23,6 @@ ssize_t __read_nocancel (int fd, void *buf, size_t nbytes) { - return INLINE_SYSCALL_CALL (read, fd, buf, nbytes); + return INLINE_SYSCALL_CALL (read, fd, buf, SYSCALL_ULONG (nbytes)); } hidden_def (__read_nocancel) diff --git a/sysdeps/unix/sysv/linux/readahead.c b/sysdeps/unix/sysv/linux/readahead.c index a189c3ac79..46a98c000a 100644 --- a/sysdeps/unix/sysv/linux/readahead.c +++ b/sysdeps/unix/sysv/linux/readahead.c @@ -25,6 +25,6 @@ __readahead (int fd, off64_t offset, size_t count) { return INLINE_SYSCALL_CALL (readahead, fd, __ALIGNMENT_ARG SYSCALL_LL64 (offset), - count); + SYSCALL_ULONG (count)); } weak_alias (__readahead, readahead) diff --git a/sysdeps/unix/sysv/linux/recv.c b/sysdeps/unix/sysv/linux/recv.c index 79fb3c32d1..9ab079cc7c 100644 --- a/sysdeps/unix/sysv/linux/recv.c +++ b/sysdeps/unix/sysv/linux/recv.c @@ -23,11 +23,12 @@ ssize_t __libc_recv (int fd, void *buf, size_t len, int flags) { #ifdef __ASSUME_RECV_SYSCALL - return SYSCALL_CANCEL (recv, fd, buf, len, flags); + return SYSCALL_CANCEL (recv, fd, buf, SYSCALL_ULONG (len), flags); #elif defined __ASSUME_RECVFROM_SYSCALL - return SYSCALL_CANCEL (recvfrom, fd, buf, len, flags, NULL, NULL); + return SYSCALL_CANCEL (recvfrom, fd, buf, SYSCALL_ULONG (len), flags, + NULL, NULL); #else - return SOCKETCALL_CANCEL (recv, fd, buf, len, flags); + return SOCKETCALL_CANCEL (recv, fd, buf, SYSCALL_ULONG (len), flags); #endif } weak_alias (__libc_recv, recv) diff --git a/sysdeps/unix/sysv/linux/recvfrom.c b/sysdeps/unix/sysv/linux/recvfrom.c index 70532529c9..caf3b66738 100644 --- a/sysdeps/unix/sysv/linux/recvfrom.c +++ b/sysdeps/unix/sysv/linux/recvfrom.c @@ -24,11 +24,11 @@ __libc_recvfrom (int fd, void *buf, size_t len, int flags, __SOCKADDR_ARG addr, socklen_t *addrlen) { #ifdef __ASSUME_RECVFROM_SYSCALL - return SYSCALL_CANCEL (recvfrom, fd, buf, len, flags, addr.__sockaddr__, - addrlen); + return SYSCALL_CANCEL (recvfrom, fd, buf, SYSCALL_ULONG (len), flags, + addr.__sockaddr__, addrlen); #else - return SOCKETCALL_CANCEL (recvfrom, fd, buf, len, flags, addr.__sockaddr__, - addrlen); + return SOCKETCALL_CANCEL (recvfrom, fd, buf, SYSCALL_ULONG (len), + flags, addr.__sockaddr__, addrlen); #endif } weak_alias (__libc_recvfrom, recvfrom) diff --git a/sysdeps/unix/sysv/linux/sched_setaffinity.c b/sysdeps/unix/sysv/linux/sched_setaffinity.c index fc2c692783..aea179464c 100644 --- a/sysdeps/unix/sysv/linux/sched_setaffinity.c +++ b/sysdeps/unix/sysv/linux/sched_setaffinity.c @@ -30,7 +30,8 @@ libc_hidden_proto (__sched_setaffinity_new) int __sched_setaffinity_new (pid_t pid, size_t cpusetsize, const cpu_set_t *cpuset) { - int result = INLINE_SYSCALL (sched_setaffinity, 3, pid, cpusetsize, cpuset); + int result = INLINE_SYSCALL (sched_setaffinity, 3, pid, + SYSCALL_ULONG (cpusetsize), cpuset); #ifdef RESET_VGETCPU_CACHE if (result != -1) diff --git a/sysdeps/unix/sysv/linux/semtimedop.c b/sysdeps/unix/sysv/linux/semtimedop.c index 6fdde09bad..f3b240ca9b 100644 --- a/sysdeps/unix/sysv/linux/semtimedop.c +++ b/sysdeps/unix/sysv/linux/semtimedop.c @@ -30,10 +30,12 @@ __semtimedop (int semid, struct sembuf *sops, size_t nsops, /* semtimedop wire-up syscall is not exported for 32-bit ABIs (they have semtimedop_time64 instead with uses a 64-bit time_t). */ #if defined __ASSUME_DIRECT_SYSVIPC_SYSCALLS && defined __NR_semtimedop - return INLINE_SYSCALL_CALL (semtimedop, semid, sops, nsops, timeout); + return INLINE_SYSCALL_CALL (semtimedop, semid, sops, + SYSCALL_ULONG (nsops), timeout); #else return INLINE_SYSCALL_CALL (ipc, IPCOP_semtimedop, semid, - SEMTIMEDOP_IPC_ARGS (nsops, sops, timeout)); + SEMTIMEDOP_IPC_ARGS (SYSCALL_ULONG (nsops), + sops, timeout)); #endif } weak_alias (__semtimedop, semtimedop) diff --git a/sysdeps/unix/sysv/linux/send.c b/sysdeps/unix/sysv/linux/send.c index aed7d06585..cd8725d05b 100644 --- a/sysdeps/unix/sysv/linux/send.c +++ b/sysdeps/unix/sysv/linux/send.c @@ -23,11 +23,12 @@ ssize_t __libc_send (int fd, const void *buf, size_t len, int flags) { #ifdef __ASSUME_SEND_SYSCALL - return SYSCALL_CANCEL (send, fd, buf, len, flags); + return SYSCALL_CANCEL (send, fd, buf, SYSCALL_ULONG (len), flags); #elif defined __ASSUME_SENDTO_SYSCALL - return SYSCALL_CANCEL (sendto, fd, buf, len, flags, NULL, 0); + return SYSCALL_CANCEL (sendto, fd, buf, SYSCALL_ULONG (len), flags, + NULL, 0); #else - return SOCKETCALL_CANCEL (send, fd, buf, len, flags); + return SOCKETCALL_CANCEL (send, fd, buf, SYSCALL_ULONG (len), flags); #endif } weak_alias (__libc_send, send) diff --git a/sysdeps/unix/sysv/linux/sendto.c b/sysdeps/unix/sysv/linux/sendto.c index 670d0679ea..ceb61305af 100644 --- a/sysdeps/unix/sysv/linux/sendto.c +++ b/sysdeps/unix/sysv/linux/sendto.c @@ -24,11 +24,11 @@ __libc_sendto (int fd, const void *buf, size_t len, int flags, __CONST_SOCKADDR_ARG addr, socklen_t addrlen) { #ifdef __ASSUME_SENDTO_SYSCALL - return SYSCALL_CANCEL (sendto, fd, buf, len, flags, addr.__sockaddr__, - addrlen); + return SYSCALL_CANCEL (sendto, fd, buf, SYSCALL_ULONG (len), flags, + addr.__sockaddr__, addrlen); #else - return SOCKETCALL_CANCEL (sendto, fd, buf, len, flags, addr.__sockaddr__, - addrlen); + return SOCKETCALL_CANCEL (sendto, fd, buf, SYSCALL_ULONG (len), flags, + addr.__sockaddr__, addrlen); #endif } weak_alias (__libc_sendto, sendto) diff --git a/sysdeps/unix/sysv/linux/shmget.c b/sysdeps/unix/sysv/linux/shmget.c index 6f7ce8c057..1032142170 100644 --- a/sysdeps/unix/sysv/linux/shmget.c +++ b/sysdeps/unix/sysv/linux/shmget.c @@ -28,8 +28,10 @@ int shmget (key_t key, size_t size, int shmflg) { #ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS - return INLINE_SYSCALL_CALL (shmget, key, size, shmflg, NULL); + return INLINE_SYSCALL_CALL (shmget, key, SYSCALL_ULONG (size), + shmflg, NULL); #else - return INLINE_SYSCALL_CALL (ipc, IPCOP_shmget, key, size, shmflg, NULL); + return INLINE_SYSCALL_CALL (ipc, IPCOP_shmget, key, + SYSCALL_ULONG (size), shmflg, NULL); #endif } diff --git a/sysdeps/unix/sysv/linux/splice.c b/sysdeps/unix/sysv/linux/splice.c index fe21cf1988..199608fffa 100644 --- a/sysdeps/unix/sysv/linux/splice.c +++ b/sysdeps/unix/sysv/linux/splice.c @@ -23,5 +23,6 @@ ssize_t splice (int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags) { - return SYSCALL_CANCEL (splice, fd_in, off_in, fd_out, off_out, len, flags); + return SYSCALL_CANCEL (splice, fd_in, off_in, fd_out, off_out, + SYSCALL_ULONG (len), flags); } diff --git a/sysdeps/unix/sysv/linux/sysdep.h b/sysdeps/unix/sysv/linux/sysdep.h index 5e7b6c5765..0ab65e40a5 100644 --- a/sysdeps/unix/sysv/linux/sysdep.h +++ b/sysdeps/unix/sysv/linux/sysdep.h @@ -94,6 +94,11 @@ (long) (val), \ (long) (((uint64_t) (val)) >> 32) +/* Provide common macros to pass long/unsigned long (ssize_t/size_t) + values on syscalls. */ +#define SYSCALL_LONG(val) (val) +#define SYSCALL_ULONG(val) (val) + /* Exports the __send symbol on send.c linux implementation (some ABI have it missing due the usage of a old generic version without it). */ #define HAVE_INTERNAL_SEND_SYMBOL 1 diff --git a/sysdeps/unix/sysv/linux/tee.c b/sysdeps/unix/sysv/linux/tee.c index 0e62c226dd..f404768ef6 100644 --- a/sysdeps/unix/sysv/linux/tee.c +++ b/sysdeps/unix/sysv/linux/tee.c @@ -22,5 +22,5 @@ ssize_t tee (int src, int dest, size_t len, unsigned int flags) { - return SYSCALL_CANCEL (tee, src, dest, len, flags); + return SYSCALL_CANCEL (tee, src, dest, SYSCALL_ULONG (len), flags); } diff --git a/sysdeps/unix/sysv/linux/vmsplice.c b/sysdeps/unix/sysv/linux/vmsplice.c index 17cc7bf8e7..e338a73944 100644 --- a/sysdeps/unix/sysv/linux/vmsplice.c +++ b/sysdeps/unix/sysv/linux/vmsplice.c @@ -23,5 +23,5 @@ ssize_t vmsplice (int fd, const struct iovec *iov, size_t count, unsigned int flags) { - return SYSCALL_CANCEL (vmsplice, fd, iov, count, flags); + return SYSCALL_CANCEL (vmsplice, fd, iov, SYSCALL_ULONG (count), flags); } diff --git a/sysdeps/unix/sysv/linux/write.c b/sysdeps/unix/sysv/linux/write.c index 7848f7de27..2176572425 100644 --- a/sysdeps/unix/sysv/linux/write.c +++ b/sysdeps/unix/sysv/linux/write.c @@ -23,7 +23,7 @@ ssize_t __libc_write (int fd, const void *buf, size_t nbytes) { - return SYSCALL_CANCEL (write, fd, buf, nbytes); + return SYSCALL_CANCEL (write, fd, buf, SYSCALL_ULONG (nbytes)); } libc_hidden_def (__libc_write) diff --git a/sysdeps/unix/sysv/linux/write_nocancel.c b/sysdeps/unix/sysv/linux/write_nocancel.c index 36d406cf74..17aa7d4797 100644 --- a/sysdeps/unix/sysv/linux/write_nocancel.c +++ b/sysdeps/unix/sysv/linux/write_nocancel.c @@ -23,6 +23,6 @@ ssize_t __write_nocancel (int fd, const void *buf, size_t nbytes) { - return INLINE_SYSCALL_CALL (write, fd, buf, nbytes); + return INLINE_SYSCALL_CALL (write, fd, buf, SYSCALL_ULONG (nbytes)); } hidden_def (__write_nocancel) diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h index 24d8b8ec20..a8a8e95fa5 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h +++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h @@ -57,13 +57,27 @@ # define SYSCALL_ERROR_LABEL syscall_error # endif +# 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, long_arg_1, long_arg_2) \ + .text; \ + ENTRY (name) \ + DO_CALL (syscall_name, args, long_arg_1, long_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 +85,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, long_arg_1, long_arg_2) \ + .text; \ + ENTRY (name) \ + DO_CALL (syscall_name, args, long_arg_1, long_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 +104,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, long_arg_1, long_arg_2) \ + .text; \ + ENTRY (name) \ + DO_CALL (syscall_name, args, long_arg_1, long_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,7 +188,7 @@ Syscalls of more than 6 arguments are not supported. */ # undef DO_CALL -# define DO_CALL(syscall_name, args) \ +# define DO_CALL(syscall_name, args, long_arg_1, long_arg_2) \ DOARGS_##args \ movl $SYS_ify (syscall_name), %eax; \ syscall; diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list b/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list index 58ea31d1fd..dfc551d402 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list +++ b/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list @@ -1,4 +1,14 @@ # File name Caller Syscall name # args Strong name Weak names +madvise - madvise i:pUi __madvise madvise +mincore - mincore i:aUV mincore +mprotect - mprotect i:aUi __mprotect mprotect +mlock - mlock i:bU mlock +mount EXTRA mount i:sssUp __mount mount +mremap EXTRA mremap b:aUUip __mremap mremap +munlock - munlock i:aU munlock +munmap - munmap i:aU __munmap munmap personality EXTRA personality Ei:i __personality personality posix_fadvise64 - fadvise64 Vi:iiii posix_fadvise posix_fadvise64 +remap_file_pages - remap_file_pages i:pUiUi __remap_file_pages remap_file_pages +sendfile - sendfile i:iipU sendfile sendfile64 diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h index 5bf9eed80b..d6898eb080 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h +++ b/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h @@ -26,4 +26,34 @@ #undef LO_HI_LONG #define LO_HI_LONG(val) (val) +/* How to pass pass long/unsigned long (ssize_t/size_t) on syscalls. */ +#undef SYSCALL_LONG +#define SYSCALL_LONG(val) ((int64_t) (val)) +#undef SYSCALL_ULONG +#define SYSCALL_ULONG(val) ((uint64_t) (val)) + +#ifdef __ASSEMBLER__ +# undef DO_CALL +# define DO_CALL(syscall_name, args, long_arg_1, long_arg_2) \ + DOARGS_##args \ + ZERO_EXTEND_##long_arg_1 \ + ZERO_EXTEND_##long_arg_2 \ + movl $SYS_ify (syscall_name), %eax; \ + syscall; + +# define ZERO_EXTEND_0 /* nothing */ +# define ZERO_EXTEND_1 movl %edi, %edi; +# define ZERO_EXTEND_2 movl %esi, %esi; +# define ZERO_EXTEND_3 movl %edx, %edx; +# define ZERO_EXTEND_4 movl %r10d, %r10d; +# define ZERO_EXTEND_5 movl %r8d, %r8d; +# define ZERO_EXTEND_6 movl %r9d, %r9d; + +# if SYSCALL_ULONG_ARG_1 == 4 || SYSCALL_ULONG_ARG_2 == 4 +# undef ZERO_EXTEND_4 +# define ZERO_EXTEND_4 /* nothing */ +# define DOARGS_4 movl %ecx, %r10d; +# endif +#endif /* __ASSEMBLER__ */ + #endif /* linux/x86_64/x32/sysdep.h */