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-2015 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
69static ULong n_SP_updates_fast            = 0;
70static ULong n_SP_updates_generic_known   = 0;
71static ULong n_SP_updates_generic_unknown = 0;
72
73static ULong n_PX_VexRegUpdSpAtMemAccess         = 0;
74static ULong n_PX_VexRegUpdUnwindregsAtMemAccess = 0;
75static ULong n_PX_VexRegUpdAllregsAtMemAccess    = 0;
76static ULong n_PX_VexRegUpdAllregsAtEachInsn     = 0;
77
78void 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
108static 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
145typedef
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
155static SP_Alias SP_aliases[N_ALIASES];
156static Int      next_SP_alias_slot = 0;
157
158static 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
168static 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
177static 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
198static 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. */
212static 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*/
229static
230IRSB* 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*/
270static
271IRSB* 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
730static 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))
736static
737void failure_exit ( void )
738{
739   LibVEX_ShowAllocStats();
740   VG_(core_panic)("LibVEX called failure_exit().");
741}
742
743static
744void 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
760static 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) || defined(VGA_tilegx)
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
788static 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*/
936static 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
991static IRExpr* mkU64 ( ULong n ) {
992   return IRExpr_Const(IRConst_U64(n));
993}
994static IRExpr* mkU32 ( UInt n ) {
995   return IRExpr_Const(IRConst_U32(n));
996}
997
998#if defined(VG_PLAT_USES_PPCTOC) || defined(VGP_ppc64le_linux)
999static IRExpr* mkU8 ( UChar n ) {
1000   return IRExpr_Const(IRConst_U8(n));
1001}
1002static 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
1015static 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
1113static 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
1209static 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
1228static 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
1257static
1258Bool 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
1290static 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. */
1321static
1322Bool 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. */
1378static
1379Bool 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))
1437static 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
1447typedef
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
1472Bool 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#  if defined(VGP_amd64_darwin)
1667   vex_abiinfo.guest_amd64_assume_gs_is_const = True;
1668#  endif
1669#  if defined(VGP_ppc32_linux)
1670   vex_abiinfo.guest_ppc_zap_RZ_at_blr        = False;
1671   vex_abiinfo.guest_ppc_zap_RZ_at_bl         = NULL;
1672#  endif
1673#  if defined(VGP_ppc64be_linux)
1674   vex_abiinfo.guest_ppc_zap_RZ_at_blr        = True;
1675   vex_abiinfo.guest_ppc_zap_RZ_at_bl         = const_True;
1676   vex_abiinfo.host_ppc_calls_use_fndescrs    = True;
1677#  endif
1678#  if defined(VGP_ppc64le_linux)
1679   vex_abiinfo.guest_ppc_zap_RZ_at_blr        = True;
1680   vex_abiinfo.guest_ppc_zap_RZ_at_bl         = const_True;
1681   vex_abiinfo.host_ppc_calls_use_fndescrs    = False;
1682#  endif
1683#  if defined(VGP_amd64_solaris)
1684   vex_abiinfo.guest_amd64_assume_fs_is_const = True;
1685#  endif
1686
1687   /* Set up closure args. */
1688   closure.tid    = tid;
1689   closure.nraddr = nraddr;
1690   closure.readdr = addr;
1691
1692   /* Set up args for LibVEX_Translate. */
1693   vta.arch_guest       = vex_arch;
1694   vta.archinfo_guest   = vex_archinfo;
1695   vta.arch_host        = vex_arch;
1696   vta.archinfo_host    = vex_archinfo;
1697   vta.abiinfo_both     = vex_abiinfo;
1698   vta.callback_opaque  = (void*)&closure;
1699   vta.guest_bytes      = (UChar*)addr;
1700   vta.guest_bytes_addr = addr;
1701   vta.chase_into_ok    = chase_into_ok;
1702   vta.guest_extents    = &vge;
1703   vta.host_bytes       = tmpbuf;
1704   vta.host_bytes_size  = N_TMPBUF;
1705   vta.host_bytes_used  = &tmpbuf_used;
1706   { /* At this point we have to reconcile Vex's view of the
1707        instrumentation callback - which takes a void* first argument
1708        - with Valgrind's view, in which the first arg is a
1709        VgCallbackClosure*.  Hence the following longwinded casts.
1710        They are entirely legal but longwinded so as to maximise the
1711        chance of the C typechecker picking up any type snafus. */
1712     IRSB*(*f)(VgCallbackClosure*,
1713               IRSB*,const VexGuestLayout*,const VexGuestExtents*,
1714               const VexArchInfo*,IRType,IRType)
1715        = VG_(clo_vgdb) != Vg_VgdbNo
1716             ? tool_instrument_then_gdbserver_if_needed
1717             : VG_(tdict).tool_instrument;
1718     IRSB*(*g)(void*,
1719               IRSB*,const VexGuestLayout*,const VexGuestExtents*,
1720               const VexArchInfo*,IRType,IRType) = (__typeof__(g)) f;
1721     vta.instrument1     = g;
1722   }
1723   /* No need for type kludgery here. */
1724   vta.instrument2       = need_to_handle_SP_assignment()
1725                              ? vg_SP_update_pass
1726                              : NULL;
1727   vta.finaltidy         = VG_(needs).final_IR_tidy_pass
1728                              ? VG_(tdict).tool_final_IR_tidy_pass
1729                              : NULL;
1730   vta.needs_self_check  = needs_self_check;
1731   vta.preamble_function = preamble_fn;
1732   vta.traceflags        = verbosity;
1733   vta.sigill_diag       = VG_(clo_sigill_diag);
1734   vta.addProfInc        = VG_(clo_profyle_sbs) && kind != T_NoRedir;
1735
1736   /* Set up the dispatch continuation-point info.  If this is a
1737      no-redir translation then it cannot be chained, and the chain-me
1738      points are set to NULL to indicate that.  The indir point must
1739      also be NULL, since we can't allow this translation to do an
1740      indir transfer -- that would take it back into the main
1741      translation cache too.
1742
1743      All this is because no-redir translations live outside the main
1744      translation cache (in a secondary one) and chaining them would
1745      involve more adminstrative complexity that isn't worth the
1746      hassle, because we don't expect them to get used often.  So
1747      don't bother. */
1748   if (allow_redirection) {
1749      vta.disp_cp_chain_me_to_slowEP
1750         = VG_(fnptr_to_fnentry)( &VG_(disp_cp_chain_me_to_slowEP) );
1751      vta.disp_cp_chain_me_to_fastEP
1752         = VG_(fnptr_to_fnentry)( &VG_(disp_cp_chain_me_to_fastEP) );
1753      vta.disp_cp_xindir
1754         = VG_(fnptr_to_fnentry)( &VG_(disp_cp_xindir) );
1755   } else {
1756      vta.disp_cp_chain_me_to_slowEP = NULL;
1757      vta.disp_cp_chain_me_to_fastEP = NULL;
1758      vta.disp_cp_xindir             = NULL;
1759   }
1760   /* This doesn't involve chaining and so is always allowable. */
1761   vta.disp_cp_xassisted
1762      = VG_(fnptr_to_fnentry)( &VG_(disp_cp_xassisted) );
1763
1764   /* Sheesh.  Finally, actually _do_ the translation! */
1765   tres = LibVEX_Translate ( &vta );
1766
1767   vg_assert(tres.status == VexTransOK);
1768   vg_assert(tres.n_sc_extents >= 0 && tres.n_sc_extents <= 3);
1769   vg_assert(tmpbuf_used <= N_TMPBUF);
1770   vg_assert(tmpbuf_used > 0);
1771   } /* END new scope specially for 'seg' */
1772
1773   /* Tell aspacem of all segments that have had translations taken
1774      from them. */
1775   for (i = 0; i < vge.n_used; i++) {
1776      VG_(am_set_segment_hasT)( vge.base[i] );
1777   }
1778
1779   /* Copy data at trans_addr into the translation cache. */
1780   vg_assert(tmpbuf_used > 0 && tmpbuf_used < 65536);
1781
1782   // If debugging, don't do anything with the translated block;  we
1783   // only did this for the debugging output produced along the way.
1784   if (!debugging_translation) {
1785
1786      if (kind != T_NoRedir) {
1787          // Put it into the normal TT/TC structures.  This is the
1788          // normal case.
1789
1790          // Note that we use nraddr (the non-redirected address), not
1791          // addr, which might have been changed by the redirection
1792          VG_(add_to_transtab)( &vge,
1793                                nraddr,
1794                                (Addr)(&tmpbuf[0]),
1795                                tmpbuf_used,
1796                                tres.n_sc_extents > 0,
1797                                tres.offs_profInc,
1798                                tres.n_guest_instrs );
1799      } else {
1800          vg_assert(tres.offs_profInc == -1); /* -1 == unset */
1801          VG_(add_to_unredir_transtab)( &vge,
1802                                        nraddr,
1803                                        (Addr)(&tmpbuf[0]),
1804                                        tmpbuf_used );
1805      }
1806   }
1807
1808   return True;
1809}
1810
1811/*--------------------------------------------------------------------*/
1812/*--- end                                                          ---*/
1813/*--------------------------------------------------------------------*/
1814