From patchwork Tue May 19 18:05:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 39327 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 42AD13951E5E; Tue, 19 May 2020 18:05:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 42AD13951E5E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1589911536; bh=/lCq7o8XBKOCDnkmDMWzyaYACozAI5IlKvakfssI3P4=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=fe4p852AImNsIg1cnWqSw6WWIOD4zJjqs9R5u6r6kGiHs+cAuHhQhhMQ73DCF4xRb oshHf+72Q0ZgtovqCG3G5c04wiknmK4qUxNIRR4pZkWrbCQVz0lkw9lNlSnfN+CIgq Nj9msh/Z/m6oz0D+56txQWgZgfo6O8hOXiH+kN8g= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qt1-x843.google.com (mail-qt1-x843.google.com [IPv6:2607:f8b0:4864:20::843]) by sourceware.org (Postfix) with ESMTPS id 259F33948496 for ; Tue, 19 May 2020 18:05:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 259F33948496 Received: by mail-qt1-x843.google.com with SMTP id t25so395661qtc.0 for ; Tue, 19 May 2020 11:05:33 -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:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/lCq7o8XBKOCDnkmDMWzyaYACozAI5IlKvakfssI3P4=; b=CTeZZN2dBDl9wcBnxti3UkFeGOnv5Q+eeVfvlYltSELixLU/8t4sL3L9X0iHjj7YW7 t0zK7Ivf2ScizlZynq1/FHHAncZCtyozxxX6NW3yD+lDxvOw/dkNpefCv9N4uT4yAs5a X+mJ9sTDksi+OIYkxuygQqNju/1jWoF6s0Kp2ZNzQ8Qh6kERMw4/EqeViFkwJjil3uf0 QxfE44WgI+vGvSMZHMG8z2VA8TusV9MAo4lHwaso84GX2TxhMgw7ckVc8DSxsnACqDE9 aeisr3/V4Z7+FW57EICXRkLwAtaP1UJSyQSEP8QkrGq/VrqYs4cVaJNIckhdgalrkLtQ OkBA== X-Gm-Message-State: AOAM532K2KhznQK7gm948O9fF+5nuDJ13oPhHfcMVuLPxhyLc3mGvjVT cOBH2ZUj8QzbrO1h7ch5GZ3xJbFzNN4= X-Google-Smtp-Source: ABdhPJyIXeTmP2wYVU3R+8uY/MgJX9SPITzV2muEkbzWJtiXWPKgID5NguX9Um/NjlPLwhh21q44Ng== X-Received: by 2002:aed:2941:: with SMTP id s59mr1033072qtd.385.1589911532082; Tue, 19 May 2020 11:05:32 -0700 (PDT) Received: from localhost.localdomain ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id m6sm230091qkc.4.2020.05.19.11.05.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 May 2020 11:05:31 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH 04/13] linux: Fix __NSIG_WORDS and add __NSIG_BYTES Date: Tue, 19 May 2020 15:05:09 -0300 Message-Id: <20200519180518.318733-5-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200519180518.318733-1-adhemerval.zanella@linaro.org> References: <20200519180518.318733-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-16.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, 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-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" The __NSIG_WORDS value is based on minimum number of words to hold the maximum number of signal supported by the architecture. Maximum number of signals non multiple of word is rounded up. This patch also adds __NSIG_BYTES, which is the number of bytes required to represent the support number of signals. It is used on syscall which takes a sigset_t. Checked on x86_64-linux-gnu and i686-linux-gnu. Tested-by: Carlos O'Donell --- include/signal.h | 2 ++ nptl/nptl-init.c | 2 +- nptl/pthread_sigmask.c | 2 +- sysdeps/unix/sysv/linux/aio_misc.h | 9 ++++++--- sysdeps/unix/sysv/linux/epoll_pwait.c | 2 +- sysdeps/unix/sysv/linux/internal-signals.h | 10 +++++----- sysdeps/unix/sysv/linux/ppoll.c | 7 ++++--- sysdeps/unix/sysv/linux/pselect.c | 2 +- sysdeps/unix/sysv/linux/sigaction.c | 3 ++- sysdeps/unix/sysv/linux/signalfd.c | 2 +- sysdeps/unix/sysv/linux/sigpending.c | 2 +- sysdeps/unix/sysv/linux/sigsetops.h | 18 +++++++++++++----- sysdeps/unix/sysv/linux/sigsuspend.c | 2 +- sysdeps/unix/sysv/linux/sigtimedwait.c | 3 ++- sysdeps/unix/sysv/linux/x86/setjmpP.h | 5 ++--- 15 files changed, 43 insertions(+), 28 deletions(-) diff --git a/include/signal.h b/include/signal.h index ce511cfe60..f79fd5265c 100644 --- a/include/signal.h +++ b/include/signal.h @@ -2,6 +2,8 @@ # include # ifndef _ISOMAC +# include + libc_hidden_proto (sigemptyset) libc_hidden_proto (sigfillset) libc_hidden_proto (sigaddset) diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c index 96b1444a01..ed450a09fd 100644 --- a/nptl/nptl-init.c +++ b/nptl/nptl-init.c @@ -281,7 +281,7 @@ __pthread_initialize_minimal_internal (void) __sigaddset (&sa.sa_mask, SIGCANCEL); __sigaddset (&sa.sa_mask, SIGSETXID); INTERNAL_SYSCALL_CALL (rt_sigprocmask, SIG_UNBLOCK, &sa.sa_mask, - NULL, _NSIG / 8); + NULL, __NSIG_BYTES); /* Get the size of the static and alignment requirements for the TLS block. */ diff --git a/nptl/pthread_sigmask.c b/nptl/pthread_sigmask.c index d266d296c5..7b65ae1f27 100644 --- a/nptl/pthread_sigmask.c +++ b/nptl/pthread_sigmask.c @@ -39,7 +39,7 @@ __pthread_sigmask (int how, const sigset_t *newmask, sigset_t *oldmask) /* We know that realtime signals are available if NPTL is used. */ int result = INTERNAL_SYSCALL_CALL (rt_sigprocmask, how, newmask, - oldmask, _NSIG / 8); + oldmask, __NSIG_BYTES); return (INTERNAL_SYSCALL_ERROR_P (result) ? INTERNAL_SYSCALL_ERRNO (result) diff --git a/sysdeps/unix/sysv/linux/aio_misc.h b/sysdeps/unix/sysv/linux/aio_misc.h index 30c3cd778e..e31ca8edbe 100644 --- a/sysdeps/unix/sysv/linux/aio_misc.h +++ b/sysdeps/unix/sysv/linux/aio_misc.h @@ -31,7 +31,8 @@ __aio_start_notify_thread (void) { sigset_t ss; sigemptyset (&ss); - INTERNAL_SYSCALL_CALL (rt_sigprocmask, SIG_SETMASK, &ss, NULL, _NSIG / 8); + INTERNAL_SYSCALL_CALL (rt_sigprocmask, SIG_SETMASK, &ss, NULL, + __NSIG_BYTES); } extern inline int @@ -52,12 +53,14 @@ __aio_create_helper_thread (pthread_t *threadp, void *(*tf) (void *), sigset_t ss; sigset_t oss; sigfillset (&ss); - INTERNAL_SYSCALL_CALL (rt_sigprocmask, SIG_SETMASK, &ss, &oss, _NSIG / 8); + INTERNAL_SYSCALL_CALL (rt_sigprocmask, SIG_SETMASK, &ss, &oss, + __NSIG_BYTES); int ret = pthread_create (threadp, &attr, tf, arg); /* Restore the signal mask. */ - INTERNAL_SYSCALL_CALL (rt_sigprocmask, SIG_SETMASK, &oss, NULL, _NSIG / 8); + INTERNAL_SYSCALL_CALL (rt_sigprocmask, SIG_SETMASK, &oss, NULL, + __NSIG_BYTES); (void) pthread_attr_destroy (&attr); return ret; diff --git a/sysdeps/unix/sysv/linux/epoll_pwait.c b/sysdeps/unix/sysv/linux/epoll_pwait.c index 66f04482c7..af6d0fd713 100644 --- a/sysdeps/unix/sysv/linux/epoll_pwait.c +++ b/sysdeps/unix/sysv/linux/epoll_pwait.c @@ -38,6 +38,6 @@ int epoll_pwait (int epfd, struct epoll_event *events, const sigset_t *set) { return SYSCALL_CANCEL (epoll_pwait, epfd, events, maxevents, - timeout, set, _NSIG / 8); + timeout, set, __NSIG_BYTES); } libc_hidden_def (epoll_pwait) diff --git a/sysdeps/unix/sysv/linux/internal-signals.h b/sysdeps/unix/sysv/linux/internal-signals.h index 3fbd4807d1..35f2de04c5 100644 --- a/sysdeps/unix/sysv/linux/internal-signals.h +++ b/sysdeps/unix/sysv/linux/internal-signals.h @@ -68,7 +68,7 @@ static inline void __libc_signal_block_all (sigset_t *set) { INTERNAL_SYSCALL_CALL (rt_sigprocmask, SIG_BLOCK, &sigall_set, set, - _NSIG / 8); + __NSIG_BYTES); } /* Block all application signals (excluding internal glibc ones). */ @@ -78,7 +78,7 @@ __libc_signal_block_app (sigset_t *set) sigset_t allset = sigall_set; __clear_internal_signals (&allset); INTERNAL_SYSCALL_CALL (rt_sigprocmask, SIG_BLOCK, &allset, set, - _NSIG / 8); + __NSIG_BYTES); } /* Block only SIGTIMER and return the previous set on SET. */ @@ -86,7 +86,7 @@ static inline void __libc_signal_block_sigtimer (sigset_t *set) { INTERNAL_SYSCALL_CALL (rt_sigprocmask, SIG_BLOCK, &sigtimer_set, set, - _NSIG / 8); + __NSIG_BYTES); } /* Unblock only SIGTIMER and return the previous set on SET. */ @@ -94,7 +94,7 @@ static inline void __libc_signal_unblock_sigtimer (sigset_t *set) { INTERNAL_SYSCALL_CALL (rt_sigprocmask, SIG_UNBLOCK, &sigtimer_set, set, - _NSIG / 8); + __NSIG_BYTES); } /* Restore current process signal mask. */ @@ -102,7 +102,7 @@ static inline void __libc_signal_restore_set (const sigset_t *set) { INTERNAL_SYSCALL_CALL (rt_sigprocmask, SIG_SETMASK, set, NULL, - _NSIG / 8); + __NSIG_BYTES); } /* Used to communicate with signal handler. */ diff --git a/sysdeps/unix/sysv/linux/ppoll.c b/sysdeps/unix/sysv/linux/ppoll.c index 4ffb23710e..0f15636cce 100644 --- a/sysdeps/unix/sysv/linux/ppoll.c +++ b/sysdeps/unix/sysv/linux/ppoll.c @@ -41,11 +41,12 @@ __ppoll64 (struct pollfd *fds, nfds_t nfds, const struct __timespec64 *timeout, # ifndef __NR_ppoll_time64 # define __NR_ppoll_time64 __NR_ppoll # endif - return SYSCALL_CANCEL (ppoll_time64, fds, nfds, timeout, sigmask, _NSIG / 8); + return SYSCALL_CANCEL (ppoll_time64, fds, nfds, timeout, sigmask, + __NSIG_BYTES); #else # ifdef __NR_ppoll_time64 int ret = SYSCALL_CANCEL (ppoll_time64, fds, nfds, timeout, sigmask, - _NSIG / 8); + __NSIG_BYTES); if (ret >= 0 || errno != ENOSYS) return ret; # endif @@ -62,7 +63,7 @@ __ppoll64 (struct pollfd *fds, nfds_t nfds, const struct __timespec64 *timeout, } return SYSCALL_CANCEL (ppoll, fds, nfds, timeout ? &ts32 : NULL, sigmask, - _NSIG / 8); + __NSIG_BYTES); #endif } diff --git a/sysdeps/unix/sysv/linux/pselect.c b/sysdeps/unix/sysv/linux/pselect.c index d7c6ff8fdb..304db03338 100644 --- a/sysdeps/unix/sysv/linux/pselect.c +++ b/sysdeps/unix/sysv/linux/pselect.c @@ -43,7 +43,7 @@ __pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, } data; data.ss = (__syscall_ulong_t) (uintptr_t) sigmask; - data.ss_len = _NSIG / 8; + data.ss_len = __NSIG_BYTES; return SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, exceptfds, timeout, &data); diff --git a/sysdeps/unix/sysv/linux/sigaction.c b/sysdeps/unix/sysv/linux/sigaction.c index 4e6d11a6ae..f27349d552 100644 --- a/sysdeps/unix/sysv/linux/sigaction.c +++ b/sysdeps/unix/sysv/linux/sigaction.c @@ -57,7 +57,8 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) real size of the user-level sigset_t. */ result = INLINE_SYSCALL_CALL (rt_sigaction, sig, act ? &kact : NULL, - oact ? &koact : NULL, STUB (act, _NSIG / 8)); + oact ? &koact : NULL, STUB (act, + __NSIG_BYTES)); if (oact && result >= 0) { diff --git a/sysdeps/unix/sysv/linux/signalfd.c b/sysdeps/unix/sysv/linux/signalfd.c index 64d7bccba9..71d91fdde5 100644 --- a/sysdeps/unix/sysv/linux/signalfd.c +++ b/sysdeps/unix/sysv/linux/signalfd.c @@ -24,5 +24,5 @@ int signalfd (int fd, const sigset_t *mask, int flags) { - return INLINE_SYSCALL (signalfd4, 4, fd, mask, _NSIG / 8, flags); + return INLINE_SYSCALL (signalfd4, 4, fd, mask, __NSIG_BYTES, flags); } diff --git a/sysdeps/unix/sysv/linux/sigpending.c b/sysdeps/unix/sysv/linux/sigpending.c index 458a3cf99e..8898fe8b34 100644 --- a/sysdeps/unix/sysv/linux/sigpending.c +++ b/sysdeps/unix/sysv/linux/sigpending.c @@ -24,5 +24,5 @@ int sigpending (sigset_t *set) { - return INLINE_SYSCALL (rt_sigpending, 2, set, _NSIG / 8); + return INLINE_SYSCALL_CALL (rt_sigpending, set, __NSIG_BYTES); } diff --git a/sysdeps/unix/sysv/linux/sigsetops.h b/sysdeps/unix/sysv/linux/sigsetops.h index db8f378cf0..3f29ead009 100644 --- a/sysdeps/unix/sysv/linux/sigsetops.h +++ b/sysdeps/unix/sysv/linux/sigsetops.h @@ -20,23 +20,31 @@ #define _SIGSETOPS_H 1 #include +#include +#include /* Return a mask that includes the bit for SIG only. */ -# define __sigmask(sig) \ - (((unsigned long int) 1) << (((sig) - 1) % (8 * sizeof (unsigned long int)))) +#define __sigmask(sig) \ + (1UL << (((sig) - 1) % ULONG_WIDTH)) /* Return the word index for SIG. */ static inline unsigned long int __sigword (int sig) { - return (sig - 1) / (8 * sizeof (unsigned long int)); + return (sig - 1) / ULONG_WIDTH; } /* Linux sig* functions only handle up to __NSIG_WORDS words instead of full _SIGSET_NWORDS sigset size. The signal numbers are 1-based, and bit 0 of a signal mask is for signal 1. */ - -# define __NSIG_WORDS (_NSIG / (8 * sizeof (unsigned long int ))) +#define __NSIG_WORDS (ALIGN_UP ((_NSIG - 1), ULONG_WIDTH) / ULONG_WIDTH) +_Static_assert (__NSIG_WORDS <= _SIGSET_NWORDS, + "__NSIG_WORDS > _SIGSET_WORDS"); + +/* This macro is used on syscall that takes a sigset_t to specify the expected + size in bytes. As for glibc, kernel sigset is implemented as an array of + unsigned long. */ +#define __NSIG_BYTES (__NSIG_WORDS * (ULONG_WIDTH / UCHAR_WIDTH)) static inline void __sigemptyset (sigset_t *set) diff --git a/sysdeps/unix/sysv/linux/sigsuspend.c b/sysdeps/unix/sysv/linux/sigsuspend.c index dd5df5af25..b4bf2ec4bc 100644 --- a/sysdeps/unix/sysv/linux/sigsuspend.c +++ b/sysdeps/unix/sysv/linux/sigsuspend.c @@ -23,7 +23,7 @@ int __sigsuspend (const sigset_t *set) { - return SYSCALL_CANCEL (rt_sigsuspend, set, _NSIG / 8); + return SYSCALL_CANCEL (rt_sigsuspend, set, __NSIG_BYTES); } libc_hidden_def (__sigsuspend) weak_alias (__sigsuspend, sigsuspend) diff --git a/sysdeps/unix/sysv/linux/sigtimedwait.c b/sysdeps/unix/sysv/linux/sigtimedwait.c index 6b3d8f705f..f2ef3aad45 100644 --- a/sysdeps/unix/sysv/linux/sigtimedwait.c +++ b/sysdeps/unix/sysv/linux/sigtimedwait.c @@ -26,7 +26,8 @@ __sigtimedwait (const sigset_t *set, siginfo_t *info, { /* XXX The size argument hopefully will have to be changed to the real size of the user-level sigset_t. */ - int result = SYSCALL_CANCEL (rt_sigtimedwait, set, info, timeout, _NSIG / 8); + int result = SYSCALL_CANCEL (rt_sigtimedwait, set, info, timeout, + __NSIG_BYTES); /* The kernel generates a SI_TKILL code in si_code in case tkill is used. tkill is transparently used in raise(). Since having diff --git a/sysdeps/unix/sysv/linux/x86/setjmpP.h b/sysdeps/unix/sysv/linux/x86/setjmpP.h index 1783b8eb78..a5de31bfd6 100644 --- a/sysdeps/unix/sysv/linux/x86/setjmpP.h +++ b/sysdeps/unix/sysv/linux/x86/setjmpP.h @@ -21,6 +21,7 @@ #include #include +#include /* has @@ -113,11 +114,9 @@ typedef union #include -#define _SIGPROCMASK_NSIG_WORDS (_NSIG / (8 * sizeof (unsigned long int))) - typedef struct { - unsigned long int __val[_SIGPROCMASK_NSIG_WORDS]; + unsigned long int __val[__NSIG_WORDS]; } __sigprocmask_sigset_t; extern jmp_buf ___buf;