drd: Add a consistency check
[valgrind.git] / coregrind / m_translate.c
blobb5d10fbb22698cbab7152a5bc962f5ba79a2fe73
2 /*--------------------------------------------------------------------*/
3 /*--- Interface to LibVEX_Translate, and the SP-update pass ---*/
4 /*--- m_translate.c ---*/
5 /*--------------------------------------------------------------------*/
7 /*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
11 Copyright (C) 2000-2013 Julian Seward
12 jseward@acm.org
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
27 02111-1307, USA.
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)
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"
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 /*------------------------------------------------------------*/
67 /*--- Stats ---*/
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 )
76 HChar buf[7];
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).
136 typedef
137 struct {
138 IRTemp temp;
139 Long delta;
141 SP_Alias;
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.
145 #define N_ALIASES 32
146 static SP_Alias SP_aliases[N_ALIASES];
147 static Int next_SP_alias_slot = 0;
149 static void clear_SP_aliases(void)
151 Int i;
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;
176 return True;
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;
183 return True;
186 return False;
189 static void update_SP_aliases(Long delta)
191 Int i;
192 for (i = 0; i < N_ALIASES; i++) {
193 if (SP_aliases[i].temp == IRTemp_INVALID) {
194 return;
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 )
205 UInt ecu;
206 ExeContext* ec
207 = VG_(make_depth_1_ExeContext_from_Addr)( (Addr)guest_IP );
208 vg_assert(ec);
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.
220 static
221 IRSB* tool_instrument_then_gdbserver_if_needed ( VgCallbackClosure* closureV,
222 IRSB* sb_in,
223 const VexGuestLayout* layout,
224 const VexGuestExtents* vge,
225 const VexArchInfo* vai,
226 IRType gWordTy,
227 IRType hWordTy )
229 return VG_(instrument_for_gdbserver_if_needed)
230 (VG_(tdict).tool_instrument (closureV,
231 sb_in,
232 layout,
233 vge,
234 vai,
235 gWordTy,
236 hWordTy),
237 layout,
238 vge,
239 gWordTy,
240 hWordTy);
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.
261 static
262 IRSB* vg_SP_update_pass ( void* closureV,
263 IRSB* sb_in,
264 const VexGuestLayout* layout,
265 const VexGuestExtents* vge,
266 const VexArchInfo* vai,
267 IRType gWordTy,
268 IRType hWordTy )
270 Int i, j, k, minoff_ST, maxoff_ST, sizeof_SP, offset_SP;
271 Int first_SP, last_SP, first_Put, last_Put;
272 IRDirty *dcall, *d;
273 IRStmt* st;
274 IRExpr* e;
275 IRRegArray* descr;
276 IRType typeof_SP;
277 Long delta, con;
279 /* Set up stuff for tracking the guest IP */
280 Bool curr_IP_known = False;
281 Addr64 curr_IP = 0;
283 /* Set up BB */
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;
290 delta = 0;
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) \
309 do { \
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)) \
316 goto generic; \
318 /* I don't know if it's really necessary to say that the */ \
319 /* call reads the stack pointer. But anyway, we do. */ \
320 if (w_ecu) { \
321 dcall = unsafeIRDirty_0_N( \
322 2/*regparms*/, \
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)) \
328 ); \
329 } else { \
330 dcall = unsafeIRDirty_0_N( \
331 1/*regparms*/, \
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)) \
336 ); \
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++; \
352 } while (0)
354 # define DO_DIE(syze, tmpp) \
355 do { \
356 if (!VG_(tdict).track_die_mem_stack_##syze) \
357 goto generic; \
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( \
362 1/*regparms*/, \
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)) \
367 ); \
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++; \
382 } while (0)
384 /* --- End of #defines --- */
386 clear_SP_aliases();
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 );
406 continue;
408 case2:
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);
421 } else {
422 add_SP_alias(st->Ist.WrTmp.tmp, delta - con);
424 addStmtToIRSB( bb, st );
425 continue;
427 case3:
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 );
436 continue;
438 case4:
439 /* Put(sp) = curr */
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
442 written. */
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;
447 last_Put = first_Put
448 + sizeofIRType( typeOfIRExpr( bb->tyenv, st->Ist.Put.data ))
449 - 1;
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
465 temporary. */
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);
471 switch (delta) {
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;
491 default:
492 /* common values for ppc64: 144 128 160 112 176 */
493 n_SP_updates_generic_known++;
494 goto generic;
496 } else {
497 /* Deal with an unknown update to SP. We're here because
498 either:
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
502 %sp.
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
507 or const).
509 IRTemp old_SP;
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.
515 generic:
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);
519 addStmtToIRSB(
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(
532 3/*regparms*/,
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) )
538 else
539 dcall = unsafeIRDirty_0_N(
540 2/*regparms*/,
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 );
549 } else {
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
557 3. Put old_SP
558 4. Call the helper
559 5. Put new_SP
561 IRTemp new_SP;
562 /* 1 */
563 addStmtToIRSB( bb, st );
564 /* 2 */
565 new_SP = newIRTemp(bb->tyenv, typeof_SP);
566 addStmtToIRSB(
568 IRStmt_WrTmp( new_SP, IRExpr_Get(offset_SP, typeof_SP) )
570 /* 3 */
571 addStmtToIRSB( bb, IRStmt_Put(offset_SP, IRExpr_RdTmp(old_SP) ));
572 /* 4 */
573 vg_assert(curr_IP_known);
574 if (NULL != VG_(tdict).track_new_mem_stack_w_ECU)
575 dcall = unsafeIRDirty_0_N(
576 3/*regparms*/,
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) )
583 else
584 dcall = unsafeIRDirty_0_N(
585 2/*regparms*/,
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) );
592 /* 5 */
593 addStmtToIRSB( bb, IRStmt_Put(offset_SP, IRExpr_RdTmp(new_SP) ));
596 /* Forget what we already know. */
597 clear_SP_aliases();
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)
605 == typeof_SP );
606 add_SP_alias(st->Ist.Put.data->Iex.RdTmp.tmp, 0);
608 continue;
611 case5:
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))
622 goto complain;
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)
628 continue;
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))
635 goto complain;
640 /* well, not interesting. Just copy and keep going. */
641 addStmtToIRSB( bb, st );
643 } /* for (i = 0; i < sb_in->stmts_used; i++) */
645 return bb;
647 complain:
648 VG_(core_panic)("vg_SP_update_pass: PutI or Dirty which overlaps SP");
650 #undef IS_ADD
651 #undef IS_SUB
652 #undef IS_ADD_OR_SUB
653 #undef GET_CONST
654 #undef DO_NEW
655 #undef DO_DIE
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).
665 There are 3 modes:
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).
675 ----------
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
699 checking.
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.
706 ----------
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
712 this comment.
716 /* Vex dumps the final code in here. Then we can copy it off
717 wherever we like. */
718 /* 60000: should agree with assertion in VG_(add_to_transtab) in
719 m_transtab.c. */
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))
727 static
728 void failure_exit ( void )
730 LibVEX_ShowAllocStats();
731 VG_(core_panic)("LibVEX called failure_exit().");
734 static
735 void log_bytes ( HChar* bytes, Int nbytes )
737 Int i;
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
748 segment/addr. */
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)
754 Bool allowR = True;
755 # else
756 Bool allowR = False;
757 # endif
758 return seg != NULL
759 && (seg->kind == SkAnonC || seg->kind == SkFileC || seg->kind == SkShmC)
760 && (seg->hasX
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;
782 UInt i, bitset;
784 vg_assert(vge->n_used >= 1 && vge->n_used <= 3);
785 bitset = 0;
787 for (i = 0; i < vge->n_used; i++) {
788 Bool check = False;
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)
799 check = True;
800 # endif
802 if (!check) {
803 switch (VG_(clo_smc_check)) {
804 case Vg_SmcNone:
805 /* never check (except as per Darwin hack above) */
806 break;
807 case Vg_SmcAll:
808 /* always check */
809 check = True;
810 break;
811 case Vg_SmcStack: {
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);
815 if (!segA) {
816 segA = VG_(am_find_nsegment)(addr);
818 NSegment const* segSP = VG_(am_find_nsegment)(sp);
819 if (segA && segSP && segA == segSP)
820 check = True;
821 break;
823 case Vg_SmcAllNonFile: {
824 /* check if any part of the extent is not in a
825 file-mapped segment */
826 if (!segA) {
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 */
832 } else {
833 check = True;
835 break;
837 default:
838 vg_assert(0);
842 if (check)
843 bitset |= (1 << i);
846 return bitset;
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
861 allow a chase. */
863 /* Destination not in a plausible segment? */
864 if (!translations_allowable_from_seg(seg, addr))
865 goto dontchase;
867 /* Destination is redirected? */
868 if (addr != VG_(redir_do_lookup)(addr, NULL))
869 goto dontchase;
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
874 32-bit target.*/
875 if (ULong_to_Ptr(addr64)
876 == (void*)&VG_(ppctoc_magic_redirect_return_stub))
877 goto dontchase;
878 # endif
880 /* overly conservative, but .. don't chase into the distinguished
881 address that m_transtab uses as an empty-slot marker for
882 VG_(tt_fast). */
883 if (addr == TRANSTAB_BOGUS_GUEST_ADDR)
884 goto dontchase;
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 */
895 goto dontchase;
896 # endif
898 /* well, ok then. go on and chase. */
899 return True;
901 vg_assert(0);
902 /*NOTREACHED*/
904 dontchase:
905 if (0) VG_(printf)("not chasing into 0x%lx\n", addr);
906 return False;
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) {
927 return e;
928 } else {
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
936 bomb out if so. */
938 static void gen_PUSH ( IRSB* bb, IRExpr* e )
940 IRRegArray* descr;
941 IRTemp t1;
942 IRExpr* one;
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);
950 Bool is64 = True;
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);
958 # else
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);
964 Bool is64 = False;
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);
972 # endif
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 );
980 one = mkU(1);
982 vg_assert(typeOfIRExpr(bb->tyenv, e) == ty_Word);
984 /* t1 = guest_REDIR_SP + 1 */
985 addStmtToIRSB(
986 bb,
987 IRStmt_WrTmp(
988 t1,
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. */
998 addStmtToIRSB(
1000 IRStmt_Put(offB_EMNOTE, mkU32(EmWarn_PPC64_redir_overflow))
1002 addStmtToIRSB(
1004 IRStmt_Exit(
1005 IRExpr_Binop(
1006 op_CmpNE,
1007 IRExpr_Binop(
1008 op_Sar,
1009 IRExpr_Binop(op_Sub,mkU(stack_size-1),IRExpr_RdTmp(t1)),
1010 mkU8(8 * VG_WORDSIZE - 1)
1012 mkU(0)
1014 Ijk_EmFail,
1015 is64 ? IRConst_U64(0) : IRConst_U32(0),
1016 offB_CIA
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 */
1025 addStmtToIRSB(
1026 bb,
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);
1044 Bool is64 = True;
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;
1050 # else
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);
1056 Bool is64 = False;
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;
1062 # endif
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 */
1074 addStmtToIRSB(
1075 bb,
1076 IRStmt_WrTmp( t1, IRExpr_Get( offB_REDIR_SP, ty_Word ) )
1079 /* Bomb out if t1 < 0. Same comments as gen_PUSH apply. */
1080 addStmtToIRSB(
1082 IRStmt_Put(offB_EMNOTE, mkU32(EmWarn_PPC64_redir_underflow))
1084 addStmtToIRSB(
1086 IRStmt_Exit(
1087 IRExpr_Binop(
1088 op_CmpNE,
1089 IRExpr_Binop(
1090 op_Sar,
1091 IRExpr_RdTmp(t1),
1092 mkU8(8 * VG_WORDSIZE - 1)
1094 mkU(0)
1096 Ijk_EmFail,
1097 is64 ? IRConst_U64(0) : IRConst_U32(0),
1098 offB_CIA
1102 /* res = guest_REDIR_STACK[t1+0] */
1103 /* PutI/GetI have I32-typed indexes regardless of guest word size */
1104 addStmtToIRSB(
1106 IRStmt_WrTmp(
1107 res,
1108 IRExpr_GetI(descr, narrowTo32(bb->tyenv,IRExpr_RdTmp(t1)), 0)
1112 /* guest_REDIR_SP = t1-1 */
1113 addStmtToIRSB(
1114 bb,
1115 IRStmt_Put(offB_REDIR_SP, IRExpr_Binop(op_Sub, IRExpr_RdTmp(t1), one))
1118 return res;
1121 #endif
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
1130 here. */
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 )) );
1143 # else
1144 # error Platform is not TOC-afflicted, fortunately
1145 # endif
1147 #endif
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 );
1159 /* Restore R2 */
1160 old_R2 = gen_POP( bb );
1161 addStmtToIRSB( bb, IRStmt_Put( offB_GPR2, IRExpr_RdTmp(old_R2)) );
1162 /* Restore LR */
1163 old_LR = gen_POP( bb );
1164 addStmtToIRSB( bb, IRStmt_Put( offB_LR, IRExpr_RdTmp(old_LR)) );
1165 /* Branch to 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;
1172 # else
1173 # error Platform is not TOC-afflicted, fortunately
1174 # endif
1176 #endif
1178 #if defined(VG_PLAT_USES_PPCTOC) || defined(VGP_ppc64le_linux)
1180 static
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
1191 goto LR
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. */
1198 #endif
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 )) );
1222 # endif
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. */
1244 static
1245 Bool mk_preamble__set_NRADDR_to_zero ( void* closureV, IRSB* bb )
1247 Int nraddr_szB
1248 = sizeof(((VexGuestArchState*)0)->guest_NRADDR);
1249 vg_assert(nraddr_szB == 4 || nraddr_szB == 8);
1250 vg_assert(nraddr_szB == VG_WORDSIZE);
1251 addStmtToIRSB(
1253 IRStmt_Put(
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)));
1263 # endif
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)));
1268 # endif
1269 # if defined(VG_PLAT_USES_PPCTOC)
1270 { VgCallbackClosure* closure = (VgCallbackClosure*)closureV;
1271 addStmtToIRSB(
1273 IRStmt_Put(
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 ) );
1280 # endif
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)));
1286 addStmtToIRSB(bb,
1287 IRStmt_Put(
1288 offsetof(VexGuestArchState,guest_NRADDR_GPR2),
1289 VG_WORDSIZE==8 ? mkU64(0) : mkU32(0)
1292 gen_push_R2_and_set_LR ( bb );
1293 #endif
1294 return False;
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. */
1301 static
1302 Bool mk_preamble__set_NRADDR_to_nraddr ( void* closureV, IRSB* bb )
1304 VgCallbackClosure* closure = (VgCallbackClosure*)closureV;
1305 Int nraddr_szB
1306 = sizeof(((VexGuestArchState*)0)->guest_NRADDR);
1307 vg_assert(nraddr_szB == 4 || nraddr_szB == 8);
1308 vg_assert(nraddr_szB == VG_WORDSIZE);
1309 addStmtToIRSB(
1311 IRStmt_Put(
1312 offsetof(VexGuestArchState,guest_NRADDR),
1313 nraddr_szB == 8
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)));
1322 # endif
1323 # if defined(VGP_mips64_linux)
1324 Int offB_GPR25 = offsetof(VexGuestMIPS64State, guest_r25);
1325 addStmtToIRSB(bb, IRStmt_Put(offB_GPR25, mkU64(closure->readdr)));
1326 # endif
1327 # if defined(VG_PLAT_USES_PPCTOC) && !defined(VGP_ppc64le_linux)
1328 addStmtToIRSB(
1330 IRStmt_Put(
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 ) );
1337 # endif
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);
1343 addStmtToIRSB(
1345 IRStmt_Put(
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 );
1353 #endif
1354 return False;
1357 /* --- Helpers to do with PPC related stack redzones. --- */
1359 __attribute__((unused))
1360 static Bool const_True ( Addr64 guest_addr )
1362 return True;
1365 /* --------------- main translation function --------------- */
1367 /* Note: see comments at top of m_redir.c for the Big Picture on how
1368 redirections are managed. */
1370 typedef
1371 enum {
1372 /* normal translation, redir neither requested nor inhibited */
1373 T_Normal,
1374 /* redir translation, function-wrap (set _NRADDR) style */
1375 T_Redir_Wrap,
1376 /* redir translation, replacement (don't set _NRADDR) style */
1377 T_Redir_Replace,
1378 /* a translation in which redir is specifically disallowed */
1379 T_NoRedir
1381 T_Kind;
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,
1396 Addr64 nraddr,
1397 Bool debugging_translation,
1398 Int debugging_verbosity,
1399 ULong bbs_done,
1400 Bool allow_redirection )
1402 Addr64 addr;
1403 T_Kind kind;
1404 Int tmpbuf_used, verbosity, i;
1405 Bool (*preamble_fn)(void*,IRSB*);
1406 VexArch vex_arch;
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) {
1428 Bool isWrap;
1429 Addr64 tmp = VG_(redir_do_lookup)( nraddr, &isWrap );
1430 if (tmp == nraddr) {
1431 /* no redirection found */
1432 addr = nraddr;
1433 kind = T_Normal;
1434 } else {
1435 /* found a redirect */
1436 addr = tmp;
1437 kind = isWrap ? T_Redir_Wrap : T_Redir_Replace;
1439 } else {
1440 addr = nraddr;
1441 kind = T_NoRedir;
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))) {
1450 Bool ok;
1451 const HChar *buf;
1452 const HChar *name2;
1454 /* Try also to get the soname (not the filename) of the "from"
1455 object. This makes it much easier to debug redirection
1456 problems. */
1457 const HChar* nraddr_soname = "???";
1458 DebugInfo* nraddr_di = VG_(find_DebugInfo)(nraddr);
1459 if (nraddr_di) {
1460 const HChar* t = VG_(DebugInfo_get_soname)(nraddr_di);
1461 if (t)
1462 nraddr_soname = t;
1465 ok = VG_(get_fnname_w_offset)(nraddr, &buf);
1466 if (!ok) buf = "???";
1467 // Stash away name1
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,
1476 addr, name2 );
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";
1486 OffT objoff = 0;
1487 DebugInfo* di = VG_(find_DebugInfo)( addr );
1488 if (di) {
1489 objname = VG_(DebugInfo_get_filename)(di);
1490 objoff = addr - VG_(DebugInfo_get_text_bias)(di);
1492 vg_assert(objname);
1494 const HChar *fnname;
1495 Bool ok = VG_(get_fnname_w_offset)(addr, &fnname);
1496 if (!ok) fnname = "UNKNOWN_FUNCTION";
1497 VG_(printf)(
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 */
1517 if (seg != NULL) {
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);
1523 else
1524 VG_(synth_fault_perms)(tid, addr);
1525 } else {
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);
1531 else
1532 VG_(synth_fault_mapping)(tid, addr);
1534 return False;
1537 /* True if a debug trans., or if bit N set in VG_(clo_trace_codegen). */
1538 verbosity = 0;
1539 if (debugging_translation) {
1540 verbosity = debugging_verbosity;
1542 else
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. */
1550 preamble_fn = NULL;
1551 if (kind == T_Redir_Replace)
1552 preamble_fn = mk_preamble__set_NRADDR_to_zero;
1553 else
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;
1570 # endif
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;
1587 # endif
1588 # if defined(VGP_amd64_darwin)
1589 vex_abiinfo.guest_amd64_assume_gs_is_0x60 = True;
1590 # endif
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;
1594 # endif
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;
1599 # endif
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;
1604 # endif
1606 /* Set up closure args. */
1607 closure.tid = tid;
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;
1637 IRSB*(*g)(void*,
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()
1644 ? vg_SP_update_pass
1645 : NULL;
1646 vta.finaltidy = VG_(needs).final_IR_tidy_pass
1647 ? VG_(tdict).tool_final_IR_tidy_pass
1648 : NULL;
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
1666 don't bother. */
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) );
1672 vta.disp_cp_xindir
1673 = VG_(fnptr_to_fnentry)( &VG_(disp_cp_xindir) );
1674 } else {
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++) {
1701 NSegment const* seg
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
1716 // normal case.
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,
1721 nraddr,
1722 (Addr)(&tmpbuf[0]),
1723 tmpbuf_used,
1724 tres.n_sc_extents > 0,
1725 tres.offs_profInc,
1726 tres.n_guest_instrs );
1727 } else {
1728 vg_assert(tres.offs_profInc == -1); /* -1 == unset */
1729 VG_(add_to_unredir_transtab)( &vge,
1730 nraddr,
1731 (Addr)(&tmpbuf[0]),
1732 tmpbuf_used );
1736 return True;
1739 /*--------------------------------------------------------------------*/
1740 /*--- end ---*/
1741 /*--------------------------------------------------------------------*/