From patchwork Thu Nov 10 16:07:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 60357 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7DDAA3858C52 for ; Thu, 10 Nov 2022 16:07:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7DDAA3858C52 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1668096468; bh=zi19ZD0f3FMkS53p5D5HuAgh6HwszfgLrz6xsJrvm78=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=mFw6EFpWY+dQz7dTBmQEtVgt2+8t2kQlAHUgBw5/P3OEnDv67DmLgG402K23HiNS6 qBLhVivfMMD7GrkCuQKkuBMU70xih74d3n6WI7mZ2b/fbi4RBGTAS6OAUqN4Aq5hve /pUl/DnC6dEcjFrK1jplOquqqc4nAEaxCBKH1RbA= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id ADF4E3858D38 for ; Thu, 10 Nov 2022 16:07:24 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org ADF4E3858D38 Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-98-3YBHPQ8xNfWBCdMkL9qnNw-1; Thu, 10 Nov 2022 11:07:23 -0500 X-MC-Unique: 3YBHPQ8xNfWBCdMkL9qnNw-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 45876280D727 for ; Thu, 10 Nov 2022 16:07:22 +0000 (UTC) Received: from oldenburg.str.redhat.com (unknown [10.39.193.5]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 703D54EA48 for ; Thu, 10 Nov 2022 16:07:21 +0000 (UTC) To: libc-alpha@sourceware.org Subject: [PATCH] Linux: Support non-variadic calls to prctl (bug 29770) Date: Thu, 10 Nov 2022 17:07:20 +0100 Message-ID: <878rkiu72f.fsf@oldenburg.str.redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.5 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.0 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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-Patchwork-Original-From: Florian Weimer via Libc-alpha From: Florian Weimer Reply-To: Florian Weimer Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Commit ff026950e280bc3e9487b41b460fb31bc5b57721 ("Add a C wrapper for prctl [BZ #25896]") replaced the assembler wrapper with a C function. However, the C variadic function implementation has a different ABI on powerpc64le-linux-gnu, and now requires calls with a variadic prototype. Therefore, switch to a non-variadic implementation. The internal __prctl is now non-variadic as well. Switch uses in __pthread_getname_np and __pthread_setname_np to direct system calls to avoid casts and the extra arguments. Other callers already supply the extra arguments. For the MIPS usage in elf_machine_reject_phdr_p, supply the extra arguments to __prctl. Visual inspection confirms that the x86-64 x32 version still performs zero extension on the arguments. Tested on aarch64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu, x86_64-linux-gnu. Built with build-many-glibcs.py. --- include/sys/prctl.h | 3 ++- nptl/pthread_getname.c | 2 +- nptl/pthread_setname.c | 2 +- sysdeps/mips/dl-machine-reject-phdr.h | 8 ++++---- sysdeps/unix/sysv/linux/prctl.c | 18 ++++++++++-------- 5 files changed, 18 insertions(+), 15 deletions(-) base-commit: 22a46dee24351fd5f4f188ad80554cad79c82524 diff --git a/include/sys/prctl.h b/include/sys/prctl.h index d33f3a290e..3b9a949a03 100644 --- a/include/sys/prctl.h +++ b/include/sys/prctl.h @@ -3,7 +3,8 @@ # ifndef _ISOMAC -extern int __prctl (int __option, ...); +extern int __prctl (int __option, unsigned long int, unsigned long int, + unsigned long int, unsigned long int); libc_hidden_proto (__prctl) # endif /* !_ISOMAC */ diff --git a/nptl/pthread_getname.c b/nptl/pthread_getname.c index ebec06e23f..8d485d874b 100644 --- a/nptl/pthread_getname.c +++ b/nptl/pthread_getname.c @@ -38,7 +38,7 @@ __pthread_getname_np (pthread_t th, char *buf, size_t len) return ERANGE; if (pd == THREAD_SELF) - return __prctl (PR_GET_NAME, buf) ? errno : 0; + return -INTERNAL_SYSCALL_CALL (prctl, PR_GET_NAME, buf); #define FMT "/proc/self/task/%u/comm" char fname[sizeof (FMT) + 8]; diff --git a/nptl/pthread_setname.c b/nptl/pthread_setname.c index f24560db47..1da548dbbf 100644 --- a/nptl/pthread_setname.c +++ b/nptl/pthread_setname.c @@ -40,7 +40,7 @@ __pthread_setname_np (pthread_t th, const char *name) return ERANGE; if (pd == THREAD_SELF) - return __prctl (PR_SET_NAME, name) ? errno : 0; + return -INTERNAL_SYSCALL_CALL (prctl, PR_SET_NAME, name); #define FMT "/proc/self/task/%u/comm" char fname[sizeof (FMT) + 8]; diff --git a/sysdeps/mips/dl-machine-reject-phdr.h b/sysdeps/mips/dl-machine-reject-phdr.h index 45b6bcaeac..7efd5fc92b 100644 --- a/sysdeps/mips/dl-machine-reject-phdr.h +++ b/sysdeps/mips/dl-machine-reject-phdr.h @@ -169,7 +169,7 @@ elf_machine_reject_phdr_p (const ElfW(Phdr) *phdr, unsigned int phnum, bool cannot_mode_switch = false; /* Get the current hardware mode. */ - cur_mode = __prctl (PR_GET_FP_MODE); + cur_mode = __prctl (PR_GET_FP_MODE, 0, 0, 0, 0); # endif #endif @@ -305,15 +305,15 @@ elf_machine_reject_phdr_p (const ElfW(Phdr) *phdr, unsigned int phnum, /* Set the new mode. Use fr1_mode if the requirements cannot be met by FR0. */ if (!in_req.fr0) - return __prctl (PR_SET_FP_MODE, fr1_mode) != 0; - else if (__prctl (PR_SET_FP_MODE, /* fr0_mode */ 0) != 0) + return __prctl (PR_SET_FP_MODE, fr1_mode, 0, 0, 0) != 0; + else if (__prctl (PR_SET_FP_MODE, /* fr0_mode */ 0, 0, 0, 0) != 0) { /* Setting FR0 can validly fail on an R6 core so retry with the FR1 mode as a fall back. */ if (errno != ENOTSUP) return true; - return __prctl (PR_SET_FP_MODE, fr1_mode) != 0; + return __prctl (PR_SET_FP_MODE, fr1_mode, 0, 0, 0) != 0; } } # endif /* HAVE_PRCTL_FP_MODE */ diff --git a/sysdeps/unix/sysv/linux/prctl.c b/sysdeps/unix/sysv/linux/prctl.c index 25fd968ae2..102d4b0a21 100644 --- a/sysdeps/unix/sysv/linux/prctl.c +++ b/sysdeps/unix/sysv/linux/prctl.c @@ -18,7 +18,15 @@ #include #include + +/* Hide the type information from GCC. The prototype in the installed + header is a variadic function. The non-variadic implementation + below is both more efficient and more compatible because some ABIs + assume additional work performed by the caller for variadic + functions (notably powerpc64le). */ +#define prctl prctl_XXX #include +#undef prctl /* Unconditionally read all potential arguments. This may pass garbage values to the kernel, but avoids the need for teaching @@ -26,15 +34,9 @@ that are added to the kernel in the future). */ int -__prctl (int option, ...) +__prctl (int option, unsigned long int arg2, unsigned long int arg3, + unsigned long int arg4, unsigned long int arg5) { - va_list arg; - va_start (arg, option); - unsigned long int arg2 = va_arg (arg, unsigned long int); - unsigned long int arg3 = va_arg (arg, unsigned long int); - unsigned long int arg4 = va_arg (arg, unsigned long int); - unsigned long int arg5 = va_arg (arg, unsigned long int); - va_end (arg); return INLINE_SYSCALL_CALL (prctl, option, arg2, arg3, arg4, arg5); }