|
From: <sv...@va...> - 2005-04-24 14:18:20
|
Author: sewardj
Date: 2005-04-24 15:18:14 +0100 (Sun, 24 Apr 2005)
New Revision: 3556
Added:
trunk/coregrind/m_sigframe/
trunk/coregrind/m_sigframe/Makefile.am
trunk/coregrind/m_sigframe/sigframe-amd64-linux.c
trunk/coregrind/m_sigframe/sigframe-arm-linux.c
trunk/coregrind/m_sigframe/sigframe-x86-linux.c
trunk/coregrind/pub_core_sigframe.h
Removed:
trunk/coregrind/amd64/signals.c
trunk/coregrind/arm/signals.c
trunk/coregrind/x86/signals.c
Modified:
trunk/configure.in
trunk/coregrind/Makefile.am
trunk/coregrind/amd64/Makefile.am
trunk/coregrind/amd64/core_arch.h
trunk/coregrind/arm/Makefile.am
trunk/coregrind/core.h
trunk/coregrind/vg_signals.c
trunk/coregrind/x86-linux/syscalls.c
trunk/coregrind/x86/Makefile.am
trunk/coregrind/x86/core_arch.h
Log:
Create a new module, "sigframe", responsible for creating/destroying
signal frames. This commit looks worse than it is -- really just a
load of moving-code-around.
This is the first multiple-implementation module, in that it has a
single interface (pub_core_sigframe.h) but multiple implementations,
depending on the os-cpu pair. All the grotty details are hidden in
the implementation in m_sigframe/; callers need be aware only of the
interface. Yay.
Modified: trunk/configure.in
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/configure.in 2005-04-24 12:33:12 UTC (rev 3555)
+++ trunk/configure.in 2005-04-24 14:18:14 UTC (rev 3556)
@@ -394,6 +394,7 @@
auxprogs/Makefile
coregrind/Makefile=20
coregrind/demangle/Makefile=20
+ coregrind/m_sigframe/Makefile=20
coregrind/amd64/Makefile
coregrind/arm/Makefile
coregrind/x86/Makefile
Modified: trunk/coregrind/Makefile.am
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/Makefile.am 2005-04-24 12:33:12 UTC (rev 3555)
+++ trunk/coregrind/Makefile.am 2005-04-24 14:18:14 UTC (rev 3556)
@@ -4,9 +4,14 @@
## When building, we are only interested in the current arch/OS/platform=
.
## But when doing 'make dist', we are interested in every arch/OS/platfo=
rm.
## That's what DIST_SUBDIRS specifies.
-SUBDIRS =3D $(VG_ARCH) $(VG_OS) $(VG_PLATFORM) demangle=
.
-DIST_SUBDIRS =3D $(VG_ARCH_ALL) $(VG_OS_ALL) $(VG_PLATFORM_ALL) demangle=
.
+SUBDIRS =3D \
+ $(VG_ARCH) $(VG_OS) $(VG_PLATFORM) \
+ m_sigframe demangle .
=20
+DIST_SUBDIRS =3D \
+ $(VG_ARCH_ALL) $(VG_OS_ALL) $(VG_PLATFORM_ALL) \
+ m_sigframe demangle .
+
AM_CPPFLAGS +=3D -DVG_LIBDIR=3D"\"$(valdir)"\" -I$(srcdir)/demangle \
-DKICKSTART_BASE=3D@KICKSTART_BASE@ \
-DVG_PLATFORM=3D"\"$(VG_PLATFORM)"\"
@@ -87,6 +92,7 @@
## libplatform.a must be before libarch.a and libos.a, it seems.
stage2_extra=3D \
demangle/libdemangle.a \
+ m_sigframe/libsigframe.a \
${VG_PLATFORM}/libplatform.a \
${VG_ARCH}/libarch.a \
${VG_OS}/libos.a \
Modified: trunk/coregrind/amd64/Makefile.am
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/amd64/Makefile.am 2005-04-24 12:33:12 UTC (rev 3555)
+++ trunk/coregrind/amd64/Makefile.am 2005-04-24 14:18:14 UTC (rev 3556)
@@ -21,7 +21,6 @@
cpuid.S \
helpers.S \
dispatch.S \
- signals.c \
jmp_with_stack.c \
state.c
=20
Modified: trunk/coregrind/amd64/core_arch.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/amd64/core_arch.h 2005-04-24 12:33:12 UTC (rev 3555)
+++ trunk/coregrind/amd64/core_arch.h 2005-04-24 14:18:14 UTC (rev 3556)
@@ -127,12 +127,7 @@
// Base address of client address space.
#define VGA_CLIENT_BASE 0x0ul
=20
-/* ---------------------------------------------------------------------
- Signal stuff (should be plat)
- ------------------------------------------------------------------ */
=20
-void VGA_(signal_return)(ThreadId tid, Bool isRT);
-
#endif // __AMD64_CORE_ARCH_H
=20
/*--------------------------------------------------------------------*/
Deleted: trunk/coregrind/amd64/signals.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/amd64/signals.c 2005-04-24 12:33:12 UTC (rev 3555)
+++ trunk/coregrind/amd64/signals.c 2005-04-24 14:18:14 UTC (rev 3556)
@@ -1,679 +0,0 @@
-
-/*--------------------------------------------------------------------*/
-/*--- Arch-specific signals stuff. amd64/signals.c ---*/
-/*--------------------------------------------------------------------*/
-
-/*
- This file is part of Valgrind, a dynamic binary instrumentation
- framework.
-
- Copyright (C) 2000-2005 Nicholas Nethercote
- nj...@ca...
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- This program 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
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307, USA.
-
- The GNU General Public License is contained in the file COPYING.
-*/
-
-#include "core.h"
-
-#include "libvex_guest_amd64.h"
-
-
-/* This module creates and removes signal frames for signal deliveries
- on amd64-linux.
-
- FIXME: Note that this file is in the wrong place. It is marked as
- amd64 specific, but in fact it is specific to both amd64 and linux.
- There is nothing that ensures that (eg) amd64-netbsd will have the
- same signal frame layout as Linux.
-
- Note also, this file contains kernel-specific knowledge in the
- form of 'struct rt_sigframe'. How does that relate to the vki
- kernel interface stuff?
-
- A 'struct rtsigframe' is pushed onto the client's stack. This
- contains a subsidiary vki_ucontext. That holds the vcpu's state
- across the signal, so that the sighandler can mess with the vcpu
- state if it really wants.
-
- FIXME: sigcontexting is basically broken for the moment. When
- delivering a signal, the integer registers and %rflags are
- correctly written into the sigcontext, however the FP and SSE state
- is not. When returning from a signal, only the integer registers
- are restored from the sigcontext; the rest of the CPU state is
- restored to what it was before the signal.
-
- This will be fixed.
-*/
-
-
-/*------------------------------------------------------------*/
-/*--- Signal frame layouts ---*/
-/*------------------------------------------------------------*/
-
-// A structure in which to save the application's registers
-// during the execution of signal handlers.
-
-// In theory, so long as we get the arguments to the handler function
-// right, it doesn't matter what the exact layout of the rest of the
-// frame is. Unfortunately, things like gcc's exception unwinding
-// make assumptions about the locations of various parts of the frame,
-// so we need to duplicate it exactly.
-
-/* Valgrind-specific parts of the signal frame */
-struct vg_sigframe
-{
- /* Sanity check word. */
- UInt magicPI;
-
- UInt handlerflags; /* flags for signal handler */
-
-
- /* Safely-saved version of sigNo, as described above. */
- Int sigNo_private;
-
- /* XXX This is wrong. Surely we should store the shadow values
- into the shadow memory behind the actual values? */
- VexGuestAMD64State vex_shadow;
-
- /* HACK ALERT */
- VexGuestAMD64State vex;
- /* end HACK ALERT */
-
- /* saved signal mask to be restored when handler returns */
- vki_sigset_t mask;
-
- /* Sanity check word. Is the highest-addressed word; do not
- move!*/
- UInt magicE;
-};
-
-struct rt_sigframe
-{
- /* Sig handler's return address */
- Addr retaddr;
-
- /* ucontext */
- struct vki_ucontext uContext;
-
- /* siginfo */
- vki_siginfo_t sigInfo;
- struct _vki_fpstate fpstate;
-
- struct vg_sigframe vg;
-};
-
-
-//:: /*------------------------------------------------------------*/
-//:: /*--- Signal operations ---*/
-//:: /*------------------------------------------------------------*/
-//::=20
-//:: /*=20
-//:: Great gobs of FP state conversion taken wholesale from
-//:: linux/arch/i386/kernel/i387.c
-//:: */
-//::=20
-//:: /*
-//:: * FXSR floating point environment conversions.
-//:: */
-//:: #define X86_FXSR_MAGIC 0x0000
-//::=20
-//:: /*
-//:: * FPU tag word conversions.
-//:: */
-//::=20
-//:: static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
-//:: {
-//:: unsigned int tmp; /* to avoid 16 bit prefixes in the code */
-//:: =20
-//:: /* Transform each pair of bits into 01 (valid) or 00 (empty) */
-//:: tmp =3D ~twd;
-//:: tmp =3D (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
-//:: /* and move the valid bits to the lower byte. */
-//:: tmp =3D (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
-//:: tmp =3D (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
-//:: tmp =3D (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
-//:: return tmp;
-//:: }
-//::=20
-//:: static unsigned long twd_fxsr_to_i387( const struct i387_fxsave_str=
uct *fxsave )
-//:: {
-//:: struct _vki_fpxreg *st =3D NULL;
-//:: unsigned long twd =3D (unsigned long) fxsave->twd;
-//:: unsigned long tag;
-//:: unsigned long ret =3D 0xffff0000u;
-//:: int i;
-//::=20
-//:: #define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16);
-//::=20
-//:: for ( i =3D 0 ; i < 8 ; i++ ) {
-//:: if ( twd & 0x1 ) {
-//:: st =3D (struct _vki_fpxreg *) FPREG_ADDR( fxsave, i );
-//::=20
-//:: switch ( st->exponent & 0x7fff ) {
-//:: case 0x7fff:
-//:: tag =3D 2; /* Special */
-//:: break;
-//:: case 0x0000:
-//:: if ( !st->significand[0] &&
-//:: !st->significand[1] &&
-//:: !st->significand[2] &&
-//:: !st->significand[3] ) {
-//:: tag =3D 1; /* Zero */
-//:: } else {
-//:: tag =3D 2; /* Special */
-//:: }
-//:: break;
-//:: default:
-//:: if ( st->significand[3] & 0x8000 ) {
-//:: tag =3D 0; /* Valid */
-//:: } else {
-//:: tag =3D 2; /* Special */
-//:: }
-//:: break;
-//:: }
-//:: } else {
-//:: tag =3D 3; /* Empty */
-//:: }
-//:: ret |=3D (tag << (2 * i));
-//:: twd =3D twd >> 1;
-//:: }
-//:: return ret;
-//:: }
-//::=20
-//:: static void convert_fxsr_to_user( struct _vki_fpstate *buf,
-//:: const struct i387_fxsave_struct *fxsave )
-//:: {
-//:: unsigned long env[7];
-//:: struct _vki_fpreg *to;
-//:: struct _vki_fpxreg *from;
-//:: int i;
-//::=20
-//:: env[0] =3D (unsigned long)fxsave->cwd | 0xffff0000ul;
-//:: env[1] =3D (unsigned long)fxsave->swd | 0xffff0000ul;
-//:: env[2] =3D twd_fxsr_to_i387(fxsave);
-//:: env[3] =3D fxsave->fip;
-//:: env[4] =3D fxsave->fcs | ((unsigned long)fxsave->fop << 16);
-//:: env[5] =3D fxsave->foo;
-//:: env[6] =3D fxsave->fos;
-//:: =20
-//:: VG_(memcpy)(buf, env, 7 * sizeof(unsigned long));
-//::=20
-//:: to =3D &buf->_st[0];
-//:: from =3D (struct _vki_fpxreg *) &fxsave->st_space[0];
-//:: for ( i =3D 0 ; i < 8 ; i++, to++, from++ ) {
-//:: unsigned long __user *t =3D (unsigned long __user *)to;
-//:: unsigned long *f =3D (unsigned long *)from;
-//::=20
-//:: t[0] =3D f[0];
-//:: t[1] =3D f[1];
-//:: to->exponent =3D from->exponent;
-//:: }
-//:: }
-//::=20
-//:: static void convert_fxsr_from_user( struct i387_fxsave_struct *fxsa=
ve,
-//:: const struct _vki_fpstate *buf )
-//:: {
-//:: unsigned long env[7];
-//:: struct _vki_fpxreg *to;
-//:: const struct _vki_fpreg *from;
-//:: int i;
-//:: =09
-//:: VG_(memcpy)(env, buf, 7 * sizeof(long));
-//::=20
-//:: fxsave->cwd =3D (unsigned short)(env[0] & 0xffff);
-//:: fxsave->swd =3D (unsigned short)(env[1] & 0xffff);
-//:: fxsave->twd =3D twd_i387_to_fxsr((unsigned short)(env[2] & 0xfff=
f));
-//:: fxsave->fip =3D env[3];
-//:: fxsave->fop =3D (unsigned short)((env[4] & 0xffff0000ul) >> 16);
-//:: fxsave->fcs =3D (env[4] & 0xffff);
-//:: fxsave->foo =3D env[5];
-//:: fxsave->fos =3D env[6];
-//::=20
-//:: to =3D (struct _vki_fpxreg *) &fxsave->st_space[0];
-//:: from =3D &buf->_st[0];
-//:: for ( i =3D 0 ; i < 8 ; i++, to++, from++ ) {
-//:: unsigned long *t =3D (unsigned long *)to;
-//:: unsigned long __user *f =3D (unsigned long __user *)from;
-//::=20
-//:: t[0] =3D f[0];
-//:: t[1] =3D f[1];
-//:: to->exponent =3D from->exponent;
-//:: }
-//:: }
-//::=20
-//:: static inline void save_i387_fsave( arch_thread_t *regs, struct _vk=
i_fpstate *buf )
-//:: {
-//:: struct i387_fsave_struct *fs =3D ®s->m_sse.fsave;
-//::=20
-//:: fs->status =3D fs->swd;
-//:: VG_(memcpy)(buf, fs, sizeof(*fs));
-//:: }
-//::=20
-//:: static void save_i387_fxsave( arch_thread_t *regs, struct _vki_fpst=
ate *buf )
-//:: {
-//:: const struct i387_fxsave_struct *fx =3D ®s->m_sse.fxsave;
-//:: convert_fxsr_to_user( buf, fx );
-//::=20
-//:: buf->status =3D fx->swd;
-//:: buf->magic =3D X86_FXSR_MAGIC;
-//:: VG_(memcpy)(buf->_fxsr_env, fx, sizeof(struct i387_fxsave_struct=
));
-//:: }
-//::=20
-//:: static void save_i387( arch_thread_t *regs, struct _vki_fpstate *bu=
f )
-//:: {
-//:: if ( VG_(have_ssestate) )
-//:: save_i387_fxsave( regs, buf );
-//:: else
-//:: save_i387_fsave( regs, buf );
-//:: }
-//::=20
-//:: static inline void restore_i387_fsave( arch_thread_t *regs, const s=
truct _vki_fpstate __user *buf )
-//:: {
-//:: VG_(memcpy)( ®s->m_sse.fsave, buf, sizeof(struct i387_fsave_s=
truct) );
-//:: }
-//::=20
-//:: static void restore_i387_fxsave( arch_thread_t *regs, const struct =
_vki_fpstate __user *buf )
-//:: {
-//:: VG_(memcpy)(®s->m_sse.fxsave, &buf->_fxsr_env[0],=20
-//:: sizeof(struct i387_fxsave_struct) );
-//:: /* mxcsr reserved bits must be masked to zero for security reaso=
ns */
-//:: regs->m_sse.fxsave.mxcsr &=3D 0xffbf;
-//:: convert_fxsr_from_user( ®s->m_sse.fxsave, buf );
-//:: }
-//::=20
-//:: static void restore_i387( arch_thread_t *regs, const struct _vki_fp=
state __user *buf )
-//:: {
-//:: if ( VG_(have_ssestate) ) {
-//:: restore_i387_fxsave( regs, buf );
-//:: } else {
-//:: restore_i387_fsave( regs, buf );
-//:: }
-//:: }
-
-
-/*------------------------------------------------------------*/
-/*--- Creating signal frames ---*/
-/*------------------------------------------------------------*/
-
-/* Create a plausible-looking sigcontext from the thread's
- Vex guest state. NOTE: does not fill in the FP or SSE
- bits of sigcontext at the moment.
-*/
-static=20
-void synth_ucontext(ThreadId tid, const vki_siginfo_t *si,=20
- const vki_sigset_t *set,=20
- struct vki_ucontext *uc, struct _vki_fpstate *fpstat=
e)
-{
- ThreadState *tst =3D VG_(get_ThreadState)(tid);
- struct vki_sigcontext *sc =3D &uc->uc_mcontext;
-
- VG_(memset)(uc, 0, sizeof(*uc));
-
- uc->uc_flags =3D 0;
- uc->uc_link =3D 0;
- uc->uc_sigmask =3D *set;
- uc->uc_stack =3D tst->altstack;
- sc->fpstate =3D fpstate;
-
- // FIXME: save_i387(&tst->arch, fpstate);
-
-# define SC2(reg,REG) sc->reg =3D tst->arch.vex.guest_##REG
- SC2(r8,R8);
- SC2(r9,R9);
- SC2(r10,R10);
- SC2(r11,R11);
- SC2(r12,R12);
- SC2(r13,R13);
- SC2(r14,R14);
- SC2(r15,R15);
- SC2(rdi,RDI);
- SC2(rsi,RSI);
- SC2(rbp,RBP);
- SC2(rbx,RBX);
- SC2(rdx,RDX);
- SC2(rax,RAX);
- SC2(rcx,RCX);
- SC2(rsp,RSP);
-
- SC2(rip,RIP);
- sc->eflags =3D LibVEX_GuestAMD64_get_rflags(&tst->arch.vex);
- // FIXME: SC2(cs,CS);
- // FIXME: SC2(gs,GS);
- // FIXME: SC2(fs,FS);
- /* XXX err */
- /* XXX trapno */
-# undef SC2
-
- sc->cr2 =3D (UWord)si->_sifields._sigfault._addr;
-}
-
-
-#define SET_SIGNAL_RSP(zztid, zzval) \
- SET_THREAD_REG(zztid, zzval, STACK_PTR, post_reg_write, \
- Vg_CoreSignal, zztid, O_STACK_PTR, sizeof(Addr))
-
-
-/* Extend the stack segment downwards if needed so as to ensure the
- new signal frames are mapped to something. Return a Bool
- indicating whether or not the operation was successful.
-*/
-static Bool extend ( ThreadState *tst, Addr addr, SizeT size )
-{
- ThreadId tid =3D tst->tid;
- Segment *stackseg =3D NULL;
-
- if (VG_(extend_stack)(addr, tst->client_stack_szB)) {
- stackseg =3D VG_(find_segment)(addr);
- if (0 && stackseg)
- VG_(printf)("frame=3D%p seg=3D%p-%p\n",
- addr, stackseg->addr, stackseg->addr+stackseg->len);
- }
-
- if (stackseg =3D=3D NULL=20
- || (stackseg->prot & (VKI_PROT_READ|VKI_PROT_WRITE)) =3D=3D 0) {
- VG_(message)(
- Vg_UserMsg,
- "Can't extend stack to %p during signal delivery for thread %d:=
",
- addr, tid);
- if (stackseg =3D=3D NULL)
- VG_(message)(Vg_UserMsg, " no stack segment");
- else
- VG_(message)(Vg_UserMsg, " too small or bad protection modes")=
;
-
- /* set SIGSEGV to default handler */
- VG_(set_default_handler)(VKI_SIGSEGV);
- VG_(synth_fault_mapping)(tid, addr);
-
- /* The whole process should be about to die, since the default
- action of SIGSEGV to kill the whole process. */
- return False;
- }
-
- /* For tracking memory events, indicate the entire frame has been
- allocated. */
- VG_TRACK( new_mem_stack_signal, addr, size );
-
- return True;
-}
-
-
-/* Build the Valgrind-specific part of a signal frame. */
-
-static void build_vg_sigframe(struct vg_sigframe *frame,
- ThreadState *tst,
- const vki_sigset_t *mask,
- UInt flags,
- Int sigNo)
-{
- frame->sigNo_private =3D sigNo;
- frame->magicPI =3D 0x31415927;
- frame->vex_shadow =3D tst->arch.vex_shadow;
- /* HACK ALERT */
- frame->vex =3D tst->arch.vex;
- /* end HACK ALERT */
- frame->mask =3D tst->sig_mask;
- frame->handlerflags =3D flags;
- frame->magicE =3D 0x27182818;
-}
-
-
-static Addr build_rt_sigframe(ThreadState *tst,
- Addr rsp_top_of_frame,
- const vki_siginfo_t *siginfo,
- void *handler, UInt flags,
- const vki_sigset_t *mask,
- void *restorer)
-{
- struct rt_sigframe *frame;
- Addr rsp =3D rsp_top_of_frame;
- Int sigNo =3D siginfo->si_signo;
-
- rsp -=3D sizeof(*frame);
- rsp =3D ROUNDDN(rsp, 16);
- frame =3D (struct rt_sigframe *)rsp;
-
- if (!extend(tst, rsp, sizeof(*frame)))
- return rsp_top_of_frame;
-
- /* retaddr, siginfo, uContext fields are to be written */
- VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "rt signal handler =
frame",=20
- rsp, offsetof(struct rt_sigframe, vg) );
-
- if (flags & VKI_SA_RESTORER)
- frame->retaddr =3D (Addr)restorer;
- else
- frame->retaddr
- =3D VG_(client_trampoline_code)+VG_(tramp_rt_sigreturn_offset);
-
- VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t));
-
- /* SIGILL defines addr to be the faulting address */
- if (sigNo =3D=3D VKI_SIGILL && siginfo->si_code > 0)
- frame->sigInfo._sifields._sigfault._addr=20
- =3D (void*)tst->arch.vex.guest_RIP;
-
- synth_ucontext(tst->tid, siginfo, mask, &frame->uContext, &frame->fps=
tate);
-
- VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,=20
- rsp, offsetof(struct rt_sigframe, vg) );
-
- build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo);
- =20
- return rsp;
-}
-
-
-void VGA_(push_signal_frame)(ThreadId tid, Addr rsp_top_of_frame,
- const vki_siginfo_t *siginfo,
- void *handler, UInt flags,
- const vki_sigset_t *mask,
- void *restorer)
-{
- Addr rsp;
- struct rt_sigframe *frame;
- ThreadState* tst =3D VG_(get_ThreadState)(tid);
-
- rsp =3D build_rt_sigframe(tst, rsp_top_of_frame, siginfo,=20
- handler, flags, mask, restorer);
- frame =3D (struct rt_sigframe *)rsp;
-
- /* Set the thread so it will next run the handler. */
- /* tst->m_rsp =3D rsp; */
- SET_SIGNAL_RSP(tid, rsp);
-
- //VG_(printf)("handler =3D %p\n", handler);
- tst->arch.vex.guest_RIP =3D (Addr) handler;
- tst->arch.vex.guest_RDI =3D (ULong) siginfo->si_signo;
- tst->arch.vex.guest_RSI =3D (Addr) &frame->sigInfo;
- tst->arch.vex.guest_RDX =3D (Addr) &frame->uContext;
- /* This thread needs to be marked runnable, but we leave that the
- caller to do. */
-
- if (0)
- VG_(printf)("pushed signal frame; %%RSP now =3D %p, "
- "next %%RIP =3D %p, status=3D%d\n",=20
- rsp, tst->arch.vex.guest_RIP, tst->status);
-}
-
-
-/*------------------------------------------------------------*/
-/*--- Destroying signal frames ---*/
-/*------------------------------------------------------------*/
-
-/* Return False and don't do anything, just set the client to take a
- segfault, if it looks like the frame is corrupted. */
-static=20
-Bool restore_vg_sigframe ( ThreadState *tst,=20
- struct vg_sigframe *frame, Int *sigNo )
-{
- if (frame->magicPI !=3D 0x31415927 ||
- frame->magicE !=3D 0x27182818) {
- VG_(message)(Vg_UserMsg, "Thread %d return signal frame "
- "corrupted. Killing process.",
- tst->tid);
- VG_(set_default_handler)(VKI_SIGSEGV);
- VG_(synth_fault)(tst->tid);
- *sigNo =3D VKI_SIGSEGV;
- return False;
- }
- tst->sig_mask =3D frame->mask;
- tst->tmp_sig_mask =3D frame->mask;
- tst->arch.vex_shadow =3D frame->vex_shadow;
- /* HACK ALERT */
- tst->arch.vex =3D frame->vex;
- /* end HACK ALERT */
- *sigNo =3D frame->sigNo_private;
- return True;
-}
-
-static=20
-void restore_sigcontext( ThreadState *tst,=20
- struct vki_sigcontext *sc,=20
- struct _vki_fpstate *fpstate )
-{
- tst->arch.vex.guest_RAX =3D sc->rax;
- tst->arch.vex.guest_RCX =3D sc->rcx;
- tst->arch.vex.guest_RDX =3D sc->rdx;
- tst->arch.vex.guest_RBX =3D sc->rbx;
- tst->arch.vex.guest_RBP =3D sc->rbp;=20
- tst->arch.vex.guest_RSP =3D sc->rsp;
- tst->arch.vex.guest_RSI =3D sc->rsi;
- tst->arch.vex.guest_RDI =3D sc->rdi;
- tst->arch.vex.guest_R8 =3D sc->r8;
- tst->arch.vex.guest_R9 =3D sc->r9;
- tst->arch.vex.guest_R10 =3D sc->r10;
- tst->arch.vex.guest_R11 =3D sc->r11;
- tst->arch.vex.guest_R12 =3D sc->r12;
- tst->arch.vex.guest_R13 =3D sc->r13;
- tst->arch.vex.guest_R14 =3D sc->r14;
- tst->arch.vex.guest_R15 =3D sc->r15;
-//:: tst->arch.vex.guest_rflags =3D sc->rflags;
-//:: tst->arch.vex.guest_RIP =3D sc->rip;
-
-//:: tst->arch.vex.guest_CS =3D sc->cs;=20
-//:: tst->arch.vex.guest_FS =3D sc->fs;
-//:: tst->arch.vex.guest_GS =3D sc->gs;
-
-//:: restore_i387(&tst->arch, fpstate);
-}
-
-
-static=20
-SizeT restore_rt_sigframe ( ThreadState *tst,=20
- struct rt_sigframe *frame, Int *sigNo )
-{
- if (restore_vg_sigframe(tst, &frame->vg, sigNo))
- restore_sigcontext(tst, &frame->uContext.uc_mcontext, &frame->fpst=
ate);
-
- return sizeof(*frame);
-}
-
-
-void VGA_(signal_return)(ThreadId tid, Bool isRT)
-{
- Addr rsp;
- ThreadState* tst;
- SizeT size;
- Int sigNo;
-
- vg_assert(isRT);
-
- tst =3D VG_(get_ThreadState)(tid);
-
- /* Correctly reestablish the frame base address. */
- rsp =3D tst->arch.vex.guest_RSP;
-
- size =3D restore_rt_sigframe(tst, (struct rt_sigframe *)rsp, &sigNo);
-
- VG_TRACK( die_mem_stack_signal, rsp, size );
-
- if (VG_(clo_trace_signals))
- VG_(message)(
- Vg_DebugMsg,=20
- "VGA_(signal_return) (thread %d): isRT=3D%d valid magic; RIP=3D=
%p",=20
- tid, isRT, tst->arch.vex.guest_RIP);
-
- /* tell the tools */
- VG_TRACK( post_deliver_signal, tid, sigNo );
-}
-
-//:: /*------------------------------------------------------------*/
-//:: /*--- Making coredumps ---*/
-//:: /*------------------------------------------------------------*/
-//::=20
-//:: void VGA_(fill_elfregs_from_tst)(struct vki_user_regs_struct* regs,=
=20
-//:: const arch_thread_t* arch)
-//:: {
-//:: regs->rflags =3D arch->m_rflags;
-//:: regs->rsp =3D arch->m_rsp;
-//:: regs->rip =3D arch->m_rip;
-//::
-//:: regs->rbx =3D arch->m_rbx;
-//:: regs->rcx =3D arch->m_rcx;
-//:: regs->rdx =3D arch->m_rdx;
-//:: regs->rsi =3D arch->m_rsi;
-//:: regs->rdi =3D arch->m_rdi;
-//:: regs->rbp =3D arch->m_rbp;
-//:: regs->rax =3D arch->m_rax;
-//:: regs->r8 =3D arch->m_r8;
-//:: regs->r9 =3D arch->m_r9;
-//:: regs->r10 =3D arch->m_r10;
-//:: regs->r11 =3D arch->m_r11;
-//:: regs->r12 =3D arch->m_r12;
-//:: regs->r13 =3D arch->m_r13;
-//:: regs->r14 =3D arch->m_r14;
-//:: regs->r15 =3D arch->m_r15;
-//::=20
-//:: regs->cs =3D arch->m_cs;
-//:: regs->fs =3D arch->m_fs;
-//:: regs->gs =3D arch->m_gs;
-//:: }
-//::=20
-//:: static void fill_fpu(vki_elf_fpregset_t *fpu, const Char *from)
-//:: {
-//:: if (VG_(have_ssestate)) {
-//:: UShort *to;
-//:: Int i;
-//::=20
-//:: /* This is what the kernel does */
-//:: VG_(memcpy)(fpu, from, 7*sizeof(long));
-//:: =20
-//:: to =3D (UShort *)&fpu->st_space[0];
-//:: from +=3D 18 * sizeof(UShort);
-//::=20
-//:: for (i =3D 0; i < 8; i++, to +=3D 5, from +=3D 8)=20
-//:: VG_(memcpy)(to, from, 5*sizeof(UShort));
-//:: } else
-//:: VG_(memcpy)(fpu, from, sizeof(*fpu));
-//:: }
-//::=20
-//:: void VGA_(fill_elffpregs_from_tst)( vki_elf_fpregset_t* fpu,
-//:: const arch_thread_t* arch)
-//:: {
-//:: fill_fpu(fpu, (const Char *)&arch->m_sse);
-//:: }
-//::=20
-//:: void VGA_(fill_elffpxregs_from_tst) ( vki_elf_fpxregset_t* xfpu,
-//:: const arch_thread_t* arch )
-//:: {
-//:: VG_(memcpy)(xfpu, arch->m_sse.state, sizeof(*xfpu));
-//:: }
-//::=20
-//:: /*-----------------------------------------------------------------=
---*/
-//:: /*--- end =
---*/
-//:: /*-----------------------------------------------------------------=
---*/
Modified: trunk/coregrind/arm/Makefile.am
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/arm/Makefile.am 2005-04-24 12:33:12 UTC (rev 3555)
+++ trunk/coregrind/arm/Makefile.am 2005-04-24 14:18:14 UTC (rev 3556)
@@ -18,7 +18,6 @@
=20
libarch_a_SOURCES =3D \
dispatch.S \
- signals.c \
state.c
=20
if USE_PIE
Deleted: trunk/coregrind/arm/signals.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/arm/signals.c 2005-04-24 12:33:12 UTC (rev 3555)
+++ trunk/coregrind/arm/signals.c 2005-04-24 14:18:14 UTC (rev 3556)
@@ -1,312 +0,0 @@
-
-/*--------------------------------------------------------------------*/
-/*--- Arch-specific signals stuff. arm/signals.c ---*/
-/*--------------------------------------------------------------------*/
-
-/*
- This file is part of Valgrind, a dynamic binary instrumentation
- framework.
-
- Copyright (C) 2000-2005 Nicholas Nethercote
- nj...@ca...
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- This program 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
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307, USA.
-
- The GNU General Public License is contained in the file COPYING.
-*/
-
-#include "core.h"
-
-#include "libvex_guest_arm.h"
-
-/*------------------------------------------------------------*/
-/*--- Signal frame ---*/
-/*------------------------------------------------------------*/
-
-// A structure in which to save the application's registers
-// during the execution of signal handlers.
-
-#if 0
-typedef
- struct {
- /* There are two different stack frame formats, depending on
- whether the client set the SA_SIGINFO flag for the handler.
- This structure is put onto the client's stack as part of
- signal delivery, and therefore appears as the signal
- handler's arguments.
-
- The first two words are common for both frame formats -
- they're the return address and the signal number. */
-
- /* Sig handler's (bogus) return address */
- Addr retaddr;
- /* The arg to the sig handler. We need to inspect this after
- the handler returns, but it's unreasonable to assume that the
- handler won't change it. So we keep a second copy of it in
- sigNo_private. */
- Int sigNo;
-
- /* This is where the two frames start differing. */
- union {
- struct { /* set SA_SIGINFO */
- /* ptr to siginfo_t. */
- Addr psigInfo;
-
- /* ptr to ucontext */
- Addr puContext;
- } sigInfo;
- struct vki_sigcontext sigContext; /* did not set SA_SIGINFO */
- } handlerArgs;
-
- /* The rest are private fields which the handler is unaware of. */
-
- /* Sanity check word. */
- UInt magicPI;
- /* pointed to by psigInfo */
- vki_siginfo_t sigInfo;
- /* pointed to by puContext */
- struct vki_ucontext uContext;
-
- /* Safely-saved version of sigNo, as described above. */
- Int sigNo_private;
-
- /* Saved processor state. */
- VexGuestX86State vex;
- VexGuestX86State vex_shadow;
-
- /* saved signal mask to be restored when handler returns */
- vki_sigset_t mask;
-
- /* Scheduler-private stuff: what was the thread's status prior to
- delivering this signal? */
- ThreadStatus status;
- void* /*pthread_mutex_t* */ associated_mx;
- void* /*pthread_cond_t* */ associated_cv;
-
- /* Sanity check word. Is the highest-addressed word; do not
- move!*/
- UInt magicE;
- }
- VgSigFrame;
-#endif
-
-/*------------------------------------------------------------*/
-/*--- Signal operations ---*/
-/*------------------------------------------------------------*/
-
-#if 0
-/* Make up a plausible-looking thread state from the thread's current st=
ate */
-static void synth_ucontext(ThreadId tid, const vki_siginfo_t *si,=20
- const vki_sigset_t *set, struct vki_ucontext *uc)
-{
- ThreadState *tst =3D VG_(get_ThreadState)(tid);
- struct vki_sigcontext *sc =3D &uc->uc_mcontext;
-
- VG_(memset)(uc, 0, sizeof(*uc));
-
- uc->uc_flags =3D 0;
- uc->uc_link =3D 0;
- uc->uc_sigmask =3D *set;
- uc->uc_stack =3D tst->altstack;
-
-#define SC2(reg,REG) sc->reg =3D tst->arch.vex.guest_##REG
- SC2(gs,GS);
- SC2(fs,FS);
- SC2(es,ES);
- SC2(ds,DS);
-
- SC2(edi,EDI);
- SC2(esi,ESI);
- SC2(ebp,EBP);
- SC2(esp,ESP);
- SC2(ebx,EBX);
- SC2(edx,EDX);
- SC2(ecx,ECX);
- SC2(eax,EAX);
-
- SC2(eip,EIP);
- SC2(cs,CS);
- sc->eflags =3D LibVEX_GuestX86_get_eflags(&tst->arch.vex);
- SC2(ss,SS);
- /* XXX esp_at_signal */
- /* XXX trapno */
- /* XXX err */
-#undef SC2
-
- sc->cr2 =3D (UInt)si->_sifields._sigfault._addr;
-}
-#endif
-
-#if 0
-#define SET_SIGNAL_ESP(zztid, zzval) \
- SET_THREAD_REG(zztid, zzval, VGA_STACK_PTR, VGA_R_STACK_PTR, \
- post_reg_write_deliver_signal)
-#endif
-
-void VGA_(push_signal_frame)(ThreadId tid, Addr esp_top_of_frame,
- const vki_siginfo_t *siginfo,
- void *handler, UInt flags,
- const vki_sigset_t *mask)
-{
- I_die_here;
-#if 0
- Addr esp;
- ThreadState* tst;
- VgSigFrame* frame;
- Int sigNo =3D siginfo->si_signo;
-
- esp =3D esp_top_of_frame;
- esp -=3D sizeof(VgSigFrame);
- frame =3D (VgSigFrame*)esp;
-
- tst =3D & VG_(threads)[tid];
-
- /* For tracking memory events, indicate the entire frame has been
- * allocated, but pretend that only the first four words are written =
*/
- VG_TRACK( new_mem_stack_signal, (Addr)frame, sizeof(VgSigFrame) );
-
- /* Assert that the frame is placed correctly. */
- vg_assert( (sizeof(VgSigFrame) & 0x3) =3D=3D 0 );
- vg_assert( ((Char*)(&frame->magicE)) + sizeof(UInt)=20
- =3D=3D ((Char*)(esp_top_of_frame)) );
-
- /* retaddr, sigNo, psigInfo, puContext fields are to be written */
- VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame",=20
- (Addr)frame, offsetof(VgSigFrame, handlerArg=
s) );
- frame->retaddr =3D (UInt)VG_(client_trampoline_code)+VG_(tramp_sig=
return_offset);
- frame->sigNo =3D sigNo;
- frame->sigNo_private =3D sigNo;
- VG_TRACK( post_mem_write, (Addr)frame, offsetof(VgSigFrame, handlerAr=
gs) );
-
- if (flags & VKI_SA_SIGINFO) {
- /* if the client asked for a siginfo delivery, then build the stac=
k that way */
- VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame=
(siginfo)",=20
- (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigInfo) );
- frame->handlerArgs.sigInfo.psigInfo =3D (Addr)&frame->sigInfo;
- frame->handlerArgs.sigInfo.puContext =3D (Addr)&frame->uContext;
- VG_TRACK( post_mem_write, (Addr)&frame->handlerArgs, sizeof(frame-=
>handlerArgs.sigInfo) );
-
- VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame=
(siginfo)",=20
- (Addr)&frame->sigInfo, sizeof(frame->sigInfo) );
- VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t));
- VG_TRACK( post_mem_write, (Addr)&frame->sigInfo, sizeof(frame->sig=
Info) );
-
- VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame=
(siginfo)",=20
- (Addr)&frame->uContext, sizeof(frame->uContext) );
- synth_ucontext(tid, siginfo, mask, &frame->uContext);
- VG_TRACK( post_mem_write, (Addr)&frame->uContext, sizeof(frame->uC=
ontext) );
- } else {
- struct vki_ucontext uc;
-
- /* otherwise just put the sigcontext there */
-
- synth_ucontext(tid, siginfo, mask, &uc);
-
- VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame=
(sigcontext)",=20
- (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigContext) );
- VG_(memcpy)(&frame->handlerArgs.sigContext, &uc.uc_mcontext,=20
- sizeof(struct vki_sigcontext));
- VG_TRACK( post_mem_write, (Addr)&frame->handlerArgs,=20
- sizeof(frame->handlerArgs.sigContext) );
- =20
- frame->handlerArgs.sigContext.oldmask =3D tst->sig_mask.sig[0];
- }
-
- frame->magicPI =3D 0x31415927;
-
- frame->vex =3D tst->arch.vex;
- if (VG_(needs).shadow_regs)
- frame->vex_shadow =3D tst->arch.vex_shadow;
-
- frame->mask =3D tst->sig_mask;
-
- /* If the thread is currently blocked in a syscall, we want it to
- resume as runnable. */
- if (tst->status =3D=3D VgTs_WaitSys)
- frame->status =3D VgTs_Runnable;
- else
- frame->status =3D tst->status;
-=20
- frame->associated_mx =3D tst->associated_mx;
- frame->associated_cv =3D tst->associated_cv;
-
- frame->magicE =3D 0x27182818;
-
- /* Ensure 'tid' and 'tst' correspond */
- vg_assert(& VG_(threads)[tid] =3D=3D tst);
- /* Set the thread so it will next run the handler. */
- /* tst->m_esp =3D esp; */
- SET_SIGNAL_ESP(tid, esp);
-
- tst->arch.vex.guest_EIP =3D (Addr) handler;
- /* This thread needs to be marked runnable, but we leave that the
- caller to do. */
-
- if (0)
- VG_(printf)("pushed signal frame; %%ESP now =3D %p, next %%EBP =3D=
%p, status=3D%d\n",=20
- esp, tst->arch.vex.guest_EIP, tst->status);
-#endif
-}
-
-Int VGA_(pop_signal_frame)(ThreadId tid)
-{
- I_die_here;
-#if 0
- Addr esp;
- VgSigFrame* frame;
- ThreadState* tst;
-
- vg_assert(VG_(is_valid_tid)(tid));
- tst =3D & VG_(threads)[tid];
-
- /* Correctly reestablish the frame base address. */
- esp =3D tst->arch.vex.guest_ESP;
- frame =3D (VgSigFrame*)
- (esp -4 /* because the handler's RET pops the RA */
- +20 /* because signalreturn_bogusRA pushes 5 words */)=
;
-
- vg_assert(frame->magicPI =3D=3D 0x31415927);
- vg_assert(frame->magicE =3D=3D 0x27182818);
- if (VG_(clo_trace_signals))
- VG_(message)(Vg_DebugMsg,=20
- "vg_pop_signal_frame (thread %d): valid magic; EIP=3D%p", tid, =
frame->vex.guest_EIP);
-
- /* Mark the frame structure as nonaccessible. */
- VG_TRACK( die_mem_stack_signal, (Addr)frame, sizeof(VgSigFrame) );
-
- /* restore machine state */
- tst->arch.vex =3D frame->vex;
- if (VG_(needs).shadow_regs)
- tst->arch.vex_shadow =3D frame->vex_shadow;
-
- /* And restore the thread's status to what it was before the signal
- was delivered. */
- tst->status =3D frame->status;
-
- tst->associated_mx =3D frame->associated_mx;
- tst->associated_cv =3D frame->associated_cv;
-
- tst->sig_mask =3D frame->mask;
-
- /* don't use the copy exposed to the handler; it might have changed
- it. */
- return frame->sigNo_private;=20
-#endif
-}
-
-/*--------------------------------------------------------------------*/
-/*--- end ---*/
-/*--------------------------------------------------------------------*/
Modified: trunk/coregrind/core.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/core.h 2005-04-24 12:33:12 UTC (rev 3555)
+++ trunk/coregrind/core.h 2005-04-24 14:18:14 UTC (rev 3556)
@@ -1687,13 +1687,6 @@
// Used by leakcheck
extern void VGA_(mark_from_registers)(ThreadId tid, void (*marker)(Addr)=
);
=20
-// Signal stuff
-extern void VGA_(push_signal_frame) ( ThreadId tid, Addr sp_top_of_frame=
,
- const vki_siginfo_t *siginfo,
- void *handler, UInt flags,
- const vki_sigset_t *mask,
- void *restorer );
-
////typedef struct _ThreadArchAux ThreadArchAux;
=20
=20
Added: trunk/coregrind/m_sigframe/Makefile.am
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_sigframe/Makefile.am 2005-04-24 12:33:12 UTC (rev 3=
555)
+++ trunk/coregrind/m_sigframe/Makefile.am 2005-04-24 14:18:14 UTC (rev 3=
556)
@@ -0,0 +1,18 @@
+include $(top_srcdir)/Makefile.all.am
+include $(top_srcdir)/Makefile.core-AM_CPPFLAGS.am
+
+AM_CFLAGS =3D $(WERROR) -Wmissing-prototypes -Winline -Wall -Wshadow -O =
-g
+
+EXTRA_DIST =3D \
+ README_SIGFRAME.txt
+
+noinst_LIBRARIES =3D libsigframe.a
+
+libsigframe_a_SOURCES =3D \
+ sigframe-@VG_PLATFORM@.c
+
+if USE_PIE
+libsigframe_a_CFLAGS =3D $(AM_CFLAGS) -fpie
+else
+libsigframe_a_CFLAGS =3D $(AM_CFLAGS)
+endif
Copied: trunk/coregrind/m_sigframe/sigframe-amd64-linux.c (from rev 3550,=
trunk/coregrind/amd64/signals.c)
Copied: trunk/coregrind/m_sigframe/sigframe-arm-linux.c (from rev 3550, t=
runk/coregrind/arm/signals.c)
Copied: trunk/coregrind/m_sigframe/sigframe-x86-linux.c (from rev 3550, t=
runk/coregrind/x86/signals.c)
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/x86/signals.c 2005-04-24 00:21:01 UTC (rev 3550)
+++ trunk/coregrind/m_sigframe/sigframe-x86-linux.c 2005-04-24 14:18:14 U=
TC (rev 3556)
@@ -0,0 +1,753 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Create/destroy signal delivery frames. ---*/
+/*--- sigframe-x86-linux.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2000-2005 Nicholas Nethercote
+ nj...@ca...
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "core.h"
+#include "pub_core_sigframe.h"
+#include "libvex_guest_x86.h"
+
+
+/* This module creates and removes signal frames for signal deliveries
+ on x86-linux.
+
+ Note, this file contains kernel-specific knowledge in the form of
+ 'struct sigframe' and 'struct rt_sigframe'. How does that relate
+ to the vki kernel interface stuff?
+
+ Either a 'struct sigframe' or a 'struct rtsigframe' is pushed=20
+ onto the client's stack. This contains a subsidiary
+ vki_ucontext. That holds the vcpu's state across the signal,=20
+ so that the sighandler can mess with the vcpu state if it
+ really wants.
+
+ FIXME: sigcontexting is basically broken for the moment. When
+ delivering a signal, the integer registers and %eflags are
+ correctly written into the sigcontext, however the FP and SSE state
+ is not. When returning from a signal, only the integer registers
+ are restored from the sigcontext; the rest of the CPU state is
+ restored to what it was before the signal.
+
+ This will be fixed.
+*/
+
+
+/*------------------------------------------------------------*/
+/*--- Signal frame layouts ---*/
+/*------------------------------------------------------------*/
+
+// A structure in which to save the application's registers
+// during the execution of signal handlers.
+
+// Linux has 2 signal frame structures: one for normal signal
+// deliveries, and one for SA_SIGINFO deliveries (also known as RT
+// signals).
+//
+// In theory, so long as we get the arguments to the handler function
+// right, it doesn't matter what the exact layout of the rest of the
+// frame is. Unfortunately, things like gcc's exception unwinding
+// make assumptions about the locations of various parts of the frame,
+// so we need to duplicate it exactly.
+
+/* Valgrind-specific parts of the signal frame */
+struct vg_sigframe
+{
+ /* Sanity check word. */
+ UInt magicPI;
+
+ UInt handlerflags; /* flags for signal handler */
+
+
+ /* Safely-saved version of sigNo, as described above. */
+ Int sigNo_private;
+
+ /* XXX This is wrong. Surely we should store the shadow values
+ into the shadow memory behind the actual values? */
+ VexGuestX86State vex_shadow;
+
+ /* HACK ALERT */
+ VexGuestX86State vex;
+ /* end HACK ALERT */
+
+ /* saved signal mask to be restored when handler returns */
+ vki_sigset_t mask;
+
+ /* Sanity check word. Is the highest-addressed word; do not
+ move!*/
+ UInt magicE;
+};
+
+struct sigframe
+{
+ /* Sig handler's return address */
+ Addr retaddr;
+ Int sigNo;
+
+ struct vki_sigcontext sigContext;
+ struct _vki_fpstate fpstate;
+
+ struct vg_sigframe vg;
+};
+
+struct rt_sigframe
+{
+ /* Sig handler's return address */
+ Addr retaddr;
+ Int sigNo;
+
+ /* ptr to siginfo_t. */
+ Addr psigInfo;
+
+ /* ptr to ucontext */
+ Addr puContext;
+ /* pointed to by psigInfo */
+ vki_siginfo_t sigInfo;
+
+ /* pointed to by puContext */
+ struct vki_ucontext uContext;
+ struct _vki_fpstate fpstate;
+
+ struct vg_sigframe vg;
+};
+
+
+//:: /*------------------------------------------------------------*/
+//:: /*--- Signal operations ---*/
+//:: /*------------------------------------------------------------*/
+//::=20
+//:: /*=20
+//:: Great gobs of FP state conversion taken wholesale from
+//:: linux/arch/i386/kernel/i387.c
+//:: */
+//::=20
+//:: /*
+//:: * FXSR floating point environment conversions.
+//:: */
+//:: #define X86_FXSR_MAGIC 0x0000
+//::=20
+//:: /*
+//:: * FPU tag word conversions.
+//:: */
+//::=20
+//:: static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
+//:: {
+//:: unsigned int tmp; /* to avoid 16 bit prefixes in the code */
+//:: =20
+//:: /* Transform each pair of bits into 01 (valid) or 00 (empty) */
+//:: tmp =3D ~twd;
+//:: tmp =3D (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
+//:: /* and move the valid bits to the lower byte. */
+//:: tmp =3D (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
+//:: tmp =3D (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
+//:: tmp =3D (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
+//:: return tmp;
+//:: }
+//::=20
+//:: static unsigned long twd_fxsr_to_i387( const struct i387_fxsave_str=
uct *fxsave )
+//:: {
+//:: struct _vki_fpxreg *st =3D NULL;
+//:: unsigned long twd =3D (unsigned long) fxsave->twd;
+//:: unsigned long tag;
+//:: unsigned long ret =3D 0xffff0000u;
+//:: int i;
+//::=20
+//:: #define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16);
+//::=20
+//:: for ( i =3D 0 ; i < 8 ; i++ ) {
+//:: if ( twd & 0x1 ) {
+//:: st =3D (struct _vki_fpxreg *) FPREG_ADDR( fxsave, i );
+//::=20
+//:: switch ( st->exponent & 0x7fff ) {
+//:: case 0x7fff:
+//:: tag =3D 2; /* Special */
+//:: break;
+//:: case 0x0000:
+//:: if ( !st->significand[0] &&
+//:: !st->significand[1] &&
+//:: !st->significand[2] &&
+//:: !st->significand[3] ) {
+//:: tag =3D 1; /* Zero */
+//:: } else {
+//:: tag =3D 2; /* Special */
+//:: }
+//:: break;
+//:: default:
+//:: if ( st->significand[3] & 0x8000 ) {
+//:: tag =3D 0; /* Valid */
+//:: } else {
+//:: tag =3D 2; /* Special */
+//:: }
+//:: break;
+//:: }
+//:: } else {
+//:: tag =3D 3; /* Empty */
+//:: }
+//:: ret |=3D (tag << (2 * i));
+//:: twd =3D twd >> 1;
+//:: }
+//:: return ret;
+//:: }
+//::=20
+//:: static void convert_fxsr_to_user( struct _vki_fpstate *buf,
+//:: const struct i387_fxsave_struct *fxsave )
+//:: {
+//:: unsigned long env[7];
+//:: struct _vki_fpreg *to;
+//:: struct _vki_fpxreg *from;
+//:: int i;
+//::=20
+//:: env[0] =3D (unsigned long)fxsave->cwd | 0xffff0000ul;
+//:: env[1] =3D (unsigned long)fxsave->swd | 0xffff0000ul;
+//:: env[2] =3D twd_fxsr_to_i387(fxsave);
+//:: env[3] =3D fxsave->fip;
+//:: env[4] =3D fxsave->fcs | ((unsigned long)fxsave->fop << 16);
+//:: env[5] =3D fxsave->foo;
+//:: env[6] =3D fxsave->fos;
+//:: =20
+//:: VG_(memcpy)(buf, env, 7 * sizeof(unsigned long));
+//::=20
+//:: to =3D &buf->_st[0];
+//:: from =3D (struct _vki_fpxreg *) &fxsave->st_space[0];
+//:: for ( i =3D 0 ; i < 8 ; i++, to++, from++ ) {
+//:: unsigned long __user *t =3D (unsigned long __user *)to;
+//:: unsigned long *f =3D (unsigned long *)from;
+//::=20
+//:: t[0] =3D f[0];
+//:: t[1] =3D f[1];
+//:: to->exponent =3D from->exponent;
+//:: }
+//:: }
+//::=20
+//:: static void convert_fxsr_from_user( struct i387_fxsave_struct *fxsa=
ve,
+//:: const struct _vki_fpstate *buf )
+//:: {
+//:: unsigned long env[7];
+//:: struct _vki_fpxreg *to;
+//:: const struct _vki_fpreg *from;
+//:: int i;
+//:: =09
+//:: VG_(memcpy)(env, buf, 7 * sizeof(long));
+//::=20
+//:: fxsave->cwd =3D (unsigned short)(env[0] & 0xffff);
+//:: fxsave->swd =3D (unsigned short)(env[1] & 0xffff);
+//:: fxsave->twd =3D twd_i387_to_fxsr((unsigned short)(env[2] & 0xfff=
f));
+//:: fxsave->fip =3D env[3];
+//:: fxsave->fop =3D (unsigned short)((env[4] & 0xffff0000ul) >> 16);
+//:: fxsave->fcs =3D (env[4] & 0xffff);
+//:: fxsave->foo =3D env[5];
+//:: fxsave->fos =3D env[6];
+//::=20
+//:: to =3D (struct _vki_fpxreg *) &fxsave->st_space[0];
+//:: from =3D &buf->_st[0];
+//:: for ( i =3D 0 ; i < 8 ; i++, to++, from++ ) {
+//:: unsigned long *t =3D (unsigned long *)to;
+//:: unsigned long __user *f =3D (unsigned long __user *)from;
+//::=20
+//:: t[0] =3D f[0];
+//:: t[1] =3D f[1];
+//:: to->exponent =3D from->exponent;
+//:: }
+//:: }
+//::=20
+//:: static inline void save_i387_fsave( arch_thread_t *regs, struct _vk=
i_fpstate *buf )
+//:: {
+//:: struct i387_fsave_struct *fs =3D ®s->m_sse.fsave;
+//::=20
+//:: fs->status =3D fs->swd;
+//:: VG_(memcpy)(buf, fs, sizeof(*fs));
+//:: }
+//::=20
+//:: static void save_i387_fxsave( arch_thread_t *regs, struct _vki_fpst=
ate *buf )
+//:: {
+//:: const struct i387_fxsave_struct *fx =3D ®s->m_sse.fxsave;
+//:: convert_fxsr_to_user( buf, fx );
+//::=20
+//:: buf->status =3D fx->swd;
+//:: buf->magic =3D X86_FXSR_MAGIC;
+//:: VG_(memcpy)(buf->_fxsr_env, fx, sizeof(struct i387_fxsave_struct=
));
+//:: }
+//::=20
+//:: static void save_i387( arch_thread_t *regs, struct _vki_fpstate *bu=
f )
+//:: {
+//:: if ( VG_(have_ssestate) )
+//:: save_i387_fxsave( regs, buf );
+//:: else
+//:: save_i387_fsave( regs, buf );
+//:: }
+//::=20
+//:: static inline void restore_i387_fsave( arch_thread_t *regs, const s=
truct _vki_fpstate __user *buf )
+//:: {
+//:: VG_(memcpy)( ®s->m_sse.fsave, buf, sizeof(struct i387_fsave_s=
truct) );
+//:: }
+//::=20
+//:: static void restore_i387_fxsave( arch_thread_t *regs, const struct =
_vki_fpstate __user *buf )
+//:: {
+//:: VG_(memcpy)(®s->m_sse.fxsave, &buf->_fxsr_env[0],=20
+//:: sizeof(struct i387_fxsave_struct) );
+//:: /* mxcsr reserved bits must be masked to zero for security reaso=
ns */
+//:: regs->m_sse.fxsave.mxcsr &=3D 0xffbf;
+//:: convert_fxsr_from_user( ®s->m_sse.fxsave, buf );
+//:: }
+//::=20
+//:: static void restore_i387( arch_thread_t *regs, const struct _vki_fp=
state __user *buf )
+//:: {
+//:: if ( VG_(have_ssestate) ) {
+//:: restore_i387_fxsave( regs, buf );
+//:: } else {
+//:: restore_i387_fsave( regs, buf );
+//:: }
+//:: }
+
+
+/*------------------------------------------------------------*/
+/*--- Creating signal frames ---*/
+/*------------------------------------------------------------*/
+
+/* Create a plausible-looking sigcontext from the thread's
+ Vex guest state. NOTE: does not fill in the FP or SSE
+ bits of sigcontext at the moment.
+*/
+static=20
+void synth_ucontext(ThreadId tid, const vki_siginfo_t *si,=20
+ const vki_sigset_t *set,=20
+ struct vki_ucontext *uc, struct _vki_fpstate *fpstat=
e)
+{
+ ThreadState *tst =3D VG_(get_ThreadState)(tid);
+ struct vki_sigcontext *sc =3D &uc->uc_mcontext;
+
+ VG_(memset)(uc, 0, sizeof(*uc));
+
+ uc->uc_flags =3D 0;
+ uc->uc_link =3D 0;
+ uc->uc_sigmask =3D *set;
+ uc->uc_stack =3D tst->altstack;
+ sc->fpstate =3D fpstate;
+
+ // FIXME: save_i387(&tst->arch, fpstate);
+
+# define SC2(reg,REG) sc->reg =3D tst->arch.vex.guest_##REG
+ SC2(gs,GS);
+ SC2(fs,FS);
+ SC2(es,ES);
+ SC2(ds,DS);
+
+ SC2(edi,EDI);
+ SC2(esi,ESI);
+ SC2(ebp,EBP);
+ SC2(esp,ESP);
+ SC2(ebx,EBX);
+ SC2(edx,EDX);
+ SC2(ecx,ECX);
+ SC2(eax,EAX);
+
+ SC2(eip,EIP);
+ SC2(cs,CS);
+ sc->eflags =3D LibVEX_GuestX86_get_eflags(&tst->arch.vex);
+ SC2(ss,SS);
+ /* XXX esp_at_signal */
+ /* XXX trapno */
+ /* XXX err */
+# undef SC2
+
+ sc->cr2 =3D (UInt)si->_sifields._sigfault._addr;
+}
+
+
+#define SET_SIGNAL_ESP(zztid, zzval) \
+ SET_THREAD_REG(zztid, zzval, STACK_PTR, post_reg_write, \
+ Vg_CoreSignal, zztid, O_STACK_PTR, sizeof(Addr))
+
+
+/* Extend the stack segment downwards if needed so as to ensure the
+ new signal frames are mapped to something. Return a Bool
+ indicating whether or not the operation was successful.
+*/
+static Bool extend ( ThreadState *tst, Addr addr, SizeT size )
+{
+ ThreadId tid =3D tst->tid;
+ Segment *stackseg =3D NULL;
+
+ if (VG_(extend_stack)(addr, tst->client_stack_szB)) {
+ stackseg =3D VG_(find_segment)(addr);
+ if (0 && stackseg)
+ VG_(printf)("frame=3D%p seg=3D%p-%p\n",
+ addr, stackseg->addr, stackseg->addr+stackseg->len);
+ }
+
+ if (stackseg =3D=3D NULL=20
+ || (stackseg->prot & (VKI_PROT_READ|VKI_PROT_WRITE)) =3D=3D 0) {
+ VG_(message)(
+ Vg_UserMsg,
+ "Can't extend stack to %p during signal delivery for thread %d:=
",
+ addr, tid);
+ if (stackseg =3D=3D NULL)
+ VG_(message)(Vg_UserMsg, " no stack segment");
+ else
+ VG_(message)(Vg_UserMsg, " too small or bad protection modes")=
;
+
+ /* set SIGSEGV to default handler */
+ VG_(set_default_handler)(VKI_SIGSEGV);
+ VG_(synth_fault_mapping)(tid, addr);
+
+ /* The whole process should be about to die, since the default
+ action of SIGSEGV to kill the whole process. */
+ return False;
+ }
+
+ /* For tracking memory events, indicate the entire frame has been
+ allocated. */
+ VG_TRACK( new_mem_stack_signal, addr, size );
+
+ return True;
+}
+
+
+/* Build the Valgrind-specific part of a signal frame. */
+
+static void build_vg_sigframe(struct vg_sigframe *frame,
+ ThreadState *tst,
+ const vki_sigset_t *mask,
+ UInt flags,
+ Int sigNo)
+{
+ frame->sigNo_private =3D sigNo;
+ frame->magicPI =3D 0x31415927;
+ frame->vex_shadow =3D tst->arch.vex_shadow;
+ /* HACK ALERT */
+ frame->vex =3D tst->arch.vex;
+ /* end HACK ALERT */
+ frame->mask =3D tst->sig_mask;
+ frame->handlerflags =3D flags;
+ frame->magicE =3D 0x27182818;
+}
+
+
+static Addr build_sigframe(ThreadState *tst,
+ Addr esp_top_of_frame,
+ const vki_siginfo_t *siginfo,
+ void *handler, UInt flags,
+ const vki_sigset_t *mask,
+ void *restorer)
+{
+ struct sigframe *frame;
+ Addr esp =3D esp_top_of_frame;
+ Int sigNo =3D siginfo->si_signo;
+ struct vki_ucontext uc;
+
+ vg_assert((flags & VKI_SA_SIGINFO) =3D=3D 0);
+
+ esp -=3D sizeof(*frame);
+ esp =3D ROUNDDN(esp, 16);
+ frame =3D (struct sigframe *)esp;
+
+ if (!extend(tst, esp, sizeof(*frame)))
+ return esp_top_of_frame;
+
+ /* retaddr, sigNo, siguContext fields are to be written */
+ VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler fra=
me",=20
+ esp, offsetof(struct sigframe, vg) );
+
+ frame->sigNo =3D sigNo;
+
+ if (flags & VKI_SA_RESTORER)
+ frame->retaddr =3D (Addr)restorer;
+ else
+ frame->retaddr
+ =3D VG_(client_trampoline_code)+VG_(tramp_sigreturn_offset);
+
+ synth_ucontext(tst->tid, siginfo, mask, &uc, &frame->fpstate);
+
+ VG_(memcpy)(&frame->sigContext, &uc.uc_mcontext,=20
+ sizeof(struct vki_sigcontext));
+ frame->sigContext.oldmask =3D mask->sig[0];
+
+ VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,=20
+ esp, offsetof(struct sigframe, vg) );
+
+ build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo);
+ =20
+ return esp;
+}
+
+
+static Addr build_rt_sigframe(ThreadState *tst,
+ Addr esp_top_of_frame,
+ const vki_siginfo_t *siginfo,
+ void *handler, UInt flags,
+ const vki_sigset_t *mask,
+ void *restorer)
+{
+ struct rt_sigframe *frame;
+ Addr esp =3D esp_top_of_frame;
+ Int sigNo =3D siginfo->si_signo;
+
+ vg_assert((flags & VKI_SA_SIGINFO) !=3D 0);
+
+ esp -=3D sizeof(*frame);
+ esp =3D ROUNDDN(esp, 16);
+ frame =3D (struct rt_sigframe *)esp;
+
+ if (!extend(tst, esp, sizeof(*frame)))
+ return esp_top_of_frame;
+
+ /* retaddr, sigNo, pSiginfo, puContext fields are to be written */
+ VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "rt signal handler =
frame",=20
+ esp, offsetof(struct rt_sigframe, vg) );
+
+ frame->sigNo =3D sigNo;
+
+ if (flags & VKI_SA_RESTORER)
+ frame->retaddr =3D (Addr)restorer;
+ else
+ frame->retaddr=20
+ =3D VG_(client_trampoline_code)+VG_(tramp_rt_sigreturn_offset);
+
+ frame->psigInfo =3D (Addr)&frame->sigInfo;
+ frame->puContext =3D (Addr)&frame->uContext;
+ VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t));
+
+ /* SIGILL defines addr to be the faulting address */
+ if (sigNo =3D=3D VKI_SIGILL && siginfo->si_code > 0)
+ frame->sigInfo._sifields._sigfault._addr=20
+ =3D (void*)tst->arch.vex.guest_EIP;
+
+ synth_ucontext(tst->tid, siginfo, mask, &frame->uContext, &frame->fps=
tate);
+
+ VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,=20
+ esp, offsetof(struct rt_sigframe, vg) );
+
+ build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo);
+ =20
+ return esp;
+}
+
+
+/* EXPORTED */
+void VG_(sigframe_create)( ThreadId tid,=20
+ Addr esp_top_of_frame,
+ const vki_siginfo_t *siginfo,
+ void *handler,=20
+ UInt flags,
+ const vki_sigset_t *mask,
+ void *restorer )
+{
+ Addr esp;
+ ThreadState* tst =3D VG_(get_ThreadState)(tid);
+
+ if (flags & VKI_SA_SIGINFO)
+ esp =3D build_rt_sigframe(tst, esp_top_of_frame, siginfo,=20
+ handler, flags, mask, restorer);
+ else
+ esp =3D build_sigframe(tst, esp_top_of_frame,=20
+ siginfo, handler, flags, mask, restorer)=
;
+
+ /* Set the thread so it will next run the handler. */
+ /* tst->m_esp =3D esp; */
+ SET_SIGNAL_ESP(tid, esp);
+
+ //VG_(printf)("handler =3D %p\n", handler);
+ tst->arch.vex.guest_EIP =3D (Addr) handler;
+ /* This thread needs to be marked runnable, but we leave that the
+ caller to do. */
+
+ if (0)
+ VG_(printf)("pushed signal frame; %%ESP now =3D %p, "
+ "next %%EIP =3D %p, status=3D%d\n",=20
+ esp, tst->arch.vex.guest_EIP, tst->status);
+}
+
+
+/*------------------------------------------------------------...
[truncated message content] |