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-2013 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_(instrument_for_gdbserver_if_needed)
64 #include "libvex_emnote.h" // For PPC, EmWarn_PPC64_redir_underflow
66 /*------------------------------------------------------------*/
68 /*------------------------------------------------------------*/
70 static UInt n_SP_updates_fast
= 0;
71 static UInt n_SP_updates_generic_known
= 0;
72 static UInt n_SP_updates_generic_unknown
= 0;
74 void VG_(print_translation_stats
) ( void )
77 UInt n_SP_updates
= n_SP_updates_fast
+ n_SP_updates_generic_known
78 + n_SP_updates_generic_unknown
;
79 VG_(percentify
)(n_SP_updates_fast
, n_SP_updates
, 1, 6, buf
);
80 VG_(message
)(Vg_DebugMsg
,
81 "translate: fast SP updates identified: %'u (%s)\n",
82 n_SP_updates_fast
, buf
);
84 VG_(percentify
)(n_SP_updates_generic_known
, n_SP_updates
, 1, 6, buf
);
85 VG_(message
)(Vg_DebugMsg
,
86 "translate: generic_known SP updates identified: %'u (%s)\n",
87 n_SP_updates_generic_known
, buf
);
89 VG_(percentify
)(n_SP_updates_generic_unknown
, n_SP_updates
, 1, 6, buf
);
90 VG_(message
)(Vg_DebugMsg
,
91 "translate: generic_unknown SP updates identified: %'u (%s)\n",
92 n_SP_updates_generic_unknown
, buf
);
95 /*------------------------------------------------------------*/
96 /*--- %SP-update pass ---*/
97 /*------------------------------------------------------------*/
99 static Bool
need_to_handle_SP_assignment(void)
101 return ( VG_(tdict
).track_new_mem_stack_4
||
102 VG_(tdict
).track_die_mem_stack_4
||
103 VG_(tdict
).track_new_mem_stack_8
||
104 VG_(tdict
).track_die_mem_stack_8
||
105 VG_(tdict
).track_new_mem_stack_12
||
106 VG_(tdict
).track_die_mem_stack_12
||
107 VG_(tdict
).track_new_mem_stack_16
||
108 VG_(tdict
).track_die_mem_stack_16
||
109 VG_(tdict
).track_new_mem_stack_32
||
110 VG_(tdict
).track_die_mem_stack_32
||
111 VG_(tdict
).track_new_mem_stack_112
||
112 VG_(tdict
).track_die_mem_stack_112
||
113 VG_(tdict
).track_new_mem_stack_128
||
114 VG_(tdict
).track_die_mem_stack_128
||
115 VG_(tdict
).track_new_mem_stack_144
||
116 VG_(tdict
).track_die_mem_stack_144
||
117 VG_(tdict
).track_new_mem_stack_160
||
118 VG_(tdict
).track_die_mem_stack_160
||
119 VG_(tdict
).track_new_mem_stack
||
120 VG_(tdict
).track_die_mem_stack
);
123 // - The SP aliases are held in an array which is used as a circular buffer.
124 // This misses very few constant updates of SP (ie. < 0.1%) while using a
125 // small, constant structure that will also never fill up and cause
126 // execution to abort.
127 // - Unused slots have a .temp value of 'IRTemp_INVALID'.
128 // - 'next_SP_alias_slot' is the index where the next alias will be stored.
129 // - If the buffer fills, we circle around and start over-writing
130 // non-IRTemp_INVALID values. This is rare, and the overwriting of a
131 // value that would have subsequently be used is even rarer.
132 // - Every slot below next_SP_alias_slot holds a non-IRTemp_INVALID value.
133 // The rest either all won't (if we haven't yet circled around) or all
134 // will (if we have circled around).
143 // With 32 slots the buffer fills very rarely -- eg. once in a run of GCC.
144 // And I've tested with smaller values and the wrap-around case works ok.
146 static SP_Alias SP_aliases
[N_ALIASES
];
147 static Int next_SP_alias_slot
= 0;
149 static void clear_SP_aliases(void)
152 for (i
= 0; i
< N_ALIASES
; i
++) {
153 SP_aliases
[i
].temp
= IRTemp_INVALID
;
154 SP_aliases
[i
].delta
= 0;
156 next_SP_alias_slot
= 0;
159 static void add_SP_alias(IRTemp temp
, Long delta
)
161 vg_assert(temp
!= IRTemp_INVALID
);
162 SP_aliases
[ next_SP_alias_slot
].temp
= temp
;
163 SP_aliases
[ next_SP_alias_slot
].delta
= delta
;
164 next_SP_alias_slot
++;
165 if (N_ALIASES
== next_SP_alias_slot
) next_SP_alias_slot
= 0;
168 static Bool
get_SP_delta(IRTemp temp
, Long
* delta
)
170 Int i
; // i must be signed!
171 vg_assert(IRTemp_INVALID
!= temp
);
172 // Search backwards between current buffer position and the start.
173 for (i
= next_SP_alias_slot
-1; i
>= 0; i
--) {
174 if (temp
== SP_aliases
[i
].temp
) {
175 *delta
= SP_aliases
[i
].delta
;
179 // Search backwards between the end and the current buffer position.
180 for (i
= N_ALIASES
-1; i
>= next_SP_alias_slot
; i
--) {
181 if (temp
== SP_aliases
[i
].temp
) {
182 *delta
= SP_aliases
[i
].delta
;
189 static void update_SP_aliases(Long delta
)
192 for (i
= 0; i
< N_ALIASES
; i
++) {
193 if (SP_aliases
[i
].temp
== IRTemp_INVALID
) {
196 SP_aliases
[i
].delta
+= delta
;
200 /* Given a guest IP, get an origin tag for a 1-element stack trace,
201 and wrap it up in an IR atom that can be passed as the origin-tag
202 value for a stack-adjustment helper function. */
203 static IRExpr
* mk_ecu_Expr ( Addr64 guest_IP
)
207 = VG_(make_depth_1_ExeContext_from_Addr
)( (Addr
)guest_IP
);
209 ecu
= VG_(get_ECU_from_ExeContext
)( ec
);
210 vg_assert(VG_(is_plausible_ECU
)(ecu
));
211 /* This is always safe to do, since ecu is only 32 bits, and
212 HWord is 32 or 64. */
213 return mkIRExpr_HWord( (HWord
)ecu
);
216 /* When gdbserver is activated, the translation of a block must
217 first be done by the tool function, then followed by a pass
218 which (if needed) instruments the code for gdbserver.
221 IRSB
* tool_instrument_then_gdbserver_if_needed ( VgCallbackClosure
* closureV
,
223 const VexGuestLayout
* layout
,
224 const VexGuestExtents
* vge
,
225 const VexArchInfo
* vai
,
229 return VG_(instrument_for_gdbserver_if_needed
)
230 (VG_(tdict
).tool_instrument (closureV
,
243 /* For tools that want to know about SP changes, this pass adds
244 in the appropriate hooks. We have to do it after the tool's
245 instrumentation, so the tool doesn't have to worry about the C calls
246 it adds in, and we must do it before register allocation because
247 spilled temps make it much harder to work out the SP deltas.
248 This it is done with Vex's "second instrumentation" pass.
250 Basically, we look for GET(SP)/PUT(SP) pairs and track constant
251 increments/decrements of SP between them. (This requires tracking one or
252 more "aliases", which are not exact aliases but instead are tempregs
253 whose value is equal to the SP's plus or minus a known constant.)
254 If all the changes to SP leading up to a PUT(SP) are by known, small
255 constants, we can do a specific call to eg. new_mem_stack_4, otherwise
256 we fall back to the case that handles an unknown SP change.
258 There is some extra complexity to deal correctly with updates to
259 only parts of SP. Bizarre, but it has been known to happen.
262 IRSB
* vg_SP_update_pass ( void* closureV
,
264 const VexGuestLayout
* layout
,
265 const VexGuestExtents
* vge
,
266 const VexArchInfo
* vai
,
270 Int i
, j
, k
, minoff_ST
, maxoff_ST
, sizeof_SP
, offset_SP
;
271 Int first_SP
, last_SP
, first_Put
, last_Put
;
279 /* Set up stuff for tracking the guest IP */
280 Bool curr_IP_known
= False
;
284 IRSB
* bb
= emptyIRSB();
285 bb
->tyenv
= deepCopyIRTypeEnv(sb_in
->tyenv
);
286 bb
->next
= deepCopyIRExpr(sb_in
->next
);
287 bb
->jumpkind
= sb_in
->jumpkind
;
288 bb
->offsIP
= sb_in
->offsIP
;
292 sizeof_SP
= layout
->sizeof_SP
;
293 offset_SP
= layout
->offset_SP
;
294 typeof_SP
= sizeof_SP
==4 ? Ity_I32
: Ity_I64
;
295 vg_assert(sizeof_SP
== 4 || sizeof_SP
== 8);
297 /* --- Start of #defines --- */
299 # define IS_ADD(op) (sizeof_SP==4 ? ((op)==Iop_Add32) : ((op)==Iop_Add64))
300 # define IS_SUB(op) (sizeof_SP==4 ? ((op)==Iop_Sub32) : ((op)==Iop_Sub64))
302 # define IS_ADD_OR_SUB(op) (IS_ADD(op) || IS_SUB(op))
304 # define GET_CONST(con) \
305 (sizeof_SP==4 ? (Long)(Int)(con->Ico.U32) \
306 : (Long)(con->Ico.U64))
308 # define DO_NEW(syze, tmpp) \
310 Bool vanilla, w_ecu; \
311 vg_assert(curr_IP_known); \
312 vanilla = NULL != VG_(tdict).track_new_mem_stack_##syze; \
313 w_ecu = NULL != VG_(tdict).track_new_mem_stack_##syze##_w_ECU; \
314 vg_assert(!(vanilla && w_ecu)); /* can't have both */ \
315 if (!(vanilla || w_ecu)) \
318 /* I don't know if it's really necessary to say that the */ \
319 /* call reads the stack pointer. But anyway, we do. */ \
321 dcall = unsafeIRDirty_0_N( \
323 "track_new_mem_stack_" #syze "_w_ECU", \
324 VG_(fnptr_to_fnentry)( \
325 VG_(tdict).track_new_mem_stack_##syze##_w_ECU ), \
326 mkIRExprVec_2(IRExpr_RdTmp(tmpp), \
327 mk_ecu_Expr(curr_IP)) \
330 dcall = unsafeIRDirty_0_N( \
332 "track_new_mem_stack_" #syze , \
333 VG_(fnptr_to_fnentry)( \
334 VG_(tdict).track_new_mem_stack_##syze ), \
335 mkIRExprVec_1(IRExpr_RdTmp(tmpp)) \
338 dcall->nFxState = 1; \
339 dcall->fxState[0].fx = Ifx_Read; \
340 dcall->fxState[0].offset = layout->offset_SP; \
341 dcall->fxState[0].size = layout->sizeof_SP; \
342 dcall->fxState[0].nRepeats = 0; \
343 dcall->fxState[0].repeatLen = 0; \
345 addStmtToIRSB( bb, IRStmt_Dirty(dcall) ); \
347 vg_assert(syze > 0); \
348 update_SP_aliases(syze); \
350 n_SP_updates_fast++; \
354 # define DO_DIE(syze, tmpp) \
356 if (!VG_(tdict).track_die_mem_stack_##syze) \
359 /* I don't know if it's really necessary to say that the */ \
360 /* call reads the stack pointer. But anyway, we do. */ \
361 dcall = unsafeIRDirty_0_N( \
363 "track_die_mem_stack_" #syze, \
364 VG_(fnptr_to_fnentry)( \
365 VG_(tdict).track_die_mem_stack_##syze ), \
366 mkIRExprVec_1(IRExpr_RdTmp(tmpp)) \
368 dcall->nFxState = 1; \
369 dcall->fxState[0].fx = Ifx_Read; \
370 dcall->fxState[0].offset = layout->offset_SP; \
371 dcall->fxState[0].size = layout->sizeof_SP; \
372 dcall->fxState[0].nRepeats = 0; \
373 dcall->fxState[0].repeatLen = 0; \
375 addStmtToIRSB( bb, IRStmt_Dirty(dcall) ); \
377 vg_assert(syze > 0); \
378 update_SP_aliases(-(syze)); \
380 n_SP_updates_fast++; \
384 /* --- End of #defines --- */
388 for (i
= 0; i
< sb_in
->stmts_used
; i
++) {
390 st
= sb_in
->stmts
[i
];
392 if (st
->tag
== Ist_IMark
) {
393 curr_IP_known
= True
;
394 curr_IP
= st
->Ist
.IMark
.addr
;
397 /* t = Get(sp): curr = t, delta = 0 */
398 if (st
->tag
!= Ist_WrTmp
) goto case2
;
399 e
= st
->Ist
.WrTmp
.data
;
400 if (e
->tag
!= Iex_Get
) goto case2
;
401 if (e
->Iex
.Get
.offset
!= offset_SP
) goto case2
;
402 if (e
->Iex
.Get
.ty
!= typeof_SP
) goto case2
;
403 vg_assert( typeOfIRTemp(bb
->tyenv
, st
->Ist
.WrTmp
.tmp
) == typeof_SP
);
404 add_SP_alias(st
->Ist
.WrTmp
.tmp
, 0);
405 addStmtToIRSB( bb
, st
);
409 /* t' = curr +/- const: curr = t', delta +=/-= const */
410 if (st
->tag
!= Ist_WrTmp
) goto case3
;
411 e
= st
->Ist
.WrTmp
.data
;
412 if (e
->tag
!= Iex_Binop
) goto case3
;
413 if (e
->Iex
.Binop
.arg1
->tag
!= Iex_RdTmp
) goto case3
;
414 if (!get_SP_delta(e
->Iex
.Binop
.arg1
->Iex
.RdTmp
.tmp
, &delta
)) goto case3
;
415 if (e
->Iex
.Binop
.arg2
->tag
!= Iex_Const
) goto case3
;
416 if (!IS_ADD_OR_SUB(e
->Iex
.Binop
.op
)) goto case3
;
417 con
= GET_CONST(e
->Iex
.Binop
.arg2
->Iex
.Const
.con
);
418 vg_assert( typeOfIRTemp(bb
->tyenv
, st
->Ist
.WrTmp
.tmp
) == typeof_SP
);
419 if (IS_ADD(e
->Iex
.Binop
.op
)) {
420 add_SP_alias(st
->Ist
.WrTmp
.tmp
, delta
+ con
);
422 add_SP_alias(st
->Ist
.WrTmp
.tmp
, delta
- con
);
424 addStmtToIRSB( bb
, st
);
428 /* t' = curr: curr = t' */
429 if (st
->tag
!= Ist_WrTmp
) goto case4
;
430 e
= st
->Ist
.WrTmp
.data
;
431 if (e
->tag
!= Iex_RdTmp
) goto case4
;
432 if (!get_SP_delta(e
->Iex
.RdTmp
.tmp
, &delta
)) goto case4
;
433 vg_assert( typeOfIRTemp(bb
->tyenv
, st
->Ist
.WrTmp
.tmp
) == typeof_SP
);
434 add_SP_alias(st
->Ist
.WrTmp
.tmp
, delta
);
435 addStmtToIRSB( bb
, st
);
440 /* More generally, we must correctly handle a Put which writes
441 any part of SP, not just the case where all of SP is
443 if (st
->tag
!= Ist_Put
) goto case5
;
444 first_SP
= offset_SP
;
445 last_SP
= first_SP
+ sizeof_SP
- 1;
446 first_Put
= st
->Ist
.Put
.offset
;
448 + sizeofIRType( typeOfIRExpr( bb
->tyenv
, st
->Ist
.Put
.data
))
450 vg_assert(first_SP
<= last_SP
);
451 vg_assert(first_Put
<= last_Put
);
453 if (last_Put
< first_SP
|| last_SP
< first_Put
)
454 goto case5
; /* no overlap */
456 if (st
->Ist
.Put
.data
->tag
== Iex_RdTmp
457 && get_SP_delta(st
->Ist
.Put
.data
->Iex
.RdTmp
.tmp
, &delta
)) {
458 IRTemp tttmp
= st
->Ist
.Put
.data
->Iex
.RdTmp
.tmp
;
459 /* Why should the following assertion hold? Because any
460 alias added by put_SP_alias must be of a temporary which
461 has the same type as typeof_SP, and whose value is a Get
462 at exactly offset_SP of size typeof_SP. Each call to
463 put_SP_alias is immediately preceded by an assertion that
464 we are putting in a binding for a correctly-typed
466 vg_assert( typeOfIRTemp(bb
->tyenv
, tttmp
) == typeof_SP
);
467 /* From the same type-and-offset-correctness argument, if
468 we found a useable alias, it must for an "exact" write of SP. */
469 vg_assert(first_SP
== first_Put
);
470 vg_assert(last_SP
== last_Put
);
472 case 0: addStmtToIRSB(bb
,st
); continue;
473 case 4: DO_DIE( 4, tttmp
); addStmtToIRSB(bb
,st
); continue;
474 case -4: DO_NEW( 4, tttmp
); addStmtToIRSB(bb
,st
); continue;
475 case 8: DO_DIE( 8, tttmp
); addStmtToIRSB(bb
,st
); continue;
476 case -8: DO_NEW( 8, tttmp
); addStmtToIRSB(bb
,st
); continue;
477 case 12: DO_DIE( 12, tttmp
); addStmtToIRSB(bb
,st
); continue;
478 case -12: DO_NEW( 12, tttmp
); addStmtToIRSB(bb
,st
); continue;
479 case 16: DO_DIE( 16, tttmp
); addStmtToIRSB(bb
,st
); continue;
480 case -16: DO_NEW( 16, tttmp
); addStmtToIRSB(bb
,st
); continue;
481 case 32: DO_DIE( 32, tttmp
); addStmtToIRSB(bb
,st
); continue;
482 case -32: DO_NEW( 32, tttmp
); addStmtToIRSB(bb
,st
); continue;
483 case 112: DO_DIE( 112, tttmp
); addStmtToIRSB(bb
,st
); continue;
484 case -112: DO_NEW( 112, tttmp
); addStmtToIRSB(bb
,st
); continue;
485 case 128: DO_DIE( 128, tttmp
); addStmtToIRSB(bb
,st
); continue;
486 case -128: DO_NEW( 128, tttmp
); addStmtToIRSB(bb
,st
); continue;
487 case 144: DO_DIE( 144, tttmp
); addStmtToIRSB(bb
,st
); continue;
488 case -144: DO_NEW( 144, tttmp
); addStmtToIRSB(bb
,st
); continue;
489 case 160: DO_DIE( 160, tttmp
); addStmtToIRSB(bb
,st
); continue;
490 case -160: DO_NEW( 160, tttmp
); addStmtToIRSB(bb
,st
); continue;
492 /* common values for ppc64: 144 128 160 112 176 */
493 n_SP_updates_generic_known
++;
497 /* Deal with an unknown update to SP. We're here because
499 (1) the Put does not exactly cover SP; it is a partial update.
500 Highly unlikely, but has been known to happen for 16-bit
501 Windows apps running on Wine, doing 16-bit adjustments to
503 (2) the Put does exactly cover SP, but we are unable to
504 determine how the value relates to the old SP. In any
505 case, we cannot assume that the Put.data value is a tmp;
506 we must assume it can be anything allowed in flat IR (tmp
510 n_SP_updates_generic_unknown
++;
512 // Nb: if all is well, this generic case will typically be
513 // called something like every 1000th SP update. If it's more than
514 // that, the above code may be missing some cases.
516 /* Pass both the old and new SP values to this helper. Also,
517 pass an origin tag, even if it isn't needed. */
518 old_SP
= newIRTemp(bb
->tyenv
, typeof_SP
);
521 IRStmt_WrTmp( old_SP
, IRExpr_Get(offset_SP
, typeof_SP
) )
524 /* Now we know what the old value of SP is. But knowing the new
525 value is a bit tricky if there is a partial write. */
526 if (first_Put
== first_SP
&& last_Put
== last_SP
) {
527 /* The common case, an exact write to SP. So st->Ist.Put.data
528 does hold the new value; simple. */
529 vg_assert(curr_IP_known
);
530 if (NULL
!= VG_(tdict
).track_new_mem_stack_w_ECU
)
531 dcall
= unsafeIRDirty_0_N(
533 "VG_(unknown_SP_update_w_ECU)",
534 VG_(fnptr_to_fnentry
)( &VG_(unknown_SP_update_w_ECU
) ),
535 mkIRExprVec_3( IRExpr_RdTmp(old_SP
), st
->Ist
.Put
.data
,
536 mk_ecu_Expr(curr_IP
) )
539 dcall
= unsafeIRDirty_0_N(
541 "VG_(unknown_SP_update)",
542 VG_(fnptr_to_fnentry
)( &VG_(unknown_SP_update
) ),
543 mkIRExprVec_2( IRExpr_RdTmp(old_SP
), st
->Ist
.Put
.data
)
546 addStmtToIRSB( bb
, IRStmt_Dirty(dcall
) );
547 /* don't forget the original assignment */
548 addStmtToIRSB( bb
, st
);
550 /* We have a partial update to SP. We need to know what
551 the new SP will be, and hand that to the helper call,
552 but when the helper call happens, SP must hold the
553 value it had before the update. Tricky.
554 Therefore use the following kludge:
555 1. do the partial SP update (Put)
556 2. Get the new SP value into a tmp, new_SP
563 addStmtToIRSB( bb
, st
);
565 new_SP
= newIRTemp(bb
->tyenv
, typeof_SP
);
568 IRStmt_WrTmp( new_SP
, IRExpr_Get(offset_SP
, typeof_SP
) )
571 addStmtToIRSB( bb
, IRStmt_Put(offset_SP
, IRExpr_RdTmp(old_SP
) ));
573 vg_assert(curr_IP_known
);
574 if (NULL
!= VG_(tdict
).track_new_mem_stack_w_ECU
)
575 dcall
= unsafeIRDirty_0_N(
577 "VG_(unknown_SP_update_w_ECU)",
578 VG_(fnptr_to_fnentry
)( &VG_(unknown_SP_update_w_ECU
) ),
579 mkIRExprVec_3( IRExpr_RdTmp(old_SP
),
580 IRExpr_RdTmp(new_SP
),
581 mk_ecu_Expr(curr_IP
) )
584 dcall
= unsafeIRDirty_0_N(
586 "VG_(unknown_SP_update)",
587 VG_(fnptr_to_fnentry
)( &VG_(unknown_SP_update
) ),
588 mkIRExprVec_2( IRExpr_RdTmp(old_SP
),
589 IRExpr_RdTmp(new_SP
) )
591 addStmtToIRSB( bb
, IRStmt_Dirty(dcall
) );
593 addStmtToIRSB( bb
, IRStmt_Put(offset_SP
, IRExpr_RdTmp(new_SP
) ));
596 /* Forget what we already know. */
599 /* If this is a Put of a tmp that exactly updates SP,
600 start tracking aliases against this tmp. */
602 if (first_Put
== first_SP
&& last_Put
== last_SP
603 && st
->Ist
.Put
.data
->tag
== Iex_RdTmp
) {
604 vg_assert( typeOfIRTemp(bb
->tyenv
, st
->Ist
.Put
.data
->Iex
.RdTmp
.tmp
)
606 add_SP_alias(st
->Ist
.Put
.data
->Iex
.RdTmp
.tmp
, 0);
612 /* PutI or Dirty call which overlaps SP: complain. We can't
613 deal with SP changing in weird ways (well, we can, but not at
614 this time of night). */
615 if (st
->tag
== Ist_PutI
) {
616 descr
= st
->Ist
.PutI
.details
->descr
;
617 minoff_ST
= descr
->base
;
618 maxoff_ST
= descr
->base
619 + descr
->nElems
* sizeofIRType(descr
->elemTy
) - 1;
620 if (!(offset_SP
> maxoff_ST
621 || (offset_SP
+ sizeof_SP
- 1) < minoff_ST
))
624 if (st
->tag
== Ist_Dirty
) {
625 d
= st
->Ist
.Dirty
.details
;
626 for (j
= 0; j
< d
->nFxState
; j
++) {
627 if (d
->fxState
[j
].fx
== Ifx_Read
|| d
->fxState
[j
].fx
== Ifx_None
)
629 /* Enumerate the described state segments */
630 for (k
= 0; k
< 1 + d
->fxState
[j
].nRepeats
; k
++) {
631 minoff_ST
= d
->fxState
[j
].offset
+ k
* d
->fxState
[j
].repeatLen
;
632 maxoff_ST
= minoff_ST
+ d
->fxState
[j
].size
- 1;
633 if (!(offset_SP
> maxoff_ST
634 || (offset_SP
+ sizeof_SP
- 1) < minoff_ST
))
640 /* well, not interesting. Just copy and keep going. */
641 addStmtToIRSB( bb
, st
);
643 } /* for (i = 0; i < sb_in->stmts_used; i++) */
648 VG_(core_panic
)("vg_SP_update_pass: PutI or Dirty which overlaps SP");
658 /*------------------------------------------------------------*/
659 /*--- Main entry point for the JITter. ---*/
660 /*------------------------------------------------------------*/
662 /* Extra comments re self-checking translations and self-modifying
663 code. (JRS 14 Oct 05).
666 (1) no checking: all code assumed to be not self-modifying
667 (2) partial: known-problematic situations get a self-check
668 (3) full checking: all translations get a self-check
670 As currently implemented, the default is (2). (3) is always safe,
671 but very slow. (1) works mostly, but fails for gcc nested-function
672 code which uses trampolines on the stack; this situation is
673 detected and handled by (2).
677 A more robust and transparent solution, which is not currently
678 implemented, is a variant of (2): if a translation is made from an
679 area which aspacem says does not have 'w' permission, then it can
680 be non-self-checking. Otherwise, it needs a self-check.
682 This is complicated by Vex's basic-block chasing. If a self-check
683 is requested, then Vex will not chase over basic block boundaries
684 (it's too complex). However there is still a problem if it chases
685 from a non-'w' area into a 'w' area.
687 I think the right thing to do is:
689 - if a translation request starts in a 'w' area, ask for a
690 self-checking translation, and do not allow any chasing (make
691 chase_into_ok return False). Note that the latter is redundant
692 in the sense that Vex won't chase anyway in this situation.
694 - if a translation request starts in a non-'w' area, do not ask for
695 a self-checking translation. However, do not allow chasing (as
696 determined by chase_into_ok) to go into a 'w' area.
698 The result of this is that all code inside 'w' areas is self
701 To complete the trick, there is a caveat: we must watch the
702 client's mprotect calls. If pages are changed from non-'w' to 'w'
703 then we should throw away all translations which intersect the
704 affected area, so as to force them to be redone with self-checks.
708 The above outlines the conditions under which bb chasing is allowed
709 from a self-modifying-code point of view. There are other
710 situations pertaining to function redirection in which it is
711 necessary to disallow chasing, but those fall outside the scope of
716 /* Vex dumps the final code in here. Then we can copy it off
718 /* 60000: should agree with assertion in VG_(add_to_transtab) in
720 #define N_TMPBUF 60000
721 static UChar tmpbuf
[N_TMPBUF
];
724 /* Function pointers we must supply to LibVEX in order that it
725 can bomb out and emit messages under Valgrind's control. */
726 __attribute__ ((noreturn
))
728 void failure_exit ( void )
730 LibVEX_ShowAllocStats();
731 VG_(core_panic
)("LibVEX called failure_exit().");
735 void log_bytes ( HChar
* bytes
, Int nbytes
)
738 for (i
= 0; i
< nbytes
-3; i
+= 4)
739 VG_(printf
)("%c%c%c%c", bytes
[i
], bytes
[i
+1], bytes
[i
+2], bytes
[i
+3]);
740 for (; i
< nbytes
; i
++)
741 VG_(printf
)("%c", bytes
[i
]);
745 /* --------- Various helper functions for translation --------- */
747 /* Look for reasons to disallow making translations from the given
750 static Bool
translations_allowable_from_seg ( NSegment
const* seg
, Addr addr
)
752 # if defined(VGA_x86) || defined(VGA_s390x) || defined(VGA_mips32) \
753 || defined(VGA_mips64)
759 && (seg
->kind
== SkAnonC
|| seg
->kind
== SkFileC
|| seg
->kind
== SkShmC
)
761 || (seg
->hasR
&& (allowR
762 || VG_(has_gdbserver_breakpoint
) (addr
))));
763 /* If GDB/gdbsrv has inserted a breakpoint at addr, assume this is a valid
764 location to translate if seg is not executable but is readable.
765 This is needed for inferior function calls from GDB: GDB inserts a
766 breakpoint on the stack, and expects to regain control before the
767 breakpoint instruction at the breakpoint address is really
768 executed. For this, the breakpoint instruction must be translated
769 so as to have the call to gdbserver executed. */
773 /* Produce a bitmask stating which of the supplied extents needs a
774 self-check. See documentation of
775 VexTranslateArgs::needs_self_check for more details about the
776 return convention. */
778 static UInt
needs_self_check ( void* closureV
,
779 const VexGuestExtents
* vge
)
781 VgCallbackClosure
* closure
= (VgCallbackClosure
*)closureV
;
784 vg_assert(vge
->n_used
>= 1 && vge
->n_used
<= 3);
787 for (i
= 0; i
< vge
->n_used
; i
++) {
789 Addr addr
= (Addr
)vge
->base
[i
];
790 SizeT len
= (SizeT
)vge
->len
[i
];
791 NSegment
const* segA
= NULL
;
793 # if defined(VGO_darwin)
794 // GrP fixme hack - dyld i386 IMPORT gets rewritten.
795 // To really do this correctly, we'd need to flush the
796 // translation cache whenever a segment became +WX.
797 segA
= VG_(am_find_nsegment
)(addr
);
798 if (segA
&& segA
->hasX
&& segA
->hasW
)
803 switch (VG_(clo_smc_check
)) {
805 /* never check (except as per Darwin hack above) */
812 /* check if the address is in the same segment as this
813 thread's stack pointer */
814 Addr sp
= VG_(get_SP
)(closure
->tid
);
816 segA
= VG_(am_find_nsegment
)(addr
);
818 NSegment
const* segSP
= VG_(am_find_nsegment
)(sp
);
819 if (segA
&& segSP
&& segA
== segSP
)
823 case Vg_SmcAllNonFile
: {
824 /* check if any part of the extent is not in a
825 file-mapped segment */
827 segA
= VG_(am_find_nsegment
)(addr
);
829 if (segA
&& segA
->kind
== SkFileC
&& segA
->start
<= addr
830 && (len
== 0 || addr
+ len
<= segA
->end
+ 1)) {
831 /* in a file-mapped segment; skip the check */
850 /* This is a callback passed to LibVEX_Translate. It stops Vex from
851 chasing into function entry points that we wish to redirect.
852 Chasing across them obviously defeats the redirect mechanism, with
853 bad effects for Memcheck, Helgrind, DRD, Massif, and possibly others.
855 static Bool
chase_into_ok ( void* closureV
, Addr64 addr64
)
857 Addr addr
= (Addr
)addr64
;
858 NSegment
const* seg
= VG_(am_find_nsegment
)(addr
);
860 /* Work through a list of possibilities why we might not want to
863 /* Destination not in a plausible segment? */
864 if (!translations_allowable_from_seg(seg
, addr
))
867 /* Destination is redirected? */
868 if (addr
!= VG_(redir_do_lookup
)(addr
, NULL
))
871 # if defined(VG_PLAT_USES_PPCTOC) || defined(VGP_ppc64le_linux)
872 /* This needs to be at the start of its own block. Don't chase. Re
873 ULong_to_Ptr, be careful to ensure we only compare 32 bits on a
875 if (ULong_to_Ptr(addr64
)
876 == (void*)&VG_(ppctoc_magic_redirect_return_stub
))
880 /* overly conservative, but .. don't chase into the distinguished
881 address that m_transtab uses as an empty-slot marker for
883 if (addr
== TRANSTAB_BOGUS_GUEST_ADDR
)
886 # if defined(VGA_s390x)
887 /* Never chase into an EX instruction. Generating IR for EX causes
888 a round-trip through the scheduler including VG_(discard_translations).
889 And that's expensive as shown by perf/tinycc.c:
890 Chasing into EX increases the number of EX translations from 21 to
891 102666 causing a 7x runtime increase for "none" and a 3.2x runtime
892 increase for memcheck. */
893 if (((UChar
*)ULong_to_Ptr(addr
))[0] == 0x44 || /* EX */
894 ((UChar
*)ULong_to_Ptr(addr
))[0] == 0xC6) /* EXRL */
898 /* well, ok then. go on and chase. */
905 if (0) VG_(printf
)("not chasing into 0x%lx\n", addr
);
910 /* --------------- helpers for with-TOC platforms --------------- */
912 /* NOTE: with-TOC platforms are: ppc64-linux. */
914 static IRExpr
* mkU64 ( ULong n
) {
915 return IRExpr_Const(IRConst_U64(n
));
917 static IRExpr
* mkU32 ( UInt n
) {
918 return IRExpr_Const(IRConst_U32(n
));
921 #if defined(VG_PLAT_USES_PPCTOC) || defined(VGP_ppc64le_linux)
922 static IRExpr
* mkU8 ( UChar n
) {
923 return IRExpr_Const(IRConst_U8(n
));
925 static IRExpr
* narrowTo32 ( IRTypeEnv
* tyenv
, IRExpr
* e
) {
926 if (typeOfIRExpr(tyenv
, e
) == Ity_I32
) {
929 vg_assert(typeOfIRExpr(tyenv
, e
) == Ity_I64
);
930 return IRExpr_Unop(Iop_64to32
, e
);
934 /* Generate code to push word-typed expression 'e' onto this thread's
935 redir stack, checking for stack overflow and generating code to
938 static void gen_PUSH ( IRSB
* bb
, IRExpr
* e
)
944 # if defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
945 Int stack_size
= VEX_GUEST_PPC64_REDIR_STACK_SIZE
;
946 Int offB_REDIR_SP
= offsetof(VexGuestPPC64State
,guest_REDIR_SP
);
947 Int offB_REDIR_STACK
= offsetof(VexGuestPPC64State
,guest_REDIR_STACK
);
948 Int offB_EMNOTE
= offsetof(VexGuestPPC64State
,guest_EMNOTE
);
949 Int offB_CIA
= offsetof(VexGuestPPC64State
,guest_CIA
);
951 IRType ty_Word
= Ity_I64
;
952 IROp op_CmpNE
= Iop_CmpNE64
;
953 IROp op_Sar
= Iop_Sar64
;
954 IROp op_Sub
= Iop_Sub64
;
955 IROp op_Add
= Iop_Add64
;
956 IRExpr
*(*mkU
)(ULong
) = mkU64
;
957 vg_assert(VG_WORDSIZE
== 8);
959 Int stack_size
= VEX_GUEST_PPC32_REDIR_STACK_SIZE
;
960 Int offB_REDIR_SP
= offsetof(VexGuestPPC32State
,guest_REDIR_SP
);
961 Int offB_REDIR_STACK
= offsetof(VexGuestPPC32State
,guest_REDIR_STACK
);
962 Int offB_EMNOTE
= offsetof(VexGuestPPC32State
,guest_EMNOTE
);
963 Int offB_CIA
= offsetof(VexGuestPPC32State
,guest_CIA
);
965 IRType ty_Word
= Ity_I32
;
966 IROp op_CmpNE
= Iop_CmpNE32
;
967 IROp op_Sar
= Iop_Sar32
;
968 IROp op_Sub
= Iop_Sub32
;
969 IROp op_Add
= Iop_Add32
;
970 IRExpr
*(*mkU
)(UInt
) = mkU32
;
971 vg_assert(VG_WORDSIZE
== 4);
974 vg_assert(sizeof(void*) == VG_WORDSIZE
);
975 vg_assert(sizeof(Word
) == VG_WORDSIZE
);
976 vg_assert(sizeof(Addr
) == VG_WORDSIZE
);
978 descr
= mkIRRegArray( offB_REDIR_STACK
, ty_Word
, stack_size
);
979 t1
= newIRTemp( bb
->tyenv
, ty_Word
);
982 vg_assert(typeOfIRExpr(bb
->tyenv
, e
) == ty_Word
);
984 /* t1 = guest_REDIR_SP + 1 */
989 IRExpr_Binop(op_Add
, IRExpr_Get( offB_REDIR_SP
, ty_Word
), one
)
993 /* Bomb out if t1 >=s stack_size, that is, (stack_size-1)-t1 <s 0.
994 The destination (0) is a bit bogus but it doesn't matter since
995 this is an unrecoverable error and will lead to Valgrind
996 shutting down. _EMNOTE is set regardless - that's harmless
997 since is only has a meaning if the exit is taken. */
1000 IRStmt_Put(offB_EMNOTE
, mkU32(EmWarn_PPC64_redir_overflow
))
1009 IRExpr_Binop(op_Sub
,mkU(stack_size
-1),IRExpr_RdTmp(t1
)),
1010 mkU8(8 * VG_WORDSIZE
- 1)
1015 is64
? IRConst_U64(0) : IRConst_U32(0),
1020 /* guest_REDIR_SP = t1 */
1021 addStmtToIRSB(bb
, IRStmt_Put(offB_REDIR_SP
, IRExpr_RdTmp(t1
)));
1023 /* guest_REDIR_STACK[t1+0] = e */
1024 /* PutI/GetI have I32-typed indexes regardless of guest word size */
1027 IRStmt_PutI(mkIRPutI(descr
,
1028 narrowTo32(bb
->tyenv
,IRExpr_RdTmp(t1
)), 0, e
)));
1032 /* Generate code to pop a word-sized value from this thread's redir
1033 stack, binding it to a new temporary, which is returned. As with
1034 gen_PUSH, an overflow check is also performed. */
1036 static IRTemp
gen_POP ( IRSB
* bb
)
1038 # if defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
1039 Int stack_size
= VEX_GUEST_PPC64_REDIR_STACK_SIZE
;
1040 Int offB_REDIR_SP
= offsetof(VexGuestPPC64State
,guest_REDIR_SP
);
1041 Int offB_REDIR_STACK
= offsetof(VexGuestPPC64State
,guest_REDIR_STACK
);
1042 Int offB_EMNOTE
= offsetof(VexGuestPPC64State
,guest_EMNOTE
);
1043 Int offB_CIA
= offsetof(VexGuestPPC64State
,guest_CIA
);
1045 IRType ty_Word
= Ity_I64
;
1046 IROp op_CmpNE
= Iop_CmpNE64
;
1047 IROp op_Sar
= Iop_Sar64
;
1048 IROp op_Sub
= Iop_Sub64
;
1049 IRExpr
*(*mkU
)(ULong
) = mkU64
;
1051 Int stack_size
= VEX_GUEST_PPC32_REDIR_STACK_SIZE
;
1052 Int offB_REDIR_SP
= offsetof(VexGuestPPC32State
,guest_REDIR_SP
);
1053 Int offB_REDIR_STACK
= offsetof(VexGuestPPC32State
,guest_REDIR_STACK
);
1054 Int offB_EMNOTE
= offsetof(VexGuestPPC32State
,guest_EMNOTE
);
1055 Int offB_CIA
= offsetof(VexGuestPPC32State
,guest_CIA
);
1057 IRType ty_Word
= Ity_I32
;
1058 IROp op_CmpNE
= Iop_CmpNE32
;
1059 IROp op_Sar
= Iop_Sar32
;
1060 IROp op_Sub
= Iop_Sub32
;
1061 IRExpr
*(*mkU
)(UInt
) = mkU32
;
1064 IRRegArray
* descr
= mkIRRegArray( offB_REDIR_STACK
, ty_Word
, stack_size
);
1065 IRTemp t1
= newIRTemp( bb
->tyenv
, ty_Word
);
1066 IRTemp res
= newIRTemp( bb
->tyenv
, ty_Word
);
1067 IRExpr
* one
= mkU(1);
1069 vg_assert(sizeof(void*) == VG_WORDSIZE
);
1070 vg_assert(sizeof(Word
) == VG_WORDSIZE
);
1071 vg_assert(sizeof(Addr
) == VG_WORDSIZE
);
1073 /* t1 = guest_REDIR_SP */
1076 IRStmt_WrTmp( t1
, IRExpr_Get( offB_REDIR_SP
, ty_Word
) )
1079 /* Bomb out if t1 < 0. Same comments as gen_PUSH apply. */
1082 IRStmt_Put(offB_EMNOTE
, mkU32(EmWarn_PPC64_redir_underflow
))
1092 mkU8(8 * VG_WORDSIZE
- 1)
1097 is64
? IRConst_U64(0) : IRConst_U32(0),
1102 /* res = guest_REDIR_STACK[t1+0] */
1103 /* PutI/GetI have I32-typed indexes regardless of guest word size */
1108 IRExpr_GetI(descr
, narrowTo32(bb
->tyenv
,IRExpr_RdTmp(t1
)), 0)
1112 /* guest_REDIR_SP = t1-1 */
1115 IRStmt_Put(offB_REDIR_SP
, IRExpr_Binop(op_Sub
, IRExpr_RdTmp(t1
), one
))
1123 #if defined(VG_PLAT_USES_PPCTOC)
1125 /* Generate code to push LR and R2 onto this thread's redir stack,
1126 then set R2 to the new value (which is the TOC pointer to be used
1127 for the duration of the replacement function, as determined by
1128 m_debuginfo), and set LR to the magic return stub, so we get to
1129 intercept the return and restore R2 and L2 to the values saved
1132 static void gen_push_and_set_LR_R2 ( IRSB
* bb
, Addr64 new_R2_value
)
1134 # if defined(VGP_ppc64be_linux)
1135 Addr64 bogus_RA
= (Addr64
)&VG_(ppctoc_magic_redirect_return_stub
);
1136 Int offB_GPR2
= offsetof(VexGuestPPC64State
,guest_GPR2
);
1137 Int offB_LR
= offsetof(VexGuestPPC64State
,guest_LR
);
1138 gen_PUSH( bb
, IRExpr_Get(offB_LR
, Ity_I64
) );
1139 gen_PUSH( bb
, IRExpr_Get(offB_GPR2
, Ity_I64
) );
1140 addStmtToIRSB( bb
, IRStmt_Put( offB_LR
, mkU64( bogus_RA
)) );
1141 addStmtToIRSB( bb
, IRStmt_Put( offB_GPR2
, mkU64( new_R2_value
)) );
1144 # error Platform is not TOC-afflicted, fortunately
1149 #if defined(VG_PLAT_USES_PPCTOC) || defined(VGP_ppc64le_linux)
1151 static void gen_pop_R2_LR_then_bLR ( IRSB
* bb
)
1153 # if defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
1154 Int offB_GPR2
= offsetof(VexGuestPPC64State
,guest_GPR2
);
1155 Int offB_LR
= offsetof(VexGuestPPC64State
,guest_LR
);
1156 Int offB_CIA
= offsetof(VexGuestPPC64State
,guest_CIA
);
1157 IRTemp old_R2
= newIRTemp( bb
->tyenv
, Ity_I64
);
1158 IRTemp old_LR
= newIRTemp( bb
->tyenv
, Ity_I64
);
1160 old_R2
= gen_POP( bb
);
1161 addStmtToIRSB( bb
, IRStmt_Put( offB_GPR2
, IRExpr_RdTmp(old_R2
)) );
1163 old_LR
= gen_POP( bb
);
1164 addStmtToIRSB( bb
, IRStmt_Put( offB_LR
, IRExpr_RdTmp(old_LR
)) );
1166 /* re boring, we arrived here precisely because a wrapped fn did a
1167 blr (hence Ijk_Ret); so we should just mark this jump as Boring,
1168 else one _Call will have resulted in two _Rets. */
1169 bb
->jumpkind
= Ijk_Boring
;
1170 bb
->next
= IRExpr_Binop(Iop_And64
, IRExpr_RdTmp(old_LR
), mkU64(~(3ULL)));
1171 bb
->offsIP
= offB_CIA
;
1173 # error Platform is not TOC-afflicted, fortunately
1178 #if defined(VG_PLAT_USES_PPCTOC) || defined(VGP_ppc64le_linux)
1181 Bool
mk_preamble__ppctoc_magic_return_stub ( void* closureV
, IRSB
* bb
)
1183 VgCallbackClosure
* closure
= (VgCallbackClosure
*)closureV
;
1184 /* Since we're creating the entire IRSB right here, give it a
1185 proper IMark, as it won't get one any other way, and cachegrind
1186 will barf if it doesn't have one (fair enough really). */
1187 addStmtToIRSB( bb
, IRStmt_IMark( closure
->readdr
, 4, 0 ) );
1188 /* Generate the magic sequence:
1189 pop R2 from hidden stack
1190 pop LR from hidden stack
1193 gen_pop_R2_LR_then_bLR(bb
);
1194 return True
; /* True == this is the entire BB; don't disassemble any
1195 real insns into it - just hand it directly to
1196 optimiser/instrumenter/backend. */
1200 #if defined(VGP_ppc64le_linux)
1201 /* Generate code to push LR and R2 onto this thread's redir stack.
1202 Need to save R2 in case we redirect to a global entry point. The
1203 value of R2 is not preserved when entering the global entry point.
1204 Need to make sure R2 gets restored on return. Set LR to the magic
1205 return stub, so we get to intercept the return and restore R2 and
1206 L2 to the values saved here.
1208 The existing infrastruture for the TOC enabled architectures is
1209 being exploited here. So, we need to enable a number of the
1210 code sections used by VG_PLAT_USES_PPCTOC.
1213 static void gen_push_R2_and_set_LR ( IRSB
* bb
)
1215 Addr64 bogus_RA
= (Addr64
)&VG_(ppctoc_magic_redirect_return_stub
);
1216 Int offB_GPR2
= offsetof(VexGuestPPC64State
,guest_GPR2
);
1217 Int offB_LR
= offsetof(VexGuestPPC64State
,guest_LR
);
1218 gen_PUSH( bb
, IRExpr_Get(offB_LR
, Ity_I64
) );
1219 gen_PUSH( bb
, IRExpr_Get(offB_GPR2
, Ity_I64
) );
1220 addStmtToIRSB( bb
, IRStmt_Put( offB_LR
, mkU64( bogus_RA
)) );
1224 /* --------------- END helpers for with-TOC platforms --------------- */
1227 /* This is the IR preamble generator used for replacement
1228 functions. It adds code to set the guest_NRADDR{_GPR2} to zero
1229 (technically not necessary, but facilitates detecting mixups in
1230 which a replacement function has been erroneously declared using
1231 VG_REPLACE_FUNCTION_Z{U,Z} when instead it should have been written
1232 using VG_WRAP_FUNCTION_Z{U,Z}).
1234 On with-TOC platforms the follow hacks are also done: LR and R2 are
1235 pushed onto a hidden stack, R2 is set to the correct value for the
1236 replacement function, and LR is set to point at the magic
1237 return-stub address. Setting LR causes the return of the
1238 wrapped/redirected function to lead to our magic return stub, which
1239 restores LR and R2 from said stack and returns for real.
1241 VG_(get_StackTrace_wrk) understands that the LR value may point to
1242 the return stub address, and that in that case it can get the real
1243 LR value from the hidden stack instead. */
1245 Bool
mk_preamble__set_NRADDR_to_zero ( void* closureV
, IRSB
* bb
)
1248 = sizeof(((VexGuestArchState
*)0)->guest_NRADDR
);
1249 vg_assert(nraddr_szB
== 4 || nraddr_szB
== 8);
1250 vg_assert(nraddr_szB
== VG_WORDSIZE
);
1254 offsetof(VexGuestArchState
,guest_NRADDR
),
1255 nraddr_szB
== 8 ? mkU64(0) : mkU32(0)
1258 // t9 needs to be set to point to the start of the redirected function.
1259 # if defined(VGP_mips32_linux)
1260 VgCallbackClosure
* closure
= (VgCallbackClosure
*)closureV
;
1261 Int offB_GPR25
= offsetof(VexGuestMIPS32State
, guest_r25
);
1262 addStmtToIRSB(bb
, IRStmt_Put(offB_GPR25
, mkU32(closure
->readdr
)));
1264 # if defined(VGP_mips64_linux)
1265 VgCallbackClosure
* closure
= (VgCallbackClosure
*)closureV
;
1266 Int offB_GPR25
= offsetof(VexGuestMIPS64State
, guest_r25
);
1267 addStmtToIRSB(bb
, IRStmt_Put(offB_GPR25
, mkU64(closure
->readdr
)));
1269 # if defined(VG_PLAT_USES_PPCTOC)
1270 { VgCallbackClosure
* closure
= (VgCallbackClosure
*)closureV
;
1274 offsetof(VexGuestArchState
,guest_NRADDR_GPR2
),
1275 VG_WORDSIZE
==8 ? mkU64(0) : mkU32(0)
1278 gen_push_and_set_LR_R2 ( bb
, VG_(get_tocptr
)( closure
->readdr
) );
1282 #if defined(VGP_ppc64le_linux)
1283 VgCallbackClosure
* closure
= (VgCallbackClosure
*)closureV
;
1284 Int offB_GPR12
= offsetof(VexGuestArchState
, guest_GPR12
);
1285 addStmtToIRSB(bb
, IRStmt_Put(offB_GPR12
, mkU64(closure
->readdr
)));
1288 offsetof(VexGuestArchState
,guest_NRADDR_GPR2
),
1289 VG_WORDSIZE
==8 ? mkU64(0) : mkU32(0)
1292 gen_push_R2_and_set_LR ( bb
);
1297 /* Ditto, except set guest_NRADDR to nraddr (the un-redirected guest
1298 address). This is needed for function wrapping - so the wrapper
1299 can read _NRADDR and find the address of the function being
1300 wrapped. On toc-afflicted platforms we must also snarf r2. */
1302 Bool
mk_preamble__set_NRADDR_to_nraddr ( void* closureV
, IRSB
* bb
)
1304 VgCallbackClosure
* closure
= (VgCallbackClosure
*)closureV
;
1306 = sizeof(((VexGuestArchState
*)0)->guest_NRADDR
);
1307 vg_assert(nraddr_szB
== 4 || nraddr_szB
== 8);
1308 vg_assert(nraddr_szB
== VG_WORDSIZE
);
1312 offsetof(VexGuestArchState
,guest_NRADDR
),
1314 ? IRExpr_Const(IRConst_U64( closure
->nraddr
))
1315 : IRExpr_Const(IRConst_U32( (UInt
)closure
->nraddr
))
1318 // t9 needs to be set to point to the start of the redirected function.
1319 # if defined(VGP_mips32_linux)
1320 Int offB_GPR25
= offsetof(VexGuestMIPS32State
, guest_r25
);
1321 addStmtToIRSB(bb
, IRStmt_Put(offB_GPR25
, mkU32(closure
->readdr
)));
1323 # if defined(VGP_mips64_linux)
1324 Int offB_GPR25
= offsetof(VexGuestMIPS64State
, guest_r25
);
1325 addStmtToIRSB(bb
, IRStmt_Put(offB_GPR25
, mkU64(closure
->readdr
)));
1327 # if defined(VG_PLAT_USES_PPCTOC) && !defined(VGP_ppc64le_linux)
1331 offsetof(VexGuestArchState
,guest_NRADDR_GPR2
),
1332 IRExpr_Get(offsetof(VexGuestArchState
,guest_GPR2
),
1333 VG_WORDSIZE
==8 ? Ity_I64
: Ity_I32
)
1336 gen_push_and_set_LR_R2 ( bb
, VG_(get_tocptr
)( closure
->readdr
) );
1338 #if defined(VGP_ppc64le_linux)
1339 /* This saves the r2 before leaving the function. We need to move
1340 * guest_NRADDR_GPR2 back to R2 on return.
1342 Int offB_GPR12
= offsetof(VexGuestArchState
, guest_GPR12
);
1346 offsetof(VexGuestArchState
,guest_NRADDR_GPR2
),
1347 IRExpr_Get(offsetof(VexGuestArchState
,guest_GPR2
),
1348 VG_WORDSIZE
==8 ? Ity_I64
: Ity_I32
)
1351 addStmtToIRSB(bb
, IRStmt_Put(offB_GPR12
, mkU64(closure
->readdr
)));
1352 gen_push_R2_and_set_LR ( bb
);
1357 /* --- Helpers to do with PPC related stack redzones. --- */
1359 __attribute__((unused
))
1360 static Bool
const_True ( Addr64 guest_addr
)
1365 /* --------------- main translation function --------------- */
1367 /* Note: see comments at top of m_redir.c for the Big Picture on how
1368 redirections are managed. */
1372 /* normal translation, redir neither requested nor inhibited */
1374 /* redir translation, function-wrap (set _NRADDR) style */
1376 /* redir translation, replacement (don't set _NRADDR) style */
1378 /* a translation in which redir is specifically disallowed */
1383 /* Translate the basic block beginning at NRADDR, and add it to the
1384 translation cache & translation table. Unless
1385 DEBUGGING_TRANSLATION is true, in which case the call is being done
1386 for debugging purposes, so (a) throw away the translation once it
1387 is made, and (b) produce a load of debugging output. If
1388 ALLOW_REDIRECTION is False, do not attempt redirection of NRADDR,
1389 and also, put the resulting translation into the no-redirect tt/tc
1390 instead of the normal one.
1392 TID is the identity of the thread requesting this translation.
1395 Bool
VG_(translate
) ( ThreadId tid
,
1397 Bool debugging_translation
,
1398 Int debugging_verbosity
,
1400 Bool allow_redirection
)
1404 Int tmpbuf_used
, verbosity
, i
;
1405 Bool (*preamble_fn
)(void*,IRSB
*);
1407 VexArchInfo vex_archinfo
;
1408 VexAbiInfo vex_abiinfo
;
1409 VexGuestExtents vge
;
1410 VexTranslateArgs vta
;
1411 VexTranslateResult tres
;
1412 VgCallbackClosure closure
;
1414 /* Make sure Vex is initialised right. */
1416 static Bool vex_init_done
= False
;
1418 if (!vex_init_done
) {
1419 LibVEX_Init ( &failure_exit
, &log_bytes
,
1420 1, /* debug_paranoia */
1421 &VG_(clo_vex_control
) );
1422 vex_init_done
= True
;
1425 /* Establish the translation kind and actual guest address to
1426 start from. Sets (addr,kind). */
1427 if (allow_redirection
) {
1429 Addr64 tmp
= VG_(redir_do_lookup
)( nraddr
, &isWrap
);
1430 if (tmp
== nraddr
) {
1431 /* no redirection found */
1435 /* found a redirect */
1437 kind
= isWrap
? T_Redir_Wrap
: T_Redir_Replace
;
1444 /* Established: (nraddr, addr, kind) */
1446 /* Printing redirection info. */
1448 if ((kind
== T_Redir_Wrap
|| kind
== T_Redir_Replace
)
1449 && (VG_(clo_verbosity
) >= 2 || VG_(clo_trace_redir
))) {
1454 /* Try also to get the soname (not the filename) of the "from"
1455 object. This makes it much easier to debug redirection
1457 const HChar
* nraddr_soname
= "???";
1458 DebugInfo
* nraddr_di
= VG_(find_DebugInfo
)(nraddr
);
1460 const HChar
* t
= VG_(DebugInfo_get_soname
)(nraddr_di
);
1465 ok
= VG_(get_fnname_w_offset
)(nraddr
, &buf
);
1466 if (!ok
) buf
= "???";
1468 HChar name1
[VG_(strlen
)(buf
) + 1];
1469 VG_(strcpy
)(name1
, buf
);
1470 ok
= VG_(get_fnname_w_offset
)(addr
, &name2
);
1471 if (!ok
) name2
= "???";
1473 VG_(message
)(Vg_DebugMsg
,
1474 "REDIR: 0x%llx (%s:%s) redirected to 0x%llx (%s)\n",
1475 nraddr
, nraddr_soname
, name1
,
1479 if (!debugging_translation
)
1480 VG_TRACK( pre_mem_read
, Vg_CoreTranslate
,
1481 tid
, "(translator)", addr
, 1 );
1483 /* If doing any code printing, print a basic block start marker */
1484 if (VG_(clo_trace_flags
) || debugging_translation
) {
1485 const HChar
* objname
= "UNKNOWN_OBJECT";
1487 DebugInfo
* di
= VG_(find_DebugInfo
)( addr
);
1489 objname
= VG_(DebugInfo_get_filename
)(di
);
1490 objoff
= addr
- VG_(DebugInfo_get_text_bias
)(di
);
1494 const HChar
*fnname
;
1495 Bool ok
= VG_(get_fnname_w_offset
)(addr
, &fnname
);
1496 if (!ok
) fnname
= "UNKNOWN_FUNCTION";
1498 "==== SB %d (evchecks %lld) [tid %d] 0x%llx %s %s+0x%llx\n",
1499 VG_(get_bbs_translated
)(), bbs_done
, (Int
)tid
, addr
,
1500 fnname
, objname
, (ULong
)objoff
1504 /* Are we allowed to translate here? */
1506 { /* BEGIN new scope specially for 'seg' */
1507 NSegment
const* seg
= VG_(am_find_nsegment
)(addr
);
1509 if ( (!translations_allowable_from_seg(seg
, addr
))
1510 || addr
== TRANSTAB_BOGUS_GUEST_ADDR
) {
1511 if (VG_(clo_trace_signals
))
1512 VG_(message
)(Vg_DebugMsg
, "translations not allowed here (0x%llx)"
1513 " - throwing SEGV\n", addr
);
1514 /* U R busted, sonny. Place your hands on your head and step
1515 away from the orig_addr. */
1516 /* Code address is bad - deliver a signal instead */
1518 /* There's some kind of segment at the requested place, but we
1519 aren't allowed to execute code here. */
1520 if (debugging_translation
)
1521 VG_(printf
)("translations not allowed here (segment not executable)"
1522 "(0x%llx)\n", addr
);
1524 VG_(synth_fault_perms
)(tid
, addr
);
1526 /* There is no segment at all; we are attempting to execute in
1527 the middle of nowhere. */
1528 if (debugging_translation
)
1529 VG_(printf
)("translations not allowed here (no segment)"
1530 "(0x%llx)\n", addr
);
1532 VG_(synth_fault_mapping
)(tid
, addr
);
1537 /* True if a debug trans., or if bit N set in VG_(clo_trace_codegen). */
1539 if (debugging_translation
) {
1540 verbosity
= debugging_verbosity
;
1543 if ( (VG_(clo_trace_flags
) > 0
1544 && VG_(get_bbs_translated
)() <= VG_(clo_trace_notabove
)
1545 && VG_(get_bbs_translated
)() >= VG_(clo_trace_notbelow
) )) {
1546 verbosity
= VG_(clo_trace_flags
);
1549 /* Figure out which preamble-mangling callback to send. */
1551 if (kind
== T_Redir_Replace
)
1552 preamble_fn
= mk_preamble__set_NRADDR_to_zero
;
1554 if (kind
== T_Redir_Wrap
)
1555 preamble_fn
= mk_preamble__set_NRADDR_to_nraddr
;
1557 /* LE we setup the LR */
1558 # if defined(VG_PLAT_USES_PPCTOC) || defined(VGP_ppc64le_linux)
1559 if (ULong_to_Ptr(nraddr
)
1560 == (void*)&VG_(ppctoc_magic_redirect_return_stub
)) {
1561 /* If entering the special return stub, this means a wrapped or
1562 redirected function is returning. Make this translation one
1563 which restores R2 and LR from the thread's hidden redir
1564 stack, and branch to the (restored) link register, thereby
1565 really causing the function to return. */
1566 vg_assert(kind
== T_Normal
);
1567 vg_assert(nraddr
== addr
);
1568 preamble_fn
= mk_preamble__ppctoc_magic_return_stub
;
1572 /* ------ Actually do the translation. ------ */
1573 vg_assert2(VG_(tdict
).tool_instrument
,
1574 "you forgot to set VgToolInterface function 'tool_instrument'");
1576 /* Get the CPU info established at startup. */
1577 VG_(machine_get_VexArchInfo
)( &vex_arch
, &vex_archinfo
);
1579 /* Set up 'abiinfo' structure with stuff Vex needs to know about
1580 the guest and host ABIs. */
1582 LibVEX_default_VexAbiInfo( &vex_abiinfo
);
1583 vex_abiinfo
.guest_stack_redzone_size
= VG_STACK_REDZONE_SZB
;
1585 # if defined(VGP_amd64_linux)
1586 vex_abiinfo
.guest_amd64_assume_fs_is_zero
= True
;
1588 # if defined(VGP_amd64_darwin)
1589 vex_abiinfo
.guest_amd64_assume_gs_is_0x60
= True
;
1591 # if defined(VGP_ppc32_linux)
1592 vex_abiinfo
.guest_ppc_zap_RZ_at_blr
= False
;
1593 vex_abiinfo
.guest_ppc_zap_RZ_at_bl
= NULL
;
1595 # if defined(VGP_ppc64be_linux)
1596 vex_abiinfo
.guest_ppc_zap_RZ_at_blr
= True
;
1597 vex_abiinfo
.guest_ppc_zap_RZ_at_bl
= const_True
;
1598 vex_abiinfo
.host_ppc_calls_use_fndescrs
= True
;
1600 # if defined(VGP_ppc64le_linux)
1601 vex_abiinfo
.guest_ppc_zap_RZ_at_blr
= True
;
1602 vex_abiinfo
.guest_ppc_zap_RZ_at_bl
= const_True
;
1603 vex_abiinfo
.host_ppc_calls_use_fndescrs
= False
;
1606 /* Set up closure args. */
1608 closure
.nraddr
= nraddr
;
1609 closure
.readdr
= addr
;
1611 /* Set up args for LibVEX_Translate. */
1612 vta
.arch_guest
= vex_arch
;
1613 vta
.archinfo_guest
= vex_archinfo
;
1614 vta
.arch_host
= vex_arch
;
1615 vta
.archinfo_host
= vex_archinfo
;
1616 vta
.abiinfo_both
= vex_abiinfo
;
1617 vta
.callback_opaque
= (void*)&closure
;
1618 vta
.guest_bytes
= (UChar
*)ULong_to_Ptr(addr
);
1619 vta
.guest_bytes_addr
= (Addr64
)addr
;
1620 vta
.chase_into_ok
= chase_into_ok
;
1621 vta
.guest_extents
= &vge
;
1622 vta
.host_bytes
= tmpbuf
;
1623 vta
.host_bytes_size
= N_TMPBUF
;
1624 vta
.host_bytes_used
= &tmpbuf_used
;
1625 { /* At this point we have to reconcile Vex's view of the
1626 instrumentation callback - which takes a void* first argument
1627 - with Valgrind's view, in which the first arg is a
1628 VgCallbackClosure*. Hence the following longwinded casts.
1629 They are entirely legal but longwinded so as to maximise the
1630 chance of the C typechecker picking up any type snafus. */
1631 IRSB
*(*f
)(VgCallbackClosure
*,
1632 IRSB
*,const VexGuestLayout
*,const VexGuestExtents
*,
1633 const VexArchInfo
*,IRType
,IRType
)
1634 = VG_(clo_vgdb
) != Vg_VgdbNo
1635 ? tool_instrument_then_gdbserver_if_needed
1636 : VG_(tdict
).tool_instrument
;
1638 IRSB
*,const VexGuestLayout
*,const VexGuestExtents
*,
1639 const VexArchInfo
*,IRType
,IRType
) = (__typeof__(g
)) f
;
1640 vta
.instrument1
= g
;
1642 /* No need for type kludgery here. */
1643 vta
.instrument2
= need_to_handle_SP_assignment()
1646 vta
.finaltidy
= VG_(needs
).final_IR_tidy_pass
1647 ? VG_(tdict
).tool_final_IR_tidy_pass
1649 vta
.needs_self_check
= needs_self_check
;
1650 vta
.preamble_function
= preamble_fn
;
1651 vta
.traceflags
= verbosity
;
1652 vta
.sigill_diag
= VG_(clo_sigill_diag
);
1653 vta
.addProfInc
= VG_(clo_profyle_sbs
) && kind
!= T_NoRedir
;
1655 /* Set up the dispatch continuation-point info. If this is a
1656 no-redir translation then it cannot be chained, and the chain-me
1657 points are set to NULL to indicate that. The indir point must
1658 also be NULL, since we can't allow this translation to do an
1659 indir transfer -- that would take it back into the main
1660 translation cache too.
1662 All this is because no-redir translations live outside the main
1663 translation cache (in a secondary one) and chaining them would
1664 involve more adminstrative complexity that isn't worth the
1665 hassle, because we don't expect them to get used often. So
1667 if (allow_redirection
) {
1668 vta
.disp_cp_chain_me_to_slowEP
1669 = VG_(fnptr_to_fnentry
)( &VG_(disp_cp_chain_me_to_slowEP
) );
1670 vta
.disp_cp_chain_me_to_fastEP
1671 = VG_(fnptr_to_fnentry
)( &VG_(disp_cp_chain_me_to_fastEP
) );
1673 = VG_(fnptr_to_fnentry
)( &VG_(disp_cp_xindir
) );
1675 vta
.disp_cp_chain_me_to_slowEP
= NULL
;
1676 vta
.disp_cp_chain_me_to_fastEP
= NULL
;
1677 vta
.disp_cp_xindir
= NULL
;
1679 /* This doesn't involve chaining and so is always allowable. */
1680 vta
.disp_cp_xassisted
1681 = VG_(fnptr_to_fnentry
)( &VG_(disp_cp_xassisted
) );
1683 /* Sheesh. Finally, actually _do_ the translation! */
1684 tres
= LibVEX_Translate ( &vta
);
1686 vg_assert(tres
.status
== VexTransOK
);
1687 vg_assert(tres
.n_sc_extents
>= 0 && tres
.n_sc_extents
<= 3);
1688 vg_assert(tmpbuf_used
<= N_TMPBUF
);
1689 vg_assert(tmpbuf_used
> 0);
1691 /* Tell aspacem of all segments that have had translations taken
1692 from them. Optimisation: don't re-look up vge.base[0] since seg
1693 should already point to it. */
1695 vg_assert( vge
.base
[0] == (Addr64
)addr
);
1696 /* set 'translations taken from this segment' flag */
1697 VG_(am_set_segment_hasT_if_SkFileC_or_SkAnonC
)( seg
);
1698 } /* END new scope specially for 'seg' */
1700 for (i
= 1; i
< vge
.n_used
; i
++) {
1702 = VG_(am_find_nsegment
)( vge
.base
[i
] );
1703 /* set 'translations taken from this segment' flag */
1704 VG_(am_set_segment_hasT_if_SkFileC_or_SkAnonC
)( seg
);
1707 /* Copy data at trans_addr into the translation cache. */
1708 vg_assert(tmpbuf_used
> 0 && tmpbuf_used
< 65536);
1710 // If debugging, don't do anything with the translated block; we
1711 // only did this for the debugging output produced along the way.
1712 if (!debugging_translation
) {
1714 if (kind
!= T_NoRedir
) {
1715 // Put it into the normal TT/TC structures. This is the
1718 // Note that we use nraddr (the non-redirected address), not
1719 // addr, which might have been changed by the redirection
1720 VG_(add_to_transtab
)( &vge
,
1724 tres
.n_sc_extents
> 0,
1726 tres
.n_guest_instrs
);
1728 vg_assert(tres
.offs_profInc
== -1); /* -1 == unset */
1729 VG_(add_to_unredir_transtab
)( &vge
,
1739 /*--------------------------------------------------------------------*/
1741 /*--------------------------------------------------------------------*/