From patchwork Fri Nov 17 20:34:43 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 119226 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp973327qgn; Fri, 17 Nov 2017 12:35:36 -0800 (PST) X-Google-Smtp-Source: AGs4zMYrGOBMiEw8y0T2Wfjw2X5mvS9WTkPgu32BYc8hQgh36QkwXAckSI6WcP1de8DpfKzN6nNJ X-Received: by 10.84.253.1 with SMTP id z1mr2493669pll.115.1510950936412; Fri, 17 Nov 2017 12:35:36 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1510950936; cv=none; d=google.com; s=arc-20160816; b=lVNYqnCwbR/D8kyjHcO1XxxgvUAeP3e5ptS9cIIZrKa9/gHn+gG/0l41GR9qT+emfw QNEwlFU3ByDSkfdcznNE2Not+NrXlvP75abYWLAp/sq25Sprm8uMcwz1VHH6YNtWvtFx aOy4sTS/1HwZvOgWKuOTUFN4xmCAI71TtuqFdofkaAAiI3FouuFcjUBpoGnq+BRuCoeQ KXH8r1lZBqbfu8JPy+6ZlU8uvLOnMmyelkp/CxlO561MiWJhqhe4FyDf7jldkflka5HO 4ffZWsE36CsrUQEYI7wnkqWTs4bcvJkFZ9Wwc5pyT/uAFQJpR5U6RiyaWpGKp9GTgC7a 7SWw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=message-id:date:subject:to:from:delivered-to:sender:list-help :list-post:list-archive:list-subscribe:list-unsubscribe:list-id :precedence:mailing-list:dkim-signature:domainkey-signature :arc-authentication-results; bh=+gShmSULd16gS49YSmDvgpGR7Ltx/Le+TiUfNSDcv+8=; b=xH8j1DNEdb+/u3QTHJFCpef/k7DzN0QHNPa+Jn29/oOxz52h3vzDzfRLX+DvGWXZc6 753dyU5rQJr8WzKC8S9NgFh8H/DytkDOLG08TgGd97UzmtfpFdvIjkikPoe+qJQAMaWw Hg2dQSMP48rvHhgBrbxEfQmqOK6j3ultxDEUoLiYLoUq7VVZhrbmvqzg1YeOZ4FRPjOt NQ1Hs0/Omm02W1cHCTbE2reVDQhT2GU1vzJrs1VAFz2ZW2Jj2tBsJK4zTPMEgHLSS6rt dtHYGTWkWazmXpIJyexaHKk/ToCLynl45v5GAV9L+1kXtOmnOaB36J/8IKOsJ1t+JNet dqCw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=mhvawbto; spf=pass (google.com: domain of libc-alpha-return-87233-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-87233-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id 92si3346608pli.692.2017.11.17.12.35.36 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 17 Nov 2017 12:35:36 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-87233-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=mhvawbto; spf=pass (google.com: domain of libc-alpha-return-87233-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-87233-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id; q=dns; s= default; b=bo2jpatat0KkJ3RGyCZcMUaGpQtEXIM5rO3exAwL9KCabeYd/wAmq CShCCfJbhURuO/Tk/wdWx9JQqrdF1MgjmUQ3u3pQ5KuP5iK3ZnYkWIWWn7ac3sN9 I5xIhKMQAFPlyS0beXZejN3NOB+UeQLWNcNuP2ccCqu1YuInyMK70U= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id; s=default; bh=x4z9ldjOO2RX0+0b8DnKVgPD/qM=; b=mhvawbtos0qryRjqIv7bN3M6vt2A rEDCaDxP7A1MBnZpJhqpjxJcwjt7+2wm61Z+Djjig3DcMxVTb4aHMwgSO/g1zpj2 nNy0aV0aIfIXT1P8VKEF5Xvh3aFEPcVjTVYMxxXYDu2LSOh1obmqjWLxMRgydmco FCNv5ucqKpMniBY= Received: (qmail 64527 invoked by alias); 17 Nov 2017 20:35:01 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 64444 invoked by uid 89); 17 Nov 2017 20:35:01 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, KB_WAM_FROM_NAME_SINGLEWORD, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=intimate, goodbye, hardly X-HELO: mail-qt0-f172.google.com 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; bh=+gShmSULd16gS49YSmDvgpGR7Ltx/Le+TiUfNSDcv+8=; b=ByAZAlCGP7Ey7siLbM3L/zbV2rAtGA/qbC/VEtvcHvr+PDeHDm1L031ib9KQX3EJuw dJ6IXsLJN7z+gwn1vj2d/yFGQTD2feSTnqVEvEUTRF7OxvEXfz3NWl6/ETHzzDW7QT9e l9kynPexU811FR7SmJCLsij0pieGB9fK0vtZS2LssNoLsMbJo1tx8CanWJZOsPJNnpsk A8VGEoxmYl/5n9tNQIxVFrt+OrO8U3QZW0FwAf/GFy1NELFoTdSRLfOZ/shmhitQ6di5 K8wi6t8Sbl0caGHfhMKO9dmxr91ThRJ87y9V1U3UF2f6w4JREvwjRV8LOX+An2vfCb0s xYqw== X-Gm-Message-State: AJaThX5NAgGJlYTsvkETJxb+/aVRZrct25oNNsKOhA+UoJDi6yowxnEt T+yfezqDzDmkMvjsdSaq1gvB7ElKMP4= X-Received: by 10.200.47.220 with SMTP id m28mr2605338qta.146.1510950892614; Fri, 17 Nov 2017 12:34:52 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 1/2] linux: Consolidate sigaction implementation Date: Fri, 17 Nov 2017 18:34:43 -0200 Message-Id: <1510950884-1969-1-git-send-email-adhemerval.zanella@linaro.org> This patch consolidates all Linux sigaction implementation on a default one at sysdeps/unix/sysv/linux/sigaction.c. The idea is remove redundant code and simplify new ports addition by following the current generic Linux User API (UAPI). The UAPI for new ports defines a generic extensible sigaction struct as: struct sigaction { __sighandler_t sa_handler; unsigned long sa_flags; #ifdef SA_RESTORER void (*sa_restorer) (void); #endif sigset_t sa_mask; }; Where SA_RESTORER is just placed to compatibility reasons, news ports should not add it. A similar definition is used on generic kernel_sigaction.h. The user exported sigaction definition is not changed, so for most architectures it requires an adjustment to kernel expected one for the syscall. The main changes are: - All architectures now define and use a kernel_sigaction struct meant for the syscall, even for the architectures where the user sigaction has the same layout of the kernel expected one (s390-64 and ia64). Although it requires more work for these architectures, it simplifies the generic implementation. Also, sigaction is hardly a hotspot where micro optimization would play an important role. - The generic kernel_sigaction definition is now aligned with expected UAPI one for newer ports, where SA_RESTORER and sa_restorer is not expected to be defined. This means adding kernel_sigaction for current architectures that does define it (m68k, nios2, powerpc, s390, sh, sparc, and tile) and which rely on previous generic definition. - Remove old MIPS usage of sa_restorer. This was removed since 2.6.27 (2957c9e61ee9c - "[MIPS] IRIX: Goodbye and thanks for all the fish"). So for new ports the generic implementation should work if its uses Linux UAPI. If SA_RESTORER is still required (due some architecture limitation), it should define its own kernel_sigaction.h, define it and include generic header (assuming it still uses the default generic kernel layout). Checked on x86_64-linux-gnu, i686-linux-gnu, arm-linux-gnueabihf, aarch64-linux-gnu, sparc64-linux-gnu, sparcv9-linux-gnu, powerpc-linux-gnu, and powerpc64-linux-gnu. I also check the build on all remaining affected ABIs. * sysdeps/unix/sysv/linux/aarch64/sigaction.c: Use default Linux version as base implementation. * sysdeps/unix/sysv/linux/arm/sigaction.c: Likewise. * sysdeps/unix/sysv/linux/i386/sigaction.c: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c: Likewise. * sysdeps/unix/sysv/linux/x86_64/sigaction.c: Likewise. * sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h: Add include guards, remove unrequired definitions and update comments. * sysdeps/unix/sysv/linux/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/mips/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h: New file. * sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/powerpc/kernel_sigaction: Likewise. * sysdeps/unix/sysv/linux/s390/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/sh/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/tile/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/ia64/sigaction.c: Remove file. * sysdeps/unix/sysv/linux/mips/sigaction.c: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c: Likewise. * sysdeps/unix/sysv/linux/sigaction.c: Add STUB, SET_SA_RESTORER, and RESET_SA_RESTORER hooks. Signed-off-by: Adhemerval Zanella --- ChangeLog | 27 +++++ sysdeps/unix/sysv/linux/aarch64/sigaction.c | 58 ++--------- sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h | 21 ++-- sysdeps/unix/sysv/linux/arm/sigaction.c | 79 +++----------- sysdeps/unix/sysv/linux/i386/sigaction.c | 76 +++----------- sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h | 6 ++ sysdeps/unix/sysv/linux/ia64/sigaction.c | 45 -------- sysdeps/unix/sysv/linux/kernel_sigaction.h | 31 +++--- sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h | 22 ++++ sysdeps/unix/sysv/linux/mips/kernel_sigaction.h | 48 ++------- sysdeps/unix/sysv/linux/mips/sigaction.c | 116 --------------------- sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h | 8 ++ sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h | 8 ++ sysdeps/unix/sysv/linux/s390/kernel_sigaction.h | 28 +++++ sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c | 43 -------- sysdeps/unix/sysv/linux/sh/kernel_sigaction.h | 8 ++ sysdeps/unix/sysv/linux/sigaction.c | 28 ++--- sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h | 10 ++ sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c | 41 +------- sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c | 43 +------- sysdeps/unix/sysv/linux/tile/kernel_sigaction.h | 9 ++ sysdeps/unix/sysv/linux/x86_64/sigaction.c | 61 ++--------- 22 files changed, 232 insertions(+), 584 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h delete mode 100644 sysdeps/unix/sysv/linux/ia64/sigaction.c create mode 100644 sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h delete mode 100644 sysdeps/unix/sysv/linux/mips/sigaction.c create mode 100644 sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h create mode 100644 sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h create mode 100644 sysdeps/unix/sysv/linux/s390/kernel_sigaction.h delete mode 100644 sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c create mode 100644 sysdeps/unix/sysv/linux/sh/kernel_sigaction.h create mode 100644 sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h create mode 100644 sysdeps/unix/sysv/linux/tile/kernel_sigaction.h -- 2.7.4 diff --git a/sysdeps/unix/sysv/linux/aarch64/sigaction.c b/sysdeps/unix/sysv/linux/aarch64/sigaction.c index 7cbb056..1eaf1d0 100644 --- a/sysdeps/unix/sysv/linux/aarch64/sigaction.c +++ b/sysdeps/unix/sysv/linux/aarch64/sigaction.c @@ -1,5 +1,4 @@ /* Copyright (C) 1997-2017 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 @@ -16,55 +15,16 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include - -#include -#include - +/* Required for AArch32 compatibility. */ #define SA_RESTORER 0x04000000 -/* The difference here is that the sigaction structure used in the - kernel is not the same as we use in the libc. Therefore we must - translate it here. */ -#include - -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - int result; - struct kernel_sigaction kact; - struct kernel_sigaction koact; - - if (act) - { - kact.k_sa_handler = act->sa_handler; - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); - kact.sa_flags = act->sa_flags; -#ifdef HAVE_SA_RESTORER - if (kact.sa_flags & SA_RESTORER) - kact.sa_restorer = act->sa_restorer; -#endif - } +#define SET_SA_RESTORER(kact, act) \ + ({ \ + if ((kact)->sa_flags & SA_RESTORER) \ + (kact)->sa_restorer = (act)->sa_restorer; \ + }) - result = INLINE_SYSCALL (rt_sigaction, 4, sig, - act ? &kact : NULL, - oact ? &koact : NULL, _NSIG / 8); - if (result >= 0 || errno != ENOSYS) - { - if (oact && result >= 0) - { - oact->sa_handler = koact.k_sa_handler; - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); - oact->sa_flags = koact.sa_flags; -#ifdef HAVE_SA_RESTORER - oact->sa_restorer = koact.sa_restorer; -#endif - } - } - return result; -} -libc_hidden_def (__libc_sigaction) +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer; -#include +#include diff --git a/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h b/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h index 4c35d96..25180ff 100644 --- a/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h +++ b/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h @@ -1,15 +1,12 @@ -/* This is the sigaction struction from the Linux 2.1.20 kernel. */ +#ifndef _KERNEL_SIGACTION_H +# define _KERNEL_SIGACTION_H -struct old_kernel_sigaction { - __sighandler_t k_sa_handler; - unsigned long sa_mask; - unsigned int sa_flags; +/* This is the sigaction structure from the Linux 3.2 kernel. */ +struct kernel_sigaction +{ + __sighandler_t k_sa_handler; + unsigned int sa_flags; + sigset_t sa_mask; }; -/* This is the sigaction structure from the Linux 2.1.68 kernel. */ - -struct kernel_sigaction { - __sighandler_t k_sa_handler; - unsigned int sa_flags; - sigset_t sa_mask; -}; +#endif diff --git a/sysdeps/unix/sysv/linux/arm/sigaction.c b/sysdeps/unix/sysv/linux/arm/sigaction.c index e4c0d97..b7b141a 100644 --- a/sysdeps/unix/sysv/linux/arm/sigaction.c +++ b/sysdeps/unix/sysv/linux/arm/sigaction.c @@ -15,70 +15,25 @@ License along with the GNU C Library. If not, see . */ -#include -#include -#include - -#include -#include - -/* The difference here is that the sigaction structure used in the - kernel is not the same as we use in the libc. Therefore we must - translate it here. */ -#include - #define SA_RESTORER 0x04000000 extern void __default_sa_restorer (void); extern void __default_rt_sa_restorer (void); -/* When RT signals are in use we need to use a different return stub. */ -#define choose_restorer(flags) \ - (flags & SA_SIGINFO) ? __default_rt_sa_restorer \ - : __default_sa_restorer - -/* If ACT is not NULL, change the action for SIG to *ACT. - If OACT is not NULL, put the old action for SIG in *OACT. */ -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - int result; - - struct kernel_sigaction kact, koact; - - if (act) - { - kact.k_sa_handler = act->sa_handler; - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); - kact.sa_flags = act->sa_flags; -#ifdef HAVE_SA_RESTORER - if (kact.sa_flags & SA_RESTORER) - kact.sa_restorer = act->sa_restorer; - else - { - kact.sa_restorer = choose_restorer (kact.sa_flags); - kact.sa_flags |= SA_RESTORER; - } -#endif - } - - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - result = INLINE_SYSCALL (rt_sigaction, 4, sig, - act ? &kact : NULL, - oact ? &koact : NULL, _NSIG / 8); - - if (oact && result >= 0) - { - oact->sa_handler = koact.k_sa_handler; - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); - oact->sa_flags = koact.sa_flags; -#ifdef HAVE_SA_RESTORER - oact->sa_restorer = koact.sa_restorer; -#endif - } - return result; -} -libc_hidden_def (__libc_sigaction) - -#include +#define SET_SA_RESTORER(kact, act) \ + ({ \ + if ((kact)->sa_flags & SA_RESTORER) \ + (kact)->sa_restorer = (act)->sa_restorer; \ + else \ + { \ + (kact)->sa_restorer = ((kact)->sa_flags & SA_SIGINFO) \ + ? __default_rt_sa_restorer \ + : __default_sa_restorer; \ + (kact)->sa_flags |= SA_RESTORER; \ + } \ + }) + +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer; + +#include diff --git a/sysdeps/unix/sysv/linux/i386/sigaction.c b/sysdeps/unix/sysv/linux/i386/sigaction.c index 0cc9d67..041b094 100644 --- a/sysdeps/unix/sysv/linux/i386/sigaction.c +++ b/sysdeps/unix/sysv/linux/i386/sigaction.c @@ -16,78 +16,28 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include #include -#include - -#include -#include #include -/* The difference here is that the sigaction structure used in the - kernel is not the same as we use in the libc. Therefore we must - translate it here. */ -#include - -/* We do not globally define the SA_RESTORER flag so do it here. */ #define SA_RESTORER 0x04000000 - -/* Using the hidden attribute here does not change the code but it - helps to avoid warnings. */ -#ifdef __NR_rt_sigaction extern void restore_rt (void) asm ("__restore_rt") attribute_hidden; -#endif extern void restore (void) asm ("__restore") attribute_hidden; +#define SET_SA_RESTORER(kact, act) \ + ({ \ + if (GLRO(dl_sysinfo_dso) == NULL) \ + { \ + (kact)->sa_flags |= SA_RESTORER; \ + (kact)->sa_restorer = (((act)->sa_flags & SA_SIGINFO) \ + ? &restore_rt : &restore); \ + } \ + }) -/* If ACT is not NULL, change the action for SIG to *ACT. - If OACT is not NULL, put the old action for SIG in *OACT. */ -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - int result; - - struct kernel_sigaction kact, koact; - - if (act) - { - kact.k_sa_handler = act->sa_handler; - kact.sa_flags = act->sa_flags; - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); - - if (GLRO(dl_sysinfo_dso) == NULL) - { - kact.sa_flags |= SA_RESTORER; - - kact.sa_restorer = ((act->sa_flags & SA_SIGINFO) - ? &restore_rt : &restore); - } - } - - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - INTERNAL_SYSCALL_DECL (err); - result = INTERNAL_SYSCALL (rt_sigaction, err, 4, - sig, act ? &kact : NULL, - oact ? &koact : NULL, _NSIG / 8); - if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err))) - return INLINE_SYSCALL_ERROR_RETURN_VALUE (INTERNAL_SYSCALL_ERRNO (result, - err)); - else if (oact && result >= 0) - { - oact->sa_handler = koact.k_sa_handler; - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); - oact->sa_flags = koact.sa_flags; - oact->sa_restorer = koact.sa_restorer; - } - return result; -} -libc_hidden_def (__libc_sigaction) +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer -#include +#include /* NOTE: Please think twice before making any changes to the bits of code below. GDB needs some intimate knowledge about it to @@ -108,10 +58,8 @@ asm \ " int $0x80" \ ); -#ifdef __NR_rt_sigaction /* The return code for realtime-signals. */ RESTORE (restore_rt, __NR_rt_sigreturn) -#endif /* For the boring old signals. */ #undef RESTORE2 diff --git a/sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h b/sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h new file mode 100644 index 0000000..05813db --- /dev/null +++ b/sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h @@ -0,0 +1,6 @@ +/* This is the sigaction structure from the Linux 3.2 kernel. */ +struct kernel_sigaction { + __sighandler_t k_sa_handler; + unsigned long sa_flags; + sigset_t sa_mask; /* mask last for extensibility */ +}; diff --git a/sysdeps/unix/sysv/linux/ia64/sigaction.c b/sysdeps/unix/sysv/linux/ia64/sigaction.c deleted file mode 100644 index 125ce44..0000000 --- a/sysdeps/unix/sysv/linux/ia64/sigaction.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 1997-2017 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Linux/IA64 specific sigaction - Written by Jes Sorensen, , April 1999. - - 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 - . */ - -/* Linux/ia64 only has rt signals, thus we do not even want to try falling - back to the old style signals as the default Linux handler does. */ - -#include -#include -#include - -#include -#include - -/* The variable is shared between all wrappers around signal handling - functions which have RT equivalents. This is the definition. */ - - -/* If ACT is not NULL, change the action for SIG to *ACT. - If OACT is not NULL, put the old action for SIG in *OACT. */ -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - return INLINE_SYSCALL (rt_sigaction, 4, sig, act, oact, _NSIG / 8); -} -libc_hidden_def (__libc_sigaction) - -#include diff --git a/sysdeps/unix/sysv/linux/kernel_sigaction.h b/sysdeps/unix/sysv/linux/kernel_sigaction.h index d005cbc..2dbec08 100644 --- a/sysdeps/unix/sysv/linux/kernel_sigaction.h +++ b/sysdeps/unix/sysv/linux/kernel_sigaction.h @@ -1,19 +1,20 @@ -/* This is the sigaction structure from the Linux 2.1.20 kernel. */ +#ifndef _KERNEL_SIGACTION_H +# define _KERNEL_SIGACTION_H -#define HAVE_SA_RESTORER - -struct old_kernel_sigaction { - __sighandler_t k_sa_handler; - unsigned long sa_mask; - unsigned long sa_flags; - void (*sa_restorer) (void); +/* This is the sigaction structure from the Linux 3.2 kernel. */ +struct kernel_sigaction +{ + __sighandler_t k_sa_handler; + unsigned long sa_flags; +#ifdef SA_RESTORER + void (*sa_restorer) (void); +#endif + sigset_t sa_mask; }; -/* This is the sigaction structure from the Linux 2.1.68 kernel. */ +#ifndef SA_RESTORER +# define SET_SA_RESTORER(kact, act) +# define RESET_SA_RESTORER(act, kact) +#endif -struct kernel_sigaction { - __sighandler_t k_sa_handler; - unsigned long sa_flags; - void (*sa_restorer) (void); - sigset_t sa_mask; -}; +#endif diff --git a/sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h b/sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h new file mode 100644 index 0000000..54972fe --- /dev/null +++ b/sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h @@ -0,0 +1,22 @@ +#ifndef _KERNEL_SIGACTION_H +# define _KERNEL_SIGACTION_H + +#include + +#define SA_RESTORER 0x04000000 + +/* This is the sigaction structure from the Linux 3.2 kernel. */ +struct kernel_sigaction +{ + __sighandler_t k_sa_handler; + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer) (void); +}; + +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_restorer = (act)->sa_restorer +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer + +#endif diff --git a/sysdeps/unix/sysv/linux/mips/kernel_sigaction.h b/sysdeps/unix/sysv/linux/mips/kernel_sigaction.h index b6f52cc..beef976 100644 --- a/sysdeps/unix/sysv/linux/mips/kernel_sigaction.h +++ b/sysdeps/unix/sysv/linux/mips/kernel_sigaction.h @@ -1,40 +1,12 @@ -/* This is the sigaction structure from the Linux 2.1.24 kernel. */ - -#include - -#define HAVE_SA_RESTORER - -struct old_kernel_sigaction { - unsigned int sa_flags; - __sighandler_t k_sa_handler; - unsigned long sa_mask; - unsigned int __pad0[3]; /* reserved, keep size constant */ - - /* Abi says here follows reserved int[2] */ - void (*sa_restorer)(void); -#if (_MIPS_SZPTR < 64) - /* - * For 32 bit code we have to pad struct sigaction to get - * constant size for the ABI - */ - int pad1[1]; /* reserved */ -#endif +#ifndef _KERNEL_SIGACTION_H +# define _KERNEL_SIGACTION_H + +/* This is the sigaction structure from the Linux 3.2 kernel. */ +struct kernel_sigaction +{ + unsigned int sa_flags; + __sighandler_t k_sa_handler; + sigset_t sa_mask; }; - -#define _KERNEL_NSIG 128 -#define _KERNEL_NSIG_BPW _MIPS_SZLONG -#define _KERNEL_NSIG_WORDS (_KERNEL_NSIG / _KERNEL_NSIG_BPW) - -typedef struct { - unsigned long sig[_KERNEL_NSIG_WORDS]; -} kernel_sigset_t; - -/* This is the sigaction structure from the Linux 2.1.68 kernel. */ -struct kernel_sigaction { - unsigned int sa_flags; - __sighandler_t k_sa_handler; - kernel_sigset_t sa_mask; - void (*sa_restorer)(void); - int s_resv[1]; /* reserved */ -}; +#endif diff --git a/sysdeps/unix/sysv/linux/mips/sigaction.c b/sysdeps/unix/sysv/linux/mips/sigaction.c deleted file mode 100644 index f6be3f2..0000000 --- a/sysdeps/unix/sysv/linux/mips/sigaction.c +++ /dev/null @@ -1,116 +0,0 @@ -/* Copyright (C) 1997-2017 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 - -#include - -/* The difference here is that the sigaction structure used in the - kernel is not the same as we use in the libc. Therefore we must - translate it here. */ -#include - -#if _MIPS_SIM != _ABIO32 - -# ifdef __NR_rt_sigreturn -static void restore_rt (void) asm ("__restore_rt"); -# endif -# ifdef __NR_sigreturn -static void restore (void) asm ("__restore"); -# endif -#endif - -/* If ACT is not NULL, change the action for SIG to *ACT. - If OACT is not NULL, put the old action for SIG in *OACT. */ -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - int result; - - struct kernel_sigaction kact, koact; - - if (act) - { - kact.k_sa_handler = act->sa_handler; - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (kernel_sigset_t)); - kact.sa_flags = act->sa_flags; -#ifdef HAVE_SA_RESTORER -# if _MIPS_SIM == _ABIO32 - kact.sa_restorer = act->sa_restorer; -# else - kact.sa_restorer = &restore_rt; -# endif -#endif - } - - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - result = INLINE_SYSCALL (rt_sigaction, 4, sig, - act ? &kact : NULL, - oact ? &koact : NULL, - sizeof (kernel_sigset_t)); - - if (oact && result >= 0) - { - oact->sa_handler = koact.k_sa_handler; - memcpy (&oact->sa_mask, &koact.sa_mask, - sizeof (kernel_sigset_t)); - oact->sa_flags = koact.sa_flags; -#ifdef HAVE_SA_RESTORER - oact->sa_restorer = koact.sa_restorer; -#endif - } - return result; -} -libc_hidden_def (__libc_sigaction) - -#include - - -/* NOTE: Please think twice before making any changes to the bits of - code below. GDB needs some intimate knowledge about it to - recognize them as signal trampolines, and make backtraces through - signal handlers work right. Important are both the names - (__restore_rt) and the exact instruction sequence. - If you ever feel the need to make any changes, please notify the - appropriate GDB maintainer. */ - -#define RESTORE(name, syscall) RESTORE2 (name, syscall) -#define RESTORE2(name, syscall) \ -asm \ - ( \ - ".align 4\n" \ - "__" #name ":\n" \ - " li $2, " #syscall "\n" \ - " syscall\n" \ - ); - -/* The return code for realtime-signals. */ -#if _MIPS_SIM != _ABIO32 -# ifdef __NR_rt_sigreturn -RESTORE (restore_rt, __NR_rt_sigreturn) -# endif -# ifdef __NR_sigreturn -RESTORE (restore, __NR_sigreturn) -# endif -#endif diff --git a/sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h b/sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h new file mode 100644 index 0000000..4ada322 --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h @@ -0,0 +1,8 @@ +/* NIOS2 uses the generic Linux UAPI but defines SA_RESTORER. */ +#define SA_RESTORER 0x04000000 +#include + +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_restorer = (act)->sa_restorer +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer diff --git a/sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h b/sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h new file mode 100644 index 0000000..c5213f2 --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h @@ -0,0 +1,8 @@ +/* powerpc kernel sigaction is similar to generic Linux UAPI one. */ +#define SA_RESTORER 0x04000000 +#include + +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_restorer = (act)->sa_restorer +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer diff --git a/sysdeps/unix/sysv/linux/s390/kernel_sigaction.h b/sysdeps/unix/sysv/linux/s390/kernel_sigaction.h new file mode 100644 index 0000000..a8beaf7 --- /dev/null +++ b/sysdeps/unix/sysv/linux/s390/kernel_sigaction.h @@ -0,0 +1,28 @@ +#include + +#define SA_RESTORER 0x04000000 + +/* This is the sigaction structure from the Linux 3.2 kernel. */ +struct kernel_sigaction +{ + union + { + __sighandler_t _sa_handler; + void (*_sa_sigaction)(int, siginfo_t *, void *); + } _u; +#define k_sa_handler _u._sa_handler +#ifndef __s390x__ + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +#else + unsigned long sa_flags; + void (*sa_restorer)(void); + sigset_t sa_mask; +#endif +}; + +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_restorer = (act)->sa_restorer +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c b/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c deleted file mode 100644 index a3de0ea..0000000 --- a/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (C) 2001-2017 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 - . */ - -/* 64 bit Linux for S/390 only has rt signals, thus we do not even want to try - falling back to the old style signals as the default Linux handler does. */ - -#include -#include -#include - -#include -#include - -/* The variable is shared between all wrappers around signal handling - functions which have RT equivalents. This is the definition. */ - - -/* If ACT is not NULL, change the action for SIG to *ACT. - If OACT is not NULL, put the old action for SIG in *OACT. */ -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - return INLINE_SYSCALL (rt_sigaction, 4, sig, act, oact, _NSIG / 8); -} -libc_hidden_def (__libc_sigaction) - -#include diff --git a/sysdeps/unix/sysv/linux/sh/kernel_sigaction.h b/sysdeps/unix/sysv/linux/sh/kernel_sigaction.h new file mode 100644 index 0000000..7ebcd08 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sh/kernel_sigaction.h @@ -0,0 +1,8 @@ +/* SH uses the generic Linux UAPI but defines SA_RESTORER. */ +#define SA_RESTORER 0x04000000 +#include + +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_restorer = (act)->sa_restorer +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer diff --git a/sysdeps/unix/sysv/linux/sigaction.c b/sysdeps/unix/sysv/linux/sigaction.c index c76c937..fb84394 100644 --- a/sysdeps/unix/sysv/linux/sigaction.c +++ b/sysdeps/unix/sysv/linux/sigaction.c @@ -22,11 +22,19 @@ #include #include -/* The difference here is that the sigaction structure used in the - kernel is not the same as we use in the libc. Therefore we must - translate it here. */ +/* New ports should not define the obsolete SA_RESTORER, however some + architecture requires for compat mode and/or due old ABI. */ #include +#ifndef SA_RESTORER +# define SET_SA_RESTORER(kact, act) +# define RESET_SA_RESTORER(act, kact) +#endif + +/* SPARC passes the restore function as an argument to rt_sigaction. */ +#ifndef STUB +# define STUB(act) +#endif /* If ACT is not NULL, change the action for SIG to *ACT. If OACT is not NULL, put the old action for SIG in *OACT. */ @@ -42,25 +50,21 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) kact.k_sa_handler = act->sa_handler; memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); kact.sa_flags = act->sa_flags; -#ifdef HAVE_SA_RESTORER - kact.sa_restorer = act->sa_restorer; -#endif + SET_SA_RESTORER (&kact, act); } /* XXX The size argument hopefully will have to be changed to the real size of the user-level sigset_t. */ - result = INLINE_SYSCALL (rt_sigaction, 4, sig, - act ? &kact : NULL, - oact ? &koact : NULL, _NSIG / 8); + result = INLINE_SYSCALL_CALL (rt_sigaction, sig, + act ? &kact : NULL, + oact ? &koact : NULL, STUB(act) _NSIG / 8); if (oact && result >= 0) { oact->sa_handler = koact.k_sa_handler; memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); oact->sa_flags = koact.sa_flags; -#ifdef HAVE_SA_RESTORER - oact->sa_restorer = koact.sa_restorer; -#endif + RESET_SA_RESTORER (oact, &koact); } return result; } diff --git a/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h b/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h new file mode 100644 index 0000000..bee7e9c --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h @@ -0,0 +1,10 @@ +/* SPARC 'struct __new_sigaction' is similar to generic Linux UAPI with + a sa_restorer field, even though function is passed as an argument + to rt_sigaction syscall. */ +#define SA_RESTORER 0x04000000 +#include + +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_restorer = NULL +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c index 295bfb2..59d06a4 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c @@ -27,43 +27,12 @@ static void __rt_sigreturn_stub (void); static void __sigreturn_stub (void); -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - struct kernel_sigaction kact, koact; - unsigned long stub = 0; - int ret; - - if (act) - { - kact.k_sa_handler = act->sa_handler; - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); - if (((kact.sa_flags = act->sa_flags) & SA_SIGINFO) != 0) - stub = (unsigned long) &__rt_sigreturn_stub; - else - stub = (unsigned long) &__sigreturn_stub; - stub -= 8; - kact.sa_restorer = NULL; - } - - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - ret = INLINE_SYSCALL (rt_sigaction, 5, sig, act ? &kact : 0, - oact ? &koact : 0, stub, _NSIG / 8); - - if (oact && ret >= 0) - { - oact->sa_handler = koact.k_sa_handler; - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); - oact->sa_flags = koact.sa_flags; - oact->sa_restorer = koact.sa_restorer; - } - return ret; -} -libc_hidden_def (__libc_sigaction) - -#include +#define STUB(act) \ + ((unsigned long)((act->sa_flags & SA_SIGINFO) \ + ? &__rt_sigreturn_stub \ + : &__sigreturn_stub) - 8), +#include static inhibit_stack_protector diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c b/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c index 78f8a18..c3c3451 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c @@ -21,50 +21,13 @@ #include #include #include -#include -#include - -#include - -/* SPARC 64bit userland requires a kernel that has rt signals anyway. */ static void __rt_sigreturn_stub (void); -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - int ret; - struct kernel_sigaction kact, koact; - unsigned long stub = ((unsigned long) &__rt_sigreturn_stub) - 8; - - if (act) - { - kact.k_sa_handler = act->sa_handler; - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); - kact.sa_flags = act->sa_flags; - kact.sa_restorer = NULL; - } - - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - ret = INLINE_SYSCALL (rt_sigaction, 5, sig, - act ? &kact : 0, - oact ? &koact : 0, stub, _NSIG / 8); - - if (oact && ret >= 0) - { - oact->sa_handler = koact.k_sa_handler; - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); - oact->sa_flags = koact.sa_flags; - oact->sa_restorer = koact.sa_restorer; - } - - return ret; -} -libc_hidden_def (__libc_sigaction) - -#include +#define STUB(act) \ + (((unsigned long) &__rt_sigreturn_stub) - 8), +#include static inhibit_stack_protector diff --git a/sysdeps/unix/sysv/linux/tile/kernel_sigaction.h b/sysdeps/unix/sysv/linux/tile/kernel_sigaction.h new file mode 100644 index 0000000..a943d52 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tile/kernel_sigaction.h @@ -0,0 +1,9 @@ +/* tile kernel sigaction is similar to generic Linux UAPI one + and SA_RESTORER is used only for binary compatibility. */ +#define SA_RESTORER 0x04000000 +#include + +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_restorer = (act)->sa_restorer +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer diff --git a/sysdeps/unix/sysv/linux/x86_64/sigaction.c b/sysdeps/unix/sysv/linux/x86_64/sigaction.c index be058ba..7924c10 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sigaction.c +++ b/sysdeps/unix/sysv/linux/x86_64/sigaction.c @@ -16,65 +16,20 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include #include -#include - -#include -#include - -/* The difference here is that the sigaction structure used in the - kernel is not the same as we use in the libc. Therefore we must - translate it here. */ -#include - -#include "ucontext_i.h" - -/* We do not globally define the SA_RESTORER flag so do it here. */ #define SA_RESTORER 0x04000000 +#include -/* Using the hidden attribute here does not change the code but it - helps to avoid warnings. */ extern void restore_rt (void) asm ("__restore_rt") attribute_hidden; +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_flags = (act)->sa_flags | SA_RESTORER; \ + (kact)->sa_restorer = &restore_rt -/* If ACT is not NULL, change the action for SIG to *ACT. - If OACT is not NULL, put the old action for SIG in *OACT. */ -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - int result; - struct kernel_sigaction kact, koact; - - if (act) - { - kact.k_sa_handler = act->sa_handler; - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); - kact.sa_flags = act->sa_flags | SA_RESTORER; - - kact.sa_restorer = &restore_rt; - } - - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - result = INLINE_SYSCALL (rt_sigaction, 4, - sig, act ? &kact : NULL, - oact ? &koact : NULL, _NSIG / 8); - if (oact && result >= 0) - { - oact->sa_handler = koact.k_sa_handler; - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); - oact->sa_flags = koact.sa_flags; - oact->sa_restorer = koact.sa_restorer; - } - return result; -} -libc_hidden_def (__libc_sigaction) - -#include +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer +#include /* NOTE: Please think twice before making any changes to the bits of code below. GDB needs some intimate knowledge about it to @@ -93,6 +48,8 @@ libc_hidden_def (__libc_sigaction) a bit tricky. We don't use the gas cfi directives, so that we can reliably add .cfi_signal_frame. */ +#include "ucontext_i.h" + #define do_cfa_expr \ " .byte 0x0f\n" /* DW_CFA_def_cfa_expression */ \ " .uleb128 2f-1f\n" /* length */ \ From patchwork Fri Nov 17 20:34:44 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 119225 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp973086qgn; Fri, 17 Nov 2017 12:35:17 -0800 (PST) X-Google-Smtp-Source: AGs4zMbBjuVjEzlJjDh4JwJdJUgI7xLrYAZD0p6b/Zi7C93WNM+0pvxZP4O+l5UhsBNlECIoSyfe X-Received: by 10.98.166.84 with SMTP id t81mr3294517pfe.196.1510950917286; Fri, 17 Nov 2017 12:35:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1510950917; cv=none; d=google.com; s=arc-20160816; b=Ck27P9V2NvppEw/ORdr/sm2YqEEGeIzOgOW6nuHXI0swuxCudFLjsmCXF6n8PmNbdu 3UC1PjfxX/RcFWqCPAvb1ptnIOBxeOMKH/QvpzVyNGP3ji4QSvEl4tbHCxmsSraxRkNG YsKA79k+YPRnCX70/5Z5SjEpw9g6z7BAA+kexoX6CKYxIJLRDHziLlpV35cA5GEdBrmx mRWtlHywPArolLkNp+LmdikbeCdpxxRHqyx4A8Z3IWmatHmSqpIRXFXq2z5AgPBojrlV tzrimx1Idt5ZJZYTE3e5bQc8jU9/EEONn54QMev7WpEwDwfWNB5yuYsbeMFKexz3hMol Q/dQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from:delivered-to :sender:list-help:list-post:list-archive:list-subscribe :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=5Fe4DNUVmB3mNbY2OJ+rkSDtyN1DvD6VCoalGq5vfO0=; b=zXjvnBQyPpXoMl3F9TuXbNoYxTg8Fp0es4xlNTWnVPcx+PEa1q9guwc80CtKDbPxUe Tv+1pj6EjM3Y46w9/+OCuQuidIt9VsWvcMmsnFZMovJT12mVmfkCtk+BlS0qn107udfS WeDCmHXZ6nIe3YLLMd0JEoYmhsTZ/VFtPUF9NeNnqPFnxr9o91ancbuCPMYyMDwzO04s bidqdLqUx2kpeBSVTpzVbouIVLuZ8Q5mTjaQSHyAF7SNOOgTj7kBdabTkzg0h3UH/TO3 A4WpL2Olfd+Hp3oamR7Nq5QgoOW9V8lSm/65X5xwnjJdf8br/7rDrVkXxxIdEzEwcLFK seSA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=vxTZOA9O; spf=pass (google.com: domain of libc-alpha-return-87232-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-87232-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id b5si3244069pgc.623.2017.11.17.12.35.17 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 17 Nov 2017 12:35:17 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-87232-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=vxTZOA9O; spf=pass (google.com: domain of libc-alpha-return-87232-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-87232-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=FFhM2OCnmkYzCOtArADvKAQQnBmdjmb XN4OYdXHIweY/u6TPRYy/xBg73u2034JVrNibTq7VNJhCqPvIvNxVwwSsTAn8wCG ZYNAUIi6JB77tPi3AQmHlkh1DOb/iSGNScNr1EXPKQqXzU4Wpn18ME3WAIbBk0JH utTmEyScoLS0= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; s=default; bh=A1KAA8GEdd0jo1pW0AG5q1/LjVM=; b=vxTZO A9OWuZeZ6JLh2izvQnrjb4PzbE0j8sM/ZZcNTp9Rb3IMxDZPf8IC/a9/1wJ3JHos +mtTi5V9K0dAN4xazbdoPPs6dGLUBSDkVNew81FGYEOyCjDxFOGGc2Su2cLVAqNh VigUwvf0uNx90dIMpC9RUct7UwrLUNtYWkGAHY= Received: (qmail 64375 invoked by alias); 17 Nov 2017 20:34:59 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 64366 invoked by uid 89); 17 Nov 2017 20:34:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.2 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, KB_WAM_FROM_NAME_SINGLEWORD, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=ham version=3.3.2 spammy=Fire, H*i:sk:1510950, H*f:sk:1510950, H*MI:sk:1510950 X-HELO: mail-qk0-f196.google.com 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:in-reply-to :references; bh=5Fe4DNUVmB3mNbY2OJ+rkSDtyN1DvD6VCoalGq5vfO0=; b=P6Pb/BIJZtrGRaG/WwMoqJ2xMt4EMDgPbhQLtqFKhRhrOpPK7MvIHgEDI3uvFJnz0m t678pipANRPXlEFmux3uaFWj/BX8hGFw3PzqqCJJqF9Mri2a5kDkUcj3r0D33y+J1UvF 7SJxYU3LwLI/WhScIwEGc5Y9GFn0hjLXKESuIEyZJfeR5jWk3fJwC5+SYWsXyGKCMIL1 I4y42kE5SVlU7w8LLpzTX+/15yfZj5y9eo0+txPRCpzHsr4dIIr3yockGmKXrgXN1qTS TwQGmO1OPUh4Ubux0Bd5X3e62fsgBEVLyyu+ph+Y8+HGC13vLD5tTQLriOtZ9acqrFx7 n24Q== X-Gm-Message-State: AJaThX7CE+R0PBBmf0h/qfRmXsR7UbHAQXdCY/1GcGzKVCKp7mxHQtqU +u/C7l29IUwbdVxwbSEo30Yt9ZK1etU= X-Received: by 10.55.17.72 with SMTP id b69mr10096834qkh.178.1510950893989; Fri, 17 Nov 2017 12:34:53 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 2/2] i386: Fix i386 sigaction sa_restorer initialization (BZ#21269) Date: Fri, 17 Nov 2017 18:34:44 -0200 Message-Id: <1510950884-1969-2-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1510950884-1969-1-git-send-email-adhemerval.zanella@linaro.org> References: <1510950884-1969-1-git-send-email-adhemerval.zanella@linaro.org> This patch fixes the i386 sa_restorer field initialization for sigaction syscall for kernel with vDSO. As described in bug report, x86_32 Linux (and compat on x86_64) interprets SA_RESTORER clear with nonzero sa_restorer as a request for stack switching if the SS segment is 'funny' This means that anything that tries to mix glibc's signal handling with segmentation (for instance through modify_ldt syscall) is randomly broken depending on what values lands in sa_restorer. The testcase added is based on Linux test tools/testing/selftests/x86/ldt_gdt.c, more specifically in do_multicpu_tests function. The main changes are: - C11 atomics instead of plain access. - Remove x86_64 support which simplifies the syscall handling and fallbacks. - Replicate only the test required to trigger the issue. (I added some comments of my understanding of how the testcase is triggering the issue, so if someone with more x86 knowledge could check if I get this right I will be grateful) Checked on i686-linux-gnu. [BZ #21269] * sysdeps/unix/sysv/linux/i386/Makefile (tests): Add tst-bz21269. * sysdeps/unix/sysv/linux/i386/sigaction.c (SET_SA_RESTORER): Clear sa_restorer for vDSO case. * sysdeps/unix/sysv/linux/i386/tst-bz21269.c: New file. Signed-off-by: Adhemerval Zanella --- ChangeLog | 6 + sysdeps/unix/sysv/linux/i386/Makefile | 3 + sysdeps/unix/sysv/linux/i386/sigaction.c | 2 + sysdeps/unix/sysv/linux/i386/tst-bz21269.c | 233 +++++++++++++++++++++++++++++ 4 files changed, 244 insertions(+) create mode 100644 sysdeps/unix/sysv/linux/i386/tst-bz21269.c -- 2.7.4 diff --git a/sysdeps/unix/sysv/linux/i386/Makefile b/sysdeps/unix/sysv/linux/i386/Makefile index 4080b8c..da716e2 100644 --- a/sysdeps/unix/sysv/linux/i386/Makefile +++ b/sysdeps/unix/sysv/linux/i386/Makefile @@ -3,6 +3,9 @@ default-abi := 32 ifeq ($(subdir),misc) sysdep_routines += ioperm iopl vm86 + +tests += tst-bz21269 +$(objpfx)tst-bz21269: $(shared-thread-library) endif ifeq ($(subdir),elf) diff --git a/sysdeps/unix/sysv/linux/i386/sigaction.c b/sysdeps/unix/sysv/linux/i386/sigaction.c index 041b094..4a149ce 100644 --- a/sysdeps/unix/sysv/linux/i386/sigaction.c +++ b/sysdeps/unix/sysv/linux/i386/sigaction.c @@ -32,6 +32,8 @@ extern void restore (void) asm ("__restore") attribute_hidden; (kact)->sa_restorer = (((act)->sa_flags & SA_SIGINFO) \ ? &restore_rt : &restore); \ } \ + else \ + (kact)->sa_restorer = NULL; \ }) #define RESET_SA_RESTORER(act, kact) \ diff --git a/sysdeps/unix/sysv/linux/i386/tst-bz21269.c b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c new file mode 100644 index 0000000..353e365 --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c @@ -0,0 +1,233 @@ +/* Test for i386 sigaction sa_restorer handling (BZ#21269) + Copyright (C) 2017 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 + . */ + +/* This is based on Linux test tools/testing/selftests/x86/ldt_gdt.c, + more specifically in do_multicpu_tests function. The main changes + are: + + - C11 atomics instead of plain access. + - Remove x86_64 support which simplifies the syscall handling + and fallbacks. + - Replicate only the test required to trigger the issue for the + BZ#21269. */ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +static int +xset_thread_area (struct user_desc *u_info) +{ + long ret = syscall (SYS_set_thread_area, u_info); + TEST_VERIFY_EXIT (ret == 0); + return ret; +} + +static void +xmodify_ldt (int func, const void *ptr, unsigned long bytecount) +{ + TEST_VERIFY_EXIT (syscall (SYS_modify_ldt, 1, ptr, bytecount) == 0); +} + +static int +futex (int *uaddr, int futex_op, int val, void *timeout, int *uaddr2, + int val3) +{ + return syscall (SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3); +} + +static void +xsethandler (int sig, void (*handler)(int, siginfo_t *, void *), int flags) +{ + struct sigaction sa = { 0 }; + sa.sa_sigaction = handler; + sa.sa_flags = SA_SIGINFO | flags; + TEST_VERIFY_EXIT (sigemptyset (&sa.sa_mask) == 0); + TEST_VERIFY_EXIT (sigaction (sig, &sa, 0) == 0); +} + +static jmp_buf jmpbuf; + +static void +sigsegv_handler (int sig, siginfo_t *info, void *ctx_void) +{ + siglongjmp (jmpbuf, 1); +} + +/* Points to an array of 1024 ints, each holding its own index. */ +static const unsigned int *counter_page; +static struct user_desc *low_user_desc; +static struct user_desc *low_user_desc_clear; /* Used to delete GDT entry. */ +static int gdt_entry_num; + +static void +setup_counter_page (void) +{ + long page_size = sysconf (_SC_PAGE_SIZE); + TEST_VERIFY_EXIT (page_size > 0); + unsigned int *page = xmmap (NULL, page_size, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_32BIT, -1); + for (int i = 0; i < (page_size / sizeof (unsigned int)); i++) + page[i] = i; + counter_page = page; +} + +static void +setup_low_user_desc (void) +{ + low_user_desc = xmmap (NULL, 2 * sizeof (struct user_desc), + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_32BIT, -1); + + low_user_desc->entry_number = -1; + low_user_desc->base_addr = (unsigned long) &counter_page[1]; + low_user_desc->limit = 0xffff; + low_user_desc->seg_32bit = 1; + low_user_desc->contents = 0; + low_user_desc->read_exec_only = 0; + low_user_desc->limit_in_pages = 1; + low_user_desc->seg_not_present = 0; + low_user_desc->useable = 0; + + xset_thread_area (low_user_desc); + + low_user_desc_clear = low_user_desc + 1; + low_user_desc_clear->entry_number = gdt_entry_num; + low_user_desc_clear->read_exec_only = 1; + low_user_desc_clear->seg_not_present = 1; +} + +/* Possible values of futex: + 0: thread is idle. + 1: thread armed. + 2: thread should clear LDT entry 0. + 3: thread should exit. */ +static atomic_uint ftx; + +static void * +threadproc (void *ctx) +{ + while (1) + { + futex ((int *) &ftx, FUTEX_WAIT, 1, NULL, NULL, 0); + while (atomic_load (&ftx) != 2) + { + if (atomic_load (&ftx) >= 3) + return NULL; + } + + /* clear LDT entry 0. */ + const struct user_desc desc = { 0 }; + xmodify_ldt (1, &desc, sizeof (desc)); + + /* If ftx == 2, set it to zero, If ftx == 100, quit. */ + if (atomic_fetch_add (&ftx, -2) != 2) + return NULL; + } +} + + +/* As described in testcase, for historical reasons x86_32 Linux (and compat + on x86_64) interprets SA_RESTORER clear with nonzero sa_restorer as a + request for stack switching if the SS segment is 'funny' (this is default + scenario for vDSO system). This means that anything that tries to mix + signal handling with segmentation should explicit clear the sa_restorer. + + This testcase check if sigaction in fact does it by changing the local + descriptor table (LDT) through the modify_ldt syscall and triggering + a synchronous segfault on iret fault by trying to install an invalid + segment. With a correct zeroed sa_restorer it should not trigger an + 'real' SEGSEGV and allows the siglongjmp in signal handler. */ + +static int +do_test (void) +{ + setup_counter_page (); + setup_low_user_desc (); + + pthread_t thread; + unsigned short orig_ss; + + xsethandler (SIGSEGV, sigsegv_handler, 0); + /* 32-bit kernels send SIGILL instead of SIGSEGV on IRET faults. */ + xsethandler (SIGILL, sigsegv_handler, 0); + + thread = xpthread_create (0, threadproc, 0); + + asm volatile ("mov %%ss, %0" : "=rm" (orig_ss)); + + for (int i = 0; i < 5; i++) + { + if (sigsetjmp (jmpbuf, 1) != 0) + continue; + + /* Make sure the thread is ready after the last test. */ + while (atomic_load (&ftx) != 0) + ; + + struct user_desc desc = { + .entry_number = 0, + .base_addr = 0, + .limit = 0xffff, + .seg_32bit = 1, + .contents = 0, + .read_exec_only = 0, + .limit_in_pages = 1, + .seg_not_present = 0, + .useable = 0 + }; + + xmodify_ldt (0x11, &desc, sizeof (desc)); + + /* Arm the thread. */ + ftx = 1; + futex ((int*) &ftx, FUTEX_WAKE, 0, NULL, NULL, 0); + + asm volatile ("mov %0, %%ss" : : "r" (0x7)); + + /* Fire up thread modify_ldt call. */ + atomic_store (&ftx, 2); + + while (atomic_load (&ftx) != 0) + ; + + /* On success, modify_ldt will segfault us synchronously and we will + escape via siglongjmp. */ + support_record_failure (); + } + + atomic_store (&ftx, 100); + futex ((int*) &ftx, FUTEX_WAKE, 0, NULL, NULL, 0); + + xpthread_join (thread); + + return 0; +} + +#include