2 /*--------------------------------------------------------------------*/
3 /*--- Interface to LibVEX_Translate, and the SP-update pass ---*/
4 /*--- m_translate.c ---*/
5 /*--------------------------------------------------------------------*/
8 This file is part of Valgrind, a dynamic binary instrumentation
11 Copyright (C) 2000-2010 Julian Seward
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.
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.
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
29 The GNU General Public License is contained in the file COPYING.
32 #include "pub_core_basics.h"
33 #include "pub_core_vki.h"
34 #include "pub_core_aspacemgr.h"
36 #include "pub_core_machine.h" // VG_(fnptr_to_fnentry)
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"
44 #include "pub_core_debuginfo.h" // VG_(get_fnname_w_offset)
45 #include "pub_core_redir.h" // VG_(redir_do_lookup)
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)
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)
56 #include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy
57 #include "pub_core_threadstate.h" // VexGuestArchState
58 #include "pub_core_trampoline.h" // VG_(ppctoc_magic_redirect_return_stub)
60 #include "pub_core_execontext.h" // VG_(make_depth_1_ExeContext_from_Addr)
62 #include "pub_core_gdbserver.h" // VG_(tool_instrument_then_gdbserver_if_needed)
64 /*------------------------------------------------------------*/
66 /*------------------------------------------------------------*/
68 static UInt n_SP_updates_fast = 0;
69 static UInt n_SP_updates_generic_known = 0;
70 static UInt n_SP_updates_generic_unknown = 0;
72 void VG_(print_translation_stats) ( void )
75 UInt n_SP_updates = n_SP_updates_fast + n_SP_updates_generic_known
76 + n_SP_updates_generic_unknown;
77 VG_(percentify)(n_SP_updates_fast, n_SP_updates, 1, 6, buf);
78 VG_(message)(Vg_DebugMsg,
79 "translate: fast SP updates identified: %'u (%s)\n",
80 n_SP_updates_fast, buf );
82 VG_(percentify)(n_SP_updates_generic_known, n_SP_updates, 1, 6, buf);
83 VG_(message)(Vg_DebugMsg,
84 "translate: generic_known SP updates identified: %'u (%s)\n",
85 n_SP_updates_generic_known, buf );
87 VG_(percentify)(n_SP_updates_generic_unknown, n_SP_updates, 1, 6, buf);
88 VG_(message)(Vg_DebugMsg,
89 "translate: generic_unknown SP updates identified: %'u (%s)\n",
90 n_SP_updates_generic_unknown, buf );
93 /*------------------------------------------------------------*/
94 /*--- %SP-update pass ---*/
95 /*------------------------------------------------------------*/
97 static Bool need_to_handle_SP_assignment(void)
99 return ( VG_(tdict).track_new_mem_stack_4 ||
100 VG_(tdict).track_die_mem_stack_4 ||
101 VG_(tdict).track_new_mem_stack_8 ||
102 VG_(tdict).track_die_mem_stack_8 ||
103 VG_(tdict).track_new_mem_stack_12 ||
104 VG_(tdict).track_die_mem_stack_12 ||
105 VG_(tdict).track_new_mem_stack_16 ||
106 VG_(tdict).track_die_mem_stack_16 ||
107 VG_(tdict).track_new_mem_stack_32 ||
108 VG_(tdict).track_die_mem_stack_32 ||
109 VG_(tdict).track_new_mem_stack_112 ||
110 VG_(tdict).track_die_mem_stack_112 ||
111 VG_(tdict).track_new_mem_stack_128 ||
112 VG_(tdict).track_die_mem_stack_128 ||
113 VG_(tdict).track_new_mem_stack_144 ||
114 VG_(tdict).track_die_mem_stack_144 ||
115 VG_(tdict).track_new_mem_stack_160 ||
116 VG_(tdict).track_die_mem_stack_160 ||
117 VG_(tdict).track_new_mem_stack ||
118 VG_(tdict).track_die_mem_stack );
121 // - The SP aliases are held in an array which is used as a circular buffer.
122 // This misses very few constant updates of SP (ie. < 0.1%) while using a
123 // small, constant structure that will also never fill up and cause
124 // execution to abort.
125 // - Unused slots have a .temp value of 'IRTemp_INVALID'.
126 // - 'next_SP_alias_slot' is the index where the next alias will be stored.
127 // - If the buffer fills, we circle around and start over-writing
128 // non-IRTemp_INVALID values. This is rare, and the overwriting of a
129 // value that would have subsequently be used is even rarer.
130 // - Every slot below next_SP_alias_slot holds a non-IRTemp_INVALID value.
131 // The rest either all won't (if we haven't yet circled around) or all
132 // will (if we have circled around).
141 // With 32 slots the buffer fills very rarely -- eg. once in a run of GCC.
142 // And I've tested with smaller values and the wrap-around case works ok.
144 static SP_Alias SP_aliases[N_ALIASES];
145 static Int next_SP_alias_slot = 0;
147 static void clear_SP_aliases(void)
150 for (i = 0; i < N_ALIASES; i++) {
151 SP_aliases[i].temp = IRTemp_INVALID;
152 SP_aliases[i].delta = 0;
154 next_SP_alias_slot = 0;
157 static void add_SP_alias(IRTemp temp, Long delta)
159 vg_assert(temp != IRTemp_INVALID);
160 SP_aliases[ next_SP_alias_slot ].temp = temp;
161 SP_aliases[ next_SP_alias_slot ].delta = delta;
162 next_SP_alias_slot++;
163 if (N_ALIASES == next_SP_alias_slot) next_SP_alias_slot = 0;
166 static Bool get_SP_delta(IRTemp temp, ULong* delta)
168 Int i; // i must be signed!
169 vg_assert(IRTemp_INVALID != temp);
170 // Search backwards between current buffer position and the start.
171 for (i = next_SP_alias_slot-1; i >= 0; i--) {
172 if (temp == SP_aliases[i].temp) {
173 *delta = SP_aliases[i].delta;
177 // Search backwards between the end and the current buffer position.
178 for (i = N_ALIASES-1; i >= next_SP_alias_slot; i--) {
179 if (temp == SP_aliases[i].temp) {
180 *delta = SP_aliases[i].delta;
187 static void update_SP_aliases(Long delta)
190 for (i = 0; i < N_ALIASES; i++) {
191 if (SP_aliases[i].temp == IRTemp_INVALID) {
194 SP_aliases[i].delta += delta;
198 /* Given a guest IP, get an origin tag for a 1-element stack trace,
199 and wrap it up in an IR atom that can be passed as the origin-tag
200 value for a stack-adjustment helper function. */
201 static IRExpr* mk_ecu_Expr ( Addr64 guest_IP )
205 = VG_(make_depth_1_ExeContext_from_Addr)( (Addr)guest_IP );
207 ecu = VG_(get_ECU_from_ExeContext)( ec );
208 vg_assert(VG_(is_plausible_ECU)(ecu));
209 /* This is always safe to do, since ecu is only 32 bits, and
210 HWord is 32 or 64. */
211 return mkIRExpr_HWord( (HWord)ecu );
214 /* When gdbserver is activated, the translation of a block must
215 first be done by the tool function, then followed by a pass
216 which (if needed) instruments the code for gdbserver.
219 IRSB* tool_instrument_then_gdbserver_if_needed ( VgCallbackClosure* closureV,
221 VexGuestLayout* layout,
222 VexGuestExtents* vge,
226 return VG_(instrument_for_gdbserver_if_needed)
227 (VG_(tdict).tool_instrument (closureV,
239 /* For tools that want to know about SP changes, this pass adds
240 in the appropriate hooks. We have to do it after the tool's
241 instrumentation, so the tool doesn't have to worry about the C calls
242 it adds in, and we must do it before register allocation because
243 spilled temps make it much harder to work out the SP deltas.
244 This it is done with Vex's "second instrumentation" pass.
246 Basically, we look for GET(SP)/PUT(SP) pairs and track constant
247 increments/decrements of SP between them. (This requires tracking one or
248 more "aliases", which are not exact aliases but instead are tempregs
249 whose value is equal to the SP's plus or minus a known constant.)
250 If all the changes to SP leading up to a PUT(SP) are by known, small
251 constants, we can do a specific call to eg. new_mem_stack_4, otherwise
252 we fall back to the case that handles an unknown SP change.
254 There is some extra complexity to deal correctly with updates to
255 only parts of SP. Bizarre, but it has been known to happen.
258 IRSB* vg_SP_update_pass ( void* closureV,
260 VexGuestLayout* layout,
261 VexGuestExtents* vge,
265 Int i, j, minoff_ST, maxoff_ST, sizeof_SP, offset_SP;
266 Int first_SP, last_SP, first_Put, last_Put;
274 /* Set up stuff for tracking the guest IP */
275 Bool curr_IP_known = False;
279 IRSB* bb = emptyIRSB();
280 bb->tyenv = deepCopyIRTypeEnv(sb_in->tyenv);
281 bb->next = deepCopyIRExpr(sb_in->next);
282 bb->jumpkind = sb_in->jumpkind;
286 sizeof_SP = layout->sizeof_SP;
287 offset_SP = layout->offset_SP;
288 typeof_SP = sizeof_SP==4 ? Ity_I32 : Ity_I64;
289 vg_assert(sizeof_SP == 4 || sizeof_SP == 8);
291 /* --- Start of #defines --- */
293 # define IS_ADD(op) (sizeof_SP==4 ? ((op)==Iop_Add32) : ((op)==Iop_Add64))
294 # define IS_SUB(op) (sizeof_SP==4 ? ((op)==Iop_Sub32) : ((op)==Iop_Sub64))
296 # define IS_ADD_OR_SUB(op) (IS_ADD(op) || IS_SUB(op))
298 # define GET_CONST(con) \
299 (sizeof_SP==4 ? (Long)(Int)(con->Ico.U32) \
300 : (Long)(con->Ico.U64))
302 # define DO_NEW(syze, tmpp) \
304 Bool vanilla, w_ecu; \
305 vg_assert(curr_IP_known); \
306 vanilla = NULL != VG_(tdict).track_new_mem_stack_##syze; \
307 w_ecu = NULL != VG_(tdict).track_new_mem_stack_##syze##_w_ECU; \
308 vg_assert(!(vanilla && w_ecu)); /* can't have both */ \
309 if (!(vanilla || w_ecu)) \
312 /* I don't know if it's really necessary to say that the */ \
313 /* call reads the stack pointer. But anyway, we do. */ \
315 dcall = unsafeIRDirty_0_N( \
317 "track_new_mem_stack_" #syze "_w_ECU", \
318 VG_(fnptr_to_fnentry)( \
319 VG_(tdict).track_new_mem_stack_##syze##_w_ECU ), \
320 mkIRExprVec_2(IRExpr_RdTmp(tmpp), \
321 mk_ecu_Expr(curr_IP)) \
324 dcall = unsafeIRDirty_0_N( \
326 "track_new_mem_stack_" #syze , \
327 VG_(fnptr_to_fnentry)( \
328 VG_(tdict).track_new_mem_stack_##syze ), \
329 mkIRExprVec_1(IRExpr_RdTmp(tmpp)) \
332 dcall->nFxState = 1; \
333 dcall->fxState[0].fx = Ifx_Read; \
334 dcall->fxState[0].offset = layout->offset_SP; \
335 dcall->fxState[0].size = layout->sizeof_SP; \
337 addStmtToIRSB( bb, IRStmt_Dirty(dcall) ); \
339 tl_assert(syze > 0); \
340 update_SP_aliases(syze); \
342 n_SP_updates_fast++; \
346 # define DO_DIE(syze, tmpp) \
348 if (!VG_(tdict).track_die_mem_stack_##syze) \
351 /* I don't know if it's really necessary to say that the */ \
352 /* call reads the stack pointer. But anyway, we do. */ \
353 dcall = unsafeIRDirty_0_N( \
355 "track_die_mem_stack_" #syze, \
356 VG_(fnptr_to_fnentry)( \
357 VG_(tdict).track_die_mem_stack_##syze ), \
358 mkIRExprVec_1(IRExpr_RdTmp(tmpp)) \
360 dcall->nFxState = 1; \
361 dcall->fxState[0].fx = Ifx_Read; \
362 dcall->fxState[0].offset = layout->offset_SP; \
363 dcall->fxState[0].size = layout->sizeof_SP; \
365 addStmtToIRSB( bb, IRStmt_Dirty(dcall) ); \
367 tl_assert(syze > 0); \
368 update_SP_aliases(-(syze)); \
370 n_SP_updates_fast++; \
374 /* --- End of #defines --- */
378 for (i = 0; i < sb_in->stmts_used; i++) {
380 st = sb_in->stmts[i];
382 if (st->tag == Ist_IMark) {
383 curr_IP_known = True;
384 curr_IP = st->Ist.IMark.addr;
387 /* t = Get(sp): curr = t, delta = 0 */
388 if (st->tag != Ist_WrTmp) goto case2;
389 e = st->Ist.WrTmp.data;
390 if (e->tag != Iex_Get) goto case2;
391 if (e->Iex.Get.offset != offset_SP) goto case2;
392 if (e->Iex.Get.ty != typeof_SP) goto case2;
393 vg_assert( typeOfIRTemp(bb->tyenv, st->Ist.WrTmp.tmp) == typeof_SP );
394 add_SP_alias(st->Ist.WrTmp.tmp, 0);
395 addStmtToIRSB( bb, st );
399 /* t' = curr +/- const: curr = t', delta +=/-= const */
400 if (st->tag != Ist_WrTmp) goto case3;
401 e = st->Ist.WrTmp.data;
402 if (e->tag != Iex_Binop) goto case3;
403 if (e->Iex.Binop.arg1->tag != Iex_RdTmp) goto case3;
404 if (!get_SP_delta(e->Iex.Binop.arg1->Iex.RdTmp.tmp, &delta)) goto case3;
405 if (e->Iex.Binop.arg2->tag != Iex_Const) goto case3;
406 if (!IS_ADD_OR_SUB(e->Iex.Binop.op)) goto case3;
407 con = GET_CONST(e->Iex.Binop.arg2->Iex.Const.con);
408 vg_assert( typeOfIRTemp(bb->tyenv, st->Ist.WrTmp.tmp) == typeof_SP );
409 if (IS_ADD(e->Iex.Binop.op)) {
410 add_SP_alias(st->Ist.WrTmp.tmp, delta + con);
412 add_SP_alias(st->Ist.WrTmp.tmp, delta - con);
414 addStmtToIRSB( bb, st );
418 /* t' = curr: curr = t' */
419 if (st->tag != Ist_WrTmp) goto case4;
420 e = st->Ist.WrTmp.data;
421 if (e->tag != Iex_RdTmp) goto case4;
422 if (!get_SP_delta(e->Iex.RdTmp.tmp, &delta)) goto case4;
423 vg_assert( typeOfIRTemp(bb->tyenv, st->Ist.WrTmp.tmp) == typeof_SP );
424 add_SP_alias(st->Ist.WrTmp.tmp, delta);
425 addStmtToIRSB( bb, st );
430 /* More generally, we must correctly handle a Put which writes
431 any part of SP, not just the case where all of SP is
433 if (st->tag != Ist_Put) goto case5;
434 first_SP = offset_SP;
435 last_SP = first_SP + sizeof_SP - 1;
436 first_Put = st->Ist.Put.offset;
438 + sizeofIRType( typeOfIRExpr( bb->tyenv, st->Ist.Put.data ))
440 vg_assert(first_SP <= last_SP);
441 vg_assert(first_Put <= last_Put);
443 if (last_Put < first_SP || last_SP < first_Put)
444 goto case5; /* no overlap */
446 if (st->Ist.Put.data->tag == Iex_RdTmp
447 && get_SP_delta(st->Ist.Put.data->Iex.RdTmp.tmp, &delta)) {
448 IRTemp tttmp = st->Ist.Put.data->Iex.RdTmp.tmp;
449 /* Why should the following assertion hold? Because any
450 alias added by put_SP_alias must be of a temporary which
451 has the same type as typeof_SP, and whose value is a Get
452 at exactly offset_SP of size typeof_SP. Each call to
453 put_SP_alias is immediately preceded by an assertion that
454 we are putting in a binding for a correctly-typed
456 vg_assert( typeOfIRTemp(bb->tyenv, tttmp) == typeof_SP );
457 /* From the same type-and-offset-correctness argument, if
458 we found a useable alias, it must for an "exact" write of SP. */
459 vg_assert(first_SP == first_Put);
460 vg_assert(last_SP == last_Put);
462 case 0: addStmtToIRSB(bb,st); continue;
463 case 4: DO_DIE( 4, tttmp); addStmtToIRSB(bb,st); continue;
464 case -4: DO_NEW( 4, tttmp); addStmtToIRSB(bb,st); continue;
465 case 8: DO_DIE( 8, tttmp); addStmtToIRSB(bb,st); continue;
466 case -8: DO_NEW( 8, tttmp); addStmtToIRSB(bb,st); continue;
467 case 12: DO_DIE( 12, tttmp); addStmtToIRSB(bb,st); continue;
468 case -12: DO_NEW( 12, tttmp); addStmtToIRSB(bb,st); continue;
469 case 16: DO_DIE( 16, tttmp); addStmtToIRSB(bb,st); continue;
470 case -16: DO_NEW( 16, tttmp); addStmtToIRSB(bb,st); continue;
471 case 32: DO_DIE( 32, tttmp); addStmtToIRSB(bb,st); continue;
472 case -32: DO_NEW( 32, tttmp); addStmtToIRSB(bb,st); continue;
473 case 112: DO_DIE( 112, tttmp); addStmtToIRSB(bb,st); continue;
474 case -112: DO_NEW( 112, tttmp); addStmtToIRSB(bb,st); continue;
475 case 128: DO_DIE( 128, tttmp); addStmtToIRSB(bb,st); continue;
476 case -128: DO_NEW( 128, tttmp); addStmtToIRSB(bb,st); continue;
477 case 144: DO_DIE( 144, tttmp); addStmtToIRSB(bb,st); continue;
478 case -144: DO_NEW( 144, tttmp); addStmtToIRSB(bb,st); continue;
479 case 160: DO_DIE( 160, tttmp); addStmtToIRSB(bb,st); continue;
480 case -160: DO_NEW( 160, tttmp); addStmtToIRSB(bb,st); continue;
482 /* common values for ppc64: 144 128 160 112 176 */
483 n_SP_updates_generic_known++;
487 /* Deal with an unknown update to SP. We're here because
489 (1) the Put does not exactly cover SP; it is a partial update.
490 Highly unlikely, but has been known to happen for 16-bit
491 Windows apps running on Wine, doing 16-bit adjustments to
493 (2) the Put does exactly cover SP, but we are unable to
494 determine how the value relates to the old SP. In any
495 case, we cannot assume that the Put.data value is a tmp;
496 we must assume it can be anything allowed in flat IR (tmp
500 n_SP_updates_generic_unknown++;
502 // Nb: if all is well, this generic case will typically be
503 // called something like every 1000th SP update. If it's more than
504 // that, the above code may be missing some cases.
506 /* Pass both the old and new SP values to this helper. Also,
507 pass an origin tag, even if it isn't needed. */
508 old_SP = newIRTemp(bb->tyenv, typeof_SP);
511 IRStmt_WrTmp( old_SP, IRExpr_Get(offset_SP, typeof_SP) )
514 /* Now we know what the old value of SP is. But knowing the new
515 value is a bit tricky if there is a partial write. */
516 if (first_Put == first_SP && last_Put == last_SP) {
517 /* The common case, an exact write to SP. So st->Ist.Put.data
518 does hold the new value; simple. */
519 vg_assert(curr_IP_known);
520 dcall = unsafeIRDirty_0_N(
522 "VG_(unknown_SP_update)",
523 VG_(fnptr_to_fnentry)( &VG_(unknown_SP_update) ),
524 mkIRExprVec_3( IRExpr_RdTmp(old_SP), st->Ist.Put.data,
525 mk_ecu_Expr(curr_IP) )
527 addStmtToIRSB( bb, IRStmt_Dirty(dcall) );
528 /* don't forget the original assignment */
529 addStmtToIRSB( bb, st );
531 /* We have a partial update to SP. We need to know what
532 the new SP will be, and hand that to the helper call,
533 but when the helper call happens, SP must hold the
534 value it had before the update. Tricky.
535 Therefore use the following kludge:
536 1. do the partial SP update (Put)
537 2. Get the new SP value into a tmp, new_SP
544 addStmtToIRSB( bb, st );
546 new_SP = newIRTemp(bb->tyenv, typeof_SP);
549 IRStmt_WrTmp( new_SP, IRExpr_Get(offset_SP, typeof_SP) )
552 addStmtToIRSB( bb, IRStmt_Put(offset_SP, IRExpr_RdTmp(old_SP) ));
554 vg_assert(curr_IP_known);
555 dcall = unsafeIRDirty_0_N(
557 "VG_(unknown_SP_update)",
558 VG_(fnptr_to_fnentry)( &VG_(unknown_SP_update) ),
559 mkIRExprVec_3( IRExpr_RdTmp(old_SP),
560 IRExpr_RdTmp(new_SP),
561 mk_ecu_Expr(curr_IP) )
563 addStmtToIRSB( bb, IRStmt_Dirty(dcall) );
565 addStmtToIRSB( bb, IRStmt_Put(offset_SP, IRExpr_RdTmp(new_SP) ));
568 /* Forget what we already know. */
571 /* If this is a Put of a tmp that exactly updates SP,
572 start tracking aliases against this tmp. */
574 if (first_Put == first_SP && last_Put == last_SP
575 && st->Ist.Put.data->tag == Iex_RdTmp) {
576 vg_assert( typeOfIRTemp(bb->tyenv, st->Ist.Put.data->Iex.RdTmp.tmp)
578 add_SP_alias(st->Ist.Put.data->Iex.RdTmp.tmp, 0);
584 /* PutI or Dirty call which overlaps SP: complain. We can't
585 deal with SP changing in weird ways (well, we can, but not at
586 this time of night). */
587 if (st->tag == Ist_PutI) {
588 descr = st->Ist.PutI.descr;
589 minoff_ST = descr->base;
590 maxoff_ST = descr->base
591 + descr->nElems * sizeofIRType(descr->elemTy) - 1;
592 if (!(offset_SP > maxoff_ST
593 || (offset_SP + sizeof_SP - 1) < minoff_ST))
596 if (st->tag == Ist_Dirty) {
597 d = st->Ist.Dirty.details;
598 for (j = 0; j < d->nFxState; j++) {
599 minoff_ST = d->fxState[j].offset;
600 maxoff_ST = d->fxState[j].offset + d->fxState[j].size - 1;
601 if (d->fxState[j].fx == Ifx_Read || d->fxState[j].fx == Ifx_None)
603 if (!(offset_SP > maxoff_ST
604 || (offset_SP + sizeof_SP - 1) < minoff_ST))
609 /* well, not interesting. Just copy and keep going. */
610 addStmtToIRSB( bb, st );
612 } /* for (i = 0; i < sb_in->stmts_used; i++) */
617 VG_(core_panic)("vg_SP_update_pass: PutI or Dirty which overlaps SP");
627 /*------------------------------------------------------------*/
628 /*--- Main entry point for the JITter. ---*/
629 /*------------------------------------------------------------*/
631 /* Extra comments re self-checking translations and self-modifying
632 code. (JRS 14 Oct 05).
635 (1) no checking: all code assumed to be not self-modifying
636 (2) partial: known-problematic situations get a self-check
637 (3) full checking: all translations get a self-check
639 As currently implemented, the default is (2). (3) is always safe,
640 but very slow. (1) works mostly, but fails for gcc nested-function
641 code which uses trampolines on the stack; this situation is
642 detected and handled by (2).
646 A more robust and transparent solution, which is not currently
647 implemented, is a variant of (2): if a translation is made from an
648 area which aspacem says does not have 'w' permission, then it can
649 be non-self-checking. Otherwise, it needs a self-check.
651 This is complicated by Vex's basic-block chasing. If a self-check
652 is requested, then Vex will not chase over basic block boundaries
653 (it's too complex). However there is still a problem if it chases
654 from a non-'w' area into a 'w' area.
656 I think the right thing to do is:
658 - if a translation request starts in a 'w' area, ask for a
659 self-checking translation, and do not allow any chasing (make
660 chase_into_ok return False). Note that the latter is redundant
661 in the sense that Vex won't chase anyway in this situation.
663 - if a translation request starts in a non-'w' area, do not ask for
664 a self-checking translation. However, do not allow chasing (as
665 determined by chase_into_ok) to go into a 'w' area.
667 The result of this is that all code inside 'w' areas is self
670 To complete the trick, there is a caveat: we must watch the
671 client's mprotect calls. If pages are changed from non-'w' to 'w'
672 then we should throw away all translations which intersect the
673 affected area, so as to force them to be redone with self-checks.
677 The above outlines the conditions under which bb chasing is allowed
678 from a self-modifying-code point of view. There are other
679 situations pertaining to function redirection in which it is
680 necessary to disallow chasing, but those fall outside the scope of
685 /* Vex dumps the final code in here. Then we can copy it off
687 /* 60000: should agree with assertion in VG_(add_to_transtab) in
689 #define N_TMPBUF 60000
690 static UChar tmpbuf[N_TMPBUF];
693 /* Function pointers we must supply to LibVEX in order that it
694 can bomb out and emit messages under Valgrind's control. */
695 __attribute__ ((noreturn))
697 void failure_exit ( void )
699 LibVEX_ShowAllocStats();
700 VG_(core_panic)("LibVEX called failure_exit().");
704 void log_bytes ( HChar* bytes, Int nbytes )
707 for (i = 0; i < nbytes-3; i += 4)
708 VG_(printf)("%c%c%c%c", bytes[i], bytes[i+1], bytes[i+2], bytes[i+3]);
709 for (; i < nbytes; i++)
710 VG_(printf)("%c", bytes[i]);
714 /* --------- Various helper functions for translation --------- */
716 /* Look for reasons to disallow making translations from the given
719 static Bool translations_allowable_from_seg ( NSegment const* seg )
721 # if defined(VGA_x86) || defined(VGA_s390x)
727 && (seg->kind == SkAnonC || seg->kind == SkFileC || seg->kind == SkShmC)
728 && (seg->hasX || (seg->hasR && allowR));
732 /* Is a self-check required for a translation of a guest address
733 inside segment SEG when requested by thread TID ? */
735 static Bool self_check_required ( NSegment const* seg, ThreadId tid )
737 #if defined(VGO_darwin)
738 // GrP fixme hack - dyld i386 IMPORT gets rewritten
739 // to really do this correctly, we'd need to flush the
740 // translation cache whenever a segment became +WX
741 if (seg->hasX && seg->hasW) {
745 switch (VG_(clo_smc_check)) {
746 case Vg_SmcNone: return False;
747 case Vg_SmcAll: return True;
750 ? (seg->start <= VG_(get_SP)(tid)
751 && VG_(get_SP)(tid)+sizeof(Word)-1 <= seg->end)
755 vg_assert2(0, "unknown VG_(clo_smc_check) value");
760 /* This is a callback passed to LibVEX_Translate. It stops Vex from
761 chasing into function entry points that we wish to redirect.
762 Chasing across them obviously defeats the redirect mechanism, with
763 bad effects for Memcheck, Addrcheck, and possibly others.
765 Also, we must stop Vex chasing into blocks for which we might want
768 static Bool chase_into_ok ( void* closureV, Addr64 addr64 )
770 Addr addr = (Addr)addr64;
771 NSegment const* seg = VG_(am_find_nsegment)(addr);
773 /* Work through a list of possibilities why we might not want to
776 /* Destination not in a plausible segment? */
777 if (!translations_allowable_from_seg(seg))
780 /* Destination is redirected? */
781 if (addr != VG_(redir_do_lookup)(addr, NULL))
784 # if defined(VG_PLAT_USES_PPCTOC)
785 /* This needs to be at the start of its own block. Don't chase. Re
786 ULong_to_Ptr, be careful to ensure we only compare 32 bits on a
788 if (ULong_to_Ptr(addr64)
789 == (void*)&VG_(ppctoc_magic_redirect_return_stub))
793 /* overly conservative, but .. don't chase into the distinguished
794 address that m_transtab uses as an empty-slot marker for
796 if (addr == TRANSTAB_BOGUS_GUEST_ADDR)
799 /* well, ok then. go on and chase. */
806 if (0) VG_(printf)("not chasing into 0x%lx\n", addr);
811 /* --------------- helpers for with-TOC platforms --------------- */
813 /* NOTE: with-TOC platforms are: ppc64-linux, ppc32-aix5, ppc64-aix5. */
815 static IRExpr* mkU64 ( ULong n ) {
816 return IRExpr_Const(IRConst_U64(n));
818 static IRExpr* mkU32 ( UInt n ) {
819 return IRExpr_Const(IRConst_U32(n));
822 #if defined(VG_PLAT_USES_PPCTOC)
823 static IRExpr* mkU8 ( UChar n ) {
824 return IRExpr_Const(IRConst_U8(n));
826 static IRExpr* narrowTo32 ( IRTypeEnv* tyenv, IRExpr* e ) {
827 if (typeOfIRExpr(tyenv, e) == Ity_I32) {
830 vg_assert(typeOfIRExpr(tyenv, e) == Ity_I64);
831 return IRExpr_Unop(Iop_64to32, e);
835 /* Generate code to push word-typed expression 'e' onto this thread's
836 redir stack, checking for stack overflow and generating code to
839 static void gen_PUSH ( IRSB* bb, IRExpr* e )
845 # if defined(VGP_ppc64_linux) || defined(VGP_ppc64_aix5)
846 Int stack_size = VEX_GUEST_PPC64_REDIR_STACK_SIZE;
847 Int offB_REDIR_SP = offsetof(VexGuestPPC64State,guest_REDIR_SP);
848 Int offB_REDIR_STACK = offsetof(VexGuestPPC64State,guest_REDIR_STACK);
849 Int offB_EMWARN = offsetof(VexGuestPPC64State,guest_EMWARN);
851 IRType ty_Word = Ity_I64;
852 IROp op_CmpNE = Iop_CmpNE64;
853 IROp op_Sar = Iop_Sar64;
854 IROp op_Sub = Iop_Sub64;
855 IROp op_Add = Iop_Add64;
856 IRExpr*(*mkU)(ULong) = mkU64;
857 vg_assert(VG_WORDSIZE == 8);
859 Int stack_size = VEX_GUEST_PPC32_REDIR_STACK_SIZE;
860 Int offB_REDIR_SP = offsetof(VexGuestPPC32State,guest_REDIR_SP);
861 Int offB_REDIR_STACK = offsetof(VexGuestPPC32State,guest_REDIR_STACK);
862 Int offB_EMWARN = offsetof(VexGuestPPC32State,guest_EMWARN);
864 IRType ty_Word = Ity_I32;
865 IROp op_CmpNE = Iop_CmpNE32;
866 IROp op_Sar = Iop_Sar32;
867 IROp op_Sub = Iop_Sub32;
868 IROp op_Add = Iop_Add32;
869 IRExpr*(*mkU)(UInt) = mkU32;
870 vg_assert(VG_WORDSIZE == 4);
873 vg_assert(sizeof(void*) == VG_WORDSIZE);
874 vg_assert(sizeof(Word) == VG_WORDSIZE);
875 vg_assert(sizeof(Addr) == VG_WORDSIZE);
877 descr = mkIRRegArray( offB_REDIR_STACK, ty_Word, stack_size );
878 t1 = newIRTemp( bb->tyenv, ty_Word );
881 vg_assert(typeOfIRExpr(bb->tyenv, e) == ty_Word);
883 /* t1 = guest_REDIR_SP + 1 */
888 IRExpr_Binop(op_Add, IRExpr_Get( offB_REDIR_SP, ty_Word ), one)
892 /* Bomb out if t1 >=s stack_size, that is, (stack_size-1)-t1 <s 0.
893 The destination (0) is a bit bogus but it doesn't matter since
894 this is an unrecoverable error and will lead to Valgrind
895 shutting down. _EMWARN is set regardless - that's harmless
896 since is only has a meaning if the exit is taken. */
899 IRStmt_Put(offB_EMWARN, mkU32(EmWarn_PPC64_redir_overflow))
908 IRExpr_Binop(op_Sub,mkU(stack_size-1),IRExpr_RdTmp(t1)),
909 mkU8(8 * VG_WORDSIZE - 1)
914 is64 ? IRConst_U64(0) : IRConst_U32(0)
918 /* guest_REDIR_SP = t1 */
919 addStmtToIRSB(bb, IRStmt_Put(offB_REDIR_SP, IRExpr_RdTmp(t1)));
921 /* guest_REDIR_STACK[t1+0] = e */
922 /* PutI/GetI have I32-typed indexes regardless of guest word size */
925 IRStmt_PutI(descr, narrowTo32(bb->tyenv,IRExpr_RdTmp(t1)), 0, e)
930 /* Generate code to pop a word-sized value from this thread's redir
931 stack, binding it to a new temporary, which is returned. As with
932 gen_PUSH, an overflow check is also performed. */
934 static IRTemp gen_POP ( IRSB* bb )
936 # if defined(VGP_ppc64_linux) || defined(VGP_ppc64_aix5)
937 Int stack_size = VEX_GUEST_PPC64_REDIR_STACK_SIZE;
938 Int offB_REDIR_SP = offsetof(VexGuestPPC64State,guest_REDIR_SP);
939 Int offB_REDIR_STACK = offsetof(VexGuestPPC64State,guest_REDIR_STACK);
940 Int offB_EMWARN = offsetof(VexGuestPPC64State,guest_EMWARN);
942 IRType ty_Word = Ity_I64;
943 IROp op_CmpNE = Iop_CmpNE64;
944 IROp op_Sar = Iop_Sar64;
945 IROp op_Sub = Iop_Sub64;
946 IRExpr*(*mkU)(ULong) = mkU64;
948 Int stack_size = VEX_GUEST_PPC32_REDIR_STACK_SIZE;
949 Int offB_REDIR_SP = offsetof(VexGuestPPC32State,guest_REDIR_SP);
950 Int offB_REDIR_STACK = offsetof(VexGuestPPC32State,guest_REDIR_STACK);
951 Int offB_EMWARN = offsetof(VexGuestPPC32State,guest_EMWARN);
953 IRType ty_Word = Ity_I32;
954 IROp op_CmpNE = Iop_CmpNE32;
955 IROp op_Sar = Iop_Sar32;
956 IROp op_Sub = Iop_Sub32;
957 IRExpr*(*mkU)(UInt) = mkU32;
960 IRRegArray* descr = mkIRRegArray( offB_REDIR_STACK, ty_Word, stack_size );
961 IRTemp t1 = newIRTemp( bb->tyenv, ty_Word );
962 IRTemp res = newIRTemp( bb->tyenv, ty_Word );
963 IRExpr* one = mkU(1);
965 vg_assert(sizeof(void*) == VG_WORDSIZE);
966 vg_assert(sizeof(Word) == VG_WORDSIZE);
967 vg_assert(sizeof(Addr) == VG_WORDSIZE);
969 /* t1 = guest_REDIR_SP */
972 IRStmt_WrTmp( t1, IRExpr_Get( offB_REDIR_SP, ty_Word ) )
975 /* Bomb out if t1 < 0. Same comments as gen_PUSH apply. */
978 IRStmt_Put(offB_EMWARN, mkU32(EmWarn_PPC64_redir_underflow))
988 mkU8(8 * VG_WORDSIZE - 1)
993 is64 ? IRConst_U64(0) : IRConst_U32(0)
997 /* res = guest_REDIR_STACK[t1+0] */
998 /* PutI/GetI have I32-typed indexes regardless of guest word size */
1003 IRExpr_GetI(descr, narrowTo32(bb->tyenv,IRExpr_RdTmp(t1)), 0)
1007 /* guest_REDIR_SP = t1-1 */
1010 IRStmt_Put(offB_REDIR_SP, IRExpr_Binop(op_Sub, IRExpr_RdTmp(t1), one))
1016 /* Generate code to push LR and R2 onto this thread's redir stack,
1017 then set R2 to the new value (which is the TOC pointer to be used
1018 for the duration of the replacement function, as determined by
1019 m_debuginfo), and set LR to the magic return stub, so we get to
1020 intercept the return and restore R2 and L2 to the values saved
1023 static void gen_push_and_set_LR_R2 ( IRSB* bb, Addr64 new_R2_value )
1025 # if defined(VGP_ppc64_linux) || defined(VGP_ppc64_aix5)
1026 Addr64 bogus_RA = (Addr64)&VG_(ppctoc_magic_redirect_return_stub);
1027 Int offB_GPR2 = offsetof(VexGuestPPC64State,guest_GPR2);
1028 Int offB_LR = offsetof(VexGuestPPC64State,guest_LR);
1029 gen_PUSH( bb, IRExpr_Get(offB_LR, Ity_I64) );
1030 gen_PUSH( bb, IRExpr_Get(offB_GPR2, Ity_I64) );
1031 addStmtToIRSB( bb, IRStmt_Put( offB_LR, mkU64( bogus_RA )) );
1032 addStmtToIRSB( bb, IRStmt_Put( offB_GPR2, mkU64( new_R2_value )) );
1034 # elif defined(VGP_ppc32_aix5)
1035 Addr32 bogus_RA = (Addr32)&VG_(ppctoc_magic_redirect_return_stub);
1036 Int offB_GPR2 = offsetof(VexGuestPPC32State,guest_GPR2);
1037 Int offB_LR = offsetof(VexGuestPPC32State,guest_LR);
1038 gen_PUSH( bb, IRExpr_Get(offB_LR, Ity_I32) );
1039 gen_PUSH( bb, IRExpr_Get(offB_GPR2, Ity_I32) );
1040 addStmtToIRSB( bb, IRStmt_Put( offB_LR, mkU32( bogus_RA )) );
1041 addStmtToIRSB( bb, IRStmt_Put( offB_GPR2, mkU32( new_R2_value )) );
1044 # error Platform is not TOC-afflicted, fortunately
1048 static void gen_pop_R2_LR_then_bLR ( IRSB* bb )
1050 # if defined(VGP_ppc64_linux) || defined(VGP_ppc64_aix5)
1051 Int offB_GPR2 = offsetof(VexGuestPPC64State,guest_GPR2);
1052 Int offB_LR = offsetof(VexGuestPPC64State,guest_LR);
1053 IRTemp old_R2 = newIRTemp( bb->tyenv, Ity_I64 );
1054 IRTemp old_LR = newIRTemp( bb->tyenv, Ity_I64 );
1056 old_R2 = gen_POP( bb );
1057 addStmtToIRSB( bb, IRStmt_Put( offB_GPR2, IRExpr_RdTmp(old_R2)) );
1059 old_LR = gen_POP( bb );
1060 addStmtToIRSB( bb, IRStmt_Put( offB_LR, IRExpr_RdTmp(old_LR)) );
1062 /* re boring, we arrived here precisely because a wrapped fn did a
1063 blr (hence Ijk_Ret); so we should just mark this jump as Boring,
1064 else one _Call will have resulted in two _Rets. */
1065 bb->jumpkind = Ijk_Boring;
1066 bb->next = IRExpr_Binop(Iop_And64, IRExpr_RdTmp(old_LR), mkU64(~(3ULL)));
1068 # elif defined(VGP_ppc32_aix5)
1069 Int offB_GPR2 = offsetof(VexGuestPPC32State,guest_GPR2);
1070 Int offB_LR = offsetof(VexGuestPPC32State,guest_LR);
1071 IRTemp old_R2 = newIRTemp( bb->tyenv, Ity_I32 );
1072 IRTemp old_LR = newIRTemp( bb->tyenv, Ity_I32 );
1074 old_R2 = gen_POP( bb );
1075 addStmtToIRSB( bb, IRStmt_Put( offB_GPR2, IRExpr_RdTmp(old_R2)) );
1077 old_LR = gen_POP( bb );
1078 addStmtToIRSB( bb, IRStmt_Put( offB_LR, IRExpr_RdTmp(old_LR)) );
1081 /* re boring, we arrived here precisely because a wrapped fn did a
1082 blr (hence Ijk_Ret); so we should just mark this jump as Boring,
1083 else one _Call will have resulted in two _Rets. */
1084 bb->jumpkind = Ijk_Boring;
1085 bb->next = IRExpr_Binop(Iop_And32, IRExpr_RdTmp(old_LR), mkU32(~3));
1088 # error Platform is not TOC-afflicted, fortunately
1093 Bool mk_preamble__ppctoc_magic_return_stub ( void* closureV, IRSB* bb )
1095 VgCallbackClosure* closure = (VgCallbackClosure*)closureV;
1096 /* Since we're creating the entire IRSB right here, give it a
1097 proper IMark, as it won't get one any other way, and cachegrind
1098 will barf if it doesn't have one (fair enough really). */
1099 addStmtToIRSB( bb, IRStmt_IMark( closure->readdr, 4 ) );
1100 /* Generate the magic sequence:
1101 pop R2 from hidden stack
1102 pop LR from hidden stack
1105 gen_pop_R2_LR_then_bLR(bb);
1106 return True; /* True == this is the entire BB; don't disassemble any
1107 real insns into it - just hand it directly to
1108 optimiser/instrumenter/backend. */
1112 /* --------------- END helpers for with-TOC platforms --------------- */
1115 /* This is the IR preamble generator used for replacement
1116 functions. It adds code to set the guest_NRADDR{_GPR2} to zero
1117 (technically not necessary, but facilitates detecting mixups in
1118 which a replacement function has been erroneously declared using
1119 VG_REPLACE_FUNCTION_Z{U,Z} when instead it should have been written
1120 using VG_WRAP_FUNCTION_Z{U,Z}).
1122 On with-TOC platforms the follow hacks are also done: LR and R2 are
1123 pushed onto a hidden stack, R2 is set to the correct value for the
1124 replacement function, and LR is set to point at the magic
1125 return-stub address. Setting LR causes the return of the
1126 wrapped/redirected function to lead to our magic return stub, which
1127 restores LR and R2 from said stack and returns for real.
1129 VG_(get_StackTrace_wrk) understands that the LR value may point to
1130 the return stub address, and that in that case it can get the real
1131 LR value from the hidden stack instead. */
1133 Bool mk_preamble__set_NRADDR_to_zero ( void* closureV, IRSB* bb )
1136 = sizeof(((VexGuestArchState*)0)->guest_NRADDR);
1137 vg_assert(nraddr_szB == 4 || nraddr_szB == 8);
1138 vg_assert(nraddr_szB == VG_WORDSIZE);
1142 offsetof(VexGuestArchState,guest_NRADDR),
1143 nraddr_szB == 8 ? mkU64(0) : mkU32(0)
1146 # if defined(VG_PLAT_USES_PPCTOC)
1147 { VgCallbackClosure* closure = (VgCallbackClosure*)closureV;
1151 offsetof(VexGuestArchState,guest_NRADDR_GPR2),
1152 VG_WORDSIZE==8 ? mkU64(0) : mkU32(0)
1155 gen_push_and_set_LR_R2 ( bb, VG_(get_tocptr)( closure->readdr ) );
1161 /* Ditto, except set guest_NRADDR to nraddr (the un-redirected guest
1162 address). This is needed for function wrapping - so the wrapper
1163 can read _NRADDR and find the address of the function being
1164 wrapped. On toc-afflicted platforms we must also snarf r2. */
1166 Bool mk_preamble__set_NRADDR_to_nraddr ( void* closureV, IRSB* bb )
1168 VgCallbackClosure* closure = (VgCallbackClosure*)closureV;
1170 = sizeof(((VexGuestArchState*)0)->guest_NRADDR);
1171 vg_assert(nraddr_szB == 4 || nraddr_szB == 8);
1172 vg_assert(nraddr_szB == VG_WORDSIZE);
1176 offsetof(VexGuestArchState,guest_NRADDR),
1178 ? IRExpr_Const(IRConst_U64( closure->nraddr ))
1179 : IRExpr_Const(IRConst_U32( (UInt)closure->nraddr ))
1182 # if defined(VGP_ppc64_linux) || defined(VGP_ppc32_aix5) \
1183 || defined(VGP_ppc64_aix5)
1187 offsetof(VexGuestArchState,guest_NRADDR_GPR2),
1188 IRExpr_Get(offsetof(VexGuestArchState,guest_GPR2),
1189 VG_WORDSIZE==8 ? Ity_I64 : Ity_I32)
1192 gen_push_and_set_LR_R2 ( bb, VG_(get_tocptr)( closure->readdr ) );
1197 /* --- Helpers to do with PPC related stack redzones. --- */
1199 __attribute__((unused))
1200 static Bool const_True ( Addr64 guest_addr )
1205 __attribute__((unused))
1206 static Bool bl_RZ_zap_ok_for_AIX ( Addr64 bl_target )
1209 if (sizeof(void*) == 4)
1210 bl_target &= 0xFFFFFFFFULL;
1212 /* don't zap the redzone for calls to millicode. */
1213 if (bl_target < 0x10000ULL)
1216 /* don't zap the redzone for calls to .$SAVEF14 .. .$SAVEF31.
1217 First we need to be reasonably sure we won't segfault by looking
1218 at the branch target. */
1219 { NSegment const*const seg = VG_(am_find_nsegment)( (Addr)bl_target );
1220 if (seg && seg->hasR) {
1221 switch ( *(UInt*)(Addr)bl_target ) {
1222 case 0xd9c1ff70: /* stfd f14,-144(r1) */
1223 case 0xd9e1ff78: /* stfd f15,-136(r1) */
1224 case 0xda01ff80: /* stfd f16,-128(r1) */
1225 case 0xda21ff88: /* stfd f17,-120(r1) */
1226 case 0xda41ff90: /* stfd f18,-112(r1) */
1227 case 0xda61ff98: /* stfd f19,-104(r1) */
1228 case 0xda81ffa0: /* stfd f20,-96(r1) */
1229 case 0xdaa1ffa8: /* stfd f21,-88(r1) */
1230 case 0xdac1ffb0: /* stfd f22,-80(r1) */
1231 case 0xdae1ffb8: /* stfd f23,-72(r1) */
1232 case 0xdb01ffc0: /* stfd f24,-64(r1) */
1233 case 0xdb21ffc8: /* stfd f25,-56(r1) */
1234 case 0xdb41ffd0: /* stfd f26,-48(r1) */
1235 case 0xdb61ffd8: /* stfd f27,-40(r1) */
1236 case 0xdb81ffe0: /* stfd f28,-32(r1) */
1237 case 0xdba1ffe8: /* stfd f29,-24(r1) */
1238 case 0xdbc1fff0: /* stfd f30,-16(r1) */
1239 case 0xdbe1fff8: /* stfd f31,-8(r1) */
1247 /* --------------- main translation function --------------- */
1249 /* Note: see comments at top of m_redir.c for the Big Picture on how
1250 redirections are managed. */
1254 /* normal translation, redir neither requested nor inhibited */
1256 /* redir translation, function-wrap (set _NRADDR) style */
1258 /* redir translation, replacement (don't set _NRADDR) style */
1260 /* a translation in which redir is specifically disallowed */
1265 /* Translate the basic block beginning at NRADDR, and add it to the
1266 translation cache & translation table. Unless
1267 DEBUGGING_TRANSLATION is true, in which case the call is being done
1268 for debugging purposes, so (a) throw away the translation once it
1269 is made, and (b) produce a load of debugging output. If
1270 ALLOW_REDIRECTION is False, do not attempt redirection of NRADDR,
1271 and also, put the resulting translation into the no-redirect tt/tc
1272 instead of the normal one.
1274 TID is the identity of the thread requesting this translation.
1277 Bool VG_(translate) ( ThreadId tid,
1279 Bool debugging_translation,
1280 Int debugging_verbosity,
1282 Bool allow_redirection )
1286 Int tmpbuf_used, verbosity, i;
1288 Bool (*preamble_fn)(void*,IRSB*);
1290 VexArchInfo vex_archinfo;
1291 VexAbiInfo vex_abiinfo;
1292 VexGuestExtents vge;
1293 VexTranslateArgs vta;
1294 VexTranslateResult tres;
1295 VgCallbackClosure closure;
1297 /* Make sure Vex is initialised right. */
1299 static Bool vex_init_done = False;
1301 if (!vex_init_done) {
1302 LibVEX_Init ( &failure_exit, &log_bytes,
1303 1, /* debug_paranoia */
1304 False, /* valgrind support */
1305 &VG_(clo_vex_control) );
1306 vex_init_done = True;
1309 /* Establish the translation kind and actual guest address to
1310 start from. Sets (addr,kind). */
1311 if (allow_redirection) {
1313 Addr64 tmp = VG_(redir_do_lookup)( nraddr, &isWrap );
1314 if (tmp == nraddr) {
1315 /* no redirection found */
1319 /* found a redirect */
1321 kind = isWrap ? T_Redir_Wrap : T_Redir_Replace;
1328 /* Established: (nraddr, addr, kind) */
1330 /* Printing redirection info. */
1332 if ((kind == T_Redir_Wrap || kind == T_Redir_Replace)
1333 && (VG_(clo_verbosity) >= 2 || VG_(clo_trace_redir))) {
1335 Char name1[64] = "";
1336 Char name2[64] = "";
1337 name1[0] = name2[0] = 0;
1338 ok = VG_(get_fnname_w_offset)(nraddr, name1, 64);
1339 if (!ok) VG_(strcpy)(name1, "???");
1340 ok = VG_(get_fnname_w_offset)(addr, name2, 64);
1341 if (!ok) VG_(strcpy)(name2, "???");
1342 VG_(message)(Vg_DebugMsg,
1343 "REDIR: 0x%llx (%s) redirected to 0x%llx (%s)\n",
1348 if (!debugging_translation)
1349 VG_TRACK( pre_mem_read, Vg_CoreTranslate,
1350 tid, "(translator)", addr, 1 );
1352 /* If doing any code printing, print a basic block start marker */
1353 if (VG_(clo_trace_flags) || debugging_translation) {
1354 Char fnname[64] = "";
1355 VG_(get_fnname_w_offset)(addr, fnname, 64);
1357 "==== SB %d [tid %d] %s(0x%llx) SBs exec'd %lld ====\n",
1358 VG_(get_bbs_translated)(), (Int)tid, fnname, addr,
1362 /* Are we allowed to translate here? */
1364 { /* BEGIN new scope specially for 'seg' */
1365 NSegment const* seg = VG_(am_find_nsegment)(addr);
1367 if ( (!translations_allowable_from_seg(seg))
1368 || addr == TRANSTAB_BOGUS_GUEST_ADDR ) {
1369 if (VG_(clo_trace_signals))
1370 VG_(message)(Vg_DebugMsg, "translations not allowed here (0x%llx)"
1371 " - throwing SEGV\n", addr);
1372 /* U R busted, sonny. Place your hands on your head and step
1373 away from the orig_addr. */
1374 /* Code address is bad - deliver a signal instead */
1376 /* There's some kind of segment at the requested place, but we
1377 aren't allowed to execute code here. */
1378 if (debugging_translation)
1379 VG_(printf)("translations not allowed here (segment not executable)"
1380 "(0x%llx)\n", addr);
1382 VG_(synth_fault_perms)(tid, addr);
1384 /* There is no segment at all; we are attempting to execute in
1385 the middle of nowhere. */
1386 if (debugging_translation)
1387 VG_(printf)("translations not allowed here (no segment)"
1388 "(0x%llx)\n", addr);
1390 VG_(synth_fault_mapping)(tid, addr);
1395 /* Do we want a self-checking translation? */
1396 do_self_check = self_check_required( seg, tid );
1398 /* True if a debug trans., or if bit N set in VG_(clo_trace_codegen). */
1400 if (debugging_translation) {
1401 verbosity = debugging_verbosity;
1404 if ( (VG_(clo_trace_flags) > 0
1405 && VG_(get_bbs_translated)() >= VG_(clo_trace_notbelow) )) {
1406 verbosity = VG_(clo_trace_flags);
1409 /* Figure out which preamble-mangling callback to send. */
1411 if (kind == T_Redir_Replace)
1412 preamble_fn = mk_preamble__set_NRADDR_to_zero;
1414 if (kind == T_Redir_Wrap)
1415 preamble_fn = mk_preamble__set_NRADDR_to_nraddr;
1417 # if defined(VG_PLAT_USES_PPCTOC)
1418 if (ULong_to_Ptr(nraddr)
1419 == (void*)&VG_(ppctoc_magic_redirect_return_stub)) {
1420 /* If entering the special return stub, this means a wrapped or
1421 redirected function is returning. Make this translation one
1422 which restores R2 and LR from the thread's hidden redir
1423 stack, and branch to the (restored) link register, thereby
1424 really causing the function to return. */
1425 vg_assert(kind == T_Normal);
1426 vg_assert(nraddr == addr);
1427 preamble_fn = mk_preamble__ppctoc_magic_return_stub;
1431 /* ------ Actually do the translation. ------ */
1432 tl_assert2(VG_(tdict).tool_instrument,
1433 "you forgot to set VgToolInterface function 'tool_instrument'");
1435 /* Get the CPU info established at startup. */
1436 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
1438 /* Set up 'abiinfo' structure with stuff Vex needs to know about
1439 the guest and host ABIs. */
1441 LibVEX_default_VexAbiInfo( &vex_abiinfo );
1442 vex_abiinfo.guest_stack_redzone_size = VG_STACK_REDZONE_SZB;
1444 # if defined(VGP_amd64_linux)
1445 vex_abiinfo.guest_amd64_assume_fs_is_zero = True;
1447 # if defined(VGP_amd64_darwin)
1448 vex_abiinfo.guest_amd64_assume_gs_is_0x60 = True;
1450 # if defined(VGP_ppc32_linux)
1451 vex_abiinfo.guest_ppc_zap_RZ_at_blr = False;
1452 vex_abiinfo.guest_ppc_zap_RZ_at_bl = NULL;
1453 vex_abiinfo.host_ppc32_regalign_int64_args = True;
1455 # if defined(VGP_ppc64_linux)
1456 vex_abiinfo.guest_ppc_zap_RZ_at_blr = True;
1457 vex_abiinfo.guest_ppc_zap_RZ_at_bl = const_True;
1458 vex_abiinfo.host_ppc_calls_use_fndescrs = True;
1460 # if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
1461 vex_abiinfo.guest_ppc_zap_RZ_at_blr = False;
1462 vex_abiinfo.guest_ppc_zap_RZ_at_bl = bl_RZ_zap_ok_for_AIX;
1463 vex_abiinfo.guest_ppc_sc_continues_at_LR = True;
1464 vex_abiinfo.host_ppc_calls_use_fndescrs = True;
1467 /* Set up closure args. */
1469 closure.nraddr = nraddr;
1470 closure.readdr = addr;
1472 /* Set up args for LibVEX_Translate. */
1473 vta.arch_guest = vex_arch;
1474 vta.archinfo_guest = vex_archinfo;
1475 vta.arch_host = vex_arch;
1476 vta.archinfo_host = vex_archinfo;
1477 vta.abiinfo_both = vex_abiinfo;
1478 vta.guest_bytes = (UChar*)ULong_to_Ptr(addr);
1479 vta.guest_bytes_addr = (Addr64)addr;
1480 vta.callback_opaque = (void*)&closure;
1481 vta.chase_into_ok = chase_into_ok;
1482 vta.preamble_function = preamble_fn;
1483 vta.guest_extents = &vge;
1484 vta.host_bytes = tmpbuf;
1485 vta.host_bytes_size = N_TMPBUF;
1486 vta.host_bytes_used = &tmpbuf_used;
1487 { /* At this point we have to reconcile Vex's view of the
1488 instrumentation callback - which takes a void* first argument
1489 - with Valgrind's view, in which the first arg is a
1490 VgCallbackClosure*. Hence the following longwinded casts.
1491 They are entirely legal but longwinded so as to maximise the
1492 chance of the C typechecker picking up any type snafus. */
1493 IRSB*(*f)(VgCallbackClosure*,
1494 IRSB*,VexGuestLayout*,VexGuestExtents*,
1496 = VG_(clo_vgdb) != Vg_VgdbNo
1497 ? tool_instrument_then_gdbserver_if_needed
1498 : VG_(tdict).tool_instrument;
1500 IRSB*,VexGuestLayout*,VexGuestExtents*,
1502 = (IRSB*(*)(void*,IRSB*,VexGuestLayout*,VexGuestExtents*,IRType,IRType))f;
1503 vta.instrument1 = g;
1505 /* No need for type kludgery here. */
1506 vta.instrument2 = need_to_handle_SP_assignment()
1509 vta.finaltidy = VG_(needs).final_IR_tidy_pass
1510 ? VG_(tdict).tool_final_IR_tidy_pass
1512 vta.do_self_check = do_self_check;
1513 vta.traceflags = verbosity;
1515 /* Set up the dispatch-return info. For archs without a link
1516 register, vex generates a jump back to the specified dispatch
1517 address. Else, it just generates a branch-to-LR. */
1518 # if defined(VGA_x86) || defined(VGA_amd64)
1520 = (!allow_redirection)
1521 ? /* It's a no-redir translation. Will be run with the nonstandard
1522 dispatcher VG_(run_a_noredir_translation)
1523 and so needs a nonstandard return point. */
1524 (void*) &VG_(run_a_noredir_translation__return_point)
1526 : /* normal translation. Uses VG_(run_innerloop). Return
1527 point depends on whether we're profiling bbs or not. */
1528 VG_(clo_profile_flags) > 0
1529 ? (void*) &VG_(run_innerloop__dispatch_profiled)
1530 : (void*) &VG_(run_innerloop__dispatch_unprofiled);
1531 # elif defined(VGA_ppc32) || defined(VGA_ppc64) \
1532 || defined(VGA_arm) || defined(VGA_s390x)
1533 /* See comment libvex.h; machine has link register --> dipatch = NULL */
1534 vta.dispatch = NULL;
1536 # error "Unknown arch"
1539 /* Sheesh. Finally, actually _do_ the translation! */
1540 tres = LibVEX_Translate ( &vta );
1542 vg_assert(tres == VexTransOK);
1543 vg_assert(tmpbuf_used <= N_TMPBUF);
1544 vg_assert(tmpbuf_used > 0);
1546 /* Tell aspacem of all segments that have had translations taken
1547 from them. Optimisation: don't re-look up vge.base[0] since seg
1548 should already point to it. */
1550 vg_assert( vge.base[0] == (Addr64)addr );
1551 /* set 'translations taken from this segment' flag */
1552 VG_(am_set_segment_hasT_if_SkFileC_or_SkAnonC)( (NSegment*)seg );
1553 } /* END new scope specially for 'seg' */
1555 for (i = 1; i < vge.n_used; i++) {
1557 = VG_(am_find_nsegment)( vge.base[i] );
1558 /* set 'translations taken from this segment' flag */
1559 VG_(am_set_segment_hasT_if_SkFileC_or_SkAnonC)( (NSegment*)seg );
1562 /* Copy data at trans_addr into the translation cache. */
1563 vg_assert(tmpbuf_used > 0 && tmpbuf_used < 65536);
1565 // If debugging, don't do anything with the translated block; we
1566 // only did this for the debugging output produced along the way.
1567 if (!debugging_translation) {
1569 if (kind != T_NoRedir) {
1570 // Put it into the normal TT/TC structures. This is the
1573 // Note that we use nraddr (the non-redirected address), not
1574 // addr, which might have been changed by the redirection
1575 VG_(add_to_transtab)( &vge,
1581 VG_(add_to_unredir_transtab)( &vge,
1591 /*--------------------------------------------------------------------*/
1593 /*--------------------------------------------------------------------*/