Home | History | Annotate | Download | only in m_sigframe
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- Create/destroy signal delivery frames.                       ---*/
      4 /*---                                  sigframe-tilegx-linux.c     ---*/
      5 /*--------------------------------------------------------------------*/
      6 
      7 /*
      8   This file is part of Valgrind, a dynamic binary instrumentation
      9   framework.
     10 
     11   Copyright (C) 2010-2015 Tilera Corp.
     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 Zhi-Gang Liu <zliu at tilera dot com> */
     32 
     33 #if defined(VGP_tilegx_linux)
     34 
     35 #include "pub_core_basics.h"
     36 #include "pub_core_vki.h"
     37 #include "pub_core_vkiscnums.h"
     38 #include "pub_core_threadstate.h"
     39 #include "pub_core_aspacemgr.h"
     40 #include "pub_core_libcbase.h"
     41 #include "pub_core_libcassert.h"
     42 #include "pub_core_libcprint.h"
     43 #include "pub_core_machine.h"
     44 #include "pub_core_options.h"
     45 #include "pub_core_sigframe.h"
     46 #include "pub_core_signals.h"
     47 #include "pub_core_tooliface.h"
     48 #include "pub_core_trampoline.h"
     49 #include "priv_sigframe.h"
     50 
     51 struct vg_sig_private
     52 {
     53   UInt magicPI;
     54   UInt sigNo_private;
     55   VexGuestTILEGXState vex_shadow1;
     56   VexGuestTILEGXState vex_shadow2;
     57 };
     58 
     59 #ifndef C_ABI_SAVE_AREA_SIZE
     60 #define C_ABI_SAVE_AREA_SIZE  16
     61 #endif
     62 struct rt_sigframe {
     63   unsigned char save_area[C_ABI_SAVE_AREA_SIZE]; /* caller save area */
     64   vki_siginfo_t rs_info;
     65   struct vki_ucontext rs_uc;
     66   struct vg_sig_private priv;
     67 };
     68 
     69 
     70 static
     71 void setup_sigcontext2 ( ThreadState* tst, struct vki_sigcontext **sc1,
     72                          const vki_siginfo_t *si )
     73 {
     74 
     75   struct vki_sigcontext *sc = *sc1;
     76 
     77   VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal frame mcontext",
     78             (Addr)sc, sizeof(unsigned long long)*34 );
     79   sc->gregs[0] = tst->arch.vex.guest_r0;
     80   sc->gregs[1] = tst->arch.vex.guest_r1;
     81   sc->gregs[2] = tst->arch.vex.guest_r2;
     82   sc->gregs[3] = tst->arch.vex.guest_r3;
     83   sc->gregs[4] = tst->arch.vex.guest_r4;
     84   sc->gregs[5] = tst->arch.vex.guest_r5;
     85   sc->gregs[6] = tst->arch.vex.guest_r6;
     86   sc->gregs[7] = tst->arch.vex.guest_r7;
     87   sc->gregs[8] = tst->arch.vex.guest_r8;
     88   sc->gregs[9] = tst->arch.vex.guest_r9;
     89   sc->gregs[10] = tst->arch.vex.guest_r10;
     90   sc->gregs[11] = tst->arch.vex.guest_r11;
     91   sc->gregs[12] = tst->arch.vex.guest_r12;
     92   sc->gregs[13] = tst->arch.vex.guest_r13;
     93   sc->gregs[14] = tst->arch.vex.guest_r14;
     94   sc->gregs[15] = tst->arch.vex.guest_r15;
     95   sc->gregs[16] = tst->arch.vex.guest_r16;
     96   sc->gregs[17] = tst->arch.vex.guest_r17;
     97   sc->gregs[18] = tst->arch.vex.guest_r18;
     98   sc->gregs[19] = tst->arch.vex.guest_r19;
     99   sc->gregs[20] = tst->arch.vex.guest_r20;
    100   sc->gregs[21] = tst->arch.vex.guest_r21;
    101   sc->gregs[22] = tst->arch.vex.guest_r22;
    102   sc->gregs[23] = tst->arch.vex.guest_r23;
    103   sc->gregs[24] = tst->arch.vex.guest_r24;
    104   sc->gregs[25] = tst->arch.vex.guest_r25;
    105   sc->gregs[26] = tst->arch.vex.guest_r26;
    106   sc->gregs[27] = tst->arch.vex.guest_r27;
    107   sc->gregs[28] = tst->arch.vex.guest_r28;
    108   sc->gregs[29] = tst->arch.vex.guest_r29;
    109   sc->gregs[30] = tst->arch.vex.guest_r30;
    110   sc->gregs[31] = tst->arch.vex.guest_r31;
    111   sc->gregs[32] = tst->arch.vex.guest_r32;
    112   sc->gregs[33] = tst->arch.vex.guest_r33;
    113   sc->gregs[34] = tst->arch.vex.guest_r34;
    114   sc->gregs[35] = tst->arch.vex.guest_r35;
    115   sc->gregs[36] = tst->arch.vex.guest_r36;
    116   sc->gregs[37] = tst->arch.vex.guest_r37;
    117   sc->gregs[38] = tst->arch.vex.guest_r38;
    118   sc->gregs[39] = tst->arch.vex.guest_r39;
    119   sc->gregs[40] = tst->arch.vex.guest_r40;
    120   sc->gregs[41] = tst->arch.vex.guest_r41;
    121   sc->gregs[42] = tst->arch.vex.guest_r42;
    122   sc->gregs[43] = tst->arch.vex.guest_r43;
    123   sc->gregs[44] = tst->arch.vex.guest_r44;
    124   sc->gregs[45] = tst->arch.vex.guest_r45;
    125   sc->gregs[46] = tst->arch.vex.guest_r46;
    126   sc->gregs[47] = tst->arch.vex.guest_r47;
    127   sc->gregs[48] = tst->arch.vex.guest_r48;
    128   sc->gregs[49] = tst->arch.vex.guest_r49;
    129   sc->gregs[50] = tst->arch.vex.guest_r50;
    130   sc->gregs[51] = tst->arch.vex.guest_r51;
    131   sc->gregs[52] = tst->arch.vex.guest_r52;
    132   sc->tp        = tst->arch.vex.guest_r53;
    133   sc->sp        = tst->arch.vex.guest_r54;
    134   sc->lr        = tst->arch.vex.guest_r55;
    135   sc->pc        = tst->arch.vex.guest_pc;
    136 }
    137 
    138 /* EXPORTED */
    139 void VG_(sigframe_create)( ThreadId tid,
    140                            Addr sp_top_of_frame,
    141                            const vki_siginfo_t *siginfo,
    142                            const struct vki_ucontext *siguc,
    143                            void *handler,
    144                            UInt flags,
    145                            const vki_sigset_t *mask,
    146                            void *restorer )
    147 {
    148   Addr sp;
    149   ThreadState* tst;
    150   Addr faultaddr;
    151   Int sigNo = siginfo->si_signo;
    152   struct vg_sig_private *priv;
    153 
    154   /* Stack must be 8-byte aligned */
    155   sp_top_of_frame &= ~0x7ULL;
    156 
    157   sp = sp_top_of_frame - sizeof(struct rt_sigframe);
    158 
    159   tst = VG_(get_ThreadState)(tid);
    160   if (! ML_(sf_maybe_extend_stack)(tst, sp, sizeof(struct rt_sigframe), flags))
    161     return;
    162 
    163   vg_assert(VG_IS_8_ALIGNED(sp));
    164 
    165   /* SIGILL defines addr to be the faulting address */
    166 
    167   faultaddr = (Addr)siginfo->_sifields._sigfault._addr;
    168   if (sigNo == VKI_SIGILL && siginfo->si_code > 0)
    169     faultaddr = tst->arch.vex.guest_pc;
    170 
    171 
    172   struct rt_sigframe *frame = (struct rt_sigframe *) sp;
    173   struct vki_ucontext *ucp = &frame->rs_uc;
    174   if (VG_(clo_trace_signals))
    175     VG_(printf)("rt_sigframe\n");
    176   /* Create siginfo.  */
    177   VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame siginfo",
    178             (Addr)&frame->rs_info, sizeof(frame->rs_info) );
    179 
    180   VG_(memcpy)(&frame->rs_info, siginfo, sizeof(*siginfo));
    181 
    182   VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
    183             (Addr)&frame->rs_info, sizeof(frame->rs_info) );
    184 
    185   /* Create the ucontext.  */
    186   VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame ucontext",
    187             (Addr)ucp, offsetof(struct vki_ucontext, uc_mcontext) );
    188 
    189   ucp->uc_flags = 0;
    190   ucp->uc_link = 0;
    191   ucp->uc_stack = tst->altstack;
    192 
    193   VG_TRACK( post_mem_write, Vg_CoreSignal, tid, (Addr)ucp,
    194             offsetof(struct vki_ucontext, uc_mcontext) );
    195 
    196   struct vki_sigcontext *scp = &(frame->rs_uc.uc_mcontext);
    197   setup_sigcontext2(tst, &(scp), siginfo);
    198 
    199   ucp->uc_sigmask = tst->sig_mask;
    200 
    201   priv = &frame->priv;
    202 
    203   /*
    204    * Arguments to signal handler:
    205    *
    206    *   r0 = signal number
    207    *   r1 = 0 (should be cause)
    208    *   r2 = pointer to ucontext
    209    *
    210    * r54 points to the struct rt_sigframe.
    211    */
    212 
    213   tst->arch.vex.guest_r0 = siginfo->si_signo;
    214   tst->arch.vex.guest_r1 = (Addr) &frame->rs_info;
    215   tst->arch.vex.guest_r2 = (Addr) &frame->rs_uc;
    216   tst->arch.vex.guest_r54 = (Addr) frame;
    217 
    218   if (flags & VKI_SA_RESTORER)
    219   {
    220     tst->arch.vex.guest_r55 = (Addr) restorer;
    221   }
    222   else
    223   {
    224     tst->arch.vex.guest_r55 = (Addr)&VG_(tilegx_linux_SUBST_FOR_rt_sigreturn);
    225   }
    226 
    227   priv->magicPI       = 0x31415927;
    228   priv->sigNo_private = sigNo;
    229   priv->vex_shadow1   = tst->arch.vex_shadow1;
    230   priv->vex_shadow2   = tst->arch.vex_shadow2;
    231   /* Set the thread so it will next run the handler. */
    232   /* tst->m_sp  = sp;  also notify the tool we've updated SP */
    233   VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(Addr));
    234   if (VG_(clo_trace_signals))
    235     VG_(printf)("handler = %p\n", handler);
    236   tst->arch.vex.guest_pc = (Addr) handler;
    237   /* This thread needs to be marked runnable, but we leave that the
    238      caller to do. */
    239   if (0)
    240     VG_(printf)("pushed signal frame; sp now = %lx, "
    241                 "next %pc = %lx, status=%d\n",
    242                 (Addr)frame, tst->arch.vex.guest_pc, (Int)tst->status);
    243 }
    244 
    245 /* EXPORTED */
    246 void VG_(sigframe_destroy)( ThreadId tid, Bool isRT )
    247 {
    248   ThreadState *tst;
    249   struct vg_sig_private *priv1;
    250   Addr sp;
    251   UInt frame_size;
    252   struct vki_sigcontext *mc;
    253   Int sigNo;
    254   Bool has_siginfo = isRT;
    255 
    256   vg_assert(VG_(is_valid_tid)(tid));
    257   tst = VG_(get_ThreadState)(tid);
    258   sp   = tst->arch.vex.guest_r54 + 8;
    259   if (has_siginfo)
    260   {
    261     struct rt_sigframe *frame = (struct rt_sigframe *)sp;
    262     struct vki_ucontext *ucp = &frame->rs_uc;
    263 
    264     if (0)
    265       VG_(printf)("destroy signal frame; sp = %lx, "
    266                   " %pc = %lx, status=%d\n",
    267                   (Addr)frame, tst->arch.vex.guest_pc, (Int)tst->status);
    268 
    269     frame_size = sizeof(*frame);
    270     mc = &ucp->uc_mcontext;
    271     priv1 = &frame->priv;
    272     vg_assert(priv1->magicPI == 0x31415927);
    273     sigNo = priv1->sigNo_private;
    274   }
    275   else
    276   {
    277     vg_assert(0);
    278   }
    279 
    280   //restore regs
    281   tst->arch.vex.guest_r0  = mc->gregs[0];
    282   tst->arch.vex.guest_r1  = mc->gregs[1];
    283   tst->arch.vex.guest_r2  = mc->gregs[2];
    284   tst->arch.vex.guest_r3  = mc->gregs[3];
    285   tst->arch.vex.guest_r4  = mc->gregs[4];
    286   tst->arch.vex.guest_r5  = mc->gregs[5];
    287   tst->arch.vex.guest_r6  = mc->gregs[6];
    288   tst->arch.vex.guest_r7  = mc->gregs[7];
    289   tst->arch.vex.guest_r8  = mc->gregs[8];
    290   tst->arch.vex.guest_r9  = mc->gregs[9];
    291   tst->arch.vex.guest_r10 = mc->gregs[10];
    292   tst->arch.vex.guest_r11 = mc->gregs[11];
    293   tst->arch.vex.guest_r12 = mc->gregs[12];
    294   tst->arch.vex.guest_r13 = mc->gregs[13];
    295   tst->arch.vex.guest_r14 = mc->gregs[14];
    296   tst->arch.vex.guest_r15 = mc->gregs[15];
    297   tst->arch.vex.guest_r16 = mc->gregs[16];
    298   tst->arch.vex.guest_r17 = mc->gregs[17];
    299   tst->arch.vex.guest_r18 = mc->gregs[18];
    300   tst->arch.vex.guest_r19 = mc->gregs[19];
    301   tst->arch.vex.guest_r20 = mc->gregs[20];
    302   tst->arch.vex.guest_r21 = mc->gregs[21];
    303   tst->arch.vex.guest_r22 = mc->gregs[22];
    304   tst->arch.vex.guest_r23 = mc->gregs[23];
    305   tst->arch.vex.guest_r24 = mc->gregs[24];
    306   tst->arch.vex.guest_r25 = mc->gregs[25];
    307   tst->arch.vex.guest_r26 = mc->gregs[26];
    308   tst->arch.vex.guest_r27 = mc->gregs[27];
    309   tst->arch.vex.guest_r28 = mc->gregs[28];
    310   tst->arch.vex.guest_r29 = mc->gregs[29];
    311   tst->arch.vex.guest_r30 = mc->gregs[30];
    312   tst->arch.vex.guest_r31 = mc->gregs[31];
    313   tst->arch.vex.guest_r32 = mc->gregs[32];
    314   tst->arch.vex.guest_r33 = mc->gregs[33];
    315   tst->arch.vex.guest_r34 = mc->gregs[34];
    316   tst->arch.vex.guest_r35 = mc->gregs[35];
    317   tst->arch.vex.guest_r36 = mc->gregs[36];
    318   tst->arch.vex.guest_r37 = mc->gregs[37];
    319   tst->arch.vex.guest_r38 = mc->gregs[38];
    320   tst->arch.vex.guest_r39 = mc->gregs[39];
    321   tst->arch.vex.guest_r40 = mc->gregs[40];
    322   tst->arch.vex.guest_r41 = mc->gregs[41];
    323   tst->arch.vex.guest_r42 = mc->gregs[42];
    324   tst->arch.vex.guest_r43 = mc->gregs[43];
    325   tst->arch.vex.guest_r44 = mc->gregs[44];
    326   tst->arch.vex.guest_r45 = mc->gregs[45];
    327   tst->arch.vex.guest_r46 = mc->gregs[46];
    328   tst->arch.vex.guest_r47 = mc->gregs[47];
    329   tst->arch.vex.guest_r48 = mc->gregs[48];
    330   tst->arch.vex.guest_r49 = mc->gregs[49];
    331   tst->arch.vex.guest_r50 = mc->gregs[50];
    332   tst->arch.vex.guest_r51 = mc->gregs[51];
    333   tst->arch.vex.guest_r52 = mc->gregs[52];
    334   tst->arch.vex.guest_r53 = mc->tp;
    335   tst->arch.vex.guest_r54 = mc->sp;
    336   tst->arch.vex.guest_r55 = mc->lr;
    337   tst->arch.vex.guest_pc  = mc->pc;
    338 
    339   VG_TRACK(die_mem_stack_signal, sp, frame_size);
    340   if (VG_(clo_trace_signals))
    341     VG_(message)( Vg_DebugMsg,
    342                   "VG_(signal_return) (thread %u): isRT=%d valid magic; EIP=%#x\n",
    343                   tid, isRT, tst->arch.vex.guest_pc);
    344   /* tell the tools */
    345   VG_TRACK( post_deliver_signal, tid, sigNo );
    346 }
    347 
    348 #endif // defined(VGP_tilegx_linux)
    349 
    350 /*--------------------------------------------------------------------*/
    351 /*--- end                                  sigframe-tilegx-linux.c ---*/
    352 /*--------------------------------------------------------------------*/
    353