From patchwork Thu Aug 15 21:18:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 171452 Delivered-To: patch@linaro.org Received: by 2002:a92:d204:0:0:0:0:0 with SMTP id y4csp16823ily; Thu, 15 Aug 2019 14:19:33 -0700 (PDT) X-Google-Smtp-Source: APXvYqw3wGy1y1mUqCFnWSlcnTWkFHLMbNEdbXVAGvsfI3mGycEmmMmA4fsU4INBlsJMD5lz5ySu X-Received: by 2002:a65:64cf:: with SMTP id t15mr4944031pgv.88.1565903973356; Thu, 15 Aug 2019 14:19:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1565903973; cv=none; d=google.com; s=arc-20160816; b=EJ44SVmfLnedhwMfYzIsW2g5sxe/5LbDxZXEkspoCHg+wrbLcQfk+l+UK+RfOC0L1U Bx6RCMYZ+J6Txx1D34OBNb9DV7PByea/S+7ty4whQ6toxsw1er6Uq1iEWlD385iNZoUr hkgdEQ6B42RN3lDwUXOSrkvEWFOThu2HtmrJE+xBIfjiX/i9wJ7EMvo9SlZgkz509b+h GWLiF00fQC1b96yHLi7vFZgo7P0ZRZ87Fz/Q6w7KrmuyteiK6CKiDrRM2OO81BqrOKCy qxLnn6jNhIvVvCq+on76XtAmn7IHMaQgtwXpAlBiVZ/wh0JWRtr+s9EIEYnB+oTRxS43 12HA== 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 :dkim-signature:delivered-to:sender:list-help:list-post:list-archive :list-subscribe:list-unsubscribe:list-id:precedence:mailing-list :dkim-signature:domainkey-signature; bh=hJjnLvfWUV+B8TlosM2UJNBlA0GzvqZVb5Tc8UhVw9A=; b=KfnbfK9F5y+zCA+HzwZzzU3vdoqBXkJFXuao6nbQ8tFLSQKBqsmy6i9bYxRYDQyHQ9 UY9DMNmsxqbVfyX1rGcFduSYyTn50ZY4a9wa2cZXJkK8b/JNiCoOR6hGAF6Jo2nV1z0M pHanRtEB4qRs5Rvg9JYxhL8IOoPrvCUJcTlYU8DCy0qduasa/Opfbja0Ne/q7REd6Ubw vHDYu/SgmyV7WSv6sjwiulki7G5Wvi4WMAnFLcJ/4Co0ol3wxR/+Y7rtvGZ3f7riHCjA KoykgaoLeTjE/PpXE4LAskouVHzbBcguY3bGjIsDT1thxLyi+qxJ32svjlCU7n5CWJrO 7NHg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=gXnClrtq; dkim=pass header.i=@linaro.org header.s=google header.b=fV7SSt82; spf=pass (google.com: domain of libc-alpha-return-104504-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-104504-patch=linaro.org@sourceware.org"; dmarc=pass (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 10si2419806pgp.78.2019.08.15.14.19.32 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 15 Aug 2019 14:19:33 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-104504-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=gXnClrtq; dkim=pass header.i=@linaro.org header.s=google header.b=fV7SSt82; spf=pass (google.com: domain of libc-alpha-return-104504-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-104504-patch=linaro.org@sourceware.org"; dmarc=pass (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=amETNeKR8Xerqg18J7/ojEM+dx2F9L0 ZbzsHiE+P9PHy+XMUZLLaN3pS3uYeiCBqJy5PfBBOBesX6awjFr0rQ0EDQ8hxzUQ TP4BFYu2rHO8MTV77VphBQhGVUBYGdhUNl8kiGIwrihTeauuRCfaj5s+3fJJM042 Ez9lvd7PYhqk= 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=j/Y2gkrX9gEB3cdj9BEY5HlVKt0=; b=gXnCl rtqd0U+fumbgS4YAfrJ9rICvqd4UCZSxSHYJUuJBEX66x0Vsm7V7XDYGO22wiLLC ZOJ5IbOEfNgAafA0p+OaJKC4m/3IGax5DbzS83jUcfLtvRjVyqyrHOfQrXmB19xk ucPcq1r8rzxApjqvReU0UjTV6tNDCNYZcDL2OM= Received: (qmail 54386 invoked by alias); 15 Aug 2019 21:19:12 -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 54266 invoked by uid 89); 15 Aug 2019 21:19:11 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-16.3 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy= X-HELO: mail-qk1-f176.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references; bh=hJjnLvfWUV+B8TlosM2UJNBlA0GzvqZVb5Tc8UhVw9A=; b=fV7SSt82AiTBwDWlFravqFKjURb6LANhKEYB+T/023GSKvW30H5XfhQMbpcSySe5L2 Q2z2PTAo2LvtenCT0jcNb+oFwUzkCybFAnQhvfVSOgw23ssaURtqug5YPJmc9d4XXkpM MSdeX3V9TzBmlqNmvQE7Ih/nRGzmB0R+bUqSdqudOFr9++rUlQLGIi4xgcHngW9tA0TR ko5T18tB0x8sTFhVq9rbKqMnlnxIuCASBBQGEgl/Dkcb6CA+IWrFYHWmplbG360hzMQ5 5xjX6G35G6Y8T+n1etQ3mprzBv05Hfro0i7TesD10n1SdESu/ytDA1IFjG9+MQOmbFHr 2Kzw== Return-Path: From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v2 3/4] Refactor sigcontextinfo.h Date: Thu, 15 Aug 2019 18:18:42 -0300 Message-Id: <20190815211843.22799-3-adhemerval.zanella@linaro.org> In-Reply-To: <20190815211843.22799-1-adhemerval.zanella@linaro.org> References: <20190815211843.22799-1-adhemerval.zanella@linaro.org> Changes from previous version: - Add a testcase for sigcontext_get_pc (Florian Weimer suggestion and initial implementation). - Fix some comment wording and trailing whitespace. --- This patch refactor sigcontextinfo.h header to use SA_SIGINFO as default for both gmon and debug implementations. This allows simplify profil-counter.h on Linux to use a single implementation and remove the requirements for newer ports to redefine __sigaction/sigaction to use SIG_SIGINFO. The GET_PC macro is also changed to a inline function, sigcontext_get_pc which return an uintptr_t instead of a void pointer. It allows easier convertion to integer on ILP32 architecture, such as x32, without the need to suppress compiler warnings. The patch also requires some refactor of register-dump.h file for some architectures (to reflect it is now called from a sa_sigaction instead of sa_handler signal context). - Alpha, i386, and s390 are straighfoward to take in consideration the new argument type. - ia64 takes in consideration the kernel pass a struct sigcontextt as third argument for sa_sigaction. - sparc take in consideration the kernel pass a pt_regs struct as third argument for sa_sigaction. - m68k dummy function is removed and the FP state is dumped on register_dump itself. - For SH the register-dump.h file is consolidate on a common implementation and the floating-point state is checked based on ownedfp field. The register_dump does not change its output format in any affected architecture. I checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu, arm-linux-gnueabihf, sparcv9-linux-gnu, sparc64-linux-gnu, powerpc-linux-gnu, powerpc64-linux-gnu, and powerpc64le-linux-gnu. I also checked the libSegFault.so through catchsegv on alpha-linux-gnu, m68k-linux-gnu and sh4-linux-gnu to confirm the output has not changed. Adhemerval Zanella Florian Weimer * debug/segfault.c (install_handler): Use SA_SIGINFO if defined. * sysdeps/generic/profil-counter.h (__profil_counter): Cast to uintptr_t. (USE_SA_SIGINFO): New define. * sysdeps/generic/sigcontextinfo.h (GET_PC): Replace with sigcontext_get_pc. * sysdeps/mach/hurd/i386/sigcontextinfo.h (GET_PC): Likewise. * sysdeps/posix/profil.c (profil_count): Change PC argument to uintptr_t. (__profil): Use SA_SIGINFO for USE_SA_SIGINFO. * sysdeps/posix/sprofil.c (profil_count): Change PCP argument to uintptr_t. (__sprofil): Use SA_SIGINFO for USE_SA_SIGINFO. * sysdeps/unix/sysv/linux/profil-counter.h: New file. * sysdeps/unix/sysv/linux/aarch64/profil-counter.h: Remove file. * sysdeps/unix/sysv/linux/csky/profil-counter.h: Likewise. * sysdeps/unix/sysv/linux/hppa/profil-counter.h: Likewise. * sysdeps/unix/sysv/linux/i386/profil-counter.h: Likewise. * sysdeps/unix/sysv/linux/ia64/profil-counter.h: Likewise. * sysdeps/unix/sysv/linux/microblaze/profil-counter.h: Likewise. * sysdeps/unix/sysv/linux/mips/profil-counter.h: Likewise. * sysdeps/unix/sysv/linux/nios2/profil-counter.h: Likewise. * sysdeps/unix/sysv/linux/powerpc/profil-counter.h: Likewise. * sysdeps/unix/sysv/linux/x86_64/profil-counter.h: Likewise. * sysdeps/unix/sysv/linux/riscv/profil-counter.h: Likewise. * sysdeps/sysv/linux/s390/s390-32/profil-counter.h: Likewise. * sysdeps/sysv/linux/s390/s390-64/profil-counter.h: Likewise. * sysdeps/unix/sysv/linux/sh/profil-counter.h: Likewise. * sysdeps/unix/sysv/linux/arm/profil-counter.h (__profil_counter): Remove function and use generic Linux implementation. * sysdeps/unix/sysv/linux/sparc/profil-counter.h: New file. * sysdeps/unix/sysv/linux/sparc/sparc64/profil-counter.h: Remove file. * sysdeps/unix/sysv/linux/sparc/sparc32/profil-counter.h: Likewise. * sysdpes/unix/sysv/linux/aarch64/sigcontextinfo.h (SIGCONTEXT, GET_PC, __sigaction, sigaction): Remove defines. (sigcontext_get_pc): New function. * sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h: Likewise. * sysdeps/unix/sysv/linux/arm/sigcontextinfo.h: Likewise. * sysdeps/unix/sysv/linux/csky/sigcontextinfo.h: Likewise. * sysdeps/unix/sysv/linux/hppa/sigcontextinfo.h: Likewise. * sysdeps/unix/sysv/linux/i386/sigcontextinfo.h: Likewise. * sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h: Likewise. * sysdeps/unix/sysv/linux/m68k/sigcontextinfo.h: Likewise. * sysdeps/unix/sysv/linux/mips/sigcontextinfo.h: Likewise. * sysdeps/unix/sysv/linux/nios2/sigcontextinfo.h: Likewise. * sysdeps/unix/sysv/linux/s390/sigcontextinfo.h: Likewise. * sysdeps/unix/sysv/linux/microblaze/sigcontextinfo.h: Likewise. * sysdeps/unix/sysv/linux/powerpc/sigcontextinfo.h: Likewise. * sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h: Likewise. * sysdeps/unix/sysv/linux/sh/sigcontextinfo.h: Likewise. * sysdeps/sysv/linux/sparc/sparc32/sigcontextinfo.h: Likewise. * sysdeps/sysv/linux/sparc/sparc64/sigcontextinfo.h: Likewise. * sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h: Likewise. * sysdeps/unix/sysv/linux/alpha/register-dump.h (register_dump): Handle CTX argument as ucontext_t. * sysdeps/unix/sysv/linux/i386/register-dump.h: Likewise. Likewise. * sysdeps/unix/sysv/linux/m68k/register-dump.h: Likewise. * sysdeps/sysv/linux/s390/s390-32/register-dump.h: Likewise. * sysdeps/sysv/linux/s390/s390-64/register-dump.h: Likewise. * sysdeps/unix/sysv/linux/sh/register-dump.h: New file. * sysdeps/unix/sysv/linux/sh/sh4/register-dump.h: Remove File. * sysdeps/unix/sysv/linux/sh/sh3/register-dump.h: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/register-dump.h: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/register-dump.h: Likewise. * sysdeps/unix/sysv/linux/Makefile (tests-internal): Add tst-sigcontextinfo-get_pc. * sysdeps/unix/sysv/linux/tst-sigcontextinfo-get_pc.c: New file. (CFLAGS-tst-sigcontextinfo-get_pc.c): New rule. --- debug/segfault.c | 16 +- sysdeps/generic/profil-counter.h | 2 +- sysdeps/generic/sigcontextinfo.h | 11 +- sysdeps/mach/hurd/i386/sigcontextinfo.h | 11 +- sysdeps/posix/profil.c | 19 +- sysdeps/posix/sprofil.c | 25 +- sysdeps/unix/sysv/linux/Makefile | 4 +- .../unix/sysv/linux/aarch64/profil-counter.h | 20 -- .../unix/sysv/linux/aarch64/sigcontextinfo.h | 22 +- sysdeps/unix/sysv/linux/alpha/register-dump.h | 283 +++++++++++------- .../unix/sysv/linux/alpha/sigcontextinfo.h | 15 +- sysdeps/unix/sysv/linux/arm/profil-counter.h | 4 +- sysdeps/unix/sysv/linux/arm/sigcontextinfo.h | 27 +- sysdeps/unix/sysv/linux/csky/profil-counter.h | 31 -- sysdeps/unix/sysv/linux/csky/sigcontextinfo.h | 20 +- .../{profil-counter.h => sigcontextinfo.h} | 16 +- sysdeps/unix/sysv/linux/i386/profil-counter.h | 31 -- sysdeps/unix/sysv/linux/i386/register-dump.h | 262 ++++++++-------- sysdeps/unix/sysv/linux/i386/sigcontextinfo.h | 12 +- sysdeps/unix/sysv/linux/ia64/profil-counter.h | 31 -- sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h | 14 +- sysdeps/unix/sysv/linux/m68k/register-dump.h | 117 ++++---- sysdeps/unix/sysv/linux/m68k/sigcontextinfo.h | 12 +- .../sysv/linux/microblaze/profil-counter.h | 2 - .../sysv/linux/microblaze/sigcontextinfo.h | 12 +- sysdeps/unix/sysv/linux/mips/profil-counter.h | 2 - sysdeps/unix/sysv/linux/mips/sigcontextinfo.h | 20 +- .../unix/sysv/linux/nios2/profil-counter.h | 2 - .../unix/sysv/linux/nios2/sigcontextinfo.h | 23 +- .../unix/sysv/linux/powerpc/profil-counter.h | 2 - .../unix/sysv/linux/powerpc/sigcontextinfo.h | 16 +- .../sysv/linux/{x86_64 => }/profil-counter.h | 13 +- .../unix/sysv/linux/riscv/profil-counter.h | 31 -- .../unix/sysv/linux/riscv/sigcontextinfo.h | 12 +- .../sysv/linux/s390/s390-32/profil-counter.h | 26 -- .../sysv/linux/s390/s390-32/register-dump.h | 38 +-- .../sysv/linux/s390/s390-64/profil-counter.h | 26 -- .../sysv/linux/s390/s390-64/register-dump.h | 38 +-- sysdeps/unix/sysv/linux/s390/sigcontextinfo.h | 16 +- sysdeps/unix/sysv/linux/sh/profil-counter.h | 32 -- .../sysv/linux/sh/{sh4 => }/register-dump.h | 118 ++++---- .../unix/sysv/linux/sh/sh3/register-dump.h | 150 ---------- sysdeps/unix/sysv/linux/sh/sigcontextinfo.h | 11 +- .../sparc/{sparc64 => }/profil-counter.h | 14 +- .../sysv/linux/sparc/sparc32/profil-counter.h | 28 -- .../sysv/linux/sparc/sparc32/register-dump.h | 36 ++- .../sysv/linux/sparc/sparc32/sigcontextinfo.h | 40 ++- .../sysv/linux/sparc/sparc64/register-dump.h | 42 ++- .../sysv/linux/sparc/sparc64/sigcontextinfo.h | 42 ++- .../sysv/linux/tst-sigcontextinfo-get_pc.c | 81 +++++ .../unix/sysv/linux/x86_64/sigcontextinfo.h | 13 +- 51 files changed, 927 insertions(+), 964 deletions(-) delete mode 100644 sysdeps/unix/sysv/linux/aarch64/profil-counter.h delete mode 100644 sysdeps/unix/sysv/linux/csky/profil-counter.h rename sysdeps/unix/sysv/linux/hppa/{profil-counter.h => sigcontextinfo.h} (76%) delete mode 100644 sysdeps/unix/sysv/linux/i386/profil-counter.h delete mode 100644 sysdeps/unix/sysv/linux/ia64/profil-counter.h delete mode 100644 sysdeps/unix/sysv/linux/microblaze/profil-counter.h delete mode 100644 sysdeps/unix/sysv/linux/mips/profil-counter.h delete mode 100644 sysdeps/unix/sysv/linux/nios2/profil-counter.h delete mode 100644 sysdeps/unix/sysv/linux/powerpc/profil-counter.h rename sysdeps/unix/sysv/linux/{x86_64 => }/profil-counter.h (66%) delete mode 100644 sysdeps/unix/sysv/linux/riscv/profil-counter.h delete mode 100644 sysdeps/unix/sysv/linux/s390/s390-32/profil-counter.h delete mode 100644 sysdeps/unix/sysv/linux/s390/s390-64/profil-counter.h delete mode 100644 sysdeps/unix/sysv/linux/sh/profil-counter.h rename sysdeps/unix/sysv/linux/sh/{sh4 => }/register-dump.h (62%) delete mode 100644 sysdeps/unix/sysv/linux/sh/sh3/register-dump.h rename sysdeps/unix/sysv/linux/sparc/{sparc64 => }/profil-counter.h (77%) delete mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/profil-counter.h create mode 100644 sysdeps/unix/sysv/linux/tst-sigcontextinfo-get_pc.c -- 2.17.1 diff --git a/debug/segfault.c b/debug/segfault.c index bd1008d9af..cd3bfab55c 100644 --- a/debug/segfault.c +++ b/debug/segfault.c @@ -35,6 +35,10 @@ passed up by the signal handler. */ #include +#ifdef SA_SIGINFO +# define SIGCONTEXT siginfo_t *info, void * +#endif + /* Get code to possibly dump the content of all registers. */ #include @@ -101,7 +105,7 @@ catch_segfault (int signal, SIGCONTEXT ctx) Normally it will be found at arr[2], but it might appear later if there were some signal handler wrappers. Allow a few bytes difference to cope with as many arches as possible. */ - pc = (uintptr_t) GET_PC (ctx); + pc = sigcontext_get_pc (ctx); for (i = 0; i < cnt; ++i) if ((uintptr_t) arr[i] >= pc - 16 && (uintptr_t) arr[i] <= pc + 16) break; @@ -148,9 +152,15 @@ install_handler (void) const char *sigs = getenv ("SEGFAULT_SIGNALS"); const char *name; - sa.sa_handler = (void *) catch_segfault; +#ifdef SA_SIGINFO + sa.sa_sigaction = catch_segfault; + sa.sa_flags = SA_SIGINFO; +#else + sa.sa_handler = (void*) catch_segfault; + sa.sa_flags = 0; +#endif sigemptyset (&sa.sa_mask); - sa.sa_flags = SA_RESTART; + sa.sa_flags |= SA_RESTART; /* Maybe we are expected to use an alternative stack. */ if (getenv ("SEGFAULT_USE_ALTSTACK") != 0) diff --git a/sysdeps/generic/profil-counter.h b/sysdeps/generic/profil-counter.h index 6d3164e101..02de4f795f 100644 --- a/sysdeps/generic/profil-counter.h +++ b/sysdeps/generic/profil-counter.h @@ -22,5 +22,5 @@ static void __profil_counter (int signr, int code, struct sigcontext *scp) { - profil_count ((void *) scp->sc_pc); + profil_count ((uintptr_t) scp->sc_pc); } diff --git a/sysdeps/generic/sigcontextinfo.h b/sysdeps/generic/sigcontextinfo.h index ff63a09043..92c0328fb7 100644 --- a/sysdeps/generic/sigcontextinfo.h +++ b/sysdeps/generic/sigcontextinfo.h @@ -16,6 +16,15 @@ License along with the GNU C Library; if not, see . */ +#ifndef _SIGCONTEXTINFO_H +#define _SIGCONTEXTINFO_H + /* In general we cannot provide any information. */ #define SIGCONTEXT struct sigcontext * -#define GET_PC(ctx) ((void *) 0) +static inline uintptr_t +sigcontext_get_pc (const struct sigcontext *ctx) +{ + return 0; +} + +#endif diff --git a/sysdeps/mach/hurd/i386/sigcontextinfo.h b/sysdeps/mach/hurd/i386/sigcontextinfo.h index 65bf12976d..3d9be4e2a6 100644 --- a/sysdeps/mach/hurd/i386/sigcontextinfo.h +++ b/sysdeps/mach/hurd/i386/sigcontextinfo.h @@ -15,5 +15,14 @@ License along with the GNU C Library; if not, see . */ +#ifndef _SIGCONTEXTINFO_H +#define _SIGCONTEXTINFO_H + #define SIGCONTEXT struct sigcontext -#define GET_PC(ctx) ((void *) (ctx).sc_eip) +static inline uintptr_t +sigcontext_get_pc (struct sigcontext ctx) +{ + return ctx.sc_eip; +} + +#endif diff --git a/sysdeps/posix/profil.c b/sysdeps/posix/profil.c index 838c36d060..4b8fd9caf1 100644 --- a/sysdeps/posix/profil.c +++ b/sysdeps/posix/profil.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -36,9 +37,9 @@ static size_t pc_offset; static u_int pc_scale; static inline void -profil_count (void *pc) +profil_count (uintptr_t pc) { - size_t i = (pc - pc_offset - (void *) 0) / 2; + size_t i = (pc - pc_offset) / 2; if (sizeof (unsigned long long int) > sizeof (size_t)) i = (unsigned long long int) i * pc_scale / 65536; @@ -71,6 +72,10 @@ __profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale) # define oact_ptr &oact # define otimer_ptr &otimer +# ifdef SA_SIGINFO + oact.sa_flags |= SA_SIGINFO; +# endif + if (sample_buffer == NULL) { /* Disable profiling. */ @@ -104,8 +109,14 @@ __profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale) pc_offset = offset; pc_scale = scale; - act.sa_handler = (sighandler_t) &__profil_counter; - act.sa_flags = SA_RESTART; +#ifdef SA_SIGINFO + act.sa_sigaction = __profil_counter; + act.sa_flags = SA_SIGINFO; +#else + act.sa_handler = __profil_counter; + act.sa_flags = 0; +#endif + act.sa_flags |= SA_RESTART; __sigfillset (&act.sa_mask); if (__sigaction (SIGPROF, &act, oact_ptr) < 0) return -1; diff --git a/sysdeps/posix/sprofil.c b/sysdeps/posix/sprofil.c index 3f76bf5174..a9d4a7f3b4 100644 --- a/sysdeps/posix/sprofil.c +++ b/sysdeps/posix/sprofil.c @@ -105,10 +105,10 @@ index_to_pc (unsigned long int n, size_t offset, unsigned int scale, } static void -profil_count (void *pcp, int prof_uint) +profil_count (uintptr_t pcp, int prof_uint) { struct region *region, *r = prof_info.last; - size_t lo, hi, mid, pc = (unsigned long int) pcp; + size_t lo, hi, mid, pc = pcp; unsigned long int i; /* Fast path: pc is in same region as before. */ @@ -165,13 +165,13 @@ profil_count (void *pcp, int prof_uint) } static inline void -profil_count_ushort (void *pcp) +profil_count_ushort (uintptr_t pcp) { profil_count (pcp, 0); } static inline void -profil_count_uint (void *pcp) +profil_count_uint (uintptr_t pcp) { profil_count (pcp, 1); } @@ -334,11 +334,18 @@ __sprofil (struct prof *profp, int profcnt, struct timeval *tvp, prof_info.last = prof_info.region; /* Install SIGPROF handler. */ - if (flags & PROF_UINT) - act.sa_handler = (sighandler_t) &__profil_counter_uint; - else - act.sa_handler = (sighandler_t) &__profil_counter_ushort; - act.sa_flags = SA_RESTART; +#ifdef SA_SIGINFO + act.sa_sigaction= flags & PROF_UINT + ? __profil_counter_uint + : __profil_counter_ushort; + act.sa_flags = SA_SIGINFO; +#else + act.sa_handler = flags & PROF_UINT + ? (sighandler_t) __profil_counter_uint + : (sighandler_t) __profil_counter_ushort; + act.sa_flags = 0; +#endif + act.sa_flags |= SA_RESTART; __sigfillset (&act.sa_mask); if (__sigaction (SIGPROF, &act, &prof_info.saved_action) < 0) return -1; diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 1ab6bcbfc8..9b4fbfac3b 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -55,7 +55,9 @@ tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \ test-errno-linux tst-memfd_create tst-mlock2 tst-pkey \ tst-rlimit-infinity tst-ofdlocks tst-gettid tst-gettid-kill \ tst-tgkill -tests-internal += tst-ofdlocks-compat +tests-internal += tst-ofdlocks-compat tst-sigcontextinfo-get_pc + +CFLAGS-tst-sigcontextinfo-get_pc.c = -fasynchronous-unwind-tables # Generate the list of SYS_* macros for the system calls (__NR_* # macros). The file syscall-names.list contains all possible system diff --git a/sysdeps/unix/sysv/linux/aarch64/profil-counter.h b/sysdeps/unix/sysv/linux/aarch64/profil-counter.h deleted file mode 100644 index 4f8b6501c0..0000000000 --- a/sysdeps/unix/sysv/linux/aarch64/profil-counter.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (C) 2009-2019 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 - . */ - -/* We can use the ix86 version. */ -#include diff --git a/sysdeps/unix/sysv/linux/aarch64/sigcontextinfo.h b/sysdeps/unix/sysv/linux/aarch64/sigcontextinfo.h index a0b0002c3d..e001e7c193 100644 --- a/sysdeps/unix/sysv/linux/aarch64/sigcontextinfo.h +++ b/sysdeps/unix/sysv/linux/aarch64/sigcontextinfo.h @@ -16,20 +16,16 @@ License along with the GNU C Library; if not, see . */ +#ifndef _SIGCONTEXTINFO_H +#define _SIGCONTEXTINFO_H + #include #include -#define SIGCONTEXT siginfo_t *_si, ucontext_t * -#define GET_PC(ctx) ((void *) (uintptr_t) (ctx)->uc_mcontext.pc) - -/* There is no reliable way to get the sigcontext unless we use a - three-argument signal handler. */ -#define __sigaction(sig, act, oact) ({ \ - (act)->sa_flags |= SA_SIGINFO; \ - (__sigaction) (sig, act, oact); \ -}) +static inline uintptr_t +sigcontext_get_pc (const ucontext_t *ctx) +{ + return ctx->uc_mcontext.pc; +} -#define sigaction(sig, act, oact) ({ \ - (act)->sa_flags |= SA_SIGINFO; \ - (sigaction) (sig, act, oact); \ -}) +#endif diff --git a/sysdeps/unix/sysv/linux/alpha/register-dump.h b/sysdeps/unix/sysv/linux/alpha/register-dump.h index 9d55bc0fc5..45dafe0a1f 100644 --- a/sysdeps/unix/sysv/linux/alpha/register-dump.h +++ b/sysdeps/unix/sysv/linux/alpha/register-dump.h @@ -16,8 +16,10 @@ License along with the GNU C Library. If not, see . */ -#include #include +#include +#include +#include <_itoa.h> /* We will print the register dump in this format: @@ -48,109 +50,190 @@ TA0: XXXXXXXXXXXXXXXX TA1: XXXXXXXXXXXXXXXX TA2: XXXXXXXXXXXXXXXX */ -#define NREGS (32+32+3) - -static const char __attribute__((aligned(8))) regnames[NREGS][8] = -{ - " V0: ", " T0: ", " T1: ", - " T2: ", " T3: ", " T4: ", - " T5: ", " T6: ", " T7: ", - " S0: ", " S1: ", " S2: ", - " S3: ", " S4: ", " S5: ", - " S6: ", " A0: ", " A1: ", - " A2: ", " A3: ", " A4: ", - " A5: ", " T8: ", " T9: ", - " T10: ", " T11: ", " RA: ", - " T12: ", " AT: ", " GP: ", - " SP: ", " PC: ", - - " FP0: ", " FP1: ", " FP2: ", - " FP3: ", " FP4: ", " FP5: ", - " FP6: ", " FP7: ", " FP8: ", - " FP9: ", " FP10: ", " FP11: ", - " FP12: ", " FP13: ", " FP14: ", - " FP15: ", " FP16: ", " FP17: ", - " FP18: ", " FP19: ", " FP20: ", - " FP21: ", " FP22: ", " FP23: ", - " FP24: ", " FP25: ", " FP26: ", - " FP27: ", " FP28: ", " FP29: ", - " FP30: ", " FPCR: ", - - " TA0: ", " TA1: ", " TA2: " -}; - -#define O(FIELD, LF) offsetof(struct sigcontext, FIELD) + LF - -static const int offsets[NREGS] = +static void +hexvalue (unsigned long int value, char *buf, size_t len) { - O(sc_regs[0], 0), O(sc_regs[1], 0), O(sc_regs[2], 1), - O(sc_regs[3], 0), O(sc_regs[4], 0), O(sc_regs[5], 1), - O(sc_regs[6], 0), O(sc_regs[7], 0), O(sc_regs[8], 1), - O(sc_regs[9], 0), O(sc_regs[10], 0), O(sc_regs[11], 1), - O(sc_regs[12], 0), O(sc_regs[13], 0), O(sc_regs[14], 1), - O(sc_regs[15], 0), O(sc_regs[16], 0), O(sc_regs[17], 1), - O(sc_regs[18], 0), O(sc_regs[19], 0), O(sc_regs[20], 1), - O(sc_regs[21], 0), O(sc_regs[22], 0), O(sc_regs[23], 1), - O(sc_regs[24], 0), O(sc_regs[25], 0), O(sc_regs[26], 1), - O(sc_regs[27], 0), O(sc_regs[28], 0), O(sc_regs[29], 1), - O(sc_regs[30], 0), O(sc_pc, 2), - - O(sc_fpregs[0], 0), O(sc_fpregs[1], 0), O(sc_fpregs[2], 1), - O(sc_fpregs[3], 0), O(sc_fpregs[4], 0), O(sc_fpregs[5], 1), - O(sc_fpregs[6], 0), O(sc_fpregs[7], 0), O(sc_fpregs[8], 1), - O(sc_fpregs[9], 0), O(sc_fpregs[10], 0), O(sc_fpregs[11], 1), - O(sc_fpregs[12], 0), O(sc_fpregs[13], 0), O(sc_fpregs[14], 1), - O(sc_fpregs[15], 0), O(sc_fpregs[16], 0), O(sc_fpregs[17], 1), - O(sc_fpregs[18], 0), O(sc_fpregs[19], 0), O(sc_fpregs[20], 1), - O(sc_fpregs[21], 0), O(sc_fpregs[22], 0), O(sc_fpregs[23], 1), - O(sc_fpregs[24], 0), O(sc_fpregs[25], 0), O(sc_fpregs[26], 1), - O(sc_fpregs[27], 0), O(sc_fpregs[28], 0), O(sc_fpregs[29], 1), - O(sc_fpregs[30], 0), O(sc_fpcr, 2), - - O(sc_traparg_a0, 0), O(sc_traparg_a1, 0), O(sc_traparg_a2, 1) -}; - -#undef O + char *cp = _itoa_word (value, buf + len, 16, 0); + while (cp > buf) + *--cp = '0'; +} static void -register_dump (int fd, struct sigcontext *ctx) +register_dump (int fd, struct ucontext_t *ctx) { - char buf[NREGS*(8+16) + 25 + 80]; - char *p = buf; - size_t i; - - p = stpcpy (p, "Register dump:\n\n"); - - for (i = 0; i < NREGS; ++i) - { - int this_offset, this_lf; - unsigned long val; - signed long j; - - this_offset = offsets[i]; - this_lf = this_offset & 7; - - val = *(unsigned long *)(((size_t)ctx + this_offset) & -8); - - memcpy (p, regnames[i], 8); - p += 8; - - for (j = 60; j >= 0; j -= 4) - { - unsigned long x = (val >> j) & 15; - x += x < 10 ? '0' : 'a' - 10; - *p++ = x; - } - - if (this_lf > 0) - { - if (this_lf > 1) - *p++ = '\n'; - *p++ = '\n'; - } - } - - write (fd, buf, p - buf); + struct iovec iov[31 * 2 + 2 /* REGS + PC. */ + + 31 * 2 + 2 /* FREGS + FPCR. */ + + (3 * 2) /* TA0, TA1, TA3. */ + + 1 /* '\n'. */]; + size_t nr = 0; + +#define ADD_STRING(str) \ + iov[nr].iov_base = (char *) str; \ + iov[nr].iov_len = strlen (str); \ + ++nr +#define ADD_MEM(str, len) \ + iov[nr].iov_base = str; \ + iov[nr].iov_len = len; \ + ++nr + + char regs[31][16]; + char pc[16]; + for (int i = 0; i < 31; i++) + hexvalue (ctx->uc_mcontext.sc_regs[i], regs[i], 16); + hexvalue (ctx->uc_mcontext.sc_pc, pc, 16); + + /* Generate the output. */ + ADD_STRING ("Register dump:\n\n V0: "); + ADD_MEM (regs[0], 16); + ADD_STRING (" T0: "); + ADD_MEM (regs[1], 16); + ADD_STRING (" T1: "); + ADD_MEM (regs[2], 16); + ADD_STRING ("\n T2: "); + ADD_MEM (regs[3], 16); + ADD_STRING (" T3: "); + ADD_MEM (regs[4], 16); + ADD_STRING (" T4: "); + ADD_MEM (regs[5], 16); + ADD_STRING ("\n T5: "); + ADD_MEM (regs[6], 16); + ADD_STRING (" T6: "); + ADD_MEM (regs[7], 16); + ADD_STRING (" T7: "); + ADD_MEM (regs[8], 16); + ADD_STRING ("\n S0: "); + ADD_MEM (regs[9], 16); + ADD_STRING (" S1: "); + ADD_MEM (regs[10], 16); + ADD_STRING (" S2: "); + ADD_MEM (regs[11], 16); + ADD_STRING ("\n S3: "); + ADD_MEM (regs[12], 16); + ADD_STRING (" S4: "); + ADD_MEM (regs[13], 16); + ADD_STRING (" S5: "); + ADD_MEM (regs[14], 16); + ADD_STRING ("\n S6: "); + ADD_MEM (regs[15], 16); + ADD_STRING (" A0: "); + ADD_MEM (regs[16], 16); + ADD_STRING (" A1: "); + ADD_MEM (regs[17], 16); + ADD_STRING ("\n A2: "); + ADD_MEM (regs[18], 16); + ADD_STRING (" A3: "); + ADD_MEM (regs[19], 16); + ADD_STRING (" A4: "); + ADD_MEM (regs[20], 16); + ADD_STRING ("\n A5: "); + ADD_MEM (regs[21], 16); + ADD_STRING (" T8: "); + ADD_MEM (regs[22], 16); + ADD_STRING (" T9: "); + ADD_MEM (regs[23], 16); + ADD_STRING ("\n T10: "); + ADD_MEM (regs[24], 16); + ADD_STRING (" T11: "); + ADD_MEM (regs[25], 16); + ADD_STRING (" RA: "); + ADD_MEM (regs[26], 16); + ADD_STRING ("\n T12: "); + ADD_MEM (regs[27], 16); + ADD_STRING (" AT: "); + ADD_MEM (regs[28], 16); + ADD_STRING (" GP: "); + ADD_MEM (regs[29], 16); + ADD_STRING ("\n SP: "); + ADD_MEM (regs[30], 16); + ADD_STRING (" PC: "); + ADD_MEM (pc, 16); + + char fpregs[31][16]; + char fpcr[16]; + for (int i = 0; i < 31; i++) + hexvalue (ctx->uc_mcontext.sc_fpregs[i], fpregs[i], 16); + hexvalue (ctx->uc_mcontext.sc_fpcr, fpcr, 16); + + ADD_STRING ("\n\n FP0: "); + ADD_MEM (fpregs[0], 16); + ADD_STRING (" FP1: "); + ADD_MEM (fpregs[1], 16); + ADD_STRING (" FP2: "); + ADD_MEM (fpregs[2], 16); + ADD_STRING ("\n FP3: "); + ADD_MEM (fpregs[3], 16); + ADD_STRING (" FP4: "); + ADD_MEM (fpregs[4], 16); + ADD_STRING (" FP5: "); + ADD_MEM (fpregs[5], 16); + ADD_STRING ("\n FP6: "); + ADD_MEM (fpregs[6], 16); + ADD_STRING (" FP7: "); + ADD_MEM (fpregs[7], 16); + ADD_STRING (" FP8: "); + ADD_MEM (fpregs[8], 16); + ADD_STRING ("\n FP9: "); + ADD_MEM (fpregs[9], 16); + ADD_STRING (" FP10: "); + ADD_MEM (fpregs[10], 16); + ADD_STRING (" FP11: "); + ADD_MEM (fpregs[11], 16); + ADD_STRING ("\n FP12: "); + ADD_MEM (fpregs[12], 16); + ADD_STRING (" FP13: "); + ADD_MEM (fpregs[13], 16); + ADD_STRING (" FP14: "); + ADD_MEM (fpregs[14], 16); + ADD_STRING ("\n FP15: "); + ADD_MEM (fpregs[15], 16); + ADD_STRING (" FP16: "); + ADD_MEM (fpregs[16], 16); + ADD_STRING (" FP17: "); + ADD_MEM (fpregs[17], 16); + ADD_STRING ("\n FP18: "); + ADD_MEM (fpregs[18], 16); + ADD_STRING (" FP19: "); + ADD_MEM (fpregs[19], 16); + ADD_STRING (" FP20: "); + ADD_MEM (fpregs[20], 16); + ADD_STRING ("\n FP21: "); + ADD_MEM (fpregs[21], 16); + ADD_STRING (" FP22: "); + ADD_MEM (fpregs[22], 16); + ADD_STRING (" FP23: "); + ADD_MEM (fpregs[23], 16); + ADD_STRING ("\n FP24: "); + ADD_MEM (fpregs[24], 16); + ADD_STRING (" FP25: "); + ADD_MEM (fpregs[25], 16); + ADD_STRING (" FP26: "); + ADD_MEM (fpregs[26], 16); + ADD_STRING ("\n FP27: "); + ADD_MEM (fpregs[27], 16); + ADD_STRING (" FP28: "); + ADD_MEM (fpregs[28], 16); + ADD_STRING (" FP29: "); + ADD_MEM (fpregs[29], 16); + ADD_STRING ("\n FP30: "); + ADD_MEM (fpregs[30], 16); + ADD_STRING (" FPCR: "); + ADD_MEM (fpcr, 16); + + char traparg[3][16]; + hexvalue (ctx->uc_mcontext.sc_traparg_a0, traparg[0], 16); + hexvalue (ctx->uc_mcontext.sc_traparg_a1, traparg[1], 16); + hexvalue (ctx->uc_mcontext.sc_traparg_a2, traparg[2], 16); + ADD_STRING ("\n\n TA0: "); + ADD_MEM (traparg[0], 16); + ADD_STRING (" TA1: "); + ADD_MEM (traparg[1], 16); + ADD_STRING (" TA2: "); + ADD_MEM (traparg[2], 16); + + ADD_STRING ("\n"); + + /* Write the stuff out. */ + writev (fd, iov, nr); } #define REGISTER_DUMP register_dump (fd, ctx) diff --git a/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h b/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h index 45d06f9a12..6147ba5f52 100644 --- a/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h +++ b/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h @@ -15,5 +15,16 @@ License along with the GNU C Library. If not, see . */ -#define SIGCONTEXT int _code, struct sigcontext * -#define GET_PC(ctx) ((void *) (ctx)->sc_pc) +#ifndef _SIGCONTEXTINFO_H +#define _SIGCONTEXTINFO_H + +#include +#include + +static inline uintptr_t +sigcontext_get_pc (const ucontext_t *ctx) +{ + return ctx->uc_mcontext.sc_pc; +} + +#endif diff --git a/sysdeps/unix/sysv/linux/arm/profil-counter.h b/sysdeps/unix/sysv/linux/arm/profil-counter.h index 494c2172b6..040c7aa59a 100644 --- a/sysdeps/unix/sysv/linux/arm/profil-counter.h +++ b/sysdeps/unix/sysv/linux/arm/profil-counter.h @@ -20,9 +20,9 @@ #include void -__profil_counter (int signo, const SIGCONTEXT scp) +__profil_counter (int signo, siginfo_t *_si, void *scp) { - profil_count ((void *) GET_PC (scp)); + profil_count (sigcontext_get_pc (scp)); /* This is a hack to prevent the compiler from implementing the above function call as a sibcall. The sibcall would overwrite diff --git a/sysdeps/unix/sysv/linux/arm/sigcontextinfo.h b/sysdeps/unix/sysv/linux/arm/sigcontextinfo.h index 0bf3beaa0f..d16ce06c3d 100644 --- a/sysdeps/unix/sysv/linux/arm/sigcontextinfo.h +++ b/sysdeps/unix/sysv/linux/arm/sigcontextinfo.h @@ -16,24 +16,13 @@ License along with the GNU C Library. If not, see . */ -#include +#ifndef _SIGCONTEXTINFO_H +#define _SIGCONTEXTINFO_H -#define SIGCONTEXT siginfo_t *_si, ucontext_t * +static inline uintptr_t +sigcontext_get_pc (const ucontext_t *ctx) +{ + return ctx->uc_mcontext.arm_pc; +} -/* The sigcontext structure changed between 2.0 and 2.1 kernels. On any - modern system we should be able to assume that the "new" format will be - in use. */ - -#define GET_PC(ctx) ((void *) (ctx)->uc_mcontext.arm_pc) - -/* There is no reliable way to get the sigcontext unless we use a - three-argument signal handler. */ -#define __sigaction(sig, act, oact) ({ \ - (act)->sa_flags |= SA_SIGINFO; \ - (__sigaction) (sig, act, oact); \ -}) - -#define sigaction(sig, act, oact) ({ \ - (act)->sa_flags |= SA_SIGINFO; \ - (sigaction) (sig, act, oact); \ -}) +#endif diff --git a/sysdeps/unix/sysv/linux/csky/profil-counter.h b/sysdeps/unix/sysv/linux/csky/profil-counter.h deleted file mode 100644 index b3e4279146..0000000000 --- a/sysdeps/unix/sysv/linux/csky/profil-counter.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Low-level statistical profiling support function. Linux/C-SKY version. - Copyright (C) 2018-2019 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 - -void -__profil_counter (int signo, const SIGCONTEXT scp) -{ - profil_count ((void *) GET_PC (scp)); - - /* This is a hack to prevent the compiler from implementing the - above function call as a sibcall. The sibcall would overwrite - the signal context. */ - asm volatile (""); -} diff --git a/sysdeps/unix/sysv/linux/csky/sigcontextinfo.h b/sysdeps/unix/sysv/linux/csky/sigcontextinfo.h index 4c1275402b..c5a775ccff 100644 --- a/sysdeps/unix/sysv/linux/csky/sigcontextinfo.h +++ b/sysdeps/unix/sysv/linux/csky/sigcontextinfo.h @@ -16,17 +16,13 @@ License along with the GNU C Library. If not, see . */ -#define SIGCONTEXT siginfo_t *_si, struct ucontext_t * -#define GET_PC(ctx) ((void *) (ctx)->uc_mcontext.__gregs.__pc) +#ifndef _SIGCONTEXTINFO_H +#define _SIGCONTEXTINFO_H -/* There is no reliable way to get the sigcontext unless we use a - three-argument signal handler. */ -#define __sigaction(sig, act, oact) ({ \ - (act)->sa_flags |= SA_SIGINFO; \ - (__sigaction) (sig, act, oact); \ -}) +static inline uintptr_t +sigcontext_get_pc (const ucontext_t *ctx) +{ + return ctx->uc_mcontext.__gregs.__pc; +} -#define sigaction(sig, act, oact) ({ \ - (act)->sa_flags |= SA_SIGINFO; \ - (sigaction) (sig, act, oact); \ -}) +#endif diff --git a/sysdeps/unix/sysv/linux/hppa/profil-counter.h b/sysdeps/unix/sysv/linux/hppa/sigcontextinfo.h similarity index 76% rename from sysdeps/unix/sysv/linux/hppa/profil-counter.h rename to sysdeps/unix/sysv/linux/hppa/sigcontextinfo.h index bea7611465..4089d17855 100644 --- a/sysdeps/unix/sysv/linux/hppa/profil-counter.h +++ b/sysdeps/unix/sysv/linux/hppa/sigcontextinfo.h @@ -1,5 +1,5 @@ /* Machine-dependent SIGPROF signal handler. PA-RISC version - Copyright (C) 1996-2019 Free Software Foundation, Inc. + Copyright (C) 2019 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,9 +16,15 @@ License along with the GNU C Library. If not, see . */ -static void -__profil_counter (int signr, siginfo_t *si, ucontext_t *uctx) +#ifndef _SIGCONTEXTINFO_H +#define _SIGCONTEXTINFO_H + +#include + +static inline uintptr_t +sigcontext_get_pc (const ucontext_t *ctx) { - unsigned long ip = uctx->uc_mcontext.sc_iaoq[0] & ~0x3; - profil_count ((void *) ip); + return ctx->uc_mcontext.sc_iaoq[0] & ~0x3; } + +#endif diff --git a/sysdeps/unix/sysv/linux/i386/profil-counter.h b/sysdeps/unix/sysv/linux/i386/profil-counter.h deleted file mode 100644 index d6bbc04be8..0000000000 --- a/sysdeps/unix/sysv/linux/i386/profil-counter.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Low-level statistical profiling support function. Linux/i386 version. - Copyright (C) 1996-2019 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 - -static void -__profil_counter (int signo, const SIGCONTEXT scp) -{ - profil_count ((void *) GET_PC (scp)); - - /* This is a hack to prevent the compiler from implementing the - above function call as a sibcall. The sibcall would overwrite - the signal context. */ - asm volatile (""); -} diff --git a/sysdeps/unix/sysv/linux/i386/register-dump.h b/sysdeps/unix/sysv/linux/i386/register-dump.h index 744e136ce7..8364238635 100644 --- a/sysdeps/unix/sysv/linux/i386/register-dump.h +++ b/sysdeps/unix/sysv/linux/i386/register-dump.h @@ -51,7 +51,7 @@ hexvalue (unsigned long int value, char *buf, size_t len) } static void -register_dump (int fd, struct sigcontext *ctx) +register_dump (int fd, struct ucontext_t *ctx) { char regs[21][8]; char fpregs[31][8]; @@ -68,27 +68,27 @@ register_dump (int fd, struct sigcontext *ctx) ++nr /* Generate strings of register contents. */ - hexvalue (ctx->eax, regs[0], 8); - hexvalue (ctx->ebx, regs[1], 8); - hexvalue (ctx->ecx, regs[2], 8); - hexvalue (ctx->edx, regs[3], 8); - hexvalue (ctx->esi, regs[4], 8); - hexvalue (ctx->edi, regs[5], 8); - hexvalue (ctx->ebp, regs[6], 8); - hexvalue (ctx->esp, regs[7], 8); - hexvalue (ctx->eip, regs[8], 8); - hexvalue (ctx->eflags, regs[9], 8); - hexvalue (ctx->cs, regs[10], 4); - hexvalue (ctx->ds, regs[11], 4); - hexvalue (ctx->es, regs[12], 4); - hexvalue (ctx->fs, regs[13], 4); - hexvalue (ctx->gs, regs[14], 4); - hexvalue (ctx->ss, regs[15], 4); - hexvalue (ctx->trapno, regs[16], 8); - hexvalue (ctx->err, regs[17], 8); - hexvalue (ctx->oldmask, regs[18], 8); - hexvalue (ctx->esp_at_signal, regs[19], 8); - hexvalue (ctx->cr2, regs[20], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_EAX], regs[0], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_EBX], regs[1], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_ECX], regs[2], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_EDX], regs[3], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_ESI], regs[4], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_EDI], regs[5], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_EBP], regs[6], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_ESP], regs[7], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_EIP], regs[8], 8); + hexvalue (ctx->uc_flags, regs[9], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_CS], regs[10], 4); + hexvalue (ctx->uc_mcontext.gregs[REG_DS], regs[11], 4); + hexvalue (ctx->uc_mcontext.gregs[REG_ES], regs[12], 4); + hexvalue (ctx->uc_mcontext.gregs[REG_FS], regs[13], 4); + hexvalue (ctx->uc_mcontext.gregs[REG_GS], regs[14], 4); + hexvalue (ctx->uc_mcontext.gregs[REG_SS], regs[15], 4); + hexvalue (ctx->uc_mcontext.gregs[REG_TRAPNO], regs[16], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_ERR], regs[17], 8); + hexvalue (ctx->uc_mcontext.oldmask, regs[18], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_UESP], regs[19], 8); + hexvalue (ctx->uc_mcontext.cr2, regs[20], 8); /* Generate the output. */ ADD_STRING ("Register dump:\n\n EAX: "); @@ -134,116 +134,112 @@ register_dump (int fd, struct sigcontext *ctx) ADD_STRING (" CR2: "); ADD_MEM (regs[20], 8); - if (ctx->fpstate != NULL) - { - - /* Generate output for the FPU control/status registers. */ - hexvalue (ctx->fpstate->cw, fpregs[0], 8); - hexvalue (ctx->fpstate->sw, fpregs[1], 8); - hexvalue (ctx->fpstate->tag, fpregs[2], 8); - hexvalue (ctx->fpstate->ipoff, fpregs[3], 8); - hexvalue (ctx->fpstate->cssel, fpregs[4], 4); - hexvalue (ctx->fpstate->dataoff, fpregs[5], 8); - hexvalue (ctx->fpstate->datasel, fpregs[6], 4); - - ADD_STRING ("\n\n FPUCW: "); - ADD_MEM (fpregs[0], 8); - ADD_STRING (" FPUSW: "); - ADD_MEM (fpregs[1], 8); - ADD_STRING (" TAG: "); - ADD_MEM (fpregs[2], 8); - ADD_STRING ("\n IPOFF: "); - ADD_MEM (fpregs[3], 8); - ADD_STRING (" CSSEL: "); - ADD_MEM (fpregs[4], 4); - ADD_STRING (" DATAOFF: "); - ADD_MEM (fpregs[5], 8); - ADD_STRING (" DATASEL: "); - ADD_MEM (fpregs[6], 4); - - /* Now the real FPU registers. */ - hexvalue (ctx->fpstate->_st[0].exponent, fpregs[7], 8); - hexvalue (ctx->fpstate->_st[0].significand[3] << 16 - | ctx->fpstate->_st[0].significand[2], fpregs[8], 8); - hexvalue (ctx->fpstate->_st[0].significand[1] << 16 - | ctx->fpstate->_st[0].significand[0], fpregs[9], 8); - hexvalue (ctx->fpstate->_st[1].exponent, fpregs[10], 8); - hexvalue (ctx->fpstate->_st[1].significand[3] << 16 - | ctx->fpstate->_st[1].significand[2], fpregs[11], 8); - hexvalue (ctx->fpstate->_st[1].significand[1] << 16 - | ctx->fpstate->_st[1].significand[0], fpregs[12], 8); - hexvalue (ctx->fpstate->_st[2].exponent, fpregs[13], 8); - hexvalue (ctx->fpstate->_st[2].significand[3] << 16 - | ctx->fpstate->_st[2].significand[2], fpregs[14], 8); - hexvalue (ctx->fpstate->_st[2].significand[1] << 16 - | ctx->fpstate->_st[2].significand[0], fpregs[15], 8); - hexvalue (ctx->fpstate->_st[3].exponent, fpregs[16], 8); - hexvalue (ctx->fpstate->_st[3].significand[3] << 16 - | ctx->fpstate->_st[3].significand[2], fpregs[17], 8); - hexvalue (ctx->fpstate->_st[3].significand[1] << 16 - | ctx->fpstate->_st[3].significand[0], fpregs[18], 8); - hexvalue (ctx->fpstate->_st[4].exponent, fpregs[19], 8); - hexvalue (ctx->fpstate->_st[4].significand[3] << 16 - | ctx->fpstate->_st[4].significand[2], fpregs[20], 8); - hexvalue (ctx->fpstate->_st[4].significand[1] << 16 - | ctx->fpstate->_st[4].significand[0], fpregs[21], 8); - hexvalue (ctx->fpstate->_st[5].exponent, fpregs[22], 8); - hexvalue (ctx->fpstate->_st[5].significand[3] << 16 - | ctx->fpstate->_st[5].significand[2], fpregs[23], 8); - hexvalue (ctx->fpstate->_st[5].significand[1] << 16 - | ctx->fpstate->_st[5].significand[0], fpregs[24], 8); - hexvalue (ctx->fpstate->_st[6].exponent, fpregs[25], 8); - hexvalue (ctx->fpstate->_st[6].significand[3] << 16 - | ctx->fpstate->_st[6].significand[2], fpregs[26], 8); - hexvalue (ctx->fpstate->_st[6].significand[1] << 16 - | ctx->fpstate->_st[6].significand[0], fpregs[27], 8); - hexvalue (ctx->fpstate->_st[7].exponent, fpregs[28], 8); - hexvalue (ctx->fpstate->_st[7].significand[3] << 16 - | ctx->fpstate->_st[7].significand[2], fpregs[29], 8); - hexvalue (ctx->fpstate->_st[7].significand[1] << 16 - | ctx->fpstate->_st[7].significand[0], fpregs[30], 8); - - ADD_STRING ("\n\n ST(0) "); - ADD_MEM (fpregs[7], 4); - ADD_STRING (" "); - ADD_MEM (fpregs[8], 8); - ADD_MEM (fpregs[9], 8); - ADD_STRING (" ST(1) "); - ADD_MEM (fpregs[10], 4); - ADD_STRING (" "); - ADD_MEM (fpregs[11], 8); - ADD_MEM (fpregs[12], 8); - ADD_STRING ("\n ST(2) "); - ADD_MEM (fpregs[13], 4); - ADD_STRING (" "); - ADD_MEM (fpregs[14], 8); - ADD_MEM (fpregs[15], 8); - ADD_STRING (" ST(3) "); - ADD_MEM (fpregs[16], 4); - ADD_STRING (" "); - ADD_MEM (fpregs[17], 8); - ADD_MEM (fpregs[18], 8); - ADD_STRING ("\n ST(4) "); - ADD_MEM (fpregs[19], 4); - ADD_STRING (" "); - ADD_MEM (fpregs[20], 8); - ADD_MEM (fpregs[21], 8); - ADD_STRING (" ST(5) "); - ADD_MEM (fpregs[22], 4); - ADD_STRING (" "); - ADD_MEM (fpregs[23], 8); - ADD_MEM (fpregs[24], 8); - ADD_STRING ("\n ST(6) "); - ADD_MEM (fpregs[25], 4); - ADD_STRING (" "); - ADD_MEM (fpregs[26], 8); - ADD_MEM (fpregs[27], 8); - ADD_STRING (" ST(7) "); - ADD_MEM (fpregs[28], 4); - ADD_STRING (" "); - ADD_MEM (fpregs[29], 8); - ADD_MEM (fpregs[30], 8); - } + /* Generate output for the FPU control/status registers. */ + hexvalue (ctx->__fpregs_mem.cw, fpregs[0], 8); + hexvalue (ctx->__fpregs_mem.sw, fpregs[1], 8); + hexvalue (ctx->__fpregs_mem.tag, fpregs[2], 8); + hexvalue (ctx->__fpregs_mem.ipoff, fpregs[3], 8); + hexvalue (ctx->__fpregs_mem.cssel, fpregs[4], 4); + hexvalue (ctx->__fpregs_mem.dataoff, fpregs[5], 8); + hexvalue (ctx->__fpregs_mem.datasel, fpregs[6], 4); + + ADD_STRING ("\n\n FPUCW: "); + ADD_MEM (fpregs[0], 8); + ADD_STRING (" FPUSW: "); + ADD_MEM (fpregs[1], 8); + ADD_STRING (" TAG: "); + ADD_MEM (fpregs[2], 8); + ADD_STRING ("\n IPOFF: "); + ADD_MEM (fpregs[3], 8); + ADD_STRING (" CSSEL: "); + ADD_MEM (fpregs[4], 4); + ADD_STRING (" DATAOFF: "); + ADD_MEM (fpregs[5], 8); + ADD_STRING (" DATASEL: "); + ADD_MEM (fpregs[6], 4); + + /* Now the real FPU registers. */ + hexvalue (ctx->__fpregs_mem._st[0].exponent, fpregs[7], 8); + hexvalue (ctx->__fpregs_mem._st[0].significand[3] << 16 + | ctx->__fpregs_mem._st[0].significand[2], fpregs[8], 8); + hexvalue (ctx->__fpregs_mem._st[0].significand[1] << 16 + | ctx->__fpregs_mem._st[0].significand[0], fpregs[9], 8); + hexvalue (ctx->__fpregs_mem._st[1].exponent, fpregs[10], 8); + hexvalue (ctx->__fpregs_mem._st[1].significand[3] << 16 + | ctx->__fpregs_mem._st[1].significand[2], fpregs[11], 8); + hexvalue (ctx->__fpregs_mem._st[1].significand[1] << 16 + | ctx->__fpregs_mem._st[1].significand[0], fpregs[12], 8); + hexvalue (ctx->__fpregs_mem._st[2].exponent, fpregs[13], 8); + hexvalue (ctx->__fpregs_mem._st[2].significand[3] << 16 + | ctx->__fpregs_mem._st[2].significand[2], fpregs[14], 8); + hexvalue (ctx->__fpregs_mem._st[2].significand[1] << 16 + | ctx->__fpregs_mem._st[2].significand[0], fpregs[15], 8); + hexvalue (ctx->__fpregs_mem._st[3].exponent, fpregs[16], 8); + hexvalue (ctx->__fpregs_mem._st[3].significand[3] << 16 + | ctx->__fpregs_mem._st[3].significand[2], fpregs[17], 8); + hexvalue (ctx->__fpregs_mem._st[3].significand[1] << 16 + | ctx->__fpregs_mem._st[3].significand[0], fpregs[18], 8); + hexvalue (ctx->__fpregs_mem._st[4].exponent, fpregs[19], 8); + hexvalue (ctx->__fpregs_mem._st[4].significand[3] << 16 + | ctx->__fpregs_mem._st[4].significand[2], fpregs[20], 8); + hexvalue (ctx->__fpregs_mem._st[4].significand[1] << 16 + | ctx->__fpregs_mem._st[4].significand[0], fpregs[21], 8); + hexvalue (ctx->__fpregs_mem._st[5].exponent, fpregs[22], 8); + hexvalue (ctx->__fpregs_mem._st[5].significand[3] << 16 + | ctx->__fpregs_mem._st[5].significand[2], fpregs[23], 8); + hexvalue (ctx->__fpregs_mem._st[5].significand[1] << 16 + | ctx->__fpregs_mem._st[5].significand[0], fpregs[24], 8); + hexvalue (ctx->__fpregs_mem._st[6].exponent, fpregs[25], 8); + hexvalue (ctx->__fpregs_mem._st[6].significand[3] << 16 + | ctx->__fpregs_mem._st[6].significand[2], fpregs[26], 8); + hexvalue (ctx->__fpregs_mem._st[6].significand[1] << 16 + | ctx->__fpregs_mem._st[6].significand[0], fpregs[27], 8); + hexvalue (ctx->__fpregs_mem._st[7].exponent, fpregs[28], 8); + hexvalue (ctx->__fpregs_mem._st[7].significand[3] << 16 + | ctx->__fpregs_mem._st[7].significand[2], fpregs[29], 8); + hexvalue (ctx->__fpregs_mem._st[7].significand[1] << 16 + | ctx->__fpregs_mem._st[7].significand[0], fpregs[30], 8); + + ADD_STRING ("\n\n ST(0) "); + ADD_MEM (fpregs[7], 4); + ADD_STRING (" "); + ADD_MEM (fpregs[8], 8); + ADD_MEM (fpregs[9], 8); + ADD_STRING (" ST(1) "); + ADD_MEM (fpregs[10], 4); + ADD_STRING (" "); + ADD_MEM (fpregs[11], 8); + ADD_MEM (fpregs[12], 8); + ADD_STRING ("\n ST(2) "); + ADD_MEM (fpregs[13], 4); + ADD_STRING (" "); + ADD_MEM (fpregs[14], 8); + ADD_MEM (fpregs[15], 8); + ADD_STRING (" ST(3) "); + ADD_MEM (fpregs[16], 4); + ADD_STRING (" "); + ADD_MEM (fpregs[17], 8); + ADD_MEM (fpregs[18], 8); + ADD_STRING ("\n ST(4) "); + ADD_MEM (fpregs[19], 4); + ADD_STRING (" "); + ADD_MEM (fpregs[20], 8); + ADD_MEM (fpregs[21], 8); + ADD_STRING (" ST(5) "); + ADD_MEM (fpregs[22], 4); + ADD_STRING (" "); + ADD_MEM (fpregs[23], 8); + ADD_MEM (fpregs[24], 8); + ADD_STRING ("\n ST(6) "); + ADD_MEM (fpregs[25], 4); + ADD_STRING (" "); + ADD_MEM (fpregs[26], 8); + ADD_MEM (fpregs[27], 8); + ADD_STRING (" ST(7) "); + ADD_MEM (fpregs[28], 4); + ADD_STRING (" "); + ADD_MEM (fpregs[29], 8); + ADD_MEM (fpregs[30], 8); ADD_STRING ("\n"); @@ -252,4 +248,4 @@ register_dump (int fd, struct sigcontext *ctx) } -#define REGISTER_DUMP register_dump (fd, &ctx) +#define REGISTER_DUMP register_dump (fd, ctx) diff --git a/sysdeps/unix/sysv/linux/i386/sigcontextinfo.h b/sysdeps/unix/sysv/linux/i386/sigcontextinfo.h index 789a127a58..d0f23f5f0e 100644 --- a/sysdeps/unix/sysv/linux/i386/sigcontextinfo.h +++ b/sysdeps/unix/sysv/linux/i386/sigcontextinfo.h @@ -16,5 +16,13 @@ License along with the GNU C Library; if not, see . */ -#define SIGCONTEXT struct sigcontext -#define GET_PC(ctx) ((void *) ctx.eip) +#ifndef _SIGCONTEXTINFO_H +#define _SIGCONTEXTINFO_H + +static inline uintptr_t +sigcontext_get_pc (const ucontext_t *ctx) +{ + return ctx->uc_mcontext.gregs[REG_EIP]; +} + +#endif diff --git a/sysdeps/unix/sysv/linux/ia64/profil-counter.h b/sysdeps/unix/sysv/linux/ia64/profil-counter.h deleted file mode 100644 index cafe0903c8..0000000000 --- a/sysdeps/unix/sysv/linux/ia64/profil-counter.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Machine-dependent SIGPROF signal handler. IA-64 version. - Copyright (C) 1996-2019 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 - . */ - -/* In many Unix systems signal handlers are called like this - and the interrupted PC is easily findable in the `struct sigcontext'. */ - -static void -__profil_counter (int signr, siginfo_t *si, struct sigcontext *scp) -{ - unsigned long ip = scp->sc_ip & ~0X3ULL, slot = scp->sc_ip & 0x3ull; - - /* Note: Linux/ia64 encodes the slot number in bits 0 and 1. We - want to multiply the slot number by four so we can use bins of - width 4 to get accurate instruction-level profiling. */ - profil_count ((void *) (ip + 4*slot)); -} diff --git a/sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h b/sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h index 06711a5eee..7e56c239bb 100644 --- a/sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h +++ b/sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h @@ -15,5 +15,15 @@ License along with the GNU C Library; if not, see . */ -#define SIGCONTEXT siginfo_t *_si, struct sigcontext * -#define GET_PC(ctx) ((ctx)->sc_ip) +#ifndef _SIGCONTEXTINFO_H +#define _SIGCONTEXTINFO_H + +/* Unlike other architectures, ia64 passes 'struct sigcontext' pointer as + the third argument to a sa_sigaction handler with SA_SIGINFO enabled. */ +static inline uintptr_t +sigcontext_get_pc (const struct sigcontext *ctx) +{ + return ctx->sc_ip; +} + +#endif diff --git a/sysdeps/unix/sysv/linux/m68k/register-dump.h b/sysdeps/unix/sysv/linux/m68k/register-dump.h index b9941e813e..69f8e4c3f0 100644 --- a/sysdeps/unix/sysv/linux/m68k/register-dump.h +++ b/sysdeps/unix/sysv/linux/m68k/register-dump.h @@ -39,35 +39,9 @@ */ -/* Linux saves only the call-clobbered registers in the sigcontext. We - need to use a trampoline that saves the rest so that the C code can - access them. We use the sc_fpstate field, since the handler is not - supposed to return anyway, thus it doesn't matter that it's clobbered. */ - -/* static */ void catch_segfault (int, int, struct sigcontext *); - -/* Dummy function so that we can use asm with arguments. */ -static void __attribute_used__ -__dummy__ (void) -{ - asm ("\n\ -catch_segfault:\n\ - move.l 12(%%sp),%%a0\n\ - lea %c0(%%a0),%%a0\n\ - /* Clear the first 4 bytes to make it a null fp state, just\n\ - in case the handler does return. */\n\ - clr.l (%%a0)+\n\ - movem.l %%d2-%%d7/%%a2-%%a6,(%%a0)\n" -#ifndef __mcoldfire__ - "fmovem.x %%fp2-%%fp7,11*4(%%a0)\n" -#elif defined __mcffpu__ - "fmovem.d %%fp2-%%fp7,11*4(%%a0)\n" -#endif - "jra real_catch_segfault" - : : "n" (offsetof (struct sigcontext, sc_fpstate))); -} -#define catch_segfault(a,b) \ - __attribute_used__ real_catch_segfault(a,b) +#define FPCONTEXT_SIZE 216 +#define uc_formatvec __glibc_reserved1[FPCONTEXT_SIZE/4] +#define uc_oldmask uc_sigmask.__val[0] static void hexvalue (unsigned long int value, char *buf, size_t len) @@ -78,13 +52,38 @@ hexvalue (unsigned long int value, char *buf, size_t len) } static void -register_dump (int fd, struct sigcontext *ctx) +register_dump (int fd, struct ucontext_t *ctx) { + /* Linux does not save the FP state in case of emulated floating point. */ +#ifndef __mcoldfire__ + __asm__ volatile (".chip 68k/68881\n\t" + "fmovem.x %%fp0-%%fp7, %0\n\t" + "fmovem.l %%fpcr, %1\n\t" + "fmovem.l %%fpsr, %2\n\t" + "fmovem.l %%fpiar, %3\n\t" + ".chip 68k" + : "=m" (*ctx->uc_mcontext.fpregs.f_fpregs), + "=m" (ctx->uc_mcontext.fpregs.f_pcr), + "=m" (ctx->uc_mcontext.fpregs.f_pcr), + "=m" (ctx->uc_mcontext.fpregs.f_pcr) + : /* no inputs. */ + : "memory"); +#elif defined __mcffpu__ + __asm__ volatile ("fmovemd %%fp0-%%fp7, %0\n\t" + "fmovel %%fpcr, %1\n\t" + "fmovel %%fpsr, %2\n\t" + "fmovel %%fpiar, %3\n\t" + : "=m" (*ctx->uc_mcontext.fpregs.f_fpregs), + "=m" (ctx->uc_mcontext.fpregs.f_pcr), + "=m" (ctx->uc_mcontext.fpregs.f_pcr), + "=m" (ctx->uc_mcontext.fpregs.f_pcr) + : /* no inputs. */ + : "memory"); +#endif + char regs[20][8]; char fpregs[11][24]; struct iovec iov[63], *next_iov = iov; - unsigned long *p = (unsigned long *) ctx->sc_fpstate + 1; - unsigned long *pfp = (unsigned long *) ctx->sc_fpregs; int i, j, fpreg_size; #define ADD_STRING(str) \ @@ -103,35 +102,33 @@ register_dump (int fd, struct sigcontext *ctx) #endif /* Generate strings of register contents. */ - hexvalue (ctx->sc_d0, regs[0], 8); - hexvalue (ctx->sc_d1, regs[1], 8); - hexvalue (*p++, regs[2], 8); - hexvalue (*p++, regs[3], 8); - hexvalue (*p++, regs[4], 8); - hexvalue (*p++, regs[5], 8); - hexvalue (*p++, regs[6], 8); - hexvalue (*p++, regs[7], 8); - hexvalue (ctx->sc_a0, regs[8], 8); - hexvalue (ctx->sc_a1, regs[9], 8); - hexvalue (*p++, regs[10], 8); - hexvalue (*p++, regs[11], 8); - hexvalue (*p++, regs[12], 8); - hexvalue (*p++, regs[13], 8); - hexvalue (*p++, regs[14], 8); - hexvalue (ctx->sc_usp, regs[15], 8); - hexvalue (ctx->sc_pc, regs[16], 8); - hexvalue (ctx->sc_sr, regs[17], 4); - hexvalue (ctx->sc_mask, regs[18], 8); - hexvalue (ctx->sc_formatvec & 0xfff, regs[19], 4); - for (i = 0; i < 2; i++) - for (j = 0; j < fpreg_size; j += 8) - hexvalue (*pfp++, fpregs[i] + j, 8); - for (i = 2; i < 8; i++) + hexvalue (ctx->uc_mcontext.gregs[R_D0], regs[0], 8); + hexvalue (ctx->uc_mcontext.gregs[R_D1], regs[1], 8); + hexvalue (ctx->uc_mcontext.gregs[R_D2], regs[2], 8); + hexvalue (ctx->uc_mcontext.gregs[R_D3], regs[3], 8); + hexvalue (ctx->uc_mcontext.gregs[R_D4], regs[4], 8); + hexvalue (ctx->uc_mcontext.gregs[R_D5], regs[5], 8); + hexvalue (ctx->uc_mcontext.gregs[R_D6], regs[6], 8); + hexvalue (ctx->uc_mcontext.gregs[R_D7], regs[7], 8); + hexvalue (ctx->uc_mcontext.gregs[R_A0], regs[8], 8); + hexvalue (ctx->uc_mcontext.gregs[R_A1], regs[9], 8); + hexvalue (ctx->uc_mcontext.gregs[R_A2], regs[10], 8); + hexvalue (ctx->uc_mcontext.gregs[R_A3], regs[11], 8); + hexvalue (ctx->uc_mcontext.gregs[R_A4], regs[12], 8); + hexvalue (ctx->uc_mcontext.gregs[R_A5], regs[13], 8); + hexvalue (ctx->uc_mcontext.gregs[R_A6], regs[14], 8); + hexvalue (ctx->uc_mcontext.gregs[R_SP], regs[15], 8); + hexvalue (ctx->uc_mcontext.gregs[R_PC], regs[16], 8); + hexvalue (ctx->uc_mcontext.gregs[R_PS], regs[17], 4); + hexvalue (ctx->uc_oldmask, regs[18], 8); + hexvalue (ctx->uc_formatvec & 0xfff, regs[19], 4); + + for (i = 0; i < 8; i++) for (j = 0; j < fpreg_size; j += 8) - hexvalue (*p++, fpregs[i] + j, 8); - hexvalue (ctx->sc_fpcntl[0], fpregs[8], 8); - hexvalue (ctx->sc_fpcntl[1], fpregs[9], 8); - hexvalue (ctx->sc_fpcntl[2], fpregs[10], 8); + hexvalue (ctx->uc_mcontext.fpregs.f_fpregs[i][j/8], fpregs[i] + j, 8); + hexvalue (ctx->uc_mcontext.fpregs.f_pcr, fpregs[8], 8); + hexvalue (ctx->uc_mcontext.fpregs.f_psr, fpregs[9], 8); + hexvalue (ctx->uc_mcontext.fpregs.f_fpiaddr, fpregs[10], 8); /* Generate the output. */ ADD_STRING ("Register dump:\n\n D0: "); diff --git a/sysdeps/unix/sysv/linux/m68k/sigcontextinfo.h b/sysdeps/unix/sysv/linux/m68k/sigcontextinfo.h index 27bfe6e747..b98fd28c11 100644 --- a/sysdeps/unix/sysv/linux/m68k/sigcontextinfo.h +++ b/sysdeps/unix/sysv/linux/m68k/sigcontextinfo.h @@ -16,5 +16,13 @@ License along with the GNU C Library. If not, see . */ -#define SIGCONTEXT int _code, struct sigcontext * -#define GET_PC(ctx) ((void *) (ctx)->sc_pc) +#ifndef _SIGCONTEXTINFO_H +#define _SIGCONTEXTINFO_H + +static inline uintptr_t +sigcontext_get_pc (const ucontext_t *ctx) +{ + return ctx->uc_mcontext.gregs[R_PC]; +} + +#endif diff --git a/sysdeps/unix/sysv/linux/microblaze/profil-counter.h b/sysdeps/unix/sysv/linux/microblaze/profil-counter.h deleted file mode 100644 index 8a6a0bcf3d..0000000000 --- a/sysdeps/unix/sysv/linux/microblaze/profil-counter.h +++ /dev/null @@ -1,2 +0,0 @@ -/* We can use the ix86 version. */ -#include diff --git a/sysdeps/unix/sysv/linux/microblaze/sigcontextinfo.h b/sysdeps/unix/sysv/linux/microblaze/sigcontextinfo.h index f8d7b858ea..7978fc3268 100644 --- a/sysdeps/unix/sysv/linux/microblaze/sigcontextinfo.h +++ b/sysdeps/unix/sysv/linux/microblaze/sigcontextinfo.h @@ -16,5 +16,13 @@ License along with the GNU C Library; if not, see . */ -#define SIGCONTEXT int _code, ucontext_t * -#define GET_PC(ctx) ((void *) (ctx)->uc_mcontext.regs.pc) +#ifndef _SIGCONTEXTINFO_H +#define _SIGCONTEXTINFO_H + +static inline uintptr_t +sigcontext_get_pc (const ucontext_t *ctx) +{ + return ctx->uc_mcontext.regs.pc; +} + +#endif diff --git a/sysdeps/unix/sysv/linux/mips/profil-counter.h b/sysdeps/unix/sysv/linux/mips/profil-counter.h deleted file mode 100644 index 8a6a0bcf3d..0000000000 --- a/sysdeps/unix/sysv/linux/mips/profil-counter.h +++ /dev/null @@ -1,2 +0,0 @@ -/* We can use the ix86 version. */ -#include diff --git a/sysdeps/unix/sysv/linux/mips/sigcontextinfo.h b/sysdeps/unix/sysv/linux/mips/sigcontextinfo.h index a28d8b23c7..89d831f6d9 100644 --- a/sysdeps/unix/sysv/linux/mips/sigcontextinfo.h +++ b/sysdeps/unix/sysv/linux/mips/sigcontextinfo.h @@ -16,17 +16,13 @@ License along with the GNU C Library. If not, see . */ - -#include - -#if _MIPS_SIM == _ABIO32 - -#define SIGCONTEXT unsigned long _code, struct sigcontext * -#define GET_PC(ctx) ((void *) (unsigned long) ctx->sc_pc) - -#else - -#define SIGCONTEXT unsigned long _code, ucontext_t * -#define GET_PC(ctx) ((void *) (unsigned long) ctx->uc_mcontext.pc) +#ifndef _SIGCONTEXTINFO_H +#define _SIGCONTEXTINFO_H + +static inline uintptr_t +sigcontext_get_pc (const ucontext_t *ctx) +{ + return ctx->uc_mcontext.pc; +} #endif diff --git a/sysdeps/unix/sysv/linux/nios2/profil-counter.h b/sysdeps/unix/sysv/linux/nios2/profil-counter.h deleted file mode 100644 index 8a6a0bcf3d..0000000000 --- a/sysdeps/unix/sysv/linux/nios2/profil-counter.h +++ /dev/null @@ -1,2 +0,0 @@ -/* We can use the ix86 version. */ -#include diff --git a/sysdeps/unix/sysv/linux/nios2/sigcontextinfo.h b/sysdeps/unix/sysv/linux/nios2/sigcontextinfo.h index dbbb47b50d..f388dcc35c 100644 --- a/sysdeps/unix/sysv/linux/nios2/sigcontextinfo.h +++ b/sysdeps/unix/sysv/linux/nios2/sigcontextinfo.h @@ -16,20 +16,13 @@ License along with the GNU C Library; if not, see . */ -#include -#include "kernel-features.h" +#ifndef _SIGCONTEXTINFO_H +#define _SIGCONTEXTINFO_H -#define SIGCONTEXT siginfo_t *_si, ucontext_t * -#define GET_PC(ctx) ((void *) (ctx)->uc_mcontext.regs[27]) +static inline uintptr_t +sigcontext_get_pc (const ucontext_t *ctx) +{ + return ctx->uc_mcontext.regs[27]; +} -/* There is no reliable way to get the sigcontext unless we use a - three-argument signal handler. */ -#define __sigaction(sig, act, oact) ({ \ - (act)->sa_flags |= SA_SIGINFO; \ - (__sigaction) (sig, act, oact); \ -}) - -#define sigaction(sig, act, oact) ({ \ - (act)->sa_flags |= SA_SIGINFO; \ - (sigaction) (sig, act, oact); \ -}) +#endif diff --git a/sysdeps/unix/sysv/linux/powerpc/profil-counter.h b/sysdeps/unix/sysv/linux/powerpc/profil-counter.h deleted file mode 100644 index 8a6a0bcf3d..0000000000 --- a/sysdeps/unix/sysv/linux/powerpc/profil-counter.h +++ /dev/null @@ -1,2 +0,0 @@ -/* We can use the ix86 version. */ -#include diff --git a/sysdeps/unix/sysv/linux/powerpc/sigcontextinfo.h b/sysdeps/unix/sysv/linux/powerpc/sigcontextinfo.h index 0c31bdcfe0..3cfba22c74 100644 --- a/sysdeps/unix/sysv/linux/powerpc/sigcontextinfo.h +++ b/sysdeps/unix/sysv/linux/powerpc/sigcontextinfo.h @@ -15,7 +15,19 @@ License along with the GNU C Library; if not, see . */ +#ifndef _SIGCONTEXTINFO_H +#define _SIGCONTEXTINFO_H + #include -#define SIGCONTEXT struct sigcontext * -#define GET_PC(ctx) ((void *)((ctx)->regs->nip)) +static inline uintptr_t +sigcontext_get_pc (const ucontext_t *ctx) +{ +#ifdef __powerpc64__ + return ctx->uc_mcontext.gp_regs[PT_NIP]; +#else + return ctx->uc_mcontext.uc_regs->gregs[PT_NIP]; +#endif +} + +#endif diff --git a/sysdeps/unix/sysv/linux/x86_64/profil-counter.h b/sysdeps/unix/sysv/linux/profil-counter.h similarity index 66% rename from sysdeps/unix/sysv/linux/x86_64/profil-counter.h rename to sysdeps/unix/sysv/linux/profil-counter.h index 48a266e3ef..50af90cb13 100644 --- a/sysdeps/unix/sysv/linux/x86_64/profil-counter.h +++ b/sysdeps/unix/sysv/linux/profil-counter.h @@ -1,11 +1,11 @@ -/* Low-level statistical profiling support function. Linux/x86-64 version. +/* Low-level statistical profiling support function. Linux version. Copyright (C) 2001-2019 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. + 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 @@ -19,10 +19,11 @@ #include #include +/* sa_sigaction signature to use along SA_SIGINFO. */ static void -__profil_counter (int signo, SIGCONTEXT scp) +__profil_counter (int signo, siginfo_t *info, void *ctx) { - profil_count ((void *) GET_PC (scp)); + profil_count (sigcontext_get_pc (ctx)); /* This is a hack to prevent the compiler from implementing the above function call as a sibcall. The sibcall would overwrite diff --git a/sysdeps/unix/sysv/linux/riscv/profil-counter.h b/sysdeps/unix/sysv/linux/riscv/profil-counter.h deleted file mode 100644 index 8ed88f12a0..0000000000 --- a/sysdeps/unix/sysv/linux/riscv/profil-counter.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Low-level statistical profiling support function. Linux/RISC-V version. - Copyright (C) 1996-2019 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 - -static void -__profil_counter (int signo, const SIGCONTEXT scp) -{ - profil_count ((void *) GET_PC (scp)); - - /* This is a hack to prevent the compiler from implementing the - above function call as a sibcall. The sibcall would overwrite - the signal context. */ - asm volatile (""); -} diff --git a/sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h b/sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h index 27ed9bdb87..f88b86dd86 100644 --- a/sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h +++ b/sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h @@ -16,7 +16,15 @@ License along with the GNU C Library. If not, see . */ +#ifndef _SIGCONTEXTINFO_H +#define _SIGCONTEXTINFO_H + #include -#define SIGCONTEXT siginfo_t *_si, ucontext_t * -#define GET_PC(ctx) ((void *) ctx->uc_mcontext.__gregs[REG_PC]) +static inline uintptr_t +sigcontext_get_pc (const ucontext_t *ctx) +{ + return ctx->uc_mcontext.__gregs[REG_PC]; +} + +#endif diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/profil-counter.h b/sysdeps/unix/sysv/linux/s390/s390-32/profil-counter.h deleted file mode 100644 index 47ab8f38e0..0000000000 --- a/sysdeps/unix/sysv/linux/s390/s390-32/profil-counter.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Low-level statistical profiling support function. Linux/s390 version. - Copyright (C) 2000-2019 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 - -static void -__profil_counter (int signo, SIGCONTEXT scp) -{ - profil_count((void *) ((unsigned long) GET_PC (scp) & 0x7fffffffUL)); -} diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/register-dump.h b/sysdeps/unix/sysv/linux/s390/s390-32/register-dump.h index bd69e8dd7d..0ad389d538 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/register-dump.h +++ b/sysdeps/unix/sysv/linux/s390/s390-32/register-dump.h @@ -45,7 +45,7 @@ hexvalue (unsigned long int value, char *buf, size_t len) } static void -register_dump (int fd, struct sigcontext *ctx) +register_dump (int fd, struct ucontext_t *ctx) { char regs[19][8]; struct iovec iov[40]; @@ -61,24 +61,24 @@ register_dump (int fd, struct sigcontext *ctx) ++nr /* Generate strings of register contents. */ - hexvalue (ctx->sregs->regs.gprs[0], regs[0], 8); - hexvalue (ctx->sregs->regs.gprs[1], regs[1], 8); - hexvalue (ctx->sregs->regs.gprs[2], regs[2], 8); - hexvalue (ctx->sregs->regs.gprs[3], regs[3], 8); - hexvalue (ctx->sregs->regs.gprs[4], regs[4], 8); - hexvalue (ctx->sregs->regs.gprs[5], regs[5], 8); - hexvalue (ctx->sregs->regs.gprs[6], regs[6], 8); - hexvalue (ctx->sregs->regs.gprs[7], regs[7], 8); - hexvalue (ctx->sregs->regs.gprs[8], regs[8], 8); - hexvalue (ctx->sregs->regs.gprs[9], regs[9], 8); - hexvalue (ctx->sregs->regs.gprs[10], regs[10], 8); - hexvalue (ctx->sregs->regs.gprs[11], regs[11], 8); - hexvalue (ctx->sregs->regs.gprs[12], regs[12], 8); - hexvalue (ctx->sregs->regs.gprs[13], regs[13], 8); - hexvalue (ctx->sregs->regs.gprs[14], regs[14], 8); - hexvalue (ctx->sregs->regs.gprs[15], regs[15], 8); - hexvalue (ctx->sregs->regs.psw.mask, regs[16], 8); - hexvalue (ctx->sregs->regs.psw.addr, regs[17], 8); + hexvalue (ctx->uc_mcontext.gregs[0], regs[0], 8); + hexvalue (ctx->uc_mcontext.gregs[1], regs[1], 8); + hexvalue (ctx->uc_mcontext.gregs[2], regs[2], 8); + hexvalue (ctx->uc_mcontext.gregs[3], regs[3], 8); + hexvalue (ctx->uc_mcontext.gregs[4], regs[4], 8); + hexvalue (ctx->uc_mcontext.gregs[5], regs[5], 8); + hexvalue (ctx->uc_mcontext.gregs[6], regs[6], 8); + hexvalue (ctx->uc_mcontext.gregs[7], regs[7], 8); + hexvalue (ctx->uc_mcontext.gregs[8], regs[8], 8); + hexvalue (ctx->uc_mcontext.gregs[9], regs[9], 8); + hexvalue (ctx->uc_mcontext.gregs[10], regs[10], 8); + hexvalue (ctx->uc_mcontext.gregs[11], regs[11], 8); + hexvalue (ctx->uc_mcontext.gregs[12], regs[12], 8); + hexvalue (ctx->uc_mcontext.gregs[13], regs[13], 8); + hexvalue (ctx->uc_mcontext.gregs[14], regs[14], 8); + hexvalue (ctx->uc_mcontext.gregs[15], regs[15], 8); + hexvalue (ctx->uc_mcontext.psw.mask, regs[16], 8); + hexvalue (ctx->uc_mcontext.psw.addr, regs[17], 8); /* Generate the output. */ ADD_STRING ("Register dump:\n\n GPR0: "); diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/profil-counter.h b/sysdeps/unix/sysv/linux/s390/s390-64/profil-counter.h deleted file mode 100644 index 41301afe9c..0000000000 --- a/sysdeps/unix/sysv/linux/s390/s390-64/profil-counter.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Low-level statistical profiling support function. Linux/s390 version. - Copyright (C) 2000-2019 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 - -static void -__profil_counter (int signo, SIGCONTEXT scp) -{ - profil_count ((void *) GET_PC (scp)); -} diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/register-dump.h b/sysdeps/unix/sysv/linux/s390/s390-64/register-dump.h index f3af16b223..a00516746a 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/register-dump.h +++ b/sysdeps/unix/sysv/linux/s390/s390-64/register-dump.h @@ -48,7 +48,7 @@ hexvalue (unsigned long int value, char *buf, size_t len) } static void -register_dump (int fd, struct sigcontext *ctx) +register_dump (int fd, struct ucontext_t *ctx) { char regs[19][16]; struct iovec iov[40]; @@ -64,24 +64,24 @@ register_dump (int fd, struct sigcontext *ctx) ++nr /* Generate strings of register contents. */ - hexvalue (ctx->sregs->regs.gprs[0], regs[0], 16); - hexvalue (ctx->sregs->regs.gprs[1], regs[1], 16); - hexvalue (ctx->sregs->regs.gprs[2], regs[2], 16); - hexvalue (ctx->sregs->regs.gprs[3], regs[3], 16); - hexvalue (ctx->sregs->regs.gprs[4], regs[4], 16); - hexvalue (ctx->sregs->regs.gprs[5], regs[5], 16); - hexvalue (ctx->sregs->regs.gprs[6], regs[6], 16); - hexvalue (ctx->sregs->regs.gprs[7], regs[7], 16); - hexvalue (ctx->sregs->regs.gprs[8], regs[8], 16); - hexvalue (ctx->sregs->regs.gprs[9], regs[9], 16); - hexvalue (ctx->sregs->regs.gprs[10], regs[10], 16); - hexvalue (ctx->sregs->regs.gprs[11], regs[11], 16); - hexvalue (ctx->sregs->regs.gprs[12], regs[12], 16); - hexvalue (ctx->sregs->regs.gprs[13], regs[13], 16); - hexvalue (ctx->sregs->regs.gprs[14], regs[14], 16); - hexvalue (ctx->sregs->regs.gprs[15], regs[15], 16); - hexvalue (ctx->sregs->regs.psw.mask, regs[16], 16); - hexvalue (ctx->sregs->regs.psw.addr, regs[17], 16); + hexvalue (ctx->uc_mcontext.gregs[0], regs[0], 16); + hexvalue (ctx->uc_mcontext.gregs[1], regs[1], 16); + hexvalue (ctx->uc_mcontext.gregs[2], regs[2], 16); + hexvalue (ctx->uc_mcontext.gregs[3], regs[3], 16); + hexvalue (ctx->uc_mcontext.gregs[4], regs[4], 16); + hexvalue (ctx->uc_mcontext.gregs[5], regs[5], 16); + hexvalue (ctx->uc_mcontext.gregs[6], regs[6], 16); + hexvalue (ctx->uc_mcontext.gregs[7], regs[7], 16); + hexvalue (ctx->uc_mcontext.gregs[8], regs[8], 16); + hexvalue (ctx->uc_mcontext.gregs[9], regs[9], 16); + hexvalue (ctx->uc_mcontext.gregs[10], regs[10], 16); + hexvalue (ctx->uc_mcontext.gregs[11], regs[11], 16); + hexvalue (ctx->uc_mcontext.gregs[12], regs[12], 16); + hexvalue (ctx->uc_mcontext.gregs[13], regs[13], 16); + hexvalue (ctx->uc_mcontext.gregs[14], regs[14], 16); + hexvalue (ctx->uc_mcontext.gregs[15], regs[15], 16); + hexvalue (ctx->uc_mcontext.psw.mask, regs[16], 16); + hexvalue (ctx->uc_mcontext.psw.addr, regs[17], 16); /* Generate the output. */ ADD_STRING ("Register dump:\n\n GPR0: "); diff --git a/sysdeps/unix/sysv/linux/s390/sigcontextinfo.h b/sysdeps/unix/sysv/linux/s390/sigcontextinfo.h index 6f911fedfc..576dc6126b 100644 --- a/sysdeps/unix/sysv/linux/s390/sigcontextinfo.h +++ b/sysdeps/unix/sysv/linux/s390/sigcontextinfo.h @@ -16,7 +16,19 @@ License along with the GNU C Library; if not, see . */ +#ifndef _SIGCONTEXTINFO_H +#define _SIGCONTEXTINFO_H + #include -#define SIGCONTEXT struct sigcontext * -#define GET_PC(ctx) ((void *)((ctx)->sregs->regs.psw.addr)) +static inline uintptr_t +sigcontext_get_pc (const ucontext_t *ctx) +{ +#ifdef __s390x__ + return ctx->uc_mcontext.psw.addr; +#else + return ctx->uc_mcontext.psw.addr & 0x7FFFFFFF; +#endif +} + +#endif diff --git a/sysdeps/unix/sysv/linux/sh/profil-counter.h b/sysdeps/unix/sysv/linux/sh/profil-counter.h deleted file mode 100644 index 691142bc74..0000000000 --- a/sysdeps/unix/sysv/linux/sh/profil-counter.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Low-level statistical profiling support function. Linux/SH version. - Copyright (C) 1996-2019 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 - -static void -__profil_counter (int signo, int _a2, int _a3, int _a4, struct sigcontext sc) -{ - void *pc; - pc = (void *) sc.sc_pc; - profil_count (pc); - - /* This is a hack to prevent the compiler from implementing the - above function call as a sibcall. The sibcall would overwrite - the signal context. */ - asm volatile (""); -} diff --git a/sysdeps/unix/sysv/linux/sh/sh4/register-dump.h b/sysdeps/unix/sysv/linux/sh/register-dump.h similarity index 62% rename from sysdeps/unix/sysv/linux/sh/sh4/register-dump.h rename to sysdeps/unix/sysv/linux/sh/register-dump.h index a35012a9c5..3bcc998290 100644 --- a/sysdeps/unix/sysv/linux/sh/sh4/register-dump.h +++ b/sysdeps/unix/sysv/linux/sh/register-dump.h @@ -53,7 +53,7 @@ hexvalue (unsigned long int value, char *buf, size_t len) } static void -register_dump (int fd, struct sigcontext *ctx) +register_dump (int fd, struct ucontext_t *ctx) { char regs[22][8]; struct iovec iov[22 * 2 + 34 * 2 + 2]; @@ -69,28 +69,28 @@ register_dump (int fd, struct sigcontext *ctx) ++nr /* Generate strings of register contents. */ - hexvalue (ctx->sc_regs[0], regs[0], 8); - hexvalue (ctx->sc_regs[1], regs[1], 8); - hexvalue (ctx->sc_regs[2], regs[2], 8); - hexvalue (ctx->sc_regs[3], regs[3], 8); - hexvalue (ctx->sc_regs[4], regs[4], 8); - hexvalue (ctx->sc_regs[5], regs[5], 8); - hexvalue (ctx->sc_regs[6], regs[6], 8); - hexvalue (ctx->sc_regs[7], regs[7], 8); - hexvalue (ctx->sc_regs[8], regs[8], 8); - hexvalue (ctx->sc_regs[9], regs[9], 8); - hexvalue (ctx->sc_regs[10], regs[10], 8); - hexvalue (ctx->sc_regs[11], regs[11], 8); - hexvalue (ctx->sc_regs[12], regs[12], 8); - hexvalue (ctx->sc_regs[13], regs[13], 8); - hexvalue (ctx->sc_regs[14], regs[14], 8); - hexvalue (ctx->sc_regs[15], regs[15], 8); - hexvalue (ctx->sc_macl, regs[16], 8); - hexvalue (ctx->sc_mach, regs[17], 8); - hexvalue (ctx->sc_pc, regs[18], 8); - hexvalue (ctx->sc_pr, regs[19], 8); - hexvalue (ctx->sc_gbr, regs[20], 8); - hexvalue (ctx->sc_sr, regs[21], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_R0], regs[0], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_R1], regs[1], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_R2], regs[2], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_R3], regs[3], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_R4], regs[4], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_R5], regs[5], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_R6], regs[6], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_R7], regs[7], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_R8], regs[8], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_R9], regs[9], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_R10], regs[10], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_R11], regs[11], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_R12], regs[12], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_R13], regs[13], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_R14], regs[14], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_R15], regs[15], 8); + hexvalue (ctx->uc_mcontext.macl, regs[16], 8); + hexvalue (ctx->uc_mcontext.mach, regs[17], 8); + hexvalue (ctx->uc_mcontext.pc, regs[18], 8); + hexvalue (ctx->uc_mcontext.pr, regs[19], 8); + hexvalue (ctx->uc_mcontext.gbr, regs[20], 8); + hexvalue (ctx->uc_mcontext.sr, regs[21], 8); /* Generate the output. */ ADD_STRING ("Register dump:\n\n R0: "); @@ -144,42 +144,42 @@ register_dump (int fd, struct sigcontext *ctx) #ifdef __SH_FPU_ANY__ char fpregs[34][8]; - if (ctx->sc_ownedfp != 0) + if (ctx->uc_mcontext.ownedfp != 0) { - hexvalue (ctx->sc_fpregs[0], fpregs[0], 8); - hexvalue (ctx->sc_fpregs[1], fpregs[1], 8); - hexvalue (ctx->sc_fpregs[2], fpregs[2], 8); - hexvalue (ctx->sc_fpregs[3], fpregs[3], 8); - hexvalue (ctx->sc_fpregs[4], fpregs[4], 8); - hexvalue (ctx->sc_fpregs[5], fpregs[5], 8); - hexvalue (ctx->sc_fpregs[6], fpregs[6], 8); - hexvalue (ctx->sc_fpregs[7], fpregs[7], 8); - hexvalue (ctx->sc_fpregs[8], fpregs[8], 8); - hexvalue (ctx->sc_fpregs[9], fpregs[9], 8); - hexvalue (ctx->sc_fpregs[10], fpregs[10], 8); - hexvalue (ctx->sc_fpregs[11], fpregs[11], 8); - hexvalue (ctx->sc_fpregs[12], fpregs[12], 8); - hexvalue (ctx->sc_fpregs[13], fpregs[13], 8); - hexvalue (ctx->sc_fpregs[14], fpregs[14], 8); - hexvalue (ctx->sc_fpregs[15], fpregs[15], 8); - hexvalue (ctx->sc_xfpregs[0], fpregs[16], 8); - hexvalue (ctx->sc_xfpregs[1], fpregs[17], 8); - hexvalue (ctx->sc_xfpregs[2], fpregs[18], 8); - hexvalue (ctx->sc_xfpregs[3], fpregs[19], 8); - hexvalue (ctx->sc_xfpregs[4], fpregs[20], 8); - hexvalue (ctx->sc_xfpregs[5], fpregs[21], 8); - hexvalue (ctx->sc_xfpregs[6], fpregs[22], 8); - hexvalue (ctx->sc_xfpregs[7], fpregs[23], 8); - hexvalue (ctx->sc_xfpregs[8], fpregs[24], 8); - hexvalue (ctx->sc_xfpregs[9], fpregs[25], 8); - hexvalue (ctx->sc_xfpregs[10], fpregs[26], 8); - hexvalue (ctx->sc_xfpregs[11], fpregs[27], 8); - hexvalue (ctx->sc_xfpregs[12], fpregs[28], 8); - hexvalue (ctx->sc_xfpregs[13], fpregs[29], 8); - hexvalue (ctx->sc_xfpregs[14], fpregs[30], 8); - hexvalue (ctx->sc_xfpregs[15], fpregs[31], 8); - hexvalue (ctx->sc_fpscr, fpregs[32], 8); - hexvalue (ctx->sc_fpul, fpregs[33], 8); + hexvalue (ctx->uc_mcontext.fpregs[0], fpregs[0], 8); + hexvalue (ctx->uc_mcontext.fpregs[1], fpregs[1], 8); + hexvalue (ctx->uc_mcontext.fpregs[2], fpregs[2], 8); + hexvalue (ctx->uc_mcontext.fpregs[3], fpregs[3], 8); + hexvalue (ctx->uc_mcontext.fpregs[4], fpregs[4], 8); + hexvalue (ctx->uc_mcontext.fpregs[5], fpregs[5], 8); + hexvalue (ctx->uc_mcontext.fpregs[6], fpregs[6], 8); + hexvalue (ctx->uc_mcontext.fpregs[7], fpregs[7], 8); + hexvalue (ctx->uc_mcontext.fpregs[8], fpregs[8], 8); + hexvalue (ctx->uc_mcontext.fpregs[9], fpregs[9], 8); + hexvalue (ctx->uc_mcontext.fpregs[10], fpregs[10], 8); + hexvalue (ctx->uc_mcontext.fpregs[11], fpregs[11], 8); + hexvalue (ctx->uc_mcontext.fpregs[12], fpregs[12], 8); + hexvalue (ctx->uc_mcontext.fpregs[13], fpregs[13], 8); + hexvalue (ctx->uc_mcontext.fpregs[14], fpregs[14], 8); + hexvalue (ctx->uc_mcontext.fpregs[15], fpregs[15], 8); + hexvalue (ctx->uc_mcontext.xfpregs[0], fpregs[16], 8); + hexvalue (ctx->uc_mcontext.xfpregs[1], fpregs[17], 8); + hexvalue (ctx->uc_mcontext.xfpregs[2], fpregs[18], 8); + hexvalue (ctx->uc_mcontext.xfpregs[3], fpregs[19], 8); + hexvalue (ctx->uc_mcontext.xfpregs[4], fpregs[20], 8); + hexvalue (ctx->uc_mcontext.xfpregs[5], fpregs[21], 8); + hexvalue (ctx->uc_mcontext.xfpregs[6], fpregs[22], 8); + hexvalue (ctx->uc_mcontext.xfpregs[7], fpregs[23], 8); + hexvalue (ctx->uc_mcontext.xfpregs[8], fpregs[24], 8); + hexvalue (ctx->uc_mcontext.xfpregs[9], fpregs[25], 8); + hexvalue (ctx->uc_mcontext.xfpregs[10], fpregs[26], 8); + hexvalue (ctx->uc_mcontext.xfpregs[11], fpregs[27], 8); + hexvalue (ctx->uc_mcontext.xfpregs[12], fpregs[28], 8); + hexvalue (ctx->uc_mcontext.xfpregs[13], fpregs[29], 8); + hexvalue (ctx->uc_mcontext.xfpregs[14], fpregs[30], 8); + hexvalue (ctx->uc_mcontext.xfpregs[15], fpregs[31], 8); + hexvalue (ctx->uc_mcontext.fpscr, fpregs[32], 8); + hexvalue (ctx->uc_mcontext.fpul, fpregs[33], 8); ADD_STRING ("\n\n FR0: "); ADD_MEM (fpregs[0], 8); @@ -260,4 +260,4 @@ register_dump (int fd, struct sigcontext *ctx) } -#define REGISTER_DUMP register_dump (fd, &ctx) +#define REGISTER_DUMP register_dump (fd, ctx) diff --git a/sysdeps/unix/sysv/linux/sh/sh3/register-dump.h b/sysdeps/unix/sysv/linux/sh/sh3/register-dump.h deleted file mode 100644 index 137ba79c8c..0000000000 --- a/sysdeps/unix/sysv/linux/sh/sh3/register-dump.h +++ /dev/null @@ -1,150 +0,0 @@ -/* Dump registers. - Copyright (C) 1999-2019 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 <_itoa.h> - -/* We will print the register dump in this format: - - R0: XXXXXXXX R1: XXXXXXXX R2: XXXXXXXX R3: XXXXXXXX - R4: XXXXXXXX R5: XXXXXXXX R6: XXXXXXXX R7: XXXXXXXX - R8: XXXXXXXX R9: XXXXXXXX R10: XXXXXXXX R11: XXXXXXXX - R12: XXXXXXXX R13: XXXXXXXX R14: XXXXXXXX R15: XXXXXXXX - -MACL: XXXXXXXX MACH: XXXXXXXX - - PC: XXXXXXXX PR: XXXXXXXX GBR: XXXXXXXX SR: XXXXXXXX - - FR0: XXXXXXXX FR1: XXXXXXXX FR2: XXXXXXXX FR3: XXXXXXXX - FR4: XXXXXXXX FR5: XXXXXXXX FR6: XXXXXXXX FR7: XXXXXXXX - FR8: XXXXXXXX FR9: XXXXXXXX FR10: XXXXXXXX FR11: XXXXXXXX -FR12: XXXXXXXX FR13: XXXXXXXX FR14: XXXXXXXX FR15: XXXXXXXX - - XR0: XXXXXXXX XR1: XXXXXXXX XR2: XXXXXXXX XR3: XXXXXXXX - XR4: XXXXXXXX XR5: XXXXXXXX XR6: XXXXXXXX XR7: XXXXXXXX - XR8: XXXXXXXX XR9: XXXXXXXX XR10: XXXXXXXX XR11: XXXXXXXX -XR12: XXXXXXXX XR13: XXXXXXXX XR14: XXXXXXXX XR15: XXXXXXXX - -FPSCR: XXXXXXXX FPUL: XXXXXXXX - - */ - -static void -hexvalue (unsigned long int value, char *buf, size_t len) -{ - char *cp = _itoa_word (value, buf + len, 16, 0); - while (cp > buf) - *--cp = '0'; -} - -static void -register_dump (int fd, struct sigcontext *ctx) -{ - char regs[22][8]; - struct iovec iov[112]; - size_t nr = 0; - -#define ADD_STRING(str) \ - iov[nr].iov_base = (char *) str; \ - iov[nr].iov_len = strlen (str); \ - ++nr -#define ADD_MEM(str, len) \ - iov[nr].iov_base = str; \ - iov[nr].iov_len = len; \ - ++nr - - /* Generate strings of register contents. */ - hexvalue (ctx->sc_regs[0], regs[0], 8); - hexvalue (ctx->sc_regs[1], regs[1], 8); - hexvalue (ctx->sc_regs[2], regs[2], 8); - hexvalue (ctx->sc_regs[3], regs[3], 8); - hexvalue (ctx->sc_regs[4], regs[4], 8); - hexvalue (ctx->sc_regs[5], regs[5], 8); - hexvalue (ctx->sc_regs[6], regs[6], 8); - hexvalue (ctx->sc_regs[7], regs[7], 8); - hexvalue (ctx->sc_regs[8], regs[8], 8); - hexvalue (ctx->sc_regs[9], regs[9], 8); - hexvalue (ctx->sc_regs[10], regs[10], 8); - hexvalue (ctx->sc_regs[11], regs[11], 8); - hexvalue (ctx->sc_regs[12], regs[12], 8); - hexvalue (ctx->sc_regs[13], regs[13], 8); - hexvalue (ctx->sc_regs[14], regs[14], 8); - hexvalue (ctx->sc_regs[15], regs[15], 8); - hexvalue (ctx->sc_macl, regs[16], 8); - hexvalue (ctx->sc_mach, regs[17], 8); - hexvalue (ctx->sc_pc, regs[18], 8); - hexvalue (ctx->sc_pr, regs[19], 8); - hexvalue (ctx->sc_gbr, regs[20], 8); - hexvalue (ctx->sc_sr, regs[21], 8); - - /* Generate the output. */ - ADD_STRING ("Register dump:\n\n R0: "); - ADD_MEM (regs[0], 8); - ADD_STRING (" R1: "); - ADD_MEM (regs[1], 8); - ADD_STRING (" R2: "); - ADD_MEM (regs[2], 8); - ADD_STRING (" R3: "); - ADD_MEM (regs[3], 8); - ADD_STRING ("\n R4: "); - ADD_MEM (regs[4], 8); - ADD_STRING (" R5: "); - ADD_MEM (regs[5], 8); - ADD_STRING (" R6: "); - ADD_MEM (regs[6], 8); - ADD_STRING (" R7: "); - ADD_MEM (regs[7], 8); - ADD_STRING ("\n R8: "); - ADD_MEM (regs[8], 8); - ADD_STRING (" R9: "); - ADD_MEM (regs[9], 8); - ADD_STRING (" R10: "); - ADD_MEM (regs[10], 8); - ADD_STRING (" R11: "); - ADD_MEM (regs[11], 8); - ADD_STRING ("\n R12: "); - ADD_MEM (regs[12], 8); - ADD_STRING (" R13: "); - ADD_MEM (regs[13], 8); - ADD_STRING (" R14: "); - ADD_MEM (regs[14], 8); - ADD_STRING (" R15: "); - ADD_MEM (regs[15], 8); - - ADD_STRING ("\n\nMACL: "); - ADD_MEM (regs[16], 8); - ADD_STRING (" MACH: "); - ADD_MEM (regs[17], 8); - - ADD_STRING ("\n\n PC: "); - ADD_MEM (regs[18], 8); - ADD_STRING (" PR: "); - ADD_MEM (regs[19], 8); - ADD_STRING (" GBR: "); - ADD_MEM (regs[20], 8); - ADD_STRING (" SR: "); - ADD_MEM (regs[21], 8); - - ADD_STRING ("\n"); - - /* Write the stuff out. */ - writev (fd, iov, nr); -} - - -#define REGISTER_DUMP register_dump (fd, &ctx) diff --git a/sysdeps/unix/sysv/linux/sh/sigcontextinfo.h b/sysdeps/unix/sysv/linux/sh/sigcontextinfo.h index d09dbea212..29d75b0cce 100644 --- a/sysdeps/unix/sysv/linux/sh/sigcontextinfo.h +++ b/sysdeps/unix/sysv/linux/sh/sigcontextinfo.h @@ -16,6 +16,13 @@ License along with the GNU C Library; if not, see . */ -#define SIGCONTEXT int _a2, int _a3, int _a4, struct sigcontext +#ifndef _SIGCONTEXTINFO_H +#define _SIGCONTEXTINFO_H -#define GET_PC(ctx) ((void *) ctx.sc_pc) +static inline uintptr_t +sigcontext_get_pc (const ucontext_t *ctx) +{ + return ctx->uc_mcontext.pc; +} + +#endif diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/profil-counter.h b/sysdeps/unix/sysv/linux/sparc/profil-counter.h similarity index 77% rename from sysdeps/unix/sysv/linux/sparc/sparc64/profil-counter.h rename to sysdeps/unix/sysv/linux/sparc/profil-counter.h index 47f8bf94a1..ad06a4fe06 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/profil-counter.h +++ b/sysdeps/unix/sysv/linux/sparc/profil-counter.h @@ -18,11 +18,17 @@ #include +#include + +#ifndef __profil_counter void -__profil_counter (int signo, struct sigcontext *si) +__profil_counter_global (int signo, struct sigcontext *si) { - profil_count ((void *) si->sigc_regs.tpc); +#ifdef __arch64__ + profil_count (si->sigc_regs.tpc); +#else + profil_count (si->si_regs.pc); +#endif } -#ifndef __profil_counter -weak_alias (__profil_counter, profil_counter) +weak_alias (__profil_counter_global, profil_counter) #endif diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/profil-counter.h b/sysdeps/unix/sysv/linux/sparc/sparc32/profil-counter.h deleted file mode 100644 index 22abf93b1b..0000000000 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/profil-counter.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Low-level statistical profiling support function. Linux/SPARC version. - Copyright (C) 1997-2019 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 - -void -__profil_counter (int signo, struct sigcontext *si) -{ - profil_count ((void *) si->si_regs.pc); -} -#ifndef __profil_counter -weak_alias (__profil_counter, profil_counter) -#endif diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/register-dump.h b/sysdeps/unix/sysv/linux/sparc/sparc32/register-dump.h index 209a6c9dac..9569c47f79 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/register-dump.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/register-dump.h @@ -84,16 +84,23 @@ struct __siginfo_sparc64_fpu unsigned int si_fprs; }; +/* Different that other architectures, SPARC32 pass a pt_regs (or pt_regs32 + in 32 bits compat mode) struct pointer as third argument for sa_sigaction + handler with SA_SIGINFO. */ static void -register_dump (int fd, SIGCONTEXT ctx) +register_dump (int fd, void *ctx) { char regs[36][8]; char fregs[68][8]; struct iovec iov[150]; size_t nr = 0; int i; - unsigned int *r = (unsigned int *) - ctx->si_regs.u_regs[14]; + struct pt_regs32 *ptregs = (struct pt_regs32 *) ctx; + struct compat_sigset_t { + unsigned int sig[2]; + }; + struct compat_sigset_t *mask = (struct compat_sigset_t *)(ptregs + 1); + unsigned int *r = (unsigned int *) ptregs->u_regs[14]; #define ADD_STRING(str) \ iov[nr].iov_base = (char *) str; \ @@ -105,15 +112,16 @@ register_dump (int fd, SIGCONTEXT ctx) ++nr /* Generate strings of register contents. */ - hexvalue (ctx->si_regs.psr, regs[0], 8); - hexvalue (ctx->si_regs.pc, regs[1], 8); - hexvalue (ctx->si_regs.npc, regs[2], 8); - hexvalue (ctx->si_regs.y, regs[3], 8); + hexvalue (ptregs->psr, regs[0], 8); + hexvalue (ptregs->pc, regs[1], 8); + hexvalue (ptregs->npc, regs[2], 8); + hexvalue (ptregs->y, regs[3], 8); for (i = 1; i <= 15; i++) - hexvalue (ctx->si_regs.u_regs[i], regs[3+i], 8); + hexvalue (ptregs->u_regs[i], regs[3+i], 8); for (i = 0; i <= 15; i++) hexvalue (r[i], regs[19+i], 8); - hexvalue (ctx->si_mask, regs[35], 8); + + hexvalue (mask->sig[0], regs[35], 8); /* Generate the output. */ ADD_STRING ("Register dump:\n\n PSR: "); @@ -189,11 +197,11 @@ register_dump (int fd, SIGCONTEXT ctx) ADD_STRING ("\n\n Old mask: "); ADD_MEM (regs[35], 8); - if ((ctx->si_regs.psr & 0xff000000) == 0xff000000) + if ((ptregs->psr & 0xff000000) == 0xff000000) { - struct __siginfo_sparc64_fpu *f; + struct __siginfo_sparc64_fpu *f = *(struct __siginfo_sparc64_fpu **) + (mask + 1); - f = *(struct __siginfo_sparc64_fpu **) (ctx + 1); if (f != NULL) { for (i = 0; i < 64; i++) @@ -277,9 +285,9 @@ register_dump (int fd, SIGCONTEXT ctx) } else { - struct __siginfo_sparc32_fpu *f; + struct __siginfo_sparc32_fpu *f = *(struct __siginfo_sparc32_fpu **) + (mask + 1); - f = *(struct __siginfo_sparc32_fpu **) (ctx + 1); if (f != NULL) { for (i = 0; i < 32; i++) diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sigcontextinfo.h b/sysdeps/unix/sysv/linux/sparc/sparc32/sigcontextinfo.h index 9eec807a23..dd21f273d6 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/sigcontextinfo.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sigcontextinfo.h @@ -16,5 +16,41 @@ License along with the GNU C Library; if not, see . */ -#define SIGCONTEXT struct sigcontext * -#define GET_PC(__ctx) ((void *) ((__ctx)->si_regs.pc)) +#ifndef _SIGCONTEXTINFO_H +#define _SIGCONTEXTINFO_H + +/* The sparc32 kernel signal frame for SA_SIGINFO is defined as: + + struct rt_signal_frame32 + { + struct sparc_stackf32 ss; + compat_siginfo_t info; + struct pt_regs32 regs; <- void *ctx + compat_sigset_t mask; + u32 fpu_save; + unsigned int insns[2]; + compat_stack_t stack; + unsigned int extra_size; + siginfo_extra_v8plus_t v8plus; + u32 rwin_save; + } __attribute__((aligned(8))); + + Unlike other architectures, sparc32 passes pt_regs32 REGS pointer as + the third argument to a sa_sigaction handler with SA_SIGINFO enabled. */ + +struct pt_regs32 +{ + unsigned int psr; + unsigned int pc; + unsigned int npc; + unsigned int y; + unsigned int u_regs[16]; +}; + +static inline uintptr_t +sigcontext_get_pc (const struct pt_regs32 *ctx) +{ + return ctx->pc; +} + +#endif diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/register-dump.h b/sysdeps/unix/sysv/linux/sparc/sparc64/register-dump.h index 0f1078ad9e..23ff36453a 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/register-dump.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/register-dump.h @@ -60,17 +60,36 @@ hexvalue (unsigned long int value, char *buf, size_t len) *--cp = '0'; } +/* The sparc64 kernel signal frame for SA_SIGINFO is defined as: + + struct rt_signal_frame + { + struct sparc_stackf ss; + siginfo_t info; + struct pt_regs regs; <- void *ctx + __siginfo_fpu_t *fpu_save; + stack_t stack; + sigset_t mask; + __siginfo_rwin_t *rwin_save; + }; + + Unlike other architectures, sparc32 passes pt_regs32 REGS pointers as + the third argument to a sa_sigaction handler with SA_SIGINFO enabled. */ + static void -register_dump (int fd, SIGCONTEXT ctx) +register_dump (int fd, void *ctx) { char regs[36][16]; char fregs[68][8]; struct iovec iov[150]; size_t nr = 0; int i; - unsigned long *r = (unsigned long *) - (ctx->sigc_regs.u_regs[14] + STACK_BIAS); - __siginfo_fpu_t *f; + struct pt_regs *ptregs = (struct pt_regs*) ((siginfo_t *)ctx + 1); + unsigned long *r = (unsigned long *) (ptregs->u_regs[14] + STACK_BIAS); + __siginfo_fpu_t *f = (__siginfo_fpu_t *)(ptregs + 1); + struct kernel_sigset_t { + unsigned long sig[1]; + } *mask = (struct kernel_sigset_t *)((stack_t *)(f + 1) + 1); #define ADD_STRING(str) \ iov[nr].iov_base = (char *) str; \ @@ -82,15 +101,15 @@ register_dump (int fd, SIGCONTEXT ctx) ++nr /* Generate strings of register contents. */ - hexvalue (ctx->sigc_regs.tstate, regs[0], 16); - hexvalue (ctx->sigc_regs.tpc, regs[1], 16); - hexvalue (ctx->sigc_regs.tnpc, regs[2], 16); - hexvalue (ctx->sigc_regs.y, regs[3], 8); + hexvalue (ptregs->tstate, regs[0], 16); + hexvalue (ptregs->tpc, regs[1], 16); + hexvalue (ptregs->tnpc, regs[2], 16); + hexvalue (ptregs->y, regs[3], 8); for (i = 1; i <= 15; i++) - hexvalue (ctx->sigc_regs.u_regs[i], regs[3+i], 16); + hexvalue (ptregs->u_regs[i], regs[3+i], 16); for (i = 0; i <= 15; i++) - hexvalue (r[i], regs[19+i], 16); - hexvalue (ctx->sigc_mask, regs[35], 16); + hexvalue (r[i], regs[19+i], 16); + hexvalue (mask->sig[0], regs[35], 16); /* Generate the output. */ ADD_STRING ("Register dump:\n\n TSTATE: "); @@ -166,7 +185,6 @@ register_dump (int fd, SIGCONTEXT ctx) ADD_STRING ("\n\n Mask: "); ADD_MEM (regs[35], 16); - f = ctx->sigc_fpu_save; if (f != NULL) { for (i = 0; i < 64; i++) diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sigcontextinfo.h b/sysdeps/unix/sysv/linux/sparc/sparc64/sigcontextinfo.h index a2f2b1f7de..adc84d3ce4 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/sigcontextinfo.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sigcontextinfo.h @@ -16,8 +16,46 @@ License along with the GNU C Library; if not, see . */ +#ifndef _SIGCONTEXTINFO_H +#define _SIGCONTEXTINFO_H + +#include + +/* The sparc64 kernel signal frame for SA_SIGINFO is defined as: + + struct rt_signal_frame + { + struct sparc_stackf ss; + siginfo_t info; + struct pt_regs regs; + __siginfo_fpu_t *fpu_save; + stack_t stack; + sigset_t mask; + __siginfo_rwin_t *rwin_save; + }; + + Unlike other architectures, sparc64 passe the siginfo_t INFO pointer + as the third argument to a sa_sigaction handler with SA_SIGINFO enabled. */ + #ifndef STACK_BIAS #define STACK_BIAS 2047 #endif -#define SIGCONTEXT struct sigcontext * -#define GET_PC(__ctx) ((void *) ((__ctx)->sigc_regs.tpc)) + +struct pt_regs +{ + unsigned long int u_regs[16]; + unsigned long int tstate; + unsigned long int tpc; + unsigned long int tnpc; + unsigned int y; + unsigned int magic; +}; + +static inline uintptr_t +sigcontext_get_pc (const siginfo_t *ctx) +{ + struct pt_regs *regs = (struct pt_regs*) ((siginfo_t *)(ctx) + 1); + return regs->tpc; +} + +#endif diff --git a/sysdeps/unix/sysv/linux/tst-sigcontextinfo-get_pc.c b/sysdeps/unix/sysv/linux/tst-sigcontextinfo-get_pc.c new file mode 100644 index 0000000000..60a4c6b8f4 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-sigcontextinfo-get_pc.c @@ -0,0 +1,81 @@ +/* Test that the GET_PC macro is consistent with the unwinder. + Copyright (C) 2019 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; see the file COPYING.LIB. If + not, see . */ + +/* This test searches for the value of the GET_PC macro in the + addresses obtained from the backtrace function. */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* This file defines macros to access the content of the sigcontext element + passed up by the signal handler. */ +#include + +static bool handler_called; + +static void +handler (int signal, siginfo_t *info, void *ctx) +{ + TEST_COMPARE (signal, SIGUSR1); + + uintptr_t pc = sigcontext_get_pc (ctx); + printf ("info: address in signal handler: 0x%" PRIxPTR "\n", pc); + + void *callstack[10]; + int callstack_count = backtrace (callstack, array_length (callstack)); + TEST_VERIFY_EXIT (callstack_count > 0); + TEST_VERIFY_EXIT (callstack_count <= array_length (callstack)); + bool found = false; + for (int i = 0; i < callstack_count; ++i) + { + const char *marker; + if ((uintptr_t) callstack[i] == pc) + { + found = true; + marker = " *"; + } + else + marker = ""; + printf ("info: call stack entry %d: 0x%" PRIxPTR "%s\n", + i, (uintptr_t) callstack[i], marker); + } + TEST_VERIFY (found); + handler_called = true; +} + +static int +do_test (void) +{ + struct sigaction sa = + { + .sa_sigaction = &handler, + .sa_flags = SA_SIGINFO + }; + xsigaction (SIGUSR1, &sa, NULL); + raise (SIGUSR1); + TEST_VERIFY (handler_called); + return 0; +} + +#include diff --git a/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h b/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h index 630f3992eb..056a42e13d 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h +++ b/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h @@ -15,8 +15,13 @@ License along with the GNU C Library; if not, see . */ -#include +#ifndef _SIGCONTEXTINFO_H +#define _SIGCONTEXTINFO_H -#define SIGCONTEXT siginfo_t *_si, ucontext_t * -#define GET_PC(ctx) \ - ((void *) (uintptr_t) (ctx)->uc_mcontext.gregs[REG_RIP]) +static inline uintptr_t +sigcontext_get_pc (const ucontext_t *ctx) +{ + return ctx->uc_mcontext.gregs[REG_RIP]; +} + +#endif