blob: a6ee66ed56c14a4c4bb1727ebe1ebc0c9ff2ba17 [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
2/*--------------------------------------------------------------------*/
3/*--- The JITter proper: register allocation & code improvement ---*/
4/*--- vg_translate.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
njnc9539842002-10-02 13:26:35 +00008 This file is part of Valgrind, an extensible x86 protected-mode
9 emulator for monitoring program execution on x86-Unixes.
sewardjde4a1d02002-03-22 01:27:54 +000010
nethercotebb1c9912004-01-04 16:43:23 +000011 Copyright (C) 2000-2004 Julian Seward
sewardjde4a1d02002-03-22 01:27:54 +000012 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +000013
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
njn25e49d8e72002-09-23 09:36:25 +000029 The GNU General Public License is contained in the file COPYING.
sewardjde4a1d02002-03-22 01:27:54 +000030*/
31
nethercotef1e5e152004-09-01 23:58:16 +000032#include "core.h"
sewardjde4a1d02002-03-22 01:27:54 +000033
sewardjde4a1d02002-03-22 01:27:54 +000034
nethercotebee3fd92004-08-02 15:17:43 +000035/*------------------------------------------------------------*/
sewardj8b635a42004-11-22 19:01:47 +000036/*--- %SP-update pass ---*/
nethercotebee3fd92004-08-02 15:17:43 +000037/*------------------------------------------------------------*/
38
sewardj8b635a42004-11-22 19:01:47 +000039/* NOTE: this comment is out of date */
njn9b007f62003-04-07 14:40:25 +000040
nethercote996901a2004-08-03 13:29:09 +000041/* For tools that want to know about %ESP changes, this pass adds
42 in the appropriate hooks. We have to do it after the tool's
43 instrumentation, so the tool doesn't have to worry about the CCALLs
njn9b007f62003-04-07 14:40:25 +000044 it adds in, and we must do it before register allocation because
45 spilled temps make it much harder to work out the %esp deltas.
njned619712003-10-01 16:45:04 +000046 Thus we have it as an extra phase between the two.
47
48 We look for "GETL %ESP, t_ESP", then track ADDs and SUBs of
49 literal values to t_ESP, and the total delta of the ADDs/SUBs. Then if
50 "PUTL t_ESP, %ESP" happens, we call the helper with the known delta. We
51 also cope with "MOVL t_ESP, tX", making tX the new t_ESP. If any other
52 instruction clobbers t_ESP, we don't track it anymore, and fall back to
53 the delta-is-unknown case. That case is also used when the delta is not
54 a nice small amount, or an unknown amount.
55*/
sewardjde4a1d02002-03-22 01:27:54 +000056
57static
sewardj8b635a42004-11-22 19:01:47 +000058IRBB* vg_SP_update_pass ( IRBB* bb_in, VexGuestLayout* layout,
59 IRType hWordTy )
sewardjde4a1d02002-03-22 01:27:54 +000060{
sewardj8b635a42004-11-22 19:01:47 +000061 Int i, j, minoff_ST, maxoff_ST;
62 IRDirty *dcall, *d;
63 IRStmt* st;
64 IRExpr* e;
65 IRArray* descr;
sewardjde4a1d02002-03-22 01:27:54 +000066
sewardj8b635a42004-11-22 19:01:47 +000067 /* Set up BB */
68 IRBB* bb = emptyIRBB();
69 bb->tyenv = dopyIRTypeEnv(bb_in->tyenv);
70 bb->next = dopyIRExpr(bb_in->next);
71 bb->jumpkind = bb_in->jumpkind;
sewardjde4a1d02002-03-22 01:27:54 +000072
sewardj8b635a42004-11-22 19:01:47 +000073 IRTemp curr = IRTemp_INVALID;
74 Long delta = 0;
sewardjde4a1d02002-03-22 01:27:54 +000075
sewardj8b635a42004-11-22 19:01:47 +000076 Int sizeof_SP = layout->sizeof_SP;
77 Int offset_SP = layout->offset_SP;
78 IRType typeof_SP = sizeof_SP==4 ? Ity_I32 : Ity_I64;
79 vg_assert(sizeof_SP == 4 || sizeof_SP == 8);
sewardjde4a1d02002-03-22 01:27:54 +000080
sewardj8b635a42004-11-22 19:01:47 +000081# define IS_ADD(op) (sizeof_SP==4 ? ((op)==Iop_Add32) : ((op)==Iop_Add64))
82# define IS_SUB(op) (sizeof_SP==4 ? ((op)==Iop_Sub32) : ((op)==Iop_Sub64))
sewardjde4a1d02002-03-22 01:27:54 +000083
sewardj8b635a42004-11-22 19:01:47 +000084# define IS_ADD_OR_SUB(op) (IS_ADD(op) || IS_SUB(op))
sewardjde4a1d02002-03-22 01:27:54 +000085
sewardj8b635a42004-11-22 19:01:47 +000086# define GET_CONST(con) \
87 (sizeof_SP==4 ? (Long)(Int)(con->Ico.U32) \
88 : (Long)(con->Ico.U64))
sewardjde4a1d02002-03-22 01:27:54 +000089
sewardj8b635a42004-11-22 19:01:47 +000090# define DO(kind, syze) \
91 do { \
92 if (!VG_(defined_##kind##_mem_stack_##syze)()) \
93 goto generic; \
94 \
95 /* I don't know if it's really necessary to say that the */ \
96 /* call reads the stack pointer. But anyway, we do. */ \
97 dcall = unsafeIRDirty_0_N( \
98 1/*regparms*/, \
99 "track_" #kind "_mem_stack_" #syze, \
100 VG_(tool_interface) \
101 .track_##kind##_mem_stack_##syze, \
102 mkIRExprVec_1(IRExpr_Tmp(curr)) \
103 ); \
104 dcall->nFxState = 1; \
105 dcall->fxState[0].fx = Ifx_Read; \
106 dcall->fxState[0].offset = layout->offset_SP; \
107 dcall->fxState[0].size = layout->sizeof_SP; \
108 \
109 addStmtToIRBB( bb, IRStmt_Dirty(dcall) ); \
110 } while (0)
sewardjde4a1d02002-03-22 01:27:54 +0000111
sewardj8b635a42004-11-22 19:01:47 +0000112 for (i = 0; i < bb_in->stmts_used; i++) {
sewardjde4a1d02002-03-22 01:27:54 +0000113
sewardj8b635a42004-11-22 19:01:47 +0000114 st = bb_in->stmts[i];
115 if (!st)
sewardjde4a1d02002-03-22 01:27:54 +0000116 continue;
117
sewardj8b635a42004-11-22 19:01:47 +0000118 /* t = Get(sp): curr = t, delta = 0 */
119 if (st->tag != Ist_Tmp) goto case2;
120 e = st->Ist.Tmp.data;
121 if (e->tag != Iex_Get) goto case2;
122 if (e->Iex.Get.offset != offset_SP) goto case2;
123 if (e->Iex.Get.ty != typeof_SP) goto case2;
124 curr = st->Ist.Tmp.tmp;
125 delta = 0;
126 addStmtToIRBB( bb, st );
127 continue;
sewardjde4a1d02002-03-22 01:27:54 +0000128
sewardj8b635a42004-11-22 19:01:47 +0000129 case2:
130 /* t' = curr +/- const: curr = t', delta +=/-= const */
131 if (st->tag != Ist_Tmp) goto case3;
132 e = st->Ist.Tmp.data;
133 if (e->tag != Iex_Binop) goto case3;
134 if (e->Iex.Binop.arg1->tag != Iex_Tmp) goto case3;
135 if (e->Iex.Binop.arg1->Iex.Tmp.tmp != curr) goto case3;
136 if (e->Iex.Binop.arg2->tag != Iex_Const) goto case3;
137 if (!IS_ADD_OR_SUB(e->Iex.Binop.op)) goto case3;
138 curr = st->Ist.Tmp.tmp;
139 if (IS_ADD(e->Iex.Binop.op))
140 delta += GET_CONST(e->Iex.Binop.arg2->Iex.Const.con);
141 else
142 delta -= GET_CONST(e->Iex.Binop.arg2->Iex.Const.con);
143 addStmtToIRBB( bb, st );
144 continue;
sewardjde4a1d02002-03-22 01:27:54 +0000145
sewardj8b635a42004-11-22 19:01:47 +0000146 case3:
147 /* t' = curr: curr = t' */
148 if (st->tag != Ist_Tmp) goto case4;
149 e = st->Ist.Tmp.data;
150 if (e->tag != Iex_Tmp) goto case4;
151 if (e->Iex.Tmp.tmp != curr) goto case4;
152 curr = st->Ist.Tmp.tmp;
153 addStmtToIRBB( bb, st );
154 continue;
sewardjde4a1d02002-03-22 01:27:54 +0000155
sewardj8b635a42004-11-22 19:01:47 +0000156 case4:
157 /* Put(sp) = curr */
158 if (st->tag != Ist_Put) goto case5;
159 if (st->Ist.Put.offset != offset_SP) goto case5;
160 if (st->Ist.Put.data->tag != Iex_Tmp) goto case5;
161 if (st->Ist.Put.data->Iex.Tmp.tmp == curr) {
162 switch (delta) {
163 case 0: addStmtToIRBB(bb,st); delta = 0; continue;
164 case 4: DO(die, 4); addStmtToIRBB(bb,st); delta = 0; continue;
165 case -4: DO(new, 4); addStmtToIRBB(bb,st); delta = 0; continue;
166 case 8: DO(die, 8); addStmtToIRBB(bb,st); delta = 0; continue;
167 case -8: DO(new, 8); addStmtToIRBB(bb,st); delta = 0; continue;
168 case 12: DO(die, 12); addStmtToIRBB(bb,st); delta = 0; continue;
169 case -12: DO(new, 12); addStmtToIRBB(bb,st); delta = 0; continue;
170 case 16: DO(die, 16); addStmtToIRBB(bb,st); delta = 0; continue;
171 case -16: DO(new, 16); addStmtToIRBB(bb,st); delta = 0; continue;
172 case 32: DO(die, 32); addStmtToIRBB(bb,st); delta = 0; continue;
173 case -32: DO(new, 32); addStmtToIRBB(bb,st); delta = 0; continue;
174 default: goto generic;
sewardjde4a1d02002-03-22 01:27:54 +0000175 }
sewardj8b635a42004-11-22 19:01:47 +0000176 } else {
177 generic:
178 /* I don't know if it's really necessary to say that the call
179 reads the stack pointer. But anyway, we do. */
180 dcall = unsafeIRDirty_0_N(
181 1/*regparms*/,
182 "VG_(unknown_SP_update)", &VG_(unknown_SP_update),
183 mkIRExprVec_1(st->Ist.Put.data)
184 );
185 dcall->nFxState = 1;
186 dcall->fxState[0].fx = Ifx_Read;
187 dcall->fxState[0].offset = layout->offset_SP;
188 dcall->fxState[0].size = layout->sizeof_SP;
sewardjde4a1d02002-03-22 01:27:54 +0000189
sewardj8b635a42004-11-22 19:01:47 +0000190 addStmtToIRBB( bb, IRStmt_Dirty(dcall) );
191 addStmtToIRBB(bb,st);
sewardjde4a1d02002-03-22 01:27:54 +0000192
sewardj8b635a42004-11-22 19:01:47 +0000193 curr = st->Ist.Put.data->Iex.Tmp.tmp;
194 delta = 0;
195 continue;
sewardjde4a1d02002-03-22 01:27:54 +0000196 }
197
sewardj8b635a42004-11-22 19:01:47 +0000198 case5:
199 /* PutI or Dirty call which overlaps SP: complain. We can't
200 deal with SP changing in weird ways (well, we can, but not at
201 this time of night). */
202 if (st->tag == Ist_PutI) {
203 descr = st->Ist.PutI.descr;
204 minoff_ST = descr->base;
205 maxoff_ST = descr->base + descr->nElems * sizeofIRType(descr->elemTy) - 1;
206 if (!(offset_SP > maxoff_ST || (offset_SP + sizeof_SP - 1) < minoff_ST))
207 goto complain;
sewardjde4a1d02002-03-22 01:27:54 +0000208 }
sewardj8b635a42004-11-22 19:01:47 +0000209 if (st->tag == Ist_Dirty) {
210 d = st->Ist.Dirty.details;
211 for (j = 0; j < d->nFxState; j++) {
212 minoff_ST = d->fxState[j].offset;
213 maxoff_ST = d->fxState[j].offset + d->fxState[j].size - 1;
214 if (d->fxState[j].fx == Ifx_Read || d->fxState[j].fx == Ifx_None)
215 continue;
216 if (!(offset_SP > maxoff_ST || (offset_SP + sizeof_SP - 1) < minoff_ST))
217 goto complain;
218 }
219 }
sewardjde4a1d02002-03-22 01:27:54 +0000220
sewardj8b635a42004-11-22 19:01:47 +0000221 /* well, not interesting. Just copy and keep going. */
222 addStmtToIRBB( bb, st );
sewardjde4a1d02002-03-22 01:27:54 +0000223
sewardj8b635a42004-11-22 19:01:47 +0000224 } /* for (i = 0; i < bb_in->stmts_used; i++) */
sewardjde4a1d02002-03-22 01:27:54 +0000225
sewardj8b635a42004-11-22 19:01:47 +0000226 return bb;
sewardjde4a1d02002-03-22 01:27:54 +0000227
sewardj8b635a42004-11-22 19:01:47 +0000228 complain:
229 VG_(core_panic)("vg_SP_update_pass: PutI or Dirty which overlaps SP");
sewardjde4a1d02002-03-22 01:27:54 +0000230
231}
sewardj7c4b6042003-06-14 15:47:15 +0000232
sewardjde4a1d02002-03-22 01:27:54 +0000233
sewardjde4a1d02002-03-22 01:27:54 +0000234
sewardj8b635a42004-11-22 19:01:47 +0000235#if 0
236 for (i = 0; i < bb_in->stmts_used; i++) {
237 st = bb_in->stmts[i];
238 if (!st)
239 continue;
240 if (st->tag != Ist_Put)
241 goto boring;
242 offP = st->Ist.Put.offset;
243 if (offP != layout->offset_SP)
244 goto boring;
245 szP = sizeofIRType(typeOfIRExpr(bb_in->tyenv, st->Ist.Put.data));
246 if (szP != layout->sizeof_SP)
247 goto boring;
248 vg_assert(isAtom(st->Ist.Put.data));
sewardj97ced732002-03-25 00:07:36 +0000249
sewardj8b635a42004-11-22 19:01:47 +0000250 /* I don't know if it's really necessary to say that the call reads
251 the stack pointer. But anyway, we do. */
252 dcall = unsafeIRDirty_0_N(
253 mkIRCallee(1, "VG_(unknown_esp_update)",
254 (HWord)&VG_(unknown_esp_update)),
255 mkIRExprVec_1(st->Ist.Put.data)
256 );
257 dcall->nFxState = 1;
258 dcall->fxState[0].fx = Ifx_Read;
259 dcall->fxState[0].offset = layout->offset_SP;
260 dcall->fxState[0].size = layout->sizeof_SP;
sewardj97ced732002-03-25 00:07:36 +0000261
sewardj8b635a42004-11-22 19:01:47 +0000262 addStmtToIRBB( bb, IRStmt_Dirty(dcall) );
263
264 boring:
265 addStmtToIRBB( bb, st );
sewardjde4a1d02002-03-22 01:27:54 +0000266 }
sewardj8b635a42004-11-22 19:01:47 +0000267#endif
268
sewardjde4a1d02002-03-22 01:27:54 +0000269
sewardjde4a1d02002-03-22 01:27:54 +0000270/*------------------------------------------------------------*/
271/*--- Main entry point for the JITter. ---*/
272/*------------------------------------------------------------*/
273
sewardj8b635a42004-11-22 19:01:47 +0000274/* Vex dumps the final code in here. Then we can copy it off
275 wherever we like. */
276#define N_TMPBUF 10000
277static UChar tmpbuf[N_TMPBUF];
278
279/* Function pointers we must supply to LibVEX in order that it
280 can bomb out and emit messages under Valgrind's control. */
281__attribute__ ((noreturn))
282static
283void failure_exit ( void )
284{
285 LibVEX_ClearTemporary(True);
286 VG_(printf)("VEX did failure_exit. Bye.\n");
287 vg_assert(0); //VG_(exit)(1);
288}
289
290static
291void log_bytes ( Char* bytes, Int nbytes )
292{
293 Int i;
294 for (i = 0; i < nbytes-3; i += 4)
295 VG_(printf)("%c%c%c%c", bytes[i], bytes[i+1], bytes[i+2], bytes[i+3]);
296 for (; i < nbytes; i++)
297 VG_(printf)("%c", bytes[i]);
298}
299
nethercote59a122d2004-08-03 17:16:51 +0000300/* Translate the basic block beginning at orig_addr, and add it to
301 the translation cache & translation table. Unless 'debugging' is true,
302 in which case the call is being done for debugging purposes, so
303 (a) throw away the translation once it is made, and (b) produce a
304 load of debugging output.
njn25e49d8e72002-09-23 09:36:25 +0000305
nethercote59a122d2004-08-03 17:16:51 +0000306 'tid' is the identity of the thread needing this block.
sewardjde4a1d02002-03-22 01:27:54 +0000307*/
sewardj8b635a42004-11-22 19:01:47 +0000308
309/* This stops Vex from chasing into function entry points that we wish
310 to redirect. Chasing across them obviously defeats the redirect
311 mechanism, with bad effects for Memcheck, Addrcheck, and possibly
312 others. */
313static Bool chase_into_ok ( Addr64 addr64 )
314{
315 Addr addr = (Addr)addr64;
316 if (addr != VG_(code_redirect)(addr)) {
317 if (0) VG_(printf)("not chasing into 0x%x\n", addr);
318 return False;
319 } else {
320 return True; /* ok to chase into 'addr' */
321 }
322}
323
nethercote4d714382004-10-13 09:47:24 +0000324Bool VG_(translate) ( ThreadId tid, Addr orig_addr,
nethercote59a122d2004-08-03 17:16:51 +0000325 Bool debugging_translation )
sewardjde4a1d02002-03-22 01:27:54 +0000326{
sewardj8b635a42004-11-22 19:01:47 +0000327 Addr redir, orig_addr0 = orig_addr;
328 Int orig_size, tmpbuf_used;
sewardja60be0e2003-05-26 08:47:27 +0000329 Bool notrace_until_done;
sewardj1e86b8b2003-06-16 23:34:12 +0000330 UInt notrace_until_limit = 0;
sewardj8b635a42004-11-22 19:01:47 +0000331 //UInt FULLTRACE_LIMIT = 1; //21068;
fitzhardinge98abfc72003-12-16 02:05:15 +0000332 Segment *seg;
sewardjde4a1d02002-03-22 01:27:54 +0000333
sewardj8b635a42004-11-22 19:01:47 +0000334 /* Make sure Vex is initialised right. */
335 TranslateResult tres;
336 static Bool vex_init_done = False;
337
338 if (!vex_init_done) {
339 LibVEX_Init ( &failure_exit, &log_bytes,
340 1, /* debug_paranoia */
341 False, /* valgrind support */
342 &VG_(clo_vex_control) );
343 vex_init_done = True;
344 }
345
346 /* profiling ... */
sewardjde4a1d02002-03-22 01:27:54 +0000347 VGP_PUSHCC(VgpTranslate);
nethercote59a122d2004-08-03 17:16:51 +0000348
sewardj25c7c3a2003-07-10 00:17:58 +0000349 /* Look in the code redirect table to see if we should
350 translate an alternative address for orig_addr. */
fitzhardinge98abfc72003-12-16 02:05:15 +0000351 redir = VG_(code_redirect)(orig_addr);
352
nethercote59a122d2004-08-03 17:16:51 +0000353 if (redir != orig_addr && VG_(clo_verbosity) >= 2) {
sewardj8b635a42004-11-22 19:01:47 +0000354 Char name1[64] = "";
355 Char name2[64] = "";
356 VG_(get_fnname_w_offset)(orig_addr, name1, 64);
357 VG_(get_fnname_w_offset)(redir, name2, 64);
fitzhardinge98abfc72003-12-16 02:05:15 +0000358 VG_(message)(Vg_UserMsg,
sewardj8b635a42004-11-22 19:01:47 +0000359 "TRANSLATE: %p (%s) redirected to %p (%s)",
360 orig_addr, name1,
361 redir, name2 );
nethercote59a122d2004-08-03 17:16:51 +0000362 }
fitzhardinge98abfc72003-12-16 02:05:15 +0000363 orig_addr = redir;
sewardj25c7c3a2003-07-10 00:17:58 +0000364
sewardja60be0e2003-05-26 08:47:27 +0000365 /* If codegen tracing, don't start tracing until
366 notrace_until_limit blocks have gone by. This avoids printing
367 huge amounts of useless junk when all we want to see is the last
368 few blocks translated prior to a failure. Set
369 notrace_until_limit to be the number of translations to be made
370 before --trace-codegen= style printing takes effect. */
nethercote92e7b7f2004-08-07 17:52:25 +0000371 notrace_until_done = VG_(get_bbs_translated)() >= notrace_until_limit;
sewardja60be0e2003-05-26 08:47:27 +0000372
fitzhardinge98abfc72003-12-16 02:05:15 +0000373 seg = VG_(find_segment)(orig_addr);
374
njn25e49d8e72002-09-23 09:36:25 +0000375 if (!debugging_translation)
njn72718642003-07-24 08:45:32 +0000376 VG_TRACK( pre_mem_read, Vg_CoreTranslate, tid, "", orig_addr, 1 );
sewardjde4a1d02002-03-22 01:27:54 +0000377
fitzhardinge98abfc72003-12-16 02:05:15 +0000378 if (seg == NULL ||
379 !VG_(seg_contains)(seg, orig_addr, 1) ||
380 (seg->prot & (VKI_PROT_READ|VKI_PROT_EXEC)) == 0) {
fitzhardinge98abfc72003-12-16 02:05:15 +0000381 /* Code address is bad - deliver a signal instead */
382 vg_assert(!VG_(is_addressable)(orig_addr, 1));
383
fitzhardinge98abfc72003-12-16 02:05:15 +0000384 if (seg != NULL && VG_(seg_contains)(seg, orig_addr, 1)) {
sewardj8b635a42004-11-22 19:01:47 +0000385 vg_assert((seg->prot & VKI_PROT_EXEC) == 0);
386 VG_(synth_fault_perms)(tid, orig_addr);
fitzhardinge98abfc72003-12-16 02:05:15 +0000387 } else
sewardj8b635a42004-11-22 19:01:47 +0000388 VG_(synth_fault_mapping)(tid, orig_addr);
jsgf855d93d2003-10-13 22:26:55 +0000389
nethercote4d714382004-10-13 09:47:24 +0000390 return False;
fitzhardinge98abfc72003-12-16 02:05:15 +0000391 } else
sewardj8b635a42004-11-22 19:01:47 +0000392 seg->flags |= SF_CODE; /* contains cached code */
sewardjde4a1d02002-03-22 01:27:54 +0000393
njn25e49d8e72002-09-23 09:36:25 +0000394 /* If doing any code printing, print a basic block start marker */
sewardj8b635a42004-11-22 19:01:47 +0000395 if (VG_(clo_trace_codegen)) {
njn25e49d8e72002-09-23 09:36:25 +0000396 Char fnname[64] = "";
sewardj8b635a42004-11-22 19:01:47 +0000397 VG_(get_fnname_w_offset)(orig_addr, fnname, 64);
njn25e49d8e72002-09-23 09:36:25 +0000398 VG_(printf)(
sewardj8b635a42004-11-22 19:01:47 +0000399 "==== BB %d %s(%p) approx BBs exec'd %llu ====\n",
nethercote92e7b7f2004-08-07 17:52:25 +0000400 VG_(get_bbs_translated)(), fnname, orig_addr,
njn25e49d8e72002-09-23 09:36:25 +0000401 VG_(bbs_done));
402 }
403
404 /* True if a debug trans., or if bit N set in VG_(clo_trace_codegen). */
sewardj8b635a42004-11-22 19:01:47 +0000405#if 0
sewardja60be0e2003-05-26 08:47:27 +0000406# define DECIDE_IF_PRINTING_CODEGEN_FOR_PHASE(n) \
407 ( debugging_translation \
408 || (notrace_until_done \
409 && (VG_(clo_trace_codegen) & (1 << (n-1))) ))
sewardj8b635a42004-11-22 19:01:47 +0000410#else
411# define DECIDE_IF_PRINTING_CODEGEN \
412 ( debugging_translation \
413 || (VG_(clo_trace_codegen) > 0 \
414 && VG_(get_bbs_translated)() >= FULLTRACE_LIMIT))
415#endif
njn25e49d8e72002-09-23 09:36:25 +0000416
sewardj8b635a42004-11-22 19:01:47 +0000417 /* Actually do the translation. */
418 tres = LibVEX_Translate (
419 InsnSetX86, InsnSetX86,
420 (Char*)orig_addr, (Addr64)orig_addr,
421 chase_into_ok,
422 &orig_size,
423 tmpbuf, N_TMPBUF, &tmpbuf_used,
424 TL_(instrument),
425 VG_(need_to_handle_SP_assignment)()
426 ? vg_SP_update_pass
427 : NULL,
428 True, /* cleanup after instrumentation */
429 NULL,
430 VG_(clo_trace_codegen)
431 );
njn25e49d8e72002-09-23 09:36:25 +0000432
sewardj8b635a42004-11-22 19:01:47 +0000433 vg_assert(tres == TransOK);
434 vg_assert(tmpbuf_used <= N_TMPBUF);
435 vg_assert(tmpbuf_used > 0);
sewardjde4a1d02002-03-22 01:27:54 +0000436
njn25e49d8e72002-09-23 09:36:25 +0000437#undef DECIDE_IF_PRINTING_CODEGEN_FOR_PHASE
438
nethercote59a122d2004-08-03 17:16:51 +0000439 /* Copy data at trans_addr into the translation cache. */
440 /* Since the .orig_size and .trans_size fields are UShort, be paranoid. */
sewardj8b635a42004-11-22 19:01:47 +0000441 vg_assert(orig_size > 0 && orig_size < 65536);
442 vg_assert(tmpbuf_used > 0 && tmpbuf_used < 65536);
nethercote59a122d2004-08-03 17:16:51 +0000443
444 // If debugging, don't do anything with the translated block; we
445 // only did this for the debugging output produced along the way.
446 if (!debugging_translation) {
447 // Note that we use orig_addr0, not orig_addr, which might have been
448 // changed by the redirection
sewardj8b635a42004-11-22 19:01:47 +0000449 VG_(add_to_trans_tab)( orig_addr0, orig_size,
450 (Addr)(&tmpbuf[0]), tmpbuf_used );
sewardjde4a1d02002-03-22 01:27:54 +0000451 }
nethercote59a122d2004-08-03 17:16:51 +0000452
njn25e49d8e72002-09-23 09:36:25 +0000453 VGP_POPCC(VgpTranslate);
nethercote4d714382004-10-13 09:47:24 +0000454
455 return True;
sewardjde4a1d02002-03-22 01:27:54 +0000456}
457
458/*--------------------------------------------------------------------*/
459/*--- end vg_translate.c ---*/
460/*--------------------------------------------------------------------*/
njned619712003-10-01 16:45:04 +0000461