Home | History | Annotate | Download | only in m_sigframe
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- Create/destroy signal delivery frames.                       ---*/
      4 /*---                                         sigframe-arm-linux.c ---*/
      5 /*--------------------------------------------------------------------*/
      6 
      7 /*
      8    This file is part of Valgrind, a dynamic binary instrumentation
      9    framework.
     10 
     11    Copyright (C) 2000-2017 Nicholas Nethercote
     12       njn (at) valgrind.org
     13    Copyright (C) 2004-2017 Paul Mackerras
     14       paulus (at) samba.org
     15    Copyright (C) 2008-2017 Evan Geller
     16       gaze (at) bea.ms
     17 
     18    This program is free software; you can redistribute it and/or
     19    modify it under the terms of the GNU General Public License as
     20    published by the Free Software Foundation; either version 2 of the
     21    License, or (at your option) any later version.
     22 
     23    This program is distributed in the hope that it will be useful, but
     24    WITHOUT ANY WARRANTY; without even the implied warranty of
     25    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     26    General Public License for more details.
     27 
     28    You should have received a copy of the GNU General Public License
     29    along with this program; if not, write to the Free Software
     30    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     31    02111-1307, USA.
     32 
     33    The GNU General Public License is contained in the file COPYING.
     34 */
     35 
     36 #if defined(VGP_arm_linux)
     37 
     38 #include "pub_core_basics.h"
     39 #include "pub_core_vki.h"
     40 #include "pub_core_vkiscnums.h"
     41 #include "pub_core_threadstate.h"
     42 #include "pub_core_aspacemgr.h"
     43 #include "pub_core_libcbase.h"
     44 #include "pub_core_libcassert.h"
     45 #include "pub_core_libcprint.h"
     46 #include "pub_core_machine.h"
     47 #include "pub_core_options.h"
     48 #include "pub_core_sigframe.h"
     49 #include "pub_core_signals.h"
     50 #include "pub_core_tooliface.h"
     51 #include "pub_core_trampoline.h"
     52 #include "priv_sigframe.h"
     53 
     54 
     55 /* This uses the hack of dumping the vex guest state along with both
     56    shadows in the frame, and restoring it afterwards from there,
     57    rather than pulling it out of the ucontext.  That means that signal
     58    handlers which modify the ucontext and then return, expecting their
     59    modifications to take effect, will have those modifications
     60    ignored.  This could be fixed properly with an hour or so more
     61    effort. */
     62 
     63 
     64 struct vg_sig_private {
     65    UInt magicPI;
     66    UInt sigNo_private;
     67    VexGuestARMState vex;
     68    VexGuestARMState vex_shadow1;
     69    VexGuestARMState vex_shadow2;
     70 };
     71 
     72 struct sigframe {
     73    struct vki_ucontext uc;
     74    unsigned long retcode[2];
     75    struct vg_sig_private vp;
     76 };
     77 
     78 struct rt_sigframe {
     79    vki_siginfo_t info;
     80    struct sigframe sig;
     81 };
     82 
     83 
     84 static void synth_ucontext( ThreadId tid, const vki_siginfo_t *si,
     85                     UWord trapno, UWord err, const vki_sigset_t *set,
     86                     struct vki_ucontext *uc){
     87 
     88    ThreadState *tst = VG_(get_ThreadState)(tid);
     89    struct vki_sigcontext *sc = &uc->uc_mcontext;
     90 
     91    VG_(memset)(uc, 0, sizeof(*uc));
     92 
     93    uc->uc_flags = 0;
     94    uc->uc_link = 0;
     95    uc->uc_sigmask = *set;
     96    uc->uc_stack = tst->altstack;
     97 
     98 #  define SC2(reg,REG)  sc->arm_##reg = tst->arch.vex.guest_##REG
     99    SC2(r0,R0);
    100    SC2(r1,R1);
    101    SC2(r2,R2);
    102    SC2(r3,R3);
    103    SC2(r4,R4);
    104    SC2(r5,R5);
    105    SC2(r6,R6);
    106    SC2(r7,R7);
    107    SC2(r8,R8);
    108    SC2(r9,R9);
    109    SC2(r10,R10);
    110    SC2(fp,R11);
    111    SC2(ip,R12);
    112    SC2(sp,R13);
    113    SC2(lr,R14);
    114    SC2(pc,R15T);
    115 #  undef SC2
    116 
    117    sc->trap_no = trapno;
    118    sc->error_code = err;
    119    sc->fault_address = (UInt)si->_sifields._sigfault._addr;
    120 }
    121 
    122 
    123 static void build_sigframe(ThreadState *tst,
    124             struct sigframe *frame,
    125             const vki_siginfo_t *siginfo,
    126             const struct vki_ucontext *siguc,
    127             void *handler, UInt flags,
    128             const vki_sigset_t *mask,
    129             void *restorer){
    130 
    131    UWord trapno;
    132    UWord err;
    133    Int  sigNo = siginfo->si_signo;
    134    struct vg_sig_private *priv = &frame->vp;
    135 
    136    VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame",
    137          (Addr)frame, offsetof(struct sigframe, vp));
    138 
    139    if(siguc) {
    140       trapno = siguc->uc_mcontext.trap_no;
    141       err = siguc->uc_mcontext.error_code;
    142    } else {
    143       trapno = 0;
    144       err = 0;
    145    }
    146 
    147    synth_ucontext(tst->tid, siginfo, trapno, err, mask, &frame->uc);
    148 
    149    VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
    150          (Addr)frame, offsetof(struct sigframe, vp));
    151 
    152    priv->magicPI = 0x31415927;
    153    priv->sigNo_private = sigNo;
    154    priv->vex         = tst->arch.vex;
    155    priv->vex_shadow1 = tst->arch.vex_shadow1;
    156    priv->vex_shadow2 = tst->arch.vex_shadow2;
    157 
    158 }
    159 
    160 
    161 
    162 /* EXPORTED */
    163 void VG_(sigframe_create)( ThreadId tid,
    164                            Bool on_altstack,
    165                            Addr sp_top_of_frame,
    166                            const vki_siginfo_t *siginfo,
    167                            const struct vki_ucontext *siguc,
    168                            void *handler,
    169                            UInt flags,
    170                            const vki_sigset_t *mask,
    171                            void *restorer )
    172 {
    173 //   struct vg_sig_private *priv;
    174    Addr sp = sp_top_of_frame;
    175    ThreadState *tst;
    176    Int sigNo = siginfo->si_signo;
    177 //   Addr faultaddr;
    178    UInt size;
    179 
    180    tst = VG_(get_ThreadState)(tid);
    181 
    182    size = flags & VKI_SA_SIGINFO ? sizeof(struct rt_sigframe) :
    183       sizeof(struct sigframe);
    184 
    185    sp -= size;
    186    sp = VG_ROUNDDN(sp, 16);
    187 
    188    if (! ML_(sf_maybe_extend_stack)(tst, sp, size, flags))
    189       I_die_here; // XXX Incorrect behavior
    190 
    191 
    192    if (flags & VKI_SA_SIGINFO){
    193       struct rt_sigframe *rsf = (struct rt_sigframe *)sp;
    194 
    195       /* Track our writes to siginfo */
    196       VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid,  /* VVVVV */
    197             "signal handler siginfo", (Addr)rsf,
    198             offsetof(struct rt_sigframe, sig));
    199 
    200       VG_(memcpy)(&rsf->info, siginfo, sizeof(vki_siginfo_t));
    201 
    202       if(sigNo == VKI_SIGILL && siginfo->si_code > 0) {
    203          rsf->info._sifields._sigfault._addr = (Addr *) (tst)->arch.vex.guest_R12; /* IP */
    204       }
    205       VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, /* ^^^^^ */
    206             (Addr)rsf, offsetof(struct rt_sigframe, sig));
    207 
    208       build_sigframe(tst, &rsf->sig, siginfo, siguc,
    209                              handler, flags, mask, restorer);
    210       tst->arch.vex.guest_R1 = (Addr)&rsf->info;
    211       tst->arch.vex.guest_R2 = (Addr)&rsf->sig.uc;
    212    }
    213    else {
    214       build_sigframe(tst, (struct sigframe *)sp, siginfo, siguc,
    215                              handler, flags, mask, restorer);
    216    }
    217 
    218    VG_(set_SP)(tid, sp);
    219    VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR,
    220          sizeof(Addr));
    221    tst->arch.vex.guest_R0  = sigNo;
    222 
    223    if (flags & VKI_SA_RESTORER)
    224        tst->arch.vex.guest_R14 = (Addr)restorer;
    225    else
    226        tst->arch.vex.guest_R14
    227           = (flags & VKI_SA_SIGINFO)
    228             ? (Addr)&VG_(arm_linux_SUBST_FOR_rt_sigreturn)
    229             : (Addr)&VG_(arm_linux_SUBST_FOR_sigreturn);
    230 
    231    tst->arch.vex.guest_R15T = (Addr) handler; /* R15 == PC */
    232 
    233    if (VG_(clo_trace_signals))
    234       VG_(message)(Vg_DebugMsg,
    235                    "VG_(sigframe_create): continuing in handler with PC=%#lx\n",
    236                    (Addr)handler);
    237 }
    238 
    239 
    240 /*------------------------------------------------------------*/
    241 /*--- Destroying signal frames                             ---*/
    242 /*------------------------------------------------------------*/
    243 
    244 /* EXPORTED */
    245 void VG_(sigframe_destroy)( ThreadId tid, Bool isRT )
    246 {
    247    ThreadState *tst;
    248    struct vg_sig_private *priv;
    249    Addr sp;
    250    UInt frame_size;
    251    Int sigNo;
    252    Bool has_siginfo = isRT;
    253 
    254    vg_assert(VG_(is_valid_tid)(tid));
    255    tst = VG_(get_ThreadState)(tid);
    256    sp = tst->arch.vex.guest_R13;
    257 
    258    if (has_siginfo) {
    259       struct rt_sigframe *frame = (struct rt_sigframe *)sp;
    260       frame_size = sizeof(*frame);
    261       priv = &frame->sig.vp;
    262       vg_assert(priv->magicPI == 0x31415927);
    263       tst->sig_mask = frame->sig.uc.uc_sigmask;
    264    } else {
    265       struct sigframe *frame = (struct sigframe *)sp;
    266       frame_size = sizeof(*frame);
    267       priv = &frame->vp;
    268       vg_assert(priv->magicPI == 0x31415927);
    269       tst->sig_mask = frame->uc.uc_sigmask;
    270       /*tst->sig_mask.sig[0] = frame->uc.uc_mcontext.oldmask;
    271       tst->sig_mask.sig[1] = frame->uc.uc_mcontext._unused[3];
    272       VG_(printf)("Setting signmask to %08x%08x\n",tst->sig_mask[0],tst->sig_mask[1]);
    273 */
    274    }
    275    tst->tmp_sig_mask = tst->sig_mask;
    276 
    277    sigNo = priv->sigNo_private;
    278 
    279 //ZZ     //XXX: restore regs
    280 //ZZ #  define REST(reg,REG)  tst->arch.vex.guest_##REG = mc->arm_##reg;
    281 //ZZ    REST(r0,R0);
    282 //ZZ    REST(r1,R1);
    283 //ZZ    REST(r2,R2);
    284 //ZZ    REST(r3,R3);
    285 //ZZ    REST(r4,R4);
    286 //ZZ    REST(r5,R5);
    287 //ZZ    REST(r6,R6);
    288 //ZZ    REST(r7,R7);
    289 //ZZ    REST(r8,R8);
    290 //ZZ    REST(r9,R9);
    291 //ZZ    REST(r10,R10);
    292 //ZZ    REST(fp,R11);
    293 //ZZ    REST(ip,R12);
    294 //ZZ    REST(sp,R13);
    295 //ZZ    REST(lr,R14);
    296 //ZZ    REST(pc,R15T);
    297 //ZZ #  undef REST
    298 
    299    /* Uh, the next line makes all the REST() above pointless. */
    300    tst->arch.vex         = priv->vex;
    301 
    302    tst->arch.vex_shadow1 = priv->vex_shadow1;
    303    tst->arch.vex_shadow2 = priv->vex_shadow2;
    304 
    305    VG_TRACK( die_mem_stack_signal, sp - VG_STACK_REDZONE_SZB,
    306              frame_size + VG_STACK_REDZONE_SZB );
    307 
    308    if (VG_(clo_trace_signals))
    309       VG_(message)(Vg_DebugMsg,
    310                    "vg_pop_signal_frame (thread %u): "
    311                    "isRT=%d valid magic; PC=%#x\n",
    312                    tid, has_siginfo, tst->arch.vex.guest_R15T);
    313 
    314    /* tell the tools */
    315    VG_TRACK( post_deliver_signal, tid, sigNo );
    316 }
    317 
    318 #endif // defined(VGP_arm_linux)
    319 
    320 /*--------------------------------------------------------------------*/
    321 /*--- end                                     sigframe-arm-linux.c ---*/
    322 /*--------------------------------------------------------------------*/
    323