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