• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*--------------------------------------------------------------------*/
3 /*--- Interface to LibVEX_Translate, and the SP-update pass        ---*/
4 /*---                                                m_translate.c ---*/
5 /*--------------------------------------------------------------------*/
6 
7 /*
8    This file is part of Valgrind, a dynamic binary instrumentation
9    framework.
10 
11    Copyright (C) 2000-2017 Julian Seward
12       jseward@acm.org
13 
14    This program is free software; you can redistribute it and/or
15    modify it under the terms of the GNU General Public License as
16    published by the Free Software Foundation; either version 2 of the
17    License, or (at your option) any later version.
18 
19    This program is distributed in the hope that it will be useful, but
20    WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22    General Public License for more details.
23 
24    You should have received a copy of the GNU General Public License
25    along with this program; if not, write to the Free Software
26    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27    02111-1307, USA.
28 
29    The GNU General Public License is contained in the file COPYING.
30 */
31 
32 #include "pub_core_basics.h"
33 #include "pub_core_vki.h"
34 #include "pub_core_aspacemgr.h"
35 
36 #include "pub_core_machine.h"    // VG_(fnptr_to_fnentry)
37                                  // VG_(get_SP)
38                                  // VG_(machine_get_VexArchInfo)
39 #include "pub_core_libcbase.h"
40 #include "pub_core_libcassert.h"
41 #include "pub_core_libcprint.h"
42 #include "pub_core_options.h"
43 
44 #include "pub_core_debuginfo.h"  // VG_(get_fnname_w_offset)
45 #include "pub_core_redir.h"      // VG_(redir_do_lookup)
46 
47 #include "pub_core_signals.h"    // VG_(synth_fault_{perms,mapping}
48 #include "pub_core_stacks.h"     // VG_(unknown_SP_update*)()
49 #include "pub_core_tooliface.h"  // VG_(tdict)
50 
51 #include "pub_core_translate.h"
52 #include "pub_core_transtab.h"
53 #include "pub_core_dispatch.h" // VG_(run_innerloop__dispatch_{un}profiled)
54                                // VG_(run_a_noredir_translation__return_point)
55 
56 #include "pub_core_threadstate.h"  // VexGuestArchState
57 #include "pub_core_trampoline.h"   // VG_(ppctoc_magic_redirect_return_stub)
58 
59 #include "pub_core_execontext.h"  // VG_(make_depth_1_ExeContext_from_Addr)
60 
61 #include "pub_core_gdbserver.h"   // VG_(instrument_for_gdbserver_if_needed)
62 
63 #include "libvex_emnote.h"        // For PPC, EmWarn_PPC64_redir_underflow
64 
65 /*------------------------------------------------------------*/
66 /*--- Stats                                                ---*/
67 /*------------------------------------------------------------*/
68 
69 static ULong n_SP_updates_fast            = 0;
70 static ULong n_SP_updates_generic_known   = 0;
71 static ULong n_SP_updates_generic_unknown = 0;
72 
73 static ULong n_PX_VexRegUpdSpAtMemAccess         = 0;
74 static ULong n_PX_VexRegUpdUnwindregsAtMemAccess = 0;
75 static ULong n_PX_VexRegUpdAllregsAtMemAccess    = 0;
76 static ULong n_PX_VexRegUpdAllregsAtEachInsn     = 0;
77 
VG_(print_translation_stats)78 void VG_(print_translation_stats) ( void )
79 {
80    UInt n_SP_updates = n_SP_updates_fast + n_SP_updates_generic_known
81                                          + n_SP_updates_generic_unknown;
82    if (n_SP_updates == 0) {
83       VG_(message)(Vg_DebugMsg, "translate: no SP updates identified\n");
84    } else {
85       VG_(message)(Vg_DebugMsg,
86          "translate:            fast SP updates identified: %'llu (%3.1f%%)\n",
87          n_SP_updates_fast, n_SP_updates_fast * 100.0 / n_SP_updates );
88 
89       VG_(message)(Vg_DebugMsg,
90          "translate:   generic_known SP updates identified: %'llu (%3.1f%%)\n",
91          n_SP_updates_generic_known,
92          n_SP_updates_generic_known * 100.0 / n_SP_updates );
93 
94       VG_(message)(Vg_DebugMsg,
95          "translate: generic_unknown SP updates identified: %'llu (%3.1f%%)\n",
96          n_SP_updates_generic_unknown,
97          n_SP_updates_generic_unknown * 100.0 / n_SP_updates );
98    }
99 
100    VG_(message)(Vg_DebugMsg,
101                 "translate: PX: SPonly %'llu,  UnwRegs %'llu,  AllRegs %'llu,  AllRegsAllInsns %'llu\n", n_PX_VexRegUpdSpAtMemAccess, n_PX_VexRegUpdUnwindregsAtMemAccess, n_PX_VexRegUpdAllregsAtMemAccess, n_PX_VexRegUpdAllregsAtEachInsn);
102 }
103 
104 /*------------------------------------------------------------*/
105 /*--- %SP-update pass                                      ---*/
106 /*------------------------------------------------------------*/
107 
need_to_handle_SP_assignment(void)108 static Bool need_to_handle_SP_assignment(void)
109 {
110    return ( VG_(tdict).track_new_mem_stack_4   ||
111             VG_(tdict).track_die_mem_stack_4   ||
112             VG_(tdict).track_new_mem_stack_8   ||
113             VG_(tdict).track_die_mem_stack_8   ||
114             VG_(tdict).track_new_mem_stack_12  ||
115             VG_(tdict).track_die_mem_stack_12  ||
116             VG_(tdict).track_new_mem_stack_16  ||
117             VG_(tdict).track_die_mem_stack_16  ||
118             VG_(tdict).track_new_mem_stack_32  ||
119             VG_(tdict).track_die_mem_stack_32  ||
120             VG_(tdict).track_new_mem_stack_112 ||
121             VG_(tdict).track_die_mem_stack_112 ||
122             VG_(tdict).track_new_mem_stack_128 ||
123             VG_(tdict).track_die_mem_stack_128 ||
124             VG_(tdict).track_new_mem_stack_144 ||
125             VG_(tdict).track_die_mem_stack_144 ||
126             VG_(tdict).track_new_mem_stack_160 ||
127             VG_(tdict).track_die_mem_stack_160 ||
128             VG_(tdict).track_new_mem_stack     ||
129             VG_(tdict).track_die_mem_stack     );
130 }
131 
132 // - The SP aliases are held in an array which is used as a circular buffer.
133 //   This misses very few constant updates of SP (ie. < 0.1%) while using a
134 //   small, constant structure that will also never fill up and cause
135 //   execution to abort.
136 // - Unused slots have a .temp value of 'IRTemp_INVALID'.
137 // - 'next_SP_alias_slot' is the index where the next alias will be stored.
138 // - If the buffer fills, we circle around and start over-writing
139 //   non-IRTemp_INVALID values.  This is rare, and the overwriting of a
140 //   value that would have subsequently be used is even rarer.
141 // - Every slot below next_SP_alias_slot holds a non-IRTemp_INVALID value.
142 //   The rest either all won't (if we haven't yet circled around) or all
143 //   will (if we have circled around).
144 
145 typedef
146    struct {
147       IRTemp temp;
148       Long   delta;
149    }
150    SP_Alias;
151 
152 // With 32 slots the buffer fills very rarely -- eg. once in a run of GCC.
153 // And I've tested with smaller values and the wrap-around case works ok.
154 #define N_ALIASES    32
155 static SP_Alias SP_aliases[N_ALIASES];
156 static Int      next_SP_alias_slot = 0;
157 
clear_SP_aliases(void)158 static void clear_SP_aliases(void)
159 {
160    Int i;
161    for (i = 0; i < N_ALIASES; i++) {
162       SP_aliases[i].temp  = IRTemp_INVALID;
163       SP_aliases[i].delta = 0;
164    }
165    next_SP_alias_slot = 0;
166 }
167 
add_SP_alias(IRTemp temp,Long delta)168 static void add_SP_alias(IRTemp temp, Long delta)
169 {
170    vg_assert(temp != IRTemp_INVALID);
171    SP_aliases[ next_SP_alias_slot ].temp  = temp;
172    SP_aliases[ next_SP_alias_slot ].delta = delta;
173    next_SP_alias_slot++;
174    if (N_ALIASES == next_SP_alias_slot) next_SP_alias_slot = 0;
175 }
176 
get_SP_delta(IRTemp temp,Long * delta)177 static Bool get_SP_delta(IRTemp temp, Long* delta)
178 {
179    Int i;      // i must be signed!
180    vg_assert(IRTemp_INVALID != temp);
181    // Search backwards between current buffer position and the start.
182    for (i = next_SP_alias_slot-1; i >= 0; i--) {
183       if (temp == SP_aliases[i].temp) {
184          *delta = SP_aliases[i].delta;
185          return True;
186       }
187    }
188    // Search backwards between the end and the current buffer position.
189    for (i = N_ALIASES-1; i >= next_SP_alias_slot; i--) {
190       if (temp == SP_aliases[i].temp) {
191          *delta = SP_aliases[i].delta;
192          return True;
193       }
194    }
195    return False;
196 }
197 
update_SP_aliases(Long delta)198 static void update_SP_aliases(Long delta)
199 {
200    Int i;
201    for (i = 0; i < N_ALIASES; i++) {
202       if (SP_aliases[i].temp == IRTemp_INVALID) {
203          return;
204       }
205       SP_aliases[i].delta += delta;
206    }
207 }
208 
209 /* Given a guest IP, get an origin tag for a 1-element stack trace,
210    and wrap it up in an IR atom that can be passed as the origin-tag
211    value for a stack-adjustment helper function. */
mk_ecu_Expr(Addr guest_IP)212 static IRExpr* mk_ecu_Expr ( Addr guest_IP )
213 {
214    UInt ecu;
215    ExeContext* ec
216       = VG_(make_depth_1_ExeContext_from_Addr)( guest_IP );
217    vg_assert(ec);
218    ecu = VG_(get_ECU_from_ExeContext)( ec );
219    vg_assert(VG_(is_plausible_ECU)(ecu));
220    /* This is always safe to do, since ecu is only 32 bits, and
221       HWord is 32 or 64. */
222    return mkIRExpr_HWord( (HWord)ecu );
223 }
224 
225 /* When gdbserver is activated, the translation of a block must
226    first be done by the tool function, then followed by a pass
227    which (if needed) instruments the code for gdbserver.
228 */
229 static
tool_instrument_then_gdbserver_if_needed(VgCallbackClosure * closureV,IRSB * sb_in,const VexGuestLayout * layout,const VexGuestExtents * vge,const VexArchInfo * vai,IRType gWordTy,IRType hWordTy)230 IRSB* tool_instrument_then_gdbserver_if_needed ( VgCallbackClosure* closureV,
231                                                  IRSB*              sb_in,
232                                                  const VexGuestLayout*  layout,
233                                                  const VexGuestExtents* vge,
234                                                  const VexArchInfo*     vai,
235                                                  IRType             gWordTy,
236                                                  IRType             hWordTy )
237 {
238    return VG_(instrument_for_gdbserver_if_needed)
239       (VG_(tdict).tool_instrument (closureV,
240                                    sb_in,
241                                    layout,
242                                    vge,
243                                    vai,
244                                    gWordTy,
245                                    hWordTy),
246        layout,
247        vge,
248        gWordTy,
249        hWordTy);
250 }
251 
252 /* For tools that want to know about SP changes, this pass adds
253    in the appropriate hooks.  We have to do it after the tool's
254    instrumentation, so the tool doesn't have to worry about the C calls
255    it adds in, and we must do it before register allocation because
256    spilled temps make it much harder to work out the SP deltas.
257    This it is done with Vex's "second instrumentation" pass.
258 
259    Basically, we look for GET(SP)/PUT(SP) pairs and track constant
260    increments/decrements of SP between them.  (This requires tracking one or
261    more "aliases", which are not exact aliases but instead are tempregs
262    whose value is equal to the SP's plus or minus a known constant.)
263    If all the changes to SP leading up to a PUT(SP) are by known, small
264    constants, we can do a specific call to eg. new_mem_stack_4, otherwise
265    we fall back to the case that handles an unknown SP change.
266 
267    There is some extra complexity to deal correctly with updates to
268    only parts of SP.  Bizarre, but it has been known to happen.
269 */
270 static
vg_SP_update_pass(void * closureV,IRSB * sb_in,const VexGuestLayout * layout,const VexGuestExtents * vge,const VexArchInfo * vai,IRType gWordTy,IRType hWordTy)271 IRSB* vg_SP_update_pass ( void*             closureV,
272                           IRSB*             sb_in,
273                           const VexGuestLayout*   layout,
274                           const VexGuestExtents*  vge,
275                           const VexArchInfo*      vai,
276                           IRType            gWordTy,
277                           IRType            hWordTy )
278 {
279    Int         i, j, k, minoff_ST, maxoff_ST, sizeof_SP, offset_SP;
280    Int         first_SP, last_SP, first_Put, last_Put;
281    IRDirty     *dcall, *d;
282    IRStmt*     st;
283    IRExpr*     e;
284    IRRegArray* descr;
285    IRType      typeof_SP;
286    Long        delta, con;
287 
288    /* Set up stuff for tracking the guest IP */
289    Bool   curr_IP_known = False;
290    Addr   curr_IP       = 0;
291 
292    /* Set up BB */
293    IRSB* bb     = emptyIRSB();
294    bb->tyenv    = deepCopyIRTypeEnv(sb_in->tyenv);
295    bb->next     = deepCopyIRExpr(sb_in->next);
296    bb->jumpkind = sb_in->jumpkind;
297    bb->offsIP   = sb_in->offsIP;
298 
299    delta = 0;
300 
301    sizeof_SP = layout->sizeof_SP;
302    offset_SP = layout->offset_SP;
303    typeof_SP = sizeof_SP==4 ? Ity_I32 : Ity_I64;
304    vg_assert(sizeof_SP == 4 || sizeof_SP == 8);
305 
306    /* --- Start of #defines --- */
307 
308 #  define IS_ADD(op) (sizeof_SP==4 ? ((op)==Iop_Add32) : ((op)==Iop_Add64))
309 #  define IS_SUB(op) (sizeof_SP==4 ? ((op)==Iop_Sub32) : ((op)==Iop_Sub64))
310 
311 #  define IS_ADD_OR_SUB(op) (IS_ADD(op) || IS_SUB(op))
312 
313 #  define GET_CONST(con)                                                \
314        (sizeof_SP==4 ? (Long)(Int)(con->Ico.U32)                        \
315                      : (Long)(con->Ico.U64))
316 
317 #  define DO_NEW(syze, tmpp)                                            \
318       do {                                                              \
319          Bool vanilla, w_ecu;                                           \
320          vg_assert(curr_IP_known);                                      \
321          vanilla = NULL != VG_(tdict).track_new_mem_stack_##syze;       \
322          w_ecu   = NULL != VG_(tdict).track_new_mem_stack_##syze##_w_ECU; \
323          vg_assert(!(vanilla && w_ecu)); /* can't have both */          \
324          if (!(vanilla || w_ecu))                                       \
325             goto generic;                                               \
326                                                                         \
327          /* I don't know if it's really necessary to say that the */    \
328          /* call reads the stack pointer.  But anyway, we do. */        \
329          if (w_ecu) {                                                   \
330             dcall = unsafeIRDirty_0_N(                                  \
331                        2/*regparms*/,                                   \
332                        "track_new_mem_stack_" #syze "_w_ECU",           \
333                        VG_(fnptr_to_fnentry)(                           \
334                           VG_(tdict).track_new_mem_stack_##syze##_w_ECU ), \
335                        mkIRExprVec_2(IRExpr_RdTmp(tmpp),                \
336                                      mk_ecu_Expr(curr_IP))              \
337                     );                                                  \
338          } else {                                                       \
339             dcall = unsafeIRDirty_0_N(                                  \
340                        1/*regparms*/,                                   \
341                        "track_new_mem_stack_" #syze ,                   \
342                        VG_(fnptr_to_fnentry)(                           \
343                           VG_(tdict).track_new_mem_stack_##syze ),      \
344                        mkIRExprVec_1(IRExpr_RdTmp(tmpp))                \
345                     );                                                  \
346          }                                                              \
347          dcall->nFxState = 1;                                           \
348          dcall->fxState[0].fx     = Ifx_Read;                           \
349          dcall->fxState[0].offset = layout->offset_SP;                  \
350          dcall->fxState[0].size   = layout->sizeof_SP;                  \
351          dcall->fxState[0].nRepeats  = 0;                               \
352          dcall->fxState[0].repeatLen = 0;                               \
353                                                                         \
354          addStmtToIRSB( bb, IRStmt_Dirty(dcall) );                      \
355                                                                         \
356          vg_assert(syze > 0);                                           \
357          update_SP_aliases(syze);                                       \
358                                                                         \
359          n_SP_updates_fast++;                                           \
360                                                                         \
361       } while (0)
362 
363 #  define DO_DIE(syze, tmpp)                                            \
364       do {                                                              \
365          if (!VG_(tdict).track_die_mem_stack_##syze)                    \
366             goto generic;                                               \
367                                                                         \
368          /* I don't know if it's really necessary to say that the */    \
369          /* call reads the stack pointer.  But anyway, we do. */        \
370          dcall = unsafeIRDirty_0_N(                                     \
371                     1/*regparms*/,                                      \
372                     "track_die_mem_stack_" #syze,                       \
373                     VG_(fnptr_to_fnentry)(                              \
374                        VG_(tdict).track_die_mem_stack_##syze ),         \
375                     mkIRExprVec_1(IRExpr_RdTmp(tmpp))                   \
376                  );                                                     \
377          dcall->nFxState = 1;                                           \
378          dcall->fxState[0].fx     = Ifx_Read;                           \
379          dcall->fxState[0].offset = layout->offset_SP;                  \
380          dcall->fxState[0].size   = layout->sizeof_SP;                  \
381          dcall->fxState[0].nRepeats  = 0;                               \
382          dcall->fxState[0].repeatLen = 0;                               \
383                                                                         \
384          addStmtToIRSB( bb, IRStmt_Dirty(dcall) );                      \
385                                                                         \
386          vg_assert(syze > 0);                                           \
387          update_SP_aliases(-(syze));                                    \
388                                                                         \
389          n_SP_updates_fast++;                                           \
390                                                                         \
391       } while (0)
392 
393    /* --- End of #defines --- */
394 
395    clear_SP_aliases();
396 
397    for (i = 0; i <  sb_in->stmts_used; i++) {
398 
399       st = sb_in->stmts[i];
400 
401       if (st->tag == Ist_IMark) {
402          curr_IP_known = True;
403          curr_IP       = st->Ist.IMark.addr;
404       }
405 
406       /* t = Get(sp):   curr = t, delta = 0 */
407       if (st->tag != Ist_WrTmp) goto case2;
408       e = st->Ist.WrTmp.data;
409       if (e->tag != Iex_Get)              goto case2;
410       if (e->Iex.Get.offset != offset_SP) goto case2;
411       if (e->Iex.Get.ty != typeof_SP)     goto case2;
412       vg_assert( typeOfIRTemp(bb->tyenv, st->Ist.WrTmp.tmp) == typeof_SP );
413       add_SP_alias(st->Ist.WrTmp.tmp, 0);
414       addStmtToIRSB( bb, st );
415       continue;
416 
417      case2:
418       /* t' = curr +/- const:   curr = t',  delta +=/-= const */
419       if (st->tag != Ist_WrTmp) goto case3;
420       e = st->Ist.WrTmp.data;
421       if (e->tag != Iex_Binop) goto case3;
422       if (e->Iex.Binop.arg1->tag != Iex_RdTmp) goto case3;
423       if (!get_SP_delta(e->Iex.Binop.arg1->Iex.RdTmp.tmp, &delta)) goto case3;
424       if (e->Iex.Binop.arg2->tag != Iex_Const) goto case3;
425       if (!IS_ADD_OR_SUB(e->Iex.Binop.op)) goto case3;
426       con = GET_CONST(e->Iex.Binop.arg2->Iex.Const.con);
427       vg_assert( typeOfIRTemp(bb->tyenv, st->Ist.WrTmp.tmp) == typeof_SP );
428       if (IS_ADD(e->Iex.Binop.op)) {
429          add_SP_alias(st->Ist.WrTmp.tmp, delta + con);
430       } else {
431          add_SP_alias(st->Ist.WrTmp.tmp, delta - con);
432       }
433       addStmtToIRSB( bb, st );
434       continue;
435 
436      case3:
437       /* t' = curr:   curr = t' */
438       if (st->tag != Ist_WrTmp) goto case4;
439       e = st->Ist.WrTmp.data;
440       if (e->tag != Iex_RdTmp) goto case4;
441       if (!get_SP_delta(e->Iex.RdTmp.tmp, &delta)) goto case4;
442       vg_assert( typeOfIRTemp(bb->tyenv, st->Ist.WrTmp.tmp) == typeof_SP );
443       add_SP_alias(st->Ist.WrTmp.tmp, delta);
444       addStmtToIRSB( bb, st );
445       continue;
446 
447      case4:
448       /* Put(sp) = curr */
449       /* More generally, we must correctly handle a Put which writes
450          any part of SP, not just the case where all of SP is
451          written. */
452       if (st->tag != Ist_Put) goto case5;
453       first_SP  = offset_SP;
454       last_SP   = first_SP + sizeof_SP - 1;
455       first_Put = st->Ist.Put.offset;
456       last_Put  = first_Put
457                   + sizeofIRType( typeOfIRExpr( bb->tyenv, st->Ist.Put.data ))
458                   - 1;
459       vg_assert(first_SP <= last_SP);
460       vg_assert(first_Put <= last_Put);
461 
462       if (last_Put < first_SP || last_SP < first_Put)
463          goto case5; /* no overlap */
464 
465       if (st->Ist.Put.data->tag == Iex_RdTmp
466           && get_SP_delta(st->Ist.Put.data->Iex.RdTmp.tmp, &delta)) {
467          IRTemp tttmp = st->Ist.Put.data->Iex.RdTmp.tmp;
468          /* Why should the following assertion hold?  Because any
469             alias added by put_SP_alias must be of a temporary which
470             has the same type as typeof_SP, and whose value is a Get
471             at exactly offset_SP of size typeof_SP.  Each call to
472             put_SP_alias is immediately preceded by an assertion that
473             we are putting in a binding for a correctly-typed
474             temporary. */
475          vg_assert( typeOfIRTemp(bb->tyenv, tttmp) == typeof_SP );
476          /* From the same type-and-offset-correctness argument, if
477             we found a useable alias, it must for an "exact" write of SP. */
478          vg_assert(first_SP == first_Put);
479          vg_assert(last_SP == last_Put);
480          switch (delta) {
481             case    0:                      addStmtToIRSB(bb,st); continue;
482             case    4: DO_DIE(  4,  tttmp); addStmtToIRSB(bb,st); continue;
483             case   -4: DO_NEW(  4,  tttmp); addStmtToIRSB(bb,st); continue;
484             case    8: DO_DIE(  8,  tttmp); addStmtToIRSB(bb,st); continue;
485             case   -8: DO_NEW(  8,  tttmp); addStmtToIRSB(bb,st); continue;
486             case   12: DO_DIE(  12, tttmp); addStmtToIRSB(bb,st); continue;
487             case  -12: DO_NEW(  12, tttmp); addStmtToIRSB(bb,st); continue;
488             case   16: DO_DIE(  16, tttmp); addStmtToIRSB(bb,st); continue;
489             case  -16: DO_NEW(  16, tttmp); addStmtToIRSB(bb,st); continue;
490             case   32: DO_DIE(  32, tttmp); addStmtToIRSB(bb,st); continue;
491             case  -32: DO_NEW(  32, tttmp); addStmtToIRSB(bb,st); continue;
492             case  112: DO_DIE( 112, tttmp); addStmtToIRSB(bb,st); continue;
493             case -112: DO_NEW( 112, tttmp); addStmtToIRSB(bb,st); continue;
494             case  128: DO_DIE( 128, tttmp); addStmtToIRSB(bb,st); continue;
495             case -128: DO_NEW( 128, tttmp); addStmtToIRSB(bb,st); continue;
496             case  144: DO_DIE( 144, tttmp); addStmtToIRSB(bb,st); continue;
497             case -144: DO_NEW( 144, tttmp); addStmtToIRSB(bb,st); continue;
498             case  160: DO_DIE( 160, tttmp); addStmtToIRSB(bb,st); continue;
499             case -160: DO_NEW( 160, tttmp); addStmtToIRSB(bb,st); continue;
500             default:
501                /* common values for ppc64: 144 128 160 112 176 */
502                n_SP_updates_generic_known++;
503                goto generic;
504          }
505       } else {
506          /* Deal with an unknown update to SP.  We're here because
507             either:
508             (1) the Put does not exactly cover SP; it is a partial update.
509                 Highly unlikely, but has been known to happen for 16-bit
510                 Windows apps running on Wine, doing 16-bit adjustments to
511                 %sp.
512             (2) the Put does exactly cover SP, but we are unable to
513                 determine how the value relates to the old SP.  In any
514                 case, we cannot assume that the Put.data value is a tmp;
515                 we must assume it can be anything allowed in flat IR (tmp
516                 or const).
517          */
518          IRTemp  old_SP;
519          n_SP_updates_generic_unknown++;
520 
521          // Nb: if all is well, this generic case will typically be
522          // called something like every 1000th SP update.  If it's more than
523          // that, the above code may be missing some cases.
524         generic:
525          /* Pass both the old and new SP values to this helper.  Also,
526             pass an origin tag, even if it isn't needed. */
527          old_SP = newIRTemp(bb->tyenv, typeof_SP);
528          addStmtToIRSB(
529             bb,
530             IRStmt_WrTmp( old_SP, IRExpr_Get(offset_SP, typeof_SP) )
531          );
532 
533          /* Now we know what the old value of SP is.  But knowing the new
534             value is a bit tricky if there is a partial write. */
535          if (first_Put == first_SP && last_Put == last_SP) {
536             /* The common case, an exact write to SP.  So st->Ist.Put.data
537                does hold the new value; simple. */
538             vg_assert(curr_IP_known);
539             if (NULL != VG_(tdict).track_new_mem_stack_w_ECU)
540                dcall = unsafeIRDirty_0_N(
541                           3/*regparms*/,
542                           "VG_(unknown_SP_update_w_ECU)",
543                           VG_(fnptr_to_fnentry)( &VG_(unknown_SP_update_w_ECU) ),
544                           mkIRExprVec_3( IRExpr_RdTmp(old_SP), st->Ist.Put.data,
545                                          mk_ecu_Expr(curr_IP) )
546                        );
547             else
548                dcall = unsafeIRDirty_0_N(
549                           2/*regparms*/,
550                           "VG_(unknown_SP_update)",
551                           VG_(fnptr_to_fnentry)( &VG_(unknown_SP_update) ),
552                           mkIRExprVec_2( IRExpr_RdTmp(old_SP), st->Ist.Put.data )
553                        );
554 
555             addStmtToIRSB( bb, IRStmt_Dirty(dcall) );
556             /* don't forget the original assignment */
557             addStmtToIRSB( bb, st );
558          } else {
559             /* We have a partial update to SP.  We need to know what
560                the new SP will be, and hand that to the helper call,
561                but when the helper call happens, SP must hold the
562                value it had before the update.  Tricky.
563                Therefore use the following kludge:
564                1. do the partial SP update (Put)
565                2. Get the new SP value into a tmp, new_SP
566                3. Put old_SP
567                4. Call the helper
568                5. Put new_SP
569             */
570             IRTemp new_SP;
571             /* 1 */
572             addStmtToIRSB( bb, st );
573             /* 2 */
574             new_SP = newIRTemp(bb->tyenv, typeof_SP);
575             addStmtToIRSB(
576                bb,
577                IRStmt_WrTmp( new_SP, IRExpr_Get(offset_SP, typeof_SP) )
578             );
579             /* 3 */
580             addStmtToIRSB( bb, IRStmt_Put(offset_SP, IRExpr_RdTmp(old_SP) ));
581             /* 4 */
582             vg_assert(curr_IP_known);
583             if (NULL != VG_(tdict).track_new_mem_stack_w_ECU)
584                dcall = unsafeIRDirty_0_N(
585                           3/*regparms*/,
586                           "VG_(unknown_SP_update_w_ECU)",
587                           VG_(fnptr_to_fnentry)( &VG_(unknown_SP_update_w_ECU) ),
588                           mkIRExprVec_3( IRExpr_RdTmp(old_SP),
589                                          IRExpr_RdTmp(new_SP),
590                                          mk_ecu_Expr(curr_IP) )
591                        );
592             else
593                dcall = unsafeIRDirty_0_N(
594                           2/*regparms*/,
595                           "VG_(unknown_SP_update)",
596                           VG_(fnptr_to_fnentry)( &VG_(unknown_SP_update) ),
597                           mkIRExprVec_2( IRExpr_RdTmp(old_SP),
598                                          IRExpr_RdTmp(new_SP) )
599                        );
600             addStmtToIRSB( bb, IRStmt_Dirty(dcall) );
601             /* 5 */
602             addStmtToIRSB( bb, IRStmt_Put(offset_SP, IRExpr_RdTmp(new_SP) ));
603          }
604 
605          /* Forget what we already know. */
606          clear_SP_aliases();
607 
608          /* If this is a Put of a tmp that exactly updates SP,
609             start tracking aliases against this tmp. */
610 
611          if (first_Put == first_SP && last_Put == last_SP
612              && st->Ist.Put.data->tag == Iex_RdTmp) {
613             vg_assert( typeOfIRTemp(bb->tyenv, st->Ist.Put.data->Iex.RdTmp.tmp)
614                        == typeof_SP );
615             add_SP_alias(st->Ist.Put.data->Iex.RdTmp.tmp, 0);
616          }
617          continue;
618       }
619 
620      case5:
621       /* PutI or Dirty call which overlaps SP: complain.  We can't
622          deal with SP changing in weird ways (well, we can, but not at
623          this time of night).  */
624       if (st->tag == Ist_PutI) {
625          descr = st->Ist.PutI.details->descr;
626          minoff_ST = descr->base;
627          maxoff_ST = descr->base
628                      + descr->nElems * sizeofIRType(descr->elemTy) - 1;
629          if (!(offset_SP > maxoff_ST
630                || (offset_SP + sizeof_SP - 1) < minoff_ST))
631             goto complain;
632       }
633       if (st->tag == Ist_Dirty) {
634          d = st->Ist.Dirty.details;
635          for (j = 0; j < d->nFxState; j++) {
636             if (d->fxState[j].fx == Ifx_Read || d->fxState[j].fx == Ifx_None)
637                continue;
638             /* Enumerate the described state segments */
639             for (k = 0; k < 1 + d->fxState[j].nRepeats; k++) {
640                minoff_ST = d->fxState[j].offset + k * d->fxState[j].repeatLen;
641                maxoff_ST = minoff_ST + d->fxState[j].size - 1;
642                if (!(offset_SP > maxoff_ST
643                      || (offset_SP + sizeof_SP - 1) < minoff_ST))
644                   goto complain;
645             }
646          }
647       }
648 
649       /* well, not interesting.  Just copy and keep going. */
650       addStmtToIRSB( bb, st );
651 
652    } /* for (i = 0; i < sb_in->stmts_used; i++) */
653 
654    return bb;
655 
656   complain:
657    VG_(core_panic)("vg_SP_update_pass: PutI or Dirty which overlaps SP");
658 
659 #undef IS_ADD
660 #undef IS_SUB
661 #undef IS_ADD_OR_SUB
662 #undef GET_CONST
663 #undef DO_NEW
664 #undef DO_DIE
665 }
666 
667 /*------------------------------------------------------------*/
668 /*--- Main entry point for the JITter.                     ---*/
669 /*------------------------------------------------------------*/
670 
671 /* Extra comments re self-checking translations and self-modifying
672    code.  (JRS 14 Oct 05).
673 
674    There are 3 modes:
675    (1) no checking: all code assumed to be not self-modifying
676    (2) partial: known-problematic situations get a self-check
677    (3) full checking: all translations get a self-check
678 
679    As currently implemented, the default is (2).  (3) is always safe,
680    but very slow.  (1) works mostly, but fails for gcc nested-function
681    code which uses trampolines on the stack; this situation is
682    detected and handled by (2).
683 
684    ----------
685 
686    A more robust and transparent solution, which is not currently
687    implemented, is a variant of (2): if a translation is made from an
688    area which aspacem says does not have 'w' permission, then it can
689    be non-self-checking.  Otherwise, it needs a self-check.
690 
691    This is complicated by Vex's basic-block chasing.  If a self-check
692    is requested, then Vex will not chase over basic block boundaries
693    (it's too complex).  However there is still a problem if it chases
694    from a non-'w' area into a 'w' area.
695 
696    I think the right thing to do is:
697 
698    - if a translation request starts in a 'w' area, ask for a
699      self-checking translation, and do not allow any chasing (make
700      chase_into_ok return False).  Note that the latter is redundant
701      in the sense that Vex won't chase anyway in this situation.
702 
703    - if a translation request starts in a non-'w' area, do not ask for
704      a self-checking translation.  However, do not allow chasing (as
705      determined by chase_into_ok) to go into a 'w' area.
706 
707    The result of this is that all code inside 'w' areas is self
708    checking.
709 
710    To complete the trick, there is a caveat: we must watch the
711    client's mprotect calls.  If pages are changed from non-'w' to 'w'
712    then we should throw away all translations which intersect the
713    affected area, so as to force them to be redone with self-checks.
714 
715    ----------
716 
717    The above outlines the conditions under which bb chasing is allowed
718    from a self-modifying-code point of view.  There are other
719    situations pertaining to function redirection in which it is
720    necessary to disallow chasing, but those fall outside the scope of
721    this comment.
722 */
723 
724 
725 /* Vex dumps the final code in here.  Then we can copy it off
726    wherever we like. */
727 /* 60000: should agree with assertion in VG_(add_to_transtab) in
728    m_transtab.c. */
729 #define N_TMPBUF 60000
730 static UChar tmpbuf[N_TMPBUF];
731 
732 
733 /* Function pointers we must supply to LibVEX in order that it
734    can bomb out and emit messages under Valgrind's control. */
735 __attribute__ ((noreturn))
736 static
failure_exit(void)737 void failure_exit ( void )
738 {
739    LibVEX_ShowAllocStats();
740    VG_(core_panic)("LibVEX called failure_exit().");
741 }
742 
743 static
log_bytes(const HChar * bytes,SizeT nbytes)744 void log_bytes ( const HChar* bytes, SizeT nbytes )
745 {
746   SizeT i = 0;
747   if (nbytes >= 4)
748      for (; i < nbytes-3; i += 4)
749         VG_(printf)("%c%c%c%c", bytes[i], bytes[i+1], bytes[i+2], bytes[i+3]);
750   for (; i < nbytes; i++)
751      VG_(printf)("%c", bytes[i]);
752 }
753 
754 
755 /* --------- Various helper functions for translation --------- */
756 
757 /* Look for reasons to disallow making translations from the given
758    segment/addr. */
759 
translations_allowable_from_seg(NSegment const * seg,Addr addr)760 static Bool translations_allowable_from_seg ( NSegment const* seg, Addr addr )
761 {
762 #  if defined(VGA_x86) || defined(VGA_s390x) || defined(VGA_mips32)     \
763      || defined(VGA_mips64)
764    Bool allowR = True;
765 #  else
766    Bool allowR = False;
767 #  endif
768    return seg != NULL
769           && (seg->kind == SkAnonC || seg->kind == SkFileC || seg->kind == SkShmC)
770           && (seg->hasX
771               || (seg->hasR && (allowR
772                                 || VG_(has_gdbserver_breakpoint) (addr))));
773    /* If GDB/gdbsrv has inserted a breakpoint at addr, assume this is a valid
774       location to translate if seg is not executable but is readable.
775       This is needed for inferior function calls from GDB: GDB inserts a
776       breakpoint on the stack, and expects to regain control before the
777       breakpoint instruction at the breakpoint address is really
778       executed. For this, the breakpoint instruction must be translated
779       so as to have the call to gdbserver executed. */
780 }
781 
782 
783 /* Produce a bitmask stating which of the supplied extents needs a
784    self-check.  See documentation of
785    VexTranslateArgs::needs_self_check for more details about the
786    return convention. */
787 
needs_self_check(void * closureV,VexRegisterUpdates * pxControl,const VexGuestExtents * vge)788 static UInt needs_self_check ( void* closureV,
789                                /*MAYBE_MOD*/VexRegisterUpdates* pxControl,
790                                const VexGuestExtents* vge )
791 {
792    VgCallbackClosure* closure = (VgCallbackClosure*)closureV;
793    UInt i, bitset;
794 
795    vg_assert(vge->n_used >= 1 && vge->n_used <= 3);
796    bitset = 0;
797 
798    /* Will we need to do a second pass in order to compute a
799       revised *pxControl value? */
800    Bool pxStatusMightChange
801       = /* "the user actually set it" */
802         VG_(clo_px_file_backed) != VexRegUpd_INVALID
803         /* "and they set it to something other than the default. */
804         && *pxControl != VG_(clo_px_file_backed);
805 
806    /* First, compute |bitset|, which specifies which extent(s) need a
807       self check.  Whilst we're at it, note any NSegments that we get,
808       so as to reduce the number of calls required to
809       VG_(am_find_nsegment) in a possible second pass. */
810    const NSegment *segs[3] = { NULL, NULL, NULL };
811 
812    for (i = 0; i < vge->n_used; i++) {
813       Bool  check = False;
814       Addr  addr  = vge->base[i];
815       SizeT len   = vge->len[i];
816       NSegment const* segA = NULL;
817 
818 #     if defined(VGO_darwin)
819       // GrP fixme hack - dyld i386 IMPORT gets rewritten.
820       // To really do this correctly, we'd need to flush the
821       // translation cache whenever a segment became +WX.
822       segA = VG_(am_find_nsegment)(addr);
823       if (segA && segA->hasX && segA->hasW)
824          check = True;
825 #     endif
826 
827       if (!check) {
828          switch (VG_(clo_smc_check)) {
829             case Vg_SmcNone:
830                /* never check (except as per Darwin hack above) */
831                break;
832             case Vg_SmcAll:
833                /* always check */
834                check = True;
835                break;
836             case Vg_SmcStack: {
837                /* check if the address is in the same segment as this
838                   thread's stack pointer */
839                Addr sp = VG_(get_SP)(closure->tid);
840                if (!segA) {
841                   segA = VG_(am_find_nsegment)(addr);
842                }
843                NSegment const* segSP = VG_(am_find_nsegment)(sp);
844                if (segA && segSP && segA == segSP)
845                   check = True;
846                break;
847             }
848             case Vg_SmcAllNonFile: {
849                /* check if any part of the extent is not in a
850                   file-mapped segment */
851                if (!segA) {
852                   segA = VG_(am_find_nsegment)(addr);
853                }
854                if (segA && segA->kind == SkFileC && segA->start <= addr
855                    && (len == 0 || addr + len <= segA->end + 1)) {
856                   /* in a file-mapped segment; skip the check */
857                } else {
858                   check = True;
859                }
860                break;
861             }
862             default:
863                vg_assert(0);
864          }
865       }
866 
867       if (check)
868          bitset |= (1 << i);
869 
870       if (pxStatusMightChange && segA) {
871          vg_assert(i < sizeof(segs)/sizeof(segs[0]));
872          segs[i] = segA;
873       }
874    }
875 
876    /* Now, possibly do a second pass, to see if the PX status might
877       change.  This can happen if the user specified value via
878       --px-file-backed= which is different from the default PX value
879       specified via --vex-iropt-register-updates (also known by the
880       shorter alias --px-default). */
881    if (pxStatusMightChange) {
882 
883       Bool allFileBacked = True;
884       for (i = 0; i < vge->n_used; i++) {
885          Addr  addr  = vge->base[i];
886          SizeT len   = vge->len[i];
887          NSegment const* segA = segs[i];
888          if (!segA) {
889             /* If we don't have a cached value for |segA|, compute it now. */
890             segA = VG_(am_find_nsegment)(addr);
891          }
892          vg_assert(segA); /* Can this ever fail? */
893          if (segA && segA->kind == SkFileC && segA->start <= addr
894              && (len == 0 || addr + len <= segA->end + 1)) {
895             /* in a file-mapped segment */
896          } else {
897             /* not in a file-mapped segment, or we can't figure out
898                where it is */
899             allFileBacked = False;
900             break;
901          }
902       }
903 
904       /* So, finally, if all the extents are in file backed segments, perform
905          the user-specified PX change. */
906       if (allFileBacked) {
907          *pxControl = VG_(clo_px_file_backed);
908       }
909 
910    }
911 
912    /* Update running PX stats, as it is difficult without these to
913       check that the system is behaving as expected. */
914    switch (*pxControl) {
915       case VexRegUpdSpAtMemAccess:
916          n_PX_VexRegUpdSpAtMemAccess++; break;
917       case VexRegUpdUnwindregsAtMemAccess:
918          n_PX_VexRegUpdUnwindregsAtMemAccess++; break;
919       case VexRegUpdAllregsAtMemAccess:
920          n_PX_VexRegUpdAllregsAtMemAccess++; break;
921       case VexRegUpdAllregsAtEachInsn:
922          n_PX_VexRegUpdAllregsAtEachInsn++; break;
923       default:
924          vg_assert(0);
925    }
926 
927    return bitset;
928 }
929 
930 
931 /* This is a callback passed to LibVEX_Translate.  It stops Vex from
932    chasing into function entry points that we wish to redirect.
933    Chasing across them obviously defeats the redirect mechanism, with
934    bad effects for Memcheck, Helgrind, DRD, Massif, and possibly others.
935 */
chase_into_ok(void * closureV,Addr addr)936 static Bool chase_into_ok ( void* closureV, Addr addr )
937 {
938    NSegment const*    seg     = VG_(am_find_nsegment)(addr);
939 
940    /* Work through a list of possibilities why we might not want to
941       allow a chase. */
942 
943    /* Destination not in a plausible segment? */
944    if (!translations_allowable_from_seg(seg, addr))
945       goto dontchase;
946 
947    /* Destination is redirected? */
948    if (addr != VG_(redir_do_lookup)(addr, NULL))
949       goto dontchase;
950 
951 #  if defined(VG_PLAT_USES_PPCTOC) || defined(VGP_ppc64le_linux)
952    /* This needs to be at the start of its own block.  Don't chase. */
953    if (addr == (Addr)&VG_(ppctoc_magic_redirect_return_stub))
954       goto dontchase;
955 #  endif
956 
957    /* overly conservative, but .. don't chase into the distinguished
958       address that m_transtab uses as an empty-slot marker for
959       VG_(tt_fast). */
960    if (addr == TRANSTAB_BOGUS_GUEST_ADDR)
961       goto dontchase;
962 
963 #  if defined(VGA_s390x)
964    /* Never chase into an EX instruction. Generating IR for EX causes
965       a round-trip through the scheduler including VG_(discard_translations).
966       And that's expensive as shown by perf/tinycc.c:
967       Chasing into EX increases the number of EX translations from 21 to
968       102666 causing a 7x runtime increase for "none" and a 3.2x runtime
969       increase for memcheck. */
970    if (((UChar *)addr)[0] == 0x44 ||   /* EX */
971        ((UChar *)addr)[0] == 0xC6)     /* EXRL */
972       goto dontchase;
973 #  endif
974 
975    /* well, ok then.  go on and chase. */
976    return True;
977 
978    vg_assert(0);
979    /*NOTREACHED*/
980 
981   dontchase:
982    if (0) VG_(printf)("not chasing into 0x%lx\n", addr);
983    return False;
984 }
985 
986 
987 /* --------------- helpers for with-TOC platforms --------------- */
988 
989 /* NOTE: with-TOC platforms are: ppc64-linux. */
990 
mkU64(ULong n)991 static IRExpr* mkU64 ( ULong n ) {
992    return IRExpr_Const(IRConst_U64(n));
993 }
mkU32(UInt n)994 static IRExpr* mkU32 ( UInt n ) {
995    return IRExpr_Const(IRConst_U32(n));
996 }
997 
998 #if defined(VG_PLAT_USES_PPCTOC) || defined(VGP_ppc64le_linux)
mkU8(UChar n)999 static IRExpr* mkU8 ( UChar n ) {
1000    return IRExpr_Const(IRConst_U8(n));
1001 }
narrowTo32(IRTypeEnv * tyenv,IRExpr * e)1002 static IRExpr* narrowTo32 ( IRTypeEnv* tyenv, IRExpr* e ) {
1003    if (typeOfIRExpr(tyenv, e) == Ity_I32) {
1004       return e;
1005    } else {
1006       vg_assert(typeOfIRExpr(tyenv, e) == Ity_I64);
1007       return IRExpr_Unop(Iop_64to32, e);
1008    }
1009 }
1010 
1011 /* Generate code to push word-typed expression 'e' onto this thread's
1012    redir stack, checking for stack overflow and generating code to
1013    bomb out if so. */
1014 
gen_PUSH(IRSB * bb,IRExpr * e)1015 static void gen_PUSH ( IRSB* bb, IRExpr* e )
1016 {
1017    IRRegArray* descr;
1018    IRTemp      t1;
1019    IRExpr*     one;
1020 
1021 #  if defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
1022    Int    stack_size       = VEX_GUEST_PPC64_REDIR_STACK_SIZE;
1023    Int    offB_REDIR_SP    = offsetof(VexGuestPPC64State,guest_REDIR_SP);
1024    Int    offB_REDIR_STACK = offsetof(VexGuestPPC64State,guest_REDIR_STACK);
1025    Int    offB_EMNOTE      = offsetof(VexGuestPPC64State,guest_EMNOTE);
1026    Int    offB_CIA         = offsetof(VexGuestPPC64State,guest_CIA);
1027    Bool   is64             = True;
1028    IRType ty_Word          = Ity_I64;
1029    IROp   op_CmpNE         = Iop_CmpNE64;
1030    IROp   op_Sar           = Iop_Sar64;
1031    IROp   op_Sub           = Iop_Sub64;
1032    IROp   op_Add           = Iop_Add64;
1033    IRExpr*(*mkU)(ULong)    = mkU64;
1034    vg_assert(VG_WORDSIZE == 8);
1035 #  else
1036    Int    stack_size       = VEX_GUEST_PPC32_REDIR_STACK_SIZE;
1037    Int    offB_REDIR_SP    = offsetof(VexGuestPPC32State,guest_REDIR_SP);
1038    Int    offB_REDIR_STACK = offsetof(VexGuestPPC32State,guest_REDIR_STACK);
1039    Int    offB_EMNOTE      = offsetof(VexGuestPPC32State,guest_EMNOTE);
1040    Int    offB_CIA         = offsetof(VexGuestPPC32State,guest_CIA);
1041    Bool   is64             = False;
1042    IRType ty_Word          = Ity_I32;
1043    IROp   op_CmpNE         = Iop_CmpNE32;
1044    IROp   op_Sar           = Iop_Sar32;
1045    IROp   op_Sub           = Iop_Sub32;
1046    IROp   op_Add           = Iop_Add32;
1047    IRExpr*(*mkU)(UInt)     = mkU32;
1048    vg_assert(VG_WORDSIZE == 4);
1049 #  endif
1050 
1051    vg_assert(sizeof(void*) == VG_WORDSIZE);
1052    vg_assert(sizeof(Word)  == VG_WORDSIZE);
1053    vg_assert(sizeof(Addr)  == VG_WORDSIZE);
1054 
1055    descr = mkIRRegArray( offB_REDIR_STACK, ty_Word, stack_size );
1056    t1    = newIRTemp( bb->tyenv, ty_Word );
1057    one   = mkU(1);
1058 
1059    vg_assert(typeOfIRExpr(bb->tyenv, e) == ty_Word);
1060 
1061    /* t1 = guest_REDIR_SP + 1 */
1062    addStmtToIRSB(
1063       bb,
1064       IRStmt_WrTmp(
1065          t1,
1066          IRExpr_Binop(op_Add, IRExpr_Get( offB_REDIR_SP, ty_Word ), one)
1067       )
1068    );
1069 
1070    /* Bomb out if t1 >=s stack_size, that is, (stack_size-1)-t1 <s 0.
1071       The destination (0) is a bit bogus but it doesn't matter since
1072       this is an unrecoverable error and will lead to Valgrind
1073       shutting down.  _EMNOTE is set regardless - that's harmless
1074       since is only has a meaning if the exit is taken. */
1075    addStmtToIRSB(
1076       bb,
1077       IRStmt_Put(offB_EMNOTE, mkU32(EmWarn_PPC64_redir_overflow))
1078    );
1079    addStmtToIRSB(
1080       bb,
1081       IRStmt_Exit(
1082          IRExpr_Binop(
1083             op_CmpNE,
1084             IRExpr_Binop(
1085                op_Sar,
1086                IRExpr_Binop(op_Sub,mkU(stack_size-1),IRExpr_RdTmp(t1)),
1087                mkU8(8 * VG_WORDSIZE - 1)
1088             ),
1089             mkU(0)
1090          ),
1091          Ijk_EmFail,
1092          is64 ? IRConst_U64(0) : IRConst_U32(0),
1093          offB_CIA
1094       )
1095    );
1096 
1097    /* guest_REDIR_SP = t1 */
1098    addStmtToIRSB(bb, IRStmt_Put(offB_REDIR_SP, IRExpr_RdTmp(t1)));
1099 
1100    /* guest_REDIR_STACK[t1+0] = e */
1101    /* PutI/GetI have I32-typed indexes regardless of guest word size */
1102    addStmtToIRSB(
1103       bb,
1104       IRStmt_PutI(mkIRPutI(descr,
1105                            narrowTo32(bb->tyenv,IRExpr_RdTmp(t1)), 0, e)));
1106 }
1107 
1108 
1109 /* Generate code to pop a word-sized value from this thread's redir
1110    stack, binding it to a new temporary, which is returned.  As with
1111    gen_PUSH, an overflow check is also performed. */
1112 
gen_POP(IRSB * bb)1113 static IRTemp gen_POP ( IRSB* bb )
1114 {
1115 #  if defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
1116    Int    stack_size       = VEX_GUEST_PPC64_REDIR_STACK_SIZE;
1117    Int    offB_REDIR_SP    = offsetof(VexGuestPPC64State,guest_REDIR_SP);
1118    Int    offB_REDIR_STACK = offsetof(VexGuestPPC64State,guest_REDIR_STACK);
1119    Int    offB_EMNOTE      = offsetof(VexGuestPPC64State,guest_EMNOTE);
1120    Int    offB_CIA         = offsetof(VexGuestPPC64State,guest_CIA);
1121    Bool   is64             = True;
1122    IRType ty_Word          = Ity_I64;
1123    IROp   op_CmpNE         = Iop_CmpNE64;
1124    IROp   op_Sar           = Iop_Sar64;
1125    IROp   op_Sub           = Iop_Sub64;
1126    IRExpr*(*mkU)(ULong)    = mkU64;
1127 #  else
1128    Int    stack_size       = VEX_GUEST_PPC32_REDIR_STACK_SIZE;
1129    Int    offB_REDIR_SP    = offsetof(VexGuestPPC32State,guest_REDIR_SP);
1130    Int    offB_REDIR_STACK = offsetof(VexGuestPPC32State,guest_REDIR_STACK);
1131    Int    offB_EMNOTE      = offsetof(VexGuestPPC32State,guest_EMNOTE);
1132    Int    offB_CIA         = offsetof(VexGuestPPC32State,guest_CIA);
1133    Bool   is64             = False;
1134    IRType ty_Word          = Ity_I32;
1135    IROp   op_CmpNE         = Iop_CmpNE32;
1136    IROp   op_Sar           = Iop_Sar32;
1137    IROp   op_Sub           = Iop_Sub32;
1138    IRExpr*(*mkU)(UInt)     = mkU32;
1139 #  endif
1140 
1141    IRRegArray* descr = mkIRRegArray( offB_REDIR_STACK, ty_Word, stack_size );
1142    IRTemp      t1    = newIRTemp( bb->tyenv, ty_Word );
1143    IRTemp      res   = newIRTemp( bb->tyenv, ty_Word );
1144    IRExpr*     one   = mkU(1);
1145 
1146    vg_assert(sizeof(void*) == VG_WORDSIZE);
1147    vg_assert(sizeof(Word)  == VG_WORDSIZE);
1148    vg_assert(sizeof(Addr)  == VG_WORDSIZE);
1149 
1150    /* t1 = guest_REDIR_SP */
1151    addStmtToIRSB(
1152       bb,
1153       IRStmt_WrTmp( t1, IRExpr_Get( offB_REDIR_SP, ty_Word ) )
1154    );
1155 
1156    /* Bomb out if t1 < 0.  Same comments as gen_PUSH apply. */
1157    addStmtToIRSB(
1158       bb,
1159       IRStmt_Put(offB_EMNOTE, mkU32(EmWarn_PPC64_redir_underflow))
1160    );
1161    addStmtToIRSB(
1162       bb,
1163       IRStmt_Exit(
1164          IRExpr_Binop(
1165             op_CmpNE,
1166             IRExpr_Binop(
1167                op_Sar,
1168                IRExpr_RdTmp(t1),
1169                mkU8(8 * VG_WORDSIZE - 1)
1170             ),
1171             mkU(0)
1172          ),
1173          Ijk_EmFail,
1174          is64 ? IRConst_U64(0) : IRConst_U32(0),
1175          offB_CIA
1176       )
1177    );
1178 
1179    /* res = guest_REDIR_STACK[t1+0] */
1180    /* PutI/GetI have I32-typed indexes regardless of guest word size */
1181    addStmtToIRSB(
1182       bb,
1183       IRStmt_WrTmp(
1184          res,
1185          IRExpr_GetI(descr, narrowTo32(bb->tyenv,IRExpr_RdTmp(t1)), 0)
1186       )
1187    );
1188 
1189    /* guest_REDIR_SP = t1-1 */
1190    addStmtToIRSB(
1191       bb,
1192       IRStmt_Put(offB_REDIR_SP, IRExpr_Binop(op_Sub, IRExpr_RdTmp(t1), one))
1193    );
1194 
1195    return res;
1196 }
1197 
1198 #endif
1199 
1200 #if defined(VG_PLAT_USES_PPCTOC)
1201 
1202 /* Generate code to push LR and R2 onto this thread's redir stack,
1203    then set R2 to the new value (which is the TOC pointer to be used
1204    for the duration of the replacement function, as determined by
1205    m_debuginfo), and set LR to the magic return stub, so we get to
1206    intercept the return and restore R2 and L2 to the values saved
1207    here. */
1208 
gen_push_and_set_LR_R2(IRSB * bb,Addr new_R2_value)1209 static void gen_push_and_set_LR_R2 ( IRSB* bb, Addr new_R2_value )
1210 {
1211 #  if defined(VGP_ppc64be_linux)
1212    Addr   bogus_RA  = (Addr)&VG_(ppctoc_magic_redirect_return_stub);
1213    Int    offB_GPR2 = offsetof(VexGuestPPC64State,guest_GPR2);
1214    Int    offB_LR   = offsetof(VexGuestPPC64State,guest_LR);
1215    gen_PUSH( bb, IRExpr_Get(offB_LR,   Ity_I64) );
1216    gen_PUSH( bb, IRExpr_Get(offB_GPR2, Ity_I64) );
1217    addStmtToIRSB( bb, IRStmt_Put( offB_LR,   mkU64( bogus_RA )) );
1218    addStmtToIRSB( bb, IRStmt_Put( offB_GPR2, mkU64( new_R2_value )) );
1219 
1220 #  else
1221 #    error Platform is not TOC-afflicted, fortunately
1222 #  endif
1223 }
1224 #endif
1225 
1226 #if defined(VG_PLAT_USES_PPCTOC) || defined(VGP_ppc64le_linux)
1227 
gen_pop_R2_LR_then_bLR(IRSB * bb)1228 static void gen_pop_R2_LR_then_bLR ( IRSB* bb )
1229 {
1230 #  if defined(VGP_ppc64be_linux)  || defined(VGP_ppc64le_linux)
1231    Int    offB_GPR2 = offsetof(VexGuestPPC64State,guest_GPR2);
1232    Int    offB_LR   = offsetof(VexGuestPPC64State,guest_LR);
1233    Int    offB_CIA  = offsetof(VexGuestPPC64State,guest_CIA);
1234    IRTemp old_R2    = newIRTemp( bb->tyenv, Ity_I64 );
1235    IRTemp old_LR    = newIRTemp( bb->tyenv, Ity_I64 );
1236    /* Restore R2 */
1237    old_R2 = gen_POP( bb );
1238    addStmtToIRSB( bb, IRStmt_Put( offB_GPR2, IRExpr_RdTmp(old_R2)) );
1239    /* Restore LR */
1240    old_LR = gen_POP( bb );
1241    addStmtToIRSB( bb, IRStmt_Put( offB_LR, IRExpr_RdTmp(old_LR)) );
1242    /* Branch to LR */
1243    /* re boring, we arrived here precisely because a wrapped fn did a
1244       blr (hence Ijk_Ret); so we should just mark this jump as Boring,
1245       else one _Call will have resulted in two _Rets. */
1246    bb->jumpkind = Ijk_Boring;
1247    bb->next     = IRExpr_Binop(Iop_And64, IRExpr_RdTmp(old_LR), mkU64(~(3ULL)));
1248    bb->offsIP   = offB_CIA;
1249 #  else
1250 #    error Platform is not TOC-afflicted, fortunately
1251 #  endif
1252 }
1253 #endif
1254 
1255 #if defined(VG_PLAT_USES_PPCTOC) || defined(VGP_ppc64le_linux)
1256 
1257 static
mk_preamble__ppctoc_magic_return_stub(void * closureV,IRSB * bb)1258 Bool mk_preamble__ppctoc_magic_return_stub ( void* closureV, IRSB* bb )
1259 {
1260    VgCallbackClosure* closure = (VgCallbackClosure*)closureV;
1261    /* Since we're creating the entire IRSB right here, give it a
1262       proper IMark, as it won't get one any other way, and cachegrind
1263       will barf if it doesn't have one (fair enough really). */
1264    addStmtToIRSB( bb, IRStmt_IMark( closure->readdr, 4, 0 ) );
1265    /* Generate the magic sequence:
1266          pop R2 from hidden stack
1267          pop LR from hidden stack
1268          goto LR
1269    */
1270    gen_pop_R2_LR_then_bLR(bb);
1271    return True; /* True == this is the entire BB; don't disassemble any
1272                    real insns into it - just hand it directly to
1273                    optimiser/instrumenter/backend. */
1274 }
1275 #endif
1276 
1277 #if defined(VGP_ppc64le_linux)
1278 /* Generate code to push LR and R2 onto this thread's redir stack.
1279    Need to save R2 in case we redirect to a global entry point.  The
1280    value of R2 is not preserved when entering the global entry point.
1281    Need to make sure R2 gets restored on return.  Set LR to the magic
1282    return stub, so we get to intercept the return and restore R2 and
1283    L2 to the values saved here.
1284 
1285    The existing infrastruture for the TOC enabled architectures is
1286    being exploited here.  So, we need to enable a number of the
1287    code sections used by VG_PLAT_USES_PPCTOC.
1288 */
1289 
gen_push_R2_and_set_LR(IRSB * bb)1290 static void gen_push_R2_and_set_LR ( IRSB* bb )
1291 {
1292    Addr   bogus_RA  = (Addr)&VG_(ppctoc_magic_redirect_return_stub);
1293    Int    offB_GPR2 = offsetof(VexGuestPPC64State,guest_GPR2);
1294    Int    offB_LR   = offsetof(VexGuestPPC64State,guest_LR);
1295    gen_PUSH( bb, IRExpr_Get(offB_LR,   Ity_I64) );
1296    gen_PUSH( bb, IRExpr_Get(offB_GPR2, Ity_I64) );
1297    addStmtToIRSB( bb, IRStmt_Put( offB_LR,   mkU64( bogus_RA )) );
1298 }
1299 #  endif
1300 
1301 /* --------------- END helpers for with-TOC platforms --------------- */
1302 
1303 
1304 /* This is the IR preamble generator used for replacement
1305    functions.  It adds code to set the guest_NRADDR{_GPR2} to zero
1306    (technically not necessary, but facilitates detecting mixups in
1307    which a replacement function has been erroneously declared using
1308    VG_REPLACE_FUNCTION_Z{U,Z} when instead it should have been written
1309    using VG_WRAP_FUNCTION_Z{U,Z}).
1310 
1311    On with-TOC platforms the follow hacks are also done: LR and R2 are
1312    pushed onto a hidden stack, R2 is set to the correct value for the
1313    replacement function, and LR is set to point at the magic
1314    return-stub address.  Setting LR causes the return of the
1315    wrapped/redirected function to lead to our magic return stub, which
1316    restores LR and R2 from said stack and returns for real.
1317 
1318    VG_(get_StackTrace_wrk) understands that the LR value may point to
1319    the return stub address, and that in that case it can get the real
1320    LR value from the hidden stack instead. */
1321 static
mk_preamble__set_NRADDR_to_zero(void * closureV,IRSB * bb)1322 Bool mk_preamble__set_NRADDR_to_zero ( void* closureV, IRSB* bb )
1323 {
1324    Int nraddr_szB
1325       = sizeof(((VexGuestArchState*)0)->guest_NRADDR);
1326    vg_assert(nraddr_szB == 4 || nraddr_szB == 8);
1327    vg_assert(nraddr_szB == VG_WORDSIZE);
1328    addStmtToIRSB(
1329       bb,
1330       IRStmt_Put(
1331          offsetof(VexGuestArchState,guest_NRADDR),
1332          nraddr_szB == 8 ? mkU64(0) : mkU32(0)
1333       )
1334    );
1335    // t9 needs to be set to point to the start of the redirected function.
1336 #  if defined(VGP_mips32_linux)
1337    VgCallbackClosure* closure = (VgCallbackClosure*)closureV;
1338    Int offB_GPR25 = offsetof(VexGuestMIPS32State, guest_r25);
1339    addStmtToIRSB(bb, IRStmt_Put(offB_GPR25, mkU32(closure->readdr)));
1340 #  endif
1341 #  if defined(VGP_mips64_linux)
1342    VgCallbackClosure* closure = (VgCallbackClosure*)closureV;
1343    Int offB_GPR25 = offsetof(VexGuestMIPS64State, guest_r25);
1344    addStmtToIRSB(bb, IRStmt_Put(offB_GPR25, mkU64(closure->readdr)));
1345 #  endif
1346 #  if defined(VG_PLAT_USES_PPCTOC)
1347    { VgCallbackClosure* closure = (VgCallbackClosure*)closureV;
1348      addStmtToIRSB(
1349         bb,
1350         IRStmt_Put(
1351            offsetof(VexGuestArchState,guest_NRADDR_GPR2),
1352            VG_WORDSIZE==8 ? mkU64(0) : mkU32(0)
1353         )
1354      );
1355      gen_push_and_set_LR_R2 ( bb, VG_(get_tocptr)( closure->readdr ) );
1356    }
1357 #  endif
1358 
1359 #if defined(VGP_ppc64le_linux)
1360    VgCallbackClosure* closure = (VgCallbackClosure*)closureV;
1361    Int offB_GPR12 = offsetof(VexGuestArchState, guest_GPR12);
1362    addStmtToIRSB(bb, IRStmt_Put(offB_GPR12, mkU64(closure->readdr)));
1363    addStmtToIRSB(bb,
1364       IRStmt_Put(
1365          offsetof(VexGuestArchState,guest_NRADDR_GPR2),
1366          VG_WORDSIZE==8 ? mkU64(0) : mkU32(0)
1367       )
1368    );
1369    gen_push_R2_and_set_LR ( bb );
1370 #endif
1371    return False;
1372 }
1373 
1374 /* Ditto, except set guest_NRADDR to nraddr (the un-redirected guest
1375    address).  This is needed for function wrapping - so the wrapper
1376    can read _NRADDR and find the address of the function being
1377    wrapped.  On toc-afflicted platforms we must also snarf r2. */
1378 static
mk_preamble__set_NRADDR_to_nraddr(void * closureV,IRSB * bb)1379 Bool mk_preamble__set_NRADDR_to_nraddr ( void* closureV, IRSB* bb )
1380 {
1381    VgCallbackClosure* closure = (VgCallbackClosure*)closureV;
1382    Int nraddr_szB
1383       = sizeof(((VexGuestArchState*)0)->guest_NRADDR);
1384    vg_assert(nraddr_szB == 4 || nraddr_szB == 8);
1385    vg_assert(nraddr_szB == VG_WORDSIZE);
1386    addStmtToIRSB(
1387       bb,
1388       IRStmt_Put(
1389          offsetof(VexGuestArchState,guest_NRADDR),
1390          nraddr_szB == 8
1391             ? IRExpr_Const(IRConst_U64( closure->nraddr ))
1392             : IRExpr_Const(IRConst_U32( (UInt)closure->nraddr ))
1393       )
1394    );
1395    // t9 needs to be set to point to the start of the redirected function.
1396 #  if defined(VGP_mips32_linux)
1397    Int offB_GPR25 = offsetof(VexGuestMIPS32State, guest_r25);
1398    addStmtToIRSB(bb, IRStmt_Put(offB_GPR25, mkU32(closure->readdr)));
1399 #  endif
1400 #  if defined(VGP_mips64_linux)
1401    Int offB_GPR25 = offsetof(VexGuestMIPS64State, guest_r25);
1402    addStmtToIRSB(bb, IRStmt_Put(offB_GPR25, mkU64(closure->readdr)));
1403 #  endif
1404 #  if defined(VG_PLAT_USES_PPCTOC)
1405    addStmtToIRSB(
1406       bb,
1407       IRStmt_Put(
1408          offsetof(VexGuestArchState,guest_NRADDR_GPR2),
1409          IRExpr_Get(offsetof(VexGuestArchState,guest_GPR2),
1410                     VG_WORDSIZE==8 ? Ity_I64 : Ity_I32)
1411       )
1412    );
1413    gen_push_and_set_LR_R2 ( bb, VG_(get_tocptr)( closure->readdr ) );
1414 #  endif
1415 #if defined(VGP_ppc64le_linux)
1416    /* This saves the r2 before leaving the function.  We need to move
1417     * guest_NRADDR_GPR2 back to R2 on return.
1418     */
1419    Int offB_GPR12 = offsetof(VexGuestArchState, guest_GPR12);
1420    addStmtToIRSB(
1421       bb,
1422       IRStmt_Put(
1423          offsetof(VexGuestArchState,guest_NRADDR_GPR2),
1424          IRExpr_Get(offsetof(VexGuestArchState,guest_GPR2),
1425                     VG_WORDSIZE==8 ? Ity_I64 : Ity_I32)
1426       )
1427    );
1428    addStmtToIRSB(bb, IRStmt_Put(offB_GPR12, mkU64(closure->readdr)));
1429    gen_push_R2_and_set_LR ( bb );
1430 #endif
1431    return False;
1432 }
1433 
1434 /* --- Helpers to do with PPC related stack redzones. --- */
1435 
1436 __attribute__((unused))
const_True(Addr guest_addr)1437 static Bool const_True ( Addr guest_addr )
1438 {
1439    return True;
1440 }
1441 
1442 /* --------------- main translation function --------------- */
1443 
1444 /* Note: see comments at top of m_redir.c for the Big Picture on how
1445    redirections are managed. */
1446 
1447 typedef
1448    enum {
1449       /* normal translation, redir neither requested nor inhibited */
1450       T_Normal,
1451       /* redir translation, function-wrap (set _NRADDR) style */
1452       T_Redir_Wrap,
1453       /* redir translation, replacement (don't set _NRADDR) style */
1454       T_Redir_Replace,
1455       /* a translation in which redir is specifically disallowed */
1456       T_NoRedir
1457    }
1458    T_Kind;
1459 
1460 /* Translate the basic block beginning at NRADDR, and add it to the
1461    translation cache & translation table.  Unless
1462    DEBUGGING_TRANSLATION is true, in which case the call is being done
1463    for debugging purposes, so (a) throw away the translation once it
1464    is made, and (b) produce a load of debugging output.  If
1465    ALLOW_REDIRECTION is False, do not attempt redirection of NRADDR,
1466    and also, put the resulting translation into the no-redirect tt/tc
1467    instead of the normal one.
1468 
1469    TID is the identity of the thread requesting this translation.
1470 */
1471 
VG_(translate)1472 Bool VG_(translate) ( ThreadId tid,
1473                       Addr     nraddr,
1474                       Bool     debugging_translation,
1475                       Int      debugging_verbosity,
1476                       ULong    bbs_done,
1477                       Bool     allow_redirection )
1478 {
1479    Addr               addr;
1480    T_Kind             kind;
1481    Int                tmpbuf_used, verbosity, i;
1482    Bool (*preamble_fn)(void*,IRSB*);
1483    VexArch            vex_arch;
1484    VexArchInfo        vex_archinfo;
1485    VexAbiInfo         vex_abiinfo;
1486    VexGuestExtents    vge;
1487    VexTranslateArgs   vta;
1488    VexTranslateResult tres;
1489    VgCallbackClosure  closure;
1490 
1491    /* Make sure Vex is initialised right. */
1492 
1493    static Bool vex_init_done = False;
1494 
1495    if (!vex_init_done) {
1496       LibVEX_Init ( &failure_exit, &log_bytes,
1497                     1,     /* debug_paranoia */
1498                     &VG_(clo_vex_control) );
1499       vex_init_done = True;
1500    }
1501 
1502    /* Establish the translation kind and actual guest address to
1503       start from.  Sets (addr,kind). */
1504    if (allow_redirection) {
1505       Bool isWrap;
1506       Addr tmp = VG_(redir_do_lookup)( nraddr, &isWrap );
1507       if (tmp == nraddr) {
1508          /* no redirection found */
1509          addr = nraddr;
1510          kind = T_Normal;
1511       } else {
1512          /* found a redirect */
1513          addr = tmp;
1514          kind = isWrap ? T_Redir_Wrap : T_Redir_Replace;
1515       }
1516    } else {
1517       addr = nraddr;
1518       kind = T_NoRedir;
1519    }
1520 
1521    /* Established: (nraddr, addr, kind) */
1522 
1523    /* Printing redirection info. */
1524 
1525    if ((kind == T_Redir_Wrap || kind == T_Redir_Replace)
1526        && (VG_(clo_verbosity) >= 2 || VG_(clo_trace_redir))) {
1527       Bool ok;
1528       const HChar *buf;
1529       const HChar *name2;
1530 
1531       /* Try also to get the soname (not the filename) of the "from"
1532          object.  This makes it much easier to debug redirection
1533          problems. */
1534       const HChar* nraddr_soname = "???";
1535       DebugInfo*   nraddr_di     = VG_(find_DebugInfo)(nraddr);
1536       if (nraddr_di) {
1537          const HChar* t = VG_(DebugInfo_get_soname)(nraddr_di);
1538          if (t)
1539             nraddr_soname = t;
1540       }
1541 
1542       ok = VG_(get_fnname_w_offset)(nraddr, &buf);
1543       if (!ok) buf = "???";
1544       // Stash away name1
1545       HChar name1[VG_(strlen)(buf) + 1];
1546       VG_(strcpy)(name1, buf);
1547       ok = VG_(get_fnname_w_offset)(addr, &name2);
1548       if (!ok) name2 = "???";
1549 
1550       VG_(message)(Vg_DebugMsg,
1551                    "REDIR: 0x%lx (%s:%s) redirected to 0x%lx (%s)\n",
1552                    nraddr, nraddr_soname, name1,
1553                    addr, name2 );
1554    }
1555 
1556    if (!debugging_translation)
1557       VG_TRACK( pre_mem_read, Vg_CoreTranslate,
1558                               tid, "(translator)", addr, 1 );
1559 
1560    /* If doing any code printing, print a basic block start marker */
1561    if (VG_(clo_trace_flags) || debugging_translation) {
1562       const HChar* objname = "UNKNOWN_OBJECT";
1563       OffT         objoff  = 0;
1564       DebugInfo*   di      = VG_(find_DebugInfo)( addr );
1565       if (di) {
1566          objname = VG_(DebugInfo_get_filename)(di);
1567          objoff  = addr - VG_(DebugInfo_get_text_bias)(di);
1568       }
1569       vg_assert(objname);
1570 
1571       const HChar *fnname;
1572       Bool ok = VG_(get_fnname_w_offset)(addr, &fnname);
1573       if (!ok) fnname = "UNKNOWN_FUNCTION";
1574       VG_(printf)(
1575          "==== SB %u (evchecks %llu) [tid %u] 0x%lx %s %s%c0x%lx\n",
1576          VG_(get_bbs_translated)(), bbs_done, tid, addr,
1577          fnname, objname, objoff >= 0 ? '+' : '-',
1578          (UWord)(objoff >= 0 ? objoff : -objoff)
1579       );
1580    }
1581 
1582    /* Are we allowed to translate here? */
1583 
1584    { /* BEGIN new scope specially for 'seg' */
1585    NSegment const* seg = VG_(am_find_nsegment)(addr);
1586 
1587    if ( (!translations_allowable_from_seg(seg, addr))
1588         || addr == TRANSTAB_BOGUS_GUEST_ADDR ) {
1589       if (VG_(clo_trace_signals))
1590          VG_(message)(Vg_DebugMsg, "translations not allowed here (0x%lx)"
1591                                    " - throwing SEGV\n", addr);
1592       /* U R busted, sonny.  Place your hands on your head and step
1593          away from the orig_addr. */
1594       /* Code address is bad - deliver a signal instead */
1595       if (seg != NULL) {
1596          /* There's some kind of segment at the requested place, but we
1597             aren't allowed to execute code here. */
1598          if (debugging_translation)
1599             VG_(printf)("translations not allowed here (segment not executable)"
1600                         "(0x%lx)\n", addr);
1601          else
1602             VG_(synth_fault_perms)(tid, addr);
1603       } else {
1604         /* There is no segment at all; we are attempting to execute in
1605            the middle of nowhere. */
1606          if (debugging_translation)
1607             VG_(printf)("translations not allowed here (no segment)"
1608                         "(0x%lx)\n", addr);
1609          else
1610             VG_(synth_fault_mapping)(tid, addr);
1611       }
1612       return False;
1613    }
1614 
1615    /* True if a debug trans., or if bit N set in VG_(clo_trace_codegen). */
1616    verbosity = 0;
1617    if (debugging_translation) {
1618       verbosity = debugging_verbosity;
1619    }
1620    else
1621    if ( (VG_(clo_trace_flags) > 0
1622         && VG_(get_bbs_translated)() <= VG_(clo_trace_notabove)
1623         && VG_(get_bbs_translated)() >= VG_(clo_trace_notbelow) )) {
1624       verbosity = VG_(clo_trace_flags);
1625    }
1626 
1627    /* Figure out which preamble-mangling callback to send. */
1628    preamble_fn = NULL;
1629    if (kind == T_Redir_Replace)
1630       preamble_fn = mk_preamble__set_NRADDR_to_zero;
1631    else
1632    if (kind == T_Redir_Wrap)
1633       preamble_fn = mk_preamble__set_NRADDR_to_nraddr;
1634 
1635    /* LE we setup the LR */
1636 #  if defined(VG_PLAT_USES_PPCTOC) || defined(VGP_ppc64le_linux)
1637    if (nraddr == (Addr)&VG_(ppctoc_magic_redirect_return_stub)) {
1638       /* If entering the special return stub, this means a wrapped or
1639          redirected function is returning.  Make this translation one
1640          which restores R2 and LR from the thread's hidden redir
1641          stack, and branch to the (restored) link register, thereby
1642          really causing the function to return. */
1643       vg_assert(kind == T_Normal);
1644       vg_assert(nraddr == addr);
1645       preamble_fn = mk_preamble__ppctoc_magic_return_stub;
1646    }
1647 #  endif
1648 
1649    /* ------ Actually do the translation. ------ */
1650    vg_assert2(VG_(tdict).tool_instrument,
1651               "you forgot to set VgToolInterface function 'tool_instrument'");
1652 
1653    /* Get the CPU info established at startup. */
1654    VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
1655 
1656    /* Set up 'abiinfo' structure with stuff Vex needs to know about
1657       the guest and host ABIs. */
1658 
1659    LibVEX_default_VexAbiInfo( &vex_abiinfo );
1660    vex_abiinfo.guest_stack_redzone_size = VG_STACK_REDZONE_SZB;
1661 
1662 #  if defined(VGP_amd64_linux)
1663    vex_abiinfo.guest_amd64_assume_fs_is_const = True;
1664    vex_abiinfo.guest_amd64_assume_gs_is_const = True;
1665 #  endif
1666 
1667 #  if defined(VGP_amd64_darwin)
1668    vex_abiinfo.guest_amd64_assume_gs_is_const = True;
1669 #  endif
1670 
1671 #  if defined(VGP_amd64_solaris)
1672    vex_abiinfo.guest_amd64_assume_fs_is_const = True;
1673 #  endif
1674 
1675 #  if defined(VGP_ppc32_linux)
1676    vex_abiinfo.guest_ppc_zap_RZ_at_blr        = False;
1677    vex_abiinfo.guest_ppc_zap_RZ_at_bl         = NULL;
1678 #  endif
1679 
1680 #  if defined(VGP_ppc64be_linux)
1681    vex_abiinfo.guest_ppc_zap_RZ_at_blr        = True;
1682    vex_abiinfo.guest_ppc_zap_RZ_at_bl         = const_True;
1683    vex_abiinfo.host_ppc_calls_use_fndescrs    = True;
1684 #  endif
1685 
1686 #  if defined(VGP_ppc64le_linux)
1687    vex_abiinfo.guest_ppc_zap_RZ_at_blr        = True;
1688    vex_abiinfo.guest_ppc_zap_RZ_at_bl         = const_True;
1689    vex_abiinfo.host_ppc_calls_use_fndescrs    = False;
1690 #  endif
1691 
1692 #  if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
1693    ThreadArchState* arch = &VG_(threads)[tid].arch;
1694    vex_abiinfo.guest_mips_fp_mode64 =
1695       !!(arch->vex.guest_CP0_status & MIPS_CP0_STATUS_FR);
1696    /* Compute guest__use_fallback_LLSC, overiding any settings of
1697       VG_(clo_fallback_llsc) that we know would cause the guest to
1698       fail (loop). */
1699    if (VEX_MIPS_COMP_ID(vex_archinfo.hwcaps) == VEX_PRID_COMP_CAVIUM) {
1700       /* We must use the fallback scheme. */
1701       vex_abiinfo.guest__use_fallback_LLSC = True;
1702    } else {
1703       vex_abiinfo.guest__use_fallback_LLSC
1704          = SimHintiS(SimHint_fallback_llsc, VG_(clo_sim_hints));
1705    }
1706 #  endif
1707 
1708 #  if defined(VGP_arm64_linux)
1709    vex_abiinfo.guest__use_fallback_LLSC
1710       = /* The user asked explicitly */
1711         SimHintiS(SimHint_fallback_llsc, VG_(clo_sim_hints))
1712         || /* we autodetected that it is necessary */
1713            vex_archinfo.arm64_requires_fallback_LLSC;
1714 #  endif
1715 
1716    /* Set up closure args. */
1717    closure.tid    = tid;
1718    closure.nraddr = nraddr;
1719    closure.readdr = addr;
1720 
1721    /* Set up args for LibVEX_Translate. */
1722    vta.arch_guest       = vex_arch;
1723    vta.archinfo_guest   = vex_archinfo;
1724    vta.arch_host        = vex_arch;
1725    vta.archinfo_host    = vex_archinfo;
1726    vta.abiinfo_both     = vex_abiinfo;
1727    vta.callback_opaque  = (void*)&closure;
1728    vta.guest_bytes      = (UChar*)addr;
1729    vta.guest_bytes_addr = addr;
1730    vta.chase_into_ok    = chase_into_ok;
1731    vta.guest_extents    = &vge;
1732    vta.host_bytes       = tmpbuf;
1733    vta.host_bytes_size  = N_TMPBUF;
1734    vta.host_bytes_used  = &tmpbuf_used;
1735    { /* At this point we have to reconcile Vex's view of the
1736         instrumentation callback - which takes a void* first argument
1737         - with Valgrind's view, in which the first arg is a
1738         VgCallbackClosure*.  Hence the following longwinded casts.
1739         They are entirely legal but longwinded so as to maximise the
1740         chance of the C typechecker picking up any type snafus. */
1741      IRSB*(*f)(VgCallbackClosure*,
1742                IRSB*,const VexGuestLayout*,const VexGuestExtents*,
1743                const VexArchInfo*,IRType,IRType)
1744         = VG_(clo_vgdb) != Vg_VgdbNo
1745              ? tool_instrument_then_gdbserver_if_needed
1746              : VG_(tdict).tool_instrument;
1747      IRSB*(*g)(void*,
1748                IRSB*,const VexGuestLayout*,const VexGuestExtents*,
1749                const VexArchInfo*,IRType,IRType) = (__typeof__(g)) f;
1750      vta.instrument1     = g;
1751    }
1752    /* No need for type kludgery here. */
1753    vta.instrument2       = need_to_handle_SP_assignment()
1754                               ? vg_SP_update_pass
1755                               : NULL;
1756    vta.finaltidy         = VG_(needs).final_IR_tidy_pass
1757                               ? VG_(tdict).tool_final_IR_tidy_pass
1758                               : NULL;
1759    vta.needs_self_check  = needs_self_check;
1760    vta.preamble_function = preamble_fn;
1761    vta.traceflags        = verbosity;
1762    vta.sigill_diag       = VG_(clo_sigill_diag);
1763    vta.addProfInc        = VG_(clo_profyle_sbs) && kind != T_NoRedir;
1764 
1765    /* Set up the dispatch continuation-point info.  If this is a
1766       no-redir translation then it cannot be chained, and the chain-me
1767       points are set to NULL to indicate that.  The indir point must
1768       also be NULL, since we can't allow this translation to do an
1769       indir transfer -- that would take it back into the main
1770       translation cache too.
1771 
1772       All this is because no-redir translations live outside the main
1773       translation cache (in a secondary one) and chaining them would
1774       involve more adminstrative complexity that isn't worth the
1775       hassle, because we don't expect them to get used often.  So
1776       don't bother. */
1777    if (allow_redirection) {
1778       vta.disp_cp_chain_me_to_slowEP
1779          = VG_(fnptr_to_fnentry)( &VG_(disp_cp_chain_me_to_slowEP) );
1780       vta.disp_cp_chain_me_to_fastEP
1781          = VG_(fnptr_to_fnentry)( &VG_(disp_cp_chain_me_to_fastEP) );
1782       vta.disp_cp_xindir
1783          = VG_(fnptr_to_fnentry)( &VG_(disp_cp_xindir) );
1784    } else {
1785       vta.disp_cp_chain_me_to_slowEP = NULL;
1786       vta.disp_cp_chain_me_to_fastEP = NULL;
1787       vta.disp_cp_xindir             = NULL;
1788    }
1789    /* This doesn't involve chaining and so is always allowable. */
1790    vta.disp_cp_xassisted
1791       = VG_(fnptr_to_fnentry)( &VG_(disp_cp_xassisted) );
1792 
1793    /* Sheesh.  Finally, actually _do_ the translation! */
1794    tres = LibVEX_Translate ( &vta );
1795 
1796    vg_assert(tres.status == VexTransOK);
1797    vg_assert(tres.n_sc_extents >= 0 && tres.n_sc_extents <= 3);
1798    vg_assert(tmpbuf_used <= N_TMPBUF);
1799    vg_assert(tmpbuf_used > 0);
1800    } /* END new scope specially for 'seg' */
1801 
1802    /* Tell aspacem of all segments that have had translations taken
1803       from them. */
1804    for (i = 0; i < vge.n_used; i++) {
1805       VG_(am_set_segment_hasT)( vge.base[i] );
1806    }
1807 
1808    /* Copy data at trans_addr into the translation cache. */
1809    vg_assert(tmpbuf_used > 0 && tmpbuf_used < 65536);
1810 
1811    // If debugging, don't do anything with the translated block;  we
1812    // only did this for the debugging output produced along the way.
1813    if (!debugging_translation) {
1814 
1815       if (kind != T_NoRedir) {
1816           // Put it into the normal TT/TC structures.  This is the
1817           // normal case.
1818 
1819           // Note that we use nraddr (the non-redirected address), not
1820           // addr, which might have been changed by the redirection
1821           VG_(add_to_transtab)( &vge,
1822                                 nraddr,
1823                                 (Addr)(&tmpbuf[0]),
1824                                 tmpbuf_used,
1825                                 tres.n_sc_extents > 0,
1826                                 tres.offs_profInc,
1827                                 tres.n_guest_instrs );
1828       } else {
1829           vg_assert(tres.offs_profInc == -1); /* -1 == unset */
1830           VG_(add_to_unredir_transtab)( &vge,
1831                                         nraddr,
1832                                         (Addr)(&tmpbuf[0]),
1833                                         tmpbuf_used );
1834       }
1835    }
1836 
1837    return True;
1838 }
1839 
1840 /*--------------------------------------------------------------------*/
1841 /*--- end                                                          ---*/
1842 /*--------------------------------------------------------------------*/
1843