Home | History | Annotate | Download | only in m_sigframe
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- Create/destroy signal delivery frames.                       ---*/
      4 /*---                                       sigframe-s390x-linux.c ---*/
      5 /*--------------------------------------------------------------------*/
      6 
      7 /*
      8    This file is part of Valgrind, a dynamic binary instrumentation
      9    framework.
     10 
     11    Copyright IBM Corp. 2010-2013
     12 
     13    This program is free software; you can redistribute it and/or
     14    modify it under the terms of the GNU General Public License as
     15    published by the Free Software Foundation; either version 2 of the
     16    License, or (at your option) any later version.
     17 
     18    This program is distributed in the hope that it will be useful, but
     19    WITHOUT ANY WARRANTY; without even the implied warranty of
     20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     21    General Public License for more details.
     22 
     23    You should have received a copy of the GNU General Public License
     24    along with this program; if not, write to the Free Software
     25    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     26    02111-1307, USA.
     27 
     28    The GNU General Public License is contained in the file COPYING.
     29 */
     30 
     31 /* Contributed by Christian Borntraeger */
     32 
     33 #include "pub_core_basics.h"
     34 #include "pub_core_vki.h"
     35 #include "pub_core_vkiscnums.h"
     36 #include "pub_core_libcsetjmp.h"    // to keep _threadstate.h happy
     37 #include "pub_core_threadstate.h"
     38 #include "pub_core_aspacemgr.h"
     39 #include "pub_core_libcbase.h"
     40 #include "pub_core_libcassert.h"
     41 #include "pub_core_libcprint.h"
     42 #include "pub_core_machine.h"
     43 #include "pub_core_options.h"
     44 #include "pub_core_sigframe.h"
     45 #include "pub_core_signals.h"
     46 #include "pub_core_tooliface.h"
     47 #include "pub_core_trampoline.h"
     48 
     49 #if defined(VGA_s390x)
     50 
     51 /* This module creates and removes signal frames for signal deliveries
     52    on s390x-linux.
     53 
     54    Note, this file contains kernel-specific knowledge in the form of
     55    'struct sigframe' and 'struct rt_sigframe'.
     56 
     57    Either a 'struct sigframe' or a 'struct rtsigframe' is pushed
     58    onto the client's stack.  This contains a subsidiary
     59    vki_ucontext.  That holds the vcpu's state across the signal,
     60    so that the sighandler can mess with the vcpu state if it
     61    really wants.
     62 */
     63 
     64 #define SET_SIGNAL_GPR(zztst, zzn, zzval)                    \
     65    do { zztst->arch.vex.guest_r##zzn = (unsigned long)(zzval);              \
     66       VG_TRACK( post_reg_write, Vg_CoreSignal, zztst->tid,     \
     67                 offsetof(VexGuestS390XState,guest_r##zzn), \
     68                 sizeof(UWord) );                             \
     69    } while (0)
     70 
     71 /*------------------------------------------------------------*/
     72 /*--- Signal frame layouts                                 ---*/
     73 /*------------------------------------------------------------*/
     74 
     75 // A structure in which to save the application's registers
     76 // during the execution of signal handlers.
     77 
     78 // Linux has 2 signal frame structures: one for normal signal
     79 // deliveries, and one for SA_SIGINFO deliveries (also known as RT
     80 // signals).
     81 //
     82 // In theory, so long as we get the arguments to the handler function
     83 // right, it doesn't matter what the exact layout of the rest of the
     84 // frame is.  Unfortunately, things like gcc's exception unwinding
     85 // make assumptions about the locations of various parts of the frame,
     86 // so we need to duplicate it exactly.
     87 
     88 /* Valgrind-specific parts of the signal frame */
     89 struct vg_sigframe
     90 {
     91    /* Sanity check word. */
     92    UInt magicPI;
     93 
     94    UInt handlerflags;	/* flags for signal handler */
     95 
     96 
     97    /* Safely-saved version of sigNo, as described above. */
     98    Int  sigNo_private;
     99 
    100    /* XXX This is wrong.  Surely we should store the shadow values
    101       into the shadow memory behind the actual values? */
    102    VexGuestS390XState vex_shadow1;
    103    VexGuestS390XState vex_shadow2;
    104 
    105    /* HACK ALERT */
    106    VexGuestS390XState vex;
    107    /* end HACK ALERT */
    108 
    109    /* saved signal mask to be restored when handler returns */
    110    vki_sigset_t	mask;
    111 
    112    /* Sanity check word.  Is the highest-addressed word; do not
    113       move!*/
    114    UInt magicE;
    115 };
    116 
    117 #define S390_SYSCALL_SIZE 2
    118 
    119 struct sigframe
    120 {
    121    UChar callee_used_stack[__VKI_SIGNAL_FRAMESIZE];
    122    struct vki_sigcontext sc;
    123    _vki_sigregs sregs;
    124    Int sigNo;
    125    UChar retcode[S390_SYSCALL_SIZE];
    126 
    127    struct vg_sigframe vg;
    128 };
    129 
    130 struct rt_sigframe
    131 {
    132    UChar callee_used_stack[__VKI_SIGNAL_FRAMESIZE];
    133    UChar retcode[S390_SYSCALL_SIZE];
    134    struct vki_siginfo info;
    135    struct vki_ucontext uc;
    136 
    137    struct vg_sigframe vg;
    138 };
    139 
    140 /*------------------------------------------------------------*/
    141 /*--- Creating signal frames                               ---*/
    142 /*------------------------------------------------------------*/
    143 
    144 /* Saves all user-controlled register into a _vki_sigregs structure */
    145 static void save_sigregs(ThreadState *tst, _vki_sigregs *sigregs)
    146 {
    147    sigregs->regs.gprs[0]  = tst->arch.vex.guest_r0;
    148    sigregs->regs.gprs[1]  = tst->arch.vex.guest_r1;
    149    sigregs->regs.gprs[2]  = tst->arch.vex.guest_r2;
    150    sigregs->regs.gprs[3]  = tst->arch.vex.guest_r3;
    151    sigregs->regs.gprs[4]  = tst->arch.vex.guest_r4;
    152    sigregs->regs.gprs[5]  = tst->arch.vex.guest_r5;
    153    sigregs->regs.gprs[6]  = tst->arch.vex.guest_r6;
    154    sigregs->regs.gprs[7]  = tst->arch.vex.guest_r7;
    155    sigregs->regs.gprs[8]  = tst->arch.vex.guest_r8;
    156    sigregs->regs.gprs[9]  = tst->arch.vex.guest_r9;
    157    sigregs->regs.gprs[10] = tst->arch.vex.guest_r10;
    158    sigregs->regs.gprs[11] = tst->arch.vex.guest_r11;
    159    sigregs->regs.gprs[12] = tst->arch.vex.guest_r12;
    160    sigregs->regs.gprs[13] = tst->arch.vex.guest_r13;
    161    sigregs->regs.gprs[14] = tst->arch.vex.guest_r14;
    162    sigregs->regs.gprs[15] = tst->arch.vex.guest_r15;
    163 
    164    sigregs->regs.acrs[0]  = tst->arch.vex.guest_a0;
    165    sigregs->regs.acrs[1]  = tst->arch.vex.guest_a1;
    166    sigregs->regs.acrs[2]  = tst->arch.vex.guest_a2;
    167    sigregs->regs.acrs[3]  = tst->arch.vex.guest_a3;
    168    sigregs->regs.acrs[4]  = tst->arch.vex.guest_a4;
    169    sigregs->regs.acrs[5]  = tst->arch.vex.guest_a5;
    170    sigregs->regs.acrs[6]  = tst->arch.vex.guest_a6;
    171    sigregs->regs.acrs[7]  = tst->arch.vex.guest_a7;
    172    sigregs->regs.acrs[8]  = tst->arch.vex.guest_a8;
    173    sigregs->regs.acrs[9]  = tst->arch.vex.guest_a9;
    174    sigregs->regs.acrs[10] = tst->arch.vex.guest_a10;
    175    sigregs->regs.acrs[11] = tst->arch.vex.guest_a11;
    176    sigregs->regs.acrs[12] = tst->arch.vex.guest_a12;
    177    sigregs->regs.acrs[13] = tst->arch.vex.guest_a13;
    178    sigregs->regs.acrs[14] = tst->arch.vex.guest_a14;
    179    sigregs->regs.acrs[15] = tst->arch.vex.guest_a15;
    180 
    181    sigregs->fpregs.fprs[0] = tst->arch.vex.guest_f0;
    182    sigregs->fpregs.fprs[1] = tst->arch.vex.guest_f1;
    183    sigregs->fpregs.fprs[2] = tst->arch.vex.guest_f2;
    184    sigregs->fpregs.fprs[3] = tst->arch.vex.guest_f3;
    185    sigregs->fpregs.fprs[4] = tst->arch.vex.guest_f4;
    186    sigregs->fpregs.fprs[5] = tst->arch.vex.guest_f5;
    187    sigregs->fpregs.fprs[6] = tst->arch.vex.guest_f6;
    188    sigregs->fpregs.fprs[7] = tst->arch.vex.guest_f7;
    189    sigregs->fpregs.fprs[8] = tst->arch.vex.guest_f8;
    190    sigregs->fpregs.fprs[9] = tst->arch.vex.guest_f9;
    191    sigregs->fpregs.fprs[10] = tst->arch.vex.guest_f10;
    192    sigregs->fpregs.fprs[11] = tst->arch.vex.guest_f11;
    193    sigregs->fpregs.fprs[12] = tst->arch.vex.guest_f12;
    194    sigregs->fpregs.fprs[13] = tst->arch.vex.guest_f13;
    195    sigregs->fpregs.fprs[14] = tst->arch.vex.guest_f14;
    196    sigregs->fpregs.fprs[15] = tst->arch.vex.guest_f15;
    197    sigregs->fpregs.fpc      = tst->arch.vex.guest_fpc;
    198 
    199    sigregs->regs.psw.addr = tst->arch.vex.guest_IA;
    200    /* save a sane dummy mask */
    201    sigregs->regs.psw.mask = 0x0705000180000000UL;
    202 }
    203 
    204 static void restore_sigregs(ThreadState *tst, _vki_sigregs *sigregs)
    205 {
    206    tst->arch.vex.guest_r0  = sigregs->regs.gprs[0];
    207    tst->arch.vex.guest_r1  = sigregs->regs.gprs[1];
    208    tst->arch.vex.guest_r2  = sigregs->regs.gprs[2];
    209    tst->arch.vex.guest_r3  = sigregs->regs.gprs[3];
    210    tst->arch.vex.guest_r4  = sigregs->regs.gprs[4];
    211    tst->arch.vex.guest_r5  = sigregs->regs.gprs[5];
    212    tst->arch.vex.guest_r6  = sigregs->regs.gprs[6];
    213    tst->arch.vex.guest_r7  = sigregs->regs.gprs[7];
    214    tst->arch.vex.guest_r8  = sigregs->regs.gprs[8];
    215    tst->arch.vex.guest_r9  = sigregs->regs.gprs[9];
    216    tst->arch.vex.guest_r10 = sigregs->regs.gprs[10];
    217    tst->arch.vex.guest_r11 = sigregs->regs.gprs[11];
    218    tst->arch.vex.guest_r12 = sigregs->regs.gprs[12];
    219    tst->arch.vex.guest_r13 = sigregs->regs.gprs[13];
    220    tst->arch.vex.guest_r14 = sigregs->regs.gprs[14];
    221    tst->arch.vex.guest_r15 = sigregs->regs.gprs[15];
    222 
    223    tst->arch.vex.guest_a0  = sigregs->regs.acrs[0];
    224    tst->arch.vex.guest_a1  = sigregs->regs.acrs[1];
    225    tst->arch.vex.guest_a2  = sigregs->regs.acrs[2];
    226    tst->arch.vex.guest_a3  = sigregs->regs.acrs[3];
    227    tst->arch.vex.guest_a4  = sigregs->regs.acrs[4];
    228    tst->arch.vex.guest_a5  = sigregs->regs.acrs[5];
    229    tst->arch.vex.guest_a6  = sigregs->regs.acrs[6];
    230    tst->arch.vex.guest_a7  = sigregs->regs.acrs[7];
    231    tst->arch.vex.guest_a8  = sigregs->regs.acrs[8];
    232    tst->arch.vex.guest_a9  = sigregs->regs.acrs[9];
    233    tst->arch.vex.guest_a10 = sigregs->regs.acrs[10];
    234    tst->arch.vex.guest_a11 = sigregs->regs.acrs[11];
    235    tst->arch.vex.guest_a12 = sigregs->regs.acrs[12];
    236    tst->arch.vex.guest_a13 = sigregs->regs.acrs[13];
    237    tst->arch.vex.guest_a14 = sigregs->regs.acrs[14];
    238    tst->arch.vex.guest_a15 = sigregs->regs.acrs[15];
    239 
    240    tst->arch.vex.guest_f0  = sigregs->fpregs.fprs[0];
    241    tst->arch.vex.guest_f1  = sigregs->fpregs.fprs[1];
    242    tst->arch.vex.guest_f2  = sigregs->fpregs.fprs[2];
    243    tst->arch.vex.guest_f3  = sigregs->fpregs.fprs[3];
    244    tst->arch.vex.guest_f4  = sigregs->fpregs.fprs[4];
    245    tst->arch.vex.guest_f5  = sigregs->fpregs.fprs[5];
    246    tst->arch.vex.guest_f6  = sigregs->fpregs.fprs[6];
    247    tst->arch.vex.guest_f7  = sigregs->fpregs.fprs[7];
    248    tst->arch.vex.guest_f8  = sigregs->fpregs.fprs[8];
    249    tst->arch.vex.guest_f9  = sigregs->fpregs.fprs[9];
    250    tst->arch.vex.guest_f10 = sigregs->fpregs.fprs[10];
    251    tst->arch.vex.guest_f11 = sigregs->fpregs.fprs[11];
    252    tst->arch.vex.guest_f12 = sigregs->fpregs.fprs[12];
    253    tst->arch.vex.guest_f13 = sigregs->fpregs.fprs[13];
    254    tst->arch.vex.guest_f14 = sigregs->fpregs.fprs[14];
    255    tst->arch.vex.guest_f15 = sigregs->fpregs.fprs[15];
    256    tst->arch.vex.guest_fpc = sigregs->fpregs.fpc;
    257 
    258    tst->arch.vex.guest_IA = sigregs->regs.psw.addr;
    259 }
    260 
    261 /* Extend the stack segment downwards if needed so as to ensure the
    262    new signal frames are mapped to something.  Return a Bool
    263    indicating whether or not the operation was successful.
    264 */
    265 static Bool extend ( ThreadState *tst, Addr addr, SizeT size )
    266 {
    267    ThreadId        tid = tst->tid;
    268    NSegment const* stackseg = NULL;
    269 
    270    if (VG_(extend_stack)(addr, tst->client_stack_szB)) {
    271       stackseg = VG_(am_find_nsegment)(addr);
    272       if (0 && stackseg)
    273 	 VG_(printf)("frame=%#lx seg=%#lx-%#lx\n",
    274 		     addr, stackseg->start, stackseg->end);
    275    }
    276 
    277    if (stackseg == NULL || !stackseg->hasR || !stackseg->hasW) {
    278       VG_(message)(
    279          Vg_UserMsg,
    280          "Can't extend stack to %#lx during signal delivery for thread %d:\n",
    281          addr, tid);
    282       if (stackseg == NULL)
    283          VG_(message)(Vg_UserMsg, "  no stack segment\n");
    284       else
    285          VG_(message)(Vg_UserMsg, "  too small or bad protection modes\n");
    286 
    287       /* set SIGSEGV to default handler */
    288       VG_(set_default_handler)(VKI_SIGSEGV);
    289       VG_(synth_fault_mapping)(tid, addr);
    290 
    291       /* The whole process should be about to die, since the default
    292 	 action of SIGSEGV to kill the whole process. */
    293       return False;
    294    }
    295 
    296    /* For tracking memory events, indicate the entire frame has been
    297       allocated. */
    298    VG_TRACK( new_mem_stack_signal, addr - VG_STACK_REDZONE_SZB,
    299              size + VG_STACK_REDZONE_SZB, tid );
    300 
    301    return True;
    302 }
    303 
    304 
    305 /* Build the Valgrind-specific part of a signal frame. */
    306 
    307 static void build_vg_sigframe(struct vg_sigframe *frame,
    308 			      ThreadState *tst,
    309 			      UInt flags,
    310 			      Int sigNo)
    311 {
    312    frame->sigNo_private = sigNo;
    313    frame->magicPI       = 0x31415927;
    314    frame->vex_shadow1   = tst->arch.vex_shadow1;
    315    frame->vex_shadow2   = tst->arch.vex_shadow2;
    316    /* HACK ALERT */
    317    frame->vex           = tst->arch.vex;
    318    /* end HACK ALERT */
    319    frame->mask          = tst->sig_mask;
    320    frame->handlerflags  = flags;
    321    frame->magicE        = 0x27182818;
    322 }
    323 
    324 
    325 static Addr build_sigframe(ThreadState *tst,
    326 			   Addr sp_top_of_frame,
    327 			   const vki_siginfo_t *siginfo,
    328 			   const struct vki_ucontext *siguc,
    329 			   UInt flags,
    330 			   const vki_sigset_t *mask,
    331 			   void *restorer)
    332 {
    333    struct sigframe *frame;
    334    Addr sp = sp_top_of_frame;
    335 
    336    vg_assert((flags & VKI_SA_SIGINFO) == 0);
    337    vg_assert((sizeof(*frame) & 7) == 0);
    338    vg_assert((sp & 7) == 0);
    339 
    340    sp -= sizeof(*frame);
    341    frame = (struct sigframe *)sp;
    342 
    343    if (!extend(tst, sp, sizeof(*frame)))
    344       return sp_top_of_frame;
    345 
    346    /* retcode, sigNo, sc, sregs fields are to be written */
    347    VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame",
    348 	     sp, offsetof(struct sigframe, vg) );
    349 
    350    save_sigregs(tst, &frame->sregs);
    351 
    352    frame->sigNo = siginfo->si_signo;
    353    frame->sc.sregs = &frame->sregs;
    354    VG_(memcpy)(frame->sc.oldmask, mask->sig, sizeof(frame->sc.oldmask));
    355 
    356    if (flags & VKI_SA_RESTORER) {
    357       SET_SIGNAL_GPR(tst, 14, restorer);
    358    } else {
    359       frame->retcode[0] = 0x0a;
    360       frame->retcode[1] = __NR_sigreturn;
    361       /* This normally should be &frame->recode. but since there
    362          might be problems with non-exec stack and we must discard
    363          the translation for the on-stack sigreturn we just use the
    364          trampoline like x86,ppc. We still fill in the retcode, lets
    365          just hope that nobody actually jumps here */
    366       SET_SIGNAL_GPR(tst, 14, (Addr)&VG_(s390x_linux_SUBST_FOR_sigreturn));
    367    }
    368 
    369    SET_SIGNAL_GPR(tst, 2, siginfo->si_signo);
    370    SET_SIGNAL_GPR(tst, 3, &frame->sc);
    371    /* fixs390: we dont fill in trapno and prot_addr in r4 and r5*/
    372 
    373    /* Set up backchain. */
    374    *((Addr *) sp) = sp_top_of_frame;
    375 
    376    VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
    377              sp, offsetof(struct sigframe, vg) );
    378 
    379    build_vg_sigframe(&frame->vg, tst, flags, siginfo->si_signo);
    380 
    381    return sp;
    382 }
    383 
    384 static Addr build_rt_sigframe(ThreadState *tst,
    385 			      Addr sp_top_of_frame,
    386 			      const vki_siginfo_t *siginfo,
    387 			      const struct vki_ucontext *siguc,
    388 			      UInt flags,
    389 			      const vki_sigset_t *mask,
    390 			      void *restorer)
    391 {
    392    struct rt_sigframe *frame;
    393    Addr sp = sp_top_of_frame;
    394    Int sigNo = siginfo->si_signo;
    395 
    396    vg_assert((flags & VKI_SA_SIGINFO) != 0);
    397    vg_assert((sizeof(*frame) & 7) == 0);
    398    vg_assert((sp & 7) == 0);
    399 
    400    sp -= sizeof(*frame);
    401    frame = (struct rt_sigframe *)sp;
    402 
    403    if (!extend(tst, sp, sizeof(*frame)))
    404       return sp_top_of_frame;
    405 
    406    /* retcode, sigNo, sc, sregs fields are to be written */
    407    VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame",
    408 	     sp, offsetof(struct rt_sigframe, vg) );
    409 
    410    save_sigregs(tst, &frame->uc.uc_mcontext);
    411 
    412    if (flags & VKI_SA_RESTORER) {
    413       frame->retcode[0] = 0;
    414       frame->retcode[1] = 0;
    415       SET_SIGNAL_GPR(tst, 14, restorer);
    416    } else {
    417       frame->retcode[0] = 0x0a;
    418       frame->retcode[1] = __NR_rt_sigreturn;
    419       /* This normally should be &frame->recode. but since there
    420          might be problems with non-exec stack and we must discard
    421          the translation for the on-stack sigreturn we just use the
    422          trampoline like x86,ppc. We still fill in the retcode, lets
    423          just hope that nobody actually jumps here */
    424       SET_SIGNAL_GPR(tst, 14, (Addr)&VG_(s390x_linux_SUBST_FOR_rt_sigreturn));
    425    }
    426 
    427    VG_(memcpy)(&frame->info, siginfo, sizeof(vki_siginfo_t));
    428    frame->uc.uc_flags = 0;
    429    frame->uc.uc_link = 0;
    430    frame->uc.uc_sigmask = *mask;
    431    frame->uc.uc_stack = tst->altstack;
    432 
    433    SET_SIGNAL_GPR(tst, 2, siginfo->si_signo);
    434    SET_SIGNAL_GPR(tst, 3, &frame->info);
    435    SET_SIGNAL_GPR(tst, 4, &frame->uc);
    436 
    437    /* Set up backchain. */
    438    *((Addr *) sp) = sp_top_of_frame;
    439 
    440    VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
    441              sp, offsetof(struct rt_sigframe, vg) );
    442 
    443    build_vg_sigframe(&frame->vg, tst, flags, sigNo);
    444    return sp;
    445 }
    446 
    447 /* EXPORTED */
    448 void VG_(sigframe_create)( ThreadId tid,
    449 			   Addr sp_top_of_frame,
    450 			   const vki_siginfo_t *siginfo,
    451 			   const struct vki_ucontext *siguc,
    452 			   void *handler,
    453 			   UInt flags,
    454 			   const vki_sigset_t *mask,
    455 			   void *restorer )
    456 {
    457    Addr sp;
    458    ThreadState* tst = VG_(get_ThreadState)(tid);
    459 
    460    if (flags & VKI_SA_SIGINFO)
    461       sp = build_rt_sigframe(tst, sp_top_of_frame, siginfo, siguc,
    462 			     flags, mask, restorer);
    463    else
    464       sp = build_sigframe(tst, sp_top_of_frame, siginfo, siguc,
    465 			  flags, mask, restorer);
    466 
    467    /* Set the thread so it will next run the handler. */
    468    VG_(set_SP)(tid, sp);
    469    VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(Addr));
    470 
    471    tst->arch.vex.guest_IA = (Addr) handler;
    472    /* We might have interrupted a repeating instruction that uses the guest
    473       counter. Since our VEX requires that a new instruction will see a
    474       guest counter == 0, we have to set it here. The old value will be
    475       restored by restore_vg_sigframe. */
    476    tst->arch.vex.guest_counter = 0;
    477    /* This thread needs to be marked runnable, but we leave that the
    478       caller to do. */
    479 }
    480 
    481 
    482 /*------------------------------------------------------------*/
    483 /*--- Destroying signal frames                             ---*/
    484 /*------------------------------------------------------------*/
    485 
    486 /* Return False and don't do anything, just set the client to take a
    487    segfault, if it looks like the frame is corrupted. */
    488 static
    489 Bool restore_vg_sigframe ( ThreadState *tst,
    490                            struct vg_sigframe *frame, Int *sigNo )
    491 {
    492    if (frame->magicPI != 0x31415927 ||
    493        frame->magicE  != 0x27182818) {
    494       VG_(message)(Vg_UserMsg, "Thread %d return signal frame "
    495 			       "corrupted.  Killing process.\n",
    496 		   tst->tid);
    497       VG_(set_default_handler)(VKI_SIGSEGV);
    498       VG_(synth_fault)(tst->tid);
    499       *sigNo = VKI_SIGSEGV;
    500       return False;
    501    }
    502    tst->sig_mask         = frame->mask;
    503    tst->tmp_sig_mask     = frame->mask;
    504    tst->arch.vex_shadow1 = frame->vex_shadow1;
    505    tst->arch.vex_shadow2 = frame->vex_shadow2;
    506    /* HACK ALERT */
    507    tst->arch.vex         = frame->vex;
    508    /* end HACK ALERT */
    509    *sigNo                = frame->sigNo_private;
    510    return True;
    511 }
    512 
    513 static
    514 SizeT restore_sigframe ( ThreadState *tst,
    515                          struct sigframe *frame, Int *sigNo )
    516 {
    517    if (restore_vg_sigframe(tst, &frame->vg, sigNo))
    518       restore_sigregs(tst, frame->sc.sregs);
    519 
    520    return sizeof(*frame);
    521 }
    522 
    523 static
    524 SizeT restore_rt_sigframe ( ThreadState *tst,
    525                             struct rt_sigframe *frame, Int *sigNo )
    526 {
    527    if (restore_vg_sigframe(tst, &frame->vg, sigNo)) {
    528       restore_sigregs(tst, &frame->uc.uc_mcontext);
    529    }
    530    return sizeof(*frame);
    531 }
    532 
    533 
    534 /* EXPORTED */
    535 void VG_(sigframe_destroy)( ThreadId tid, Bool isRT )
    536 {
    537    Addr          sp;
    538    ThreadState*  tst;
    539    SizeT         size;
    540    Int            sigNo;
    541 
    542    tst = VG_(get_ThreadState)(tid);
    543 
    544    /* Correctly reestablish the frame base address. */
    545    sp   = tst->arch.vex.guest_SP;
    546 
    547    if (!isRT)
    548       size = restore_sigframe(tst, (struct sigframe *)sp, &sigNo);
    549    else
    550       size = restore_rt_sigframe(tst, (struct rt_sigframe *)sp, &sigNo);
    551 
    552    /* same as for creation: we must announce the full memory (including
    553       alignment), otherwise massif might fail on longjmp */
    554    VG_TRACK( die_mem_stack_signal, sp - VG_STACK_REDZONE_SZB,
    555              size + VG_STACK_REDZONE_SZB );
    556 
    557    if (VG_(clo_trace_signals))
    558       VG_(message)(
    559          Vg_DebugMsg,
    560          "VG_(sigframe_destroy) (thread %d): isRT=%d valid magic; IP=%#llx\n",
    561          tid, isRT, tst->arch.vex.guest_IA);
    562 
    563    /* tell the tools */
    564    VG_TRACK( post_deliver_signal, tid, sigNo );
    565 }
    566 
    567 #endif /* VGA_s390x */
    568 
    569 /*--------------------------------------------------------------------*/
    570 /*--- end                                   sigframe-s390x-linux.c ---*/
    571 /*--------------------------------------------------------------------*/
    572