mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-22 21:10:07 +00:00
Refactor sigcontextinfo.h
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 SA_SIGINFO. The GET_PC macro is also replaced with a function sigcontext_get_pc that returns 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 <adhemerval.zanella@linaro.org> Florian Weimer <fweimer@redhat.com> * debug/segfault.c (install_handler): Use SA_SIGINFO if defined. * sysdeps/generic/profil-counter.h (__profil_counter): Cast to uintptr_t. * sysdeps/generic/sigcontextinfo.h (GET_PC): Rename to sigcontext_get_pc and return aligned cast to uintptr_t. * 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. * sysdeps/posix/sprofil.c (profil_count): Change PCP argument to uintptr_t. (__sprofil): 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): Assume SA_SIGINFO and use sigcontext_get_pc instead of GET_PC. * 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.
This commit is contained in:
parent
624c109b2a
commit
a43565ac44
72
ChangeLog
72
ChangeLog
@ -1,3 +1,75 @@
|
||||
2019-08-23 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
* debug/segfault.c (install_handler): Use SA_SIGINFO if defined.
|
||||
* sysdeps/generic/profil-counter.h (__profil_counter): Cast to
|
||||
uintptr_t.
|
||||
* sysdeps/generic/sigcontextinfo.h (GET_PC): Rename to
|
||||
sigcontext_get_pc and return aligned cast to uintptr_t.
|
||||
* 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.
|
||||
* sysdeps/posix/sprofil.c (profil_count): Change PCP argument to
|
||||
uintptr_t.
|
||||
(__sprofil): 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):
|
||||
Assume SA_SIGINFO and use sigcontext_get_pc instead of GET_PC.
|
||||
* 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.
|
||||
|
||||
2019-08-23 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
* sysdeps/generic/single-thread.h (RTLD_SINGLE_THREAD_P): Add
|
||||
|
@ -35,6 +35,10 @@
|
||||
passed up by the signal handler. */
|
||||
#include <sigcontextinfo.h>
|
||||
|
||||
#ifdef SA_SIGINFO
|
||||
# define SIGCONTEXT siginfo_t *info, void *
|
||||
#endif
|
||||
|
||||
/* Get code to possibly dump the content of all registers. */
|
||||
#include <register-dump.h>
|
||||
|
||||
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -16,6 +16,15 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#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
|
||||
|
@ -15,5 +15,14 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#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
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdint.h>
|
||||
#include <libc-internal.h>
|
||||
#include <sigsetops.h>
|
||||
|
||||
@ -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;
|
||||
@ -104,8 +105,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;
|
||||
|
@ -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;
|
||||
|
@ -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-sigcontext-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
|
||||
|
@ -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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* We can use the ix86 version. */
|
||||
#include <sysdeps/unix/sysv/linux/i386/profil-counter.h>
|
@ -16,20 +16,16 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _SIGCONTEXTINFO_H
|
||||
#define _SIGCONTEXTINFO_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/ucontext.h>
|
||||
|
||||
#define SIGCONTEXT siginfo_t *_si, ucontext_t *
|
||||
#define GET_PC(ctx) ((void *) (uintptr_t) (ctx)->uc_mcontext.pc)
|
||||
static inline uintptr_t
|
||||
sigcontext_get_pc (const ucontext_t *ctx)
|
||||
{
|
||||
return 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); \
|
||||
})
|
||||
|
||||
#define sigaction(sig, act, oact) ({ \
|
||||
(act)->sa_flags |= SA_SIGINFO; \
|
||||
(sigaction) (sig, act, oact); \
|
||||
})
|
||||
#endif
|
||||
|
@ -16,8 +16,10 @@
|
||||
License along with the GNU C Library. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <ucontext.h>
|
||||
#include <sys/uio.h>
|
||||
#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] =
|
||||
static void
|
||||
hexvalue (unsigned long int value, char *buf, size_t len)
|
||||
{
|
||||
" 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] =
|
||||
{
|
||||
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;
|
||||
struct iovec iov[31 * 2 + 2 /* REGS + PC. */
|
||||
+ 31 * 2 + 2 /* FREGS + FPCR. */
|
||||
+ (3 * 2) /* TA0, TA1, TA3. */
|
||||
+ 1 /* '\n'. */];
|
||||
size_t nr = 0;
|
||||
|
||||
p = stpcpy (p, "Register dump:\n\n");
|
||||
#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
|
||||
|
||||
for (i = 0; i < NREGS; ++i)
|
||||
{
|
||||
int this_offset, this_lf;
|
||||
unsigned long val;
|
||||
signed long j;
|
||||
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);
|
||||
|
||||
this_offset = offsets[i];
|
||||
this_lf = this_offset & 7;
|
||||
/* 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);
|
||||
|
||||
val = *(unsigned long *)(((size_t)ctx + this_offset) & -8);
|
||||
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);
|
||||
|
||||
memcpy (p, regnames[i], 8);
|
||||
p += 8;
|
||||
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);
|
||||
|
||||
for (j = 60; j >= 0; j -= 4)
|
||||
{
|
||||
unsigned long x = (val >> j) & 15;
|
||||
x += x < 10 ? '0' : 'a' - 10;
|
||||
*p++ = x;
|
||||
}
|
||||
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);
|
||||
|
||||
if (this_lf > 0)
|
||||
{
|
||||
if (this_lf > 1)
|
||||
*p++ = '\n';
|
||||
*p++ = '\n';
|
||||
}
|
||||
}
|
||||
ADD_STRING ("\n");
|
||||
|
||||
write (fd, buf, p - buf);
|
||||
/* Write the stuff out. */
|
||||
writev (fd, iov, nr);
|
||||
}
|
||||
|
||||
#define REGISTER_DUMP register_dump (fd, ctx)
|
||||
|
@ -15,5 +15,16 @@
|
||||
License along with the GNU C Library. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define SIGCONTEXT int _code, struct sigcontext *
|
||||
#define GET_PC(ctx) ((void *) (ctx)->sc_pc)
|
||||
#ifndef _SIGCONTEXTINFO_H
|
||||
#define _SIGCONTEXTINFO_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/ucontext.h>
|
||||
|
||||
static inline uintptr_t
|
||||
sigcontext_get_pc (const ucontext_t *ctx)
|
||||
{
|
||||
return ctx->uc_mcontext.sc_pc;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -20,9 +20,9 @@
|
||||
#include <sigcontextinfo.h>
|
||||
|
||||
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
|
||||
|
@ -16,24 +16,13 @@
|
||||
License along with the GNU C Library. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sys/ucontext.h>
|
||||
#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
|
||||
|
@ -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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <signal.h>
|
||||
#include <sigcontextinfo.h>
|
||||
|
||||
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 ("");
|
||||
}
|
@ -16,17 +16,13 @@
|
||||
License along with the GNU C Library. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#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
|
||||
|
@ -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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
static void
|
||||
__profil_counter (int signr, siginfo_t *si, ucontext_t *uctx)
|
||||
#ifndef _SIGCONTEXTINFO_H
|
||||
#define _SIGCONTEXTINFO_H
|
||||
|
||||
#include <sys/ucontext.h>
|
||||
|
||||
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
|
@ -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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <signal.h>
|
||||
#include <sigcontextinfo.h>
|
||||
|
||||
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 ("");
|
||||
}
|
@ -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->__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);
|
||||
|
||||
/* 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);
|
||||
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
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)
|
||||
|
@ -16,5 +16,13 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#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
|
||||
|
@ -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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* 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));
|
||||
}
|
@ -15,5 +15,15 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#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
|
||||
|
@ -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,11 @@ 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[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 +75,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++)
|
||||
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 (*pfp++, fpregs[i] + j, 8);
|
||||
for (i = 2; 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: ");
|
||||
|
@ -16,5 +16,13 @@
|
||||
License along with the GNU C Library. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#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
|
||||
|
@ -1,2 +0,0 @@
|
||||
/* We can use the ix86 version. */
|
||||
#include <sysdeps/unix/sysv/linux/i386/profil-counter.h>
|
@ -16,5 +16,13 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#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
|
||||
|
@ -1,2 +0,0 @@
|
||||
/* We can use the ix86 version. */
|
||||
#include <sysdeps/unix/sysv/linux/i386/profil-counter.h>
|
@ -16,17 +16,13 @@
|
||||
License along with the GNU C Library. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _SIGCONTEXTINFO_H
|
||||
#define _SIGCONTEXTINFO_H
|
||||
|
||||
#include <sgidefs.h>
|
||||
|
||||
#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)
|
||||
static inline uintptr_t
|
||||
sigcontext_get_pc (const ucontext_t *ctx)
|
||||
{
|
||||
return ctx->uc_mcontext.pc;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,2 +0,0 @@
|
||||
/* We can use the ix86 version. */
|
||||
#include <sysdeps/unix/sysv/linux/i386/profil-counter.h>
|
@ -16,20 +16,13 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sys/ucontext.h>
|
||||
#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
|
||||
|
@ -1,2 +0,0 @@
|
||||
/* We can use the ix86 version. */
|
||||
#include <sysdeps/unix/sysv/linux/i386/profil-counter.h>
|
@ -15,7 +15,19 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _SIGCONTEXTINFO_H
|
||||
#define _SIGCONTEXTINFO_H
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#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
|
||||
|
@ -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 <signal.h>
|
||||
#include <sigcontextinfo.h>
|
||||
|
||||
/* 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
|
@ -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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <signal.h>
|
||||
#include <sigcontextinfo.h>
|
||||
|
||||
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 ("");
|
||||
}
|
@ -16,7 +16,15 @@
|
||||
License along with the GNU C Library. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _SIGCONTEXTINFO_H
|
||||
#define _SIGCONTEXTINFO_H
|
||||
|
||||
#include <sys/ucontext.h>
|
||||
|
||||
#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
|
||||
|
@ -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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <signal.h>
|
||||
#include <sigcontextinfo.h>
|
||||
|
||||
static void
|
||||
__profil_counter (int signo, SIGCONTEXT scp)
|
||||
{
|
||||
profil_count((void *) ((unsigned long) GET_PC (scp) & 0x7fffffffUL));
|
||||
}
|
@ -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: ");
|
||||
|
@ -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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <signal.h>
|
||||
#include <sigcontextinfo.h>
|
||||
|
||||
static void
|
||||
__profil_counter (int signo, SIGCONTEXT scp)
|
||||
{
|
||||
profil_count ((void *) GET_PC (scp));
|
||||
}
|
@ -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: ");
|
||||
|
@ -16,7 +16,19 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _SIGCONTEXTINFO_H
|
||||
#define _SIGCONTEXTINFO_H
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#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
|
||||
|
@ -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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
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 ("");
|
||||
}
|
@ -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)
|
@ -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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sys/uio.h>
|
||||
#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)
|
@ -16,6 +16,13 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#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
|
||||
|
@ -18,11 +18,17 @@
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
void
|
||||
__profil_counter (int signo, struct sigcontext *si)
|
||||
{
|
||||
profil_count ((void *) si->sigc_regs.tpc);
|
||||
}
|
||||
#include <sysdeps/unix/sysv/linux/profil-counter.h>
|
||||
|
||||
#ifndef __profil_counter
|
||||
weak_alias (__profil_counter, profil_counter)
|
||||
void
|
||||
__profil_counter_global (int signo, struct sigcontext *si)
|
||||
{
|
||||
#ifdef __arch64__
|
||||
profil_count (si->sigc_regs.tpc);
|
||||
#else
|
||||
profil_count (si->si_regs.pc);
|
||||
#endif
|
||||
}
|
||||
weak_alias (__profil_counter_global, profil_counter)
|
||||
#endif
|
@ -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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
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
|
@ -84,16 +84,23 @@ struct __siginfo_sparc64_fpu
|
||||
unsigned int si_fprs;
|
||||
};
|
||||
|
||||
/* Unlike other architectures, sparc32 passes pt_regs32 REGS pointer 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][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++)
|
||||
|
@ -16,5 +16,41 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#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
|
||||
|
@ -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++)
|
||||
|
@ -16,8 +16,46 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _SIGCONTEXTINFO_H
|
||||
#define _SIGCONTEXTINFO_H
|
||||
|
||||
#include <bits/types/siginfo_t.h>
|
||||
|
||||
/* 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
|
||||
|
78
sysdeps/unix/sysv/linux/tst-sigcontext-get_pc.c
Normal file
78
sysdeps/unix/sysv/linux/tst-sigcontext-get_pc.c
Normal file
@ -0,0 +1,78 @@
|
||||
/* 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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* This test searches for the value of the GET_PC macro in the
|
||||
addresses obtained from the backtrace function. */
|
||||
|
||||
#include <array_length.h>
|
||||
#include <execinfo.h>
|
||||
#include <inttypes.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <support/check.h>
|
||||
#include <support/xsignal.h>
|
||||
#include <sigcontextinfo.h>
|
||||
|
||||
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 <support/test-driver.c>
|
@ -15,8 +15,13 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stdint.h>
|
||||
#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
|
||||
|
Loading…
Reference in New Issue
Block a user