|
From: <sv...@va...> - 2005-05-13 23:11:44
|
Author: njn
Date: 2005-05-14 00:11:40 +0100 (Sat, 14 May 2005)
New Revision: 3700
Added:
trunk/coregrind/m_translate.c
trunk/coregrind/pub_core_translate.h
Removed:
trunk/coregrind/vg_translate.c
Modified:
trunk/coregrind/Makefile.am
trunk/coregrind/core.h
trunk/coregrind/m_errormgr.c
trunk/coregrind/vg_scheduler.c
trunk/coregrind/vg_transtab.c
Log:
Modularised vg_translate.c as m_translate.
Modified: trunk/coregrind/Makefile.am
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/Makefile.am 2005-05-13 22:18:47 UTC (rev 3699)
+++ trunk/coregrind/Makefile.am 2005-05-13 23:11:40 UTC (rev 3700)
@@ -78,6 +78,7 @@
m_skiplist.c \
m_stacktrace.c \
m_tooliface.c \
+ m_translate.c \
ume.c \
\
vg_scheduler.c \
@@ -94,7 +95,6 @@
vg_dwarf.c \
vg_stabs.c \
vg_symtypes.c \
- vg_translate.c \
vg_transtab.c
=20
## libplatform.a must be before libarch.a and libos.a, it seems.
Modified: trunk/coregrind/core.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/core.h 2005-05-13 22:18:47 UTC (rev 3699)
+++ trunk/coregrind/core.h 2005-05-13 23:11:40 UTC (rev 3700)
@@ -634,16 +634,6 @@
extern void VG_(nanosleep)(struct vki_timespec *);
=20
/* ---------------------------------------------------------------------
- Exports of vg_translate.c
- ------------------------------------------------------------------ */
-
-extern=20
-Bool VG_(translate) ( ThreadId tid,=20
- Addr64 orig_addr,
- Bool debugging_translation,
- Int debugging_verbosity );
-
-/* ---------------------------------------------------------------------
Exports of vg_symtab2.c
------------------------------------------------------------------ */
=20
Modified: trunk/coregrind/m_errormgr.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_errormgr.c 2005-05-13 22:18:47 UTC (rev 3699)
+++ trunk/coregrind/m_errormgr.c 2005-05-13 23:11:40 UTC (rev 3700)
@@ -33,6 +33,7 @@
#include "pub_core_execontext.h"
#include "pub_core_stacktrace.h"
#include "pub_core_tooliface.h"
+#include "pub_core_translate.h"
=20
/*------------------------------------------------------------*/
/*--- Globals ---*/
Copied: trunk/coregrind/m_translate.c (from rev 3691, trunk/coregrind/vg_=
translate.c)
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/vg_translate.c 2005-05-13 16:54:09 UTC (rev 3691)
+++ trunk/coregrind/m_translate.c 2005-05-13 23:11:40 UTC (rev 3700)
@@ -0,0 +1,513 @@
+
+/*--------------------------------------------------------------------*/
+/*--- The JITter proper: register allocation & code improvement ---*/
+/*--- m_translate.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2000-2005 Julian Seward=20
+ js...@ac...
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "core.h"
+#include "pub_core_aspacemgr.h"
+#include "pub_core_tooliface.h"
+
+
+/*------------------------------------------------------------*/
+/*--- %SP-update pass ---*/
+/*------------------------------------------------------------*/
+
+/* NOTE: this comment is out of date */
+
+/* For tools that want to know about %ESP changes, this pass adds
+ in the appropriate hooks. We have to do it after the tool's
+ instrumentation, so the tool doesn't have to worry about the CCALLs
+ it adds in, and we must do it before register allocation because
+ spilled temps make it much harder to work out the %esp deltas.
+ Thus we have it as an extra phase between the two.=20
+ =20
+ We look for "GETL %ESP, t_ESP", then track ADDs and SUBs of
+ literal values to t_ESP, and the total delta of the ADDs/SUBs. Then =
if
+ "PUTL t_ESP, %ESP" happens, we call the helper with the known delta. =
We
+ also cope with "MOVL t_ESP, tX", making tX the new t_ESP. If any oth=
er
+ instruction clobbers t_ESP, we don't track it anymore, and fall back =
to
+ the delta-is-unknown case. That case is also used when the delta is =
not
+ a nice small amount, or an unknown amount.
+*/
+
+static
+IRBB* vg_SP_update_pass ( IRBB* bb_in, VexGuestLayout* layout,=20
+ IRType gWordTy, IRType hWordTy )
+{
+ Int i, j, minoff_ST, maxoff_ST, sizeof_SP, offset_SP;
+ IRDirty *dcall, *d;
+ IRStmt* st;
+ IRExpr* e;
+ IRArray* descr;
+ IRTemp curr;
+ IRType typeof_SP;
+ Long delta;
+
+ /* Set up BB */
+ IRBB* bb =3D emptyIRBB();
+ bb->tyenv =3D dopyIRTypeEnv(bb_in->tyenv);
+ bb->next =3D dopyIRExpr(bb_in->next);
+ bb->jumpkind =3D bb_in->jumpkind;
+
+ curr =3D IRTemp_INVALID;
+ delta =3D 0;
+
+ sizeof_SP =3D layout->sizeof_SP;
+ offset_SP =3D layout->offset_SP;
+ typeof_SP =3D sizeof_SP=3D=3D4 ? Ity_I32 : Ity_I64;
+ vg_assert(sizeof_SP =3D=3D 4 || sizeof_SP =3D=3D 8);
+
+# define IS_ADD(op) (sizeof_SP=3D=3D4 ? ((op)=3D=3DIop_Add32) : ((op)=3D=
=3DIop_Add64))
+# define IS_SUB(op) (sizeof_SP=3D=3D4 ? ((op)=3D=3DIop_Sub32) : ((op)=3D=
=3DIop_Sub64))
+
+# define IS_ADD_OR_SUB(op) (IS_ADD(op) || IS_SUB(op))
+
+# define GET_CONST(con) =
\
+ (sizeof_SP=3D=3D4 ? (Long)(Int)(con->Ico.U32) =
\
+ : (Long)(con->Ico.U64))
+
+# define DO(kind, syze) =
\
+ do { =
\
+ if (!VG_(tdict).track_##kind##_mem_stack_##syze) \
+ goto generic; =
\
+ =
\
+ /* I don't know if it's really necessary to say that the */ =
\
+ /* call reads the stack pointer. But anyway, we do. */ =
\
+ dcall =3D unsafeIRDirty_0_N( =
\
+ 1/*regparms*/, =
\
+ "track_" #kind "_mem_stack_" #syze, =
\
+ VG_(tdict).track_##kind##_mem_stack_##syze, =
\
+ mkIRExprVec_1(IRExpr_Tmp(curr)) =
\
+ ); =
\
+ dcall->nFxState =3D 1; =
\
+ dcall->fxState[0].fx =3D Ifx_Read; =
\
+ dcall->fxState[0].offset =3D layout->offset_SP; =
\
+ dcall->fxState[0].size =3D layout->sizeof_SP; =
\
+ =
\
+ addStmtToIRBB( bb, IRStmt_Dirty(dcall) ); =
\
+ } while (0)
+
+ for (i =3D 0; i < bb_in->stmts_used; i++) {
+
+ st =3D bb_in->stmts[i];
+ if (!st)
+ continue;
+
+ /* t =3D Get(sp): curr =3D t, delta =3D 0 */
+ if (st->tag !=3D Ist_Tmp) goto case2;
+ e =3D st->Ist.Tmp.data;
+ if (e->tag !=3D Iex_Get) goto case2;
+ if (e->Iex.Get.offset !=3D offset_SP) goto case2;
+ if (e->Iex.Get.ty !=3D typeof_SP) goto case2;
+ curr =3D st->Ist.Tmp.tmp;
+ delta =3D 0;
+ addStmtToIRBB( bb, st );
+ continue;
+
+ case2:
+ /* t' =3D curr +/- const: curr =3D t', delta +=3D/-=3D const */
+ if (st->tag !=3D Ist_Tmp) goto case3;
+ e =3D st->Ist.Tmp.data;
+ if (e->tag !=3D Iex_Binop) goto case3;
+ if (e->Iex.Binop.arg1->tag !=3D Iex_Tmp) goto case3;
+ if (e->Iex.Binop.arg1->Iex.Tmp.tmp !=3D curr) goto case3;
+ if (e->Iex.Binop.arg2->tag !=3D Iex_Const) goto case3;
+ if (!IS_ADD_OR_SUB(e->Iex.Binop.op)) goto case3;
+ curr =3D st->Ist.Tmp.tmp;
+ if (IS_ADD(e->Iex.Binop.op))
+ delta +=3D GET_CONST(e->Iex.Binop.arg2->Iex.Const.con);
+ else
+ delta -=3D GET_CONST(e->Iex.Binop.arg2->Iex.Const.con);
+ addStmtToIRBB( bb, st );
+ continue;
+
+ case3:
+ /* t' =3D curr: curr =3D t' */
+ if (st->tag !=3D Ist_Tmp) goto case4;
+ e =3D st->Ist.Tmp.data;
+ if (e->tag !=3D Iex_Tmp) goto case4;
+ if (e->Iex.Tmp.tmp !=3D curr) goto case4;
+ curr =3D st->Ist.Tmp.tmp;
+ addStmtToIRBB( bb, st );
+ continue;
+
+ case4:
+ /* Put(sp) =3D curr */
+ if (st->tag !=3D Ist_Put) goto case5;
+ if (st->Ist.Put.offset !=3D offset_SP) goto case5;
+ if (st->Ist.Put.data->tag !=3D Iex_Tmp) goto case5;
+ if (st->Ist.Put.data->Iex.Tmp.tmp =3D=3D curr) {
+ switch (delta) {
+ case 0: addStmtToIRBB(bb,st); delta =3D 0; co=
ntinue;
+ case 4: DO(die, 4); addStmtToIRBB(bb,st); delta =3D 0; co=
ntinue;
+ case -4: DO(new, 4); addStmtToIRBB(bb,st); delta =3D 0; co=
ntinue;
+ case 8: DO(die, 8); addStmtToIRBB(bb,st); delta =3D 0; co=
ntinue;
+ case -8: DO(new, 8); addStmtToIRBB(bb,st); delta =3D 0; co=
ntinue;
+ case 12: DO(die, 12); addStmtToIRBB(bb,st); delta =3D 0; co=
ntinue;
+ case -12: DO(new, 12); addStmtToIRBB(bb,st); delta =3D 0; co=
ntinue;
+ case 16: DO(die, 16); addStmtToIRBB(bb,st); delta =3D 0; co=
ntinue;
+ case -16: DO(new, 16); addStmtToIRBB(bb,st); delta =3D 0; co=
ntinue;
+ case 32: DO(die, 32); addStmtToIRBB(bb,st); delta =3D 0; co=
ntinue;
+ case -32: DO(new, 32); addStmtToIRBB(bb,st); delta =3D 0; co=
ntinue;
+ default: goto generic;
+ }
+ } else {
+ IRTemp old_SP;
+ generic:
+ /* Pass both the old and new SP values to this helper. */
+ old_SP =3D newIRTemp(bb->tyenv, typeof_SP);
+ addStmtToIRBB(=20
+ bb,
+ IRStmt_Tmp( old_SP, IRExpr_Get(offset_SP, typeof_SP) )=20
+ );
+
+ dcall =3D unsafeIRDirty_0_N(=20
+ 2/*regparms*/,=20
+ "VG_(unknown_SP_update)", &VG_(unknown_SP_update),
+ mkIRExprVec_2( IRExpr_Tmp(old_SP), st->Ist.Put.data =
)=20
+ );
+ addStmtToIRBB( bb, IRStmt_Dirty(dcall) );
+
+ addStmtToIRBB( bb, st );
+
+ curr =3D st->Ist.Put.data->Iex.Tmp.tmp;
+ delta =3D 0;
+ continue;
+ }
+
+ case5:
+ /* PutI or Dirty call which overlaps SP: complain. We can't
+ deal with SP changing in weird ways (well, we can, but not at
+ this time of night). */
+ if (st->tag =3D=3D Ist_PutI) {
+ descr =3D st->Ist.PutI.descr;
+ minoff_ST =3D descr->base;
+ maxoff_ST =3D descr->base + descr->nElems * sizeofIRType(descr-=
>elemTy) - 1;
+ if (!(offset_SP > maxoff_ST || (offset_SP + sizeof_SP - 1) < mi=
noff_ST))
+ goto complain;
+ }
+ if (st->tag =3D=3D Ist_Dirty) {
+ d =3D st->Ist.Dirty.details;
+ for (j =3D 0; j < d->nFxState; j++) {
+ minoff_ST =3D d->fxState[j].offset;
+ maxoff_ST =3D d->fxState[j].offset + d->fxState[j].size - 1;
+ if (d->fxState[j].fx =3D=3D Ifx_Read || d->fxState[j].fx =3D=
=3D Ifx_None)
+ continue;
+ if (!(offset_SP > maxoff_ST || (offset_SP + sizeof_SP - 1) <=
minoff_ST))
+ goto complain;
+ }
+ }
+
+ /* well, not interesting. Just copy and keep going. */
+ addStmtToIRBB( bb, st );
+
+ } /* for (i =3D 0; i < bb_in->stmts_used; i++) */
+
+ return bb;
+
+ complain:
+ VG_(core_panic)("vg_SP_update_pass: PutI or Dirty which overlaps SP")=
;
+
+}
+
+
+
+#if 0
+ for (i =3D 0; i < bb_in->stmts_used; i++) {
+ st =3D bb_in->stmts[i];
+ if (!st)
+ continue;
+ if (st->tag !=3D Ist_Put)=20
+ goto boring;
+ offP =3D st->Ist.Put.offset;
+ if (offP !=3D layout->offset_SP)=20
+ goto boring;
+ szP =3D sizeofIRType(typeOfIRExpr(bb_in->tyenv, st->Ist.Put.data))=
;
+ if (szP !=3D layout->sizeof_SP)
+ goto boring;
+ vg_assert(isAtom(st->Ist.Put.data));
+
+ /* I don't know if it's really necessary to say that the call read=
s
+ the stack pointer. But anyway, we do. */ =20
+ dcall =3D unsafeIRDirty_0_N(=20
+ mkIRCallee(1, "VG_(unknown_esp_update)",=20
+ (HWord)&VG_(unknown_esp_update)),
+ mkIRExprVec_1(st->Ist.Put.data)=20
+ );
+ dcall->nFxState =3D 1;
+ dcall->fxState[0].fx =3D Ifx_Read;
+ dcall->fxState[0].offset =3D layout->offset_SP;
+ dcall->fxState[0].size =3D layout->sizeof_SP;
+
+ addStmtToIRBB( bb, IRStmt_Dirty(dcall) );
+
+ boring:
+ addStmtToIRBB( bb, st );
+ }
+#endif
+
+
+/*------------------------------------------------------------*/
+/*--- Main entry point for the JITter. ---*/
+/*------------------------------------------------------------*/
+
+/* Vex dumps the final code in here. Then we can copy it off
+ wherever we like. */
+#define N_TMPBUF 20000
+static UChar tmpbuf[N_TMPBUF];
+
+/* Function pointers we must supply to LibVEX in order that it
+ can bomb out and emit messages under Valgrind's control. */
+__attribute__ ((noreturn))
+static
+void failure_exit ( void )
+{
+ LibVEX_ShowAllocStats();
+ VG_(core_panic)("LibVEX called failure_exit().");
+}
+
+static
+void log_bytes ( HChar* bytes, Int nbytes )
+{
+ Int i;
+ for (i =3D 0; i < nbytes-3; i +=3D 4)
+ VG_(printf)("%c%c%c%c", bytes[i], bytes[i+1], bytes[i+2], bytes[i+3=
]);
+ for (; i < nbytes; i++)=20
+ VG_(printf)("%c", bytes[i]);
+}
+
+/* Translate the basic block beginning at orig_addr, and add it to
+ the translation cache & translation table. Unless 'debugging' is tru=
e,
+ in which case the call is being done for debugging purposes, so
+ (a) throw away the translation once it is made, and (b) produce a
+ load of debugging output.=20
+
+ 'tid' is the identity of the thread needing this block.
+*/
+
+/* This stops Vex from chasing into function entry points that we wish
+ to redirect. Chasing across them obviously defeats the redirect
+ mechanism, with bad effects for Memcheck, Addrcheck, and possibly
+ others. */
+static Bool chase_into_ok ( Addr64 addr64 )
+{
+ Addr addr =3D (Addr)addr64;
+ if (addr !=3D VG_(code_redirect)(addr)) {
+ if (0) VG_(printf)("not chasing into 0x%x\n", addr);
+ return False;
+ } else {
+ return True; /* ok to chase into 'addr' */
+ }
+}
+
+static Bool need_to_handle_SP_assignment(void)
+{
+ return ( VG_(tdict).track_new_mem_stack_4 ||
+ VG_(tdict).track_die_mem_stack_4 ||
+ VG_(tdict).track_new_mem_stack_8 ||
+ VG_(tdict).track_die_mem_stack_8 ||
+ VG_(tdict).track_new_mem_stack_12 ||
+ VG_(tdict).track_die_mem_stack_12 ||
+ VG_(tdict).track_new_mem_stack_16 ||
+ VG_(tdict).track_die_mem_stack_16 ||
+ VG_(tdict).track_new_mem_stack_32 ||
+ VG_(tdict).track_die_mem_stack_32 ||
+ VG_(tdict).track_new_mem_stack ||
+ VG_(tdict).track_die_mem_stack );
+}
+
+Bool VG_(translate) ( ThreadId tid,=20
+ Addr64 orig_addr,
+ Bool debugging_translation,
+ Int debugging_verbosity )
+{
+ Addr64 redir, orig_addr0 =3D orig_addr;
+ Int tmpbuf_used, verbosity;
+ Bool notrace_until_done;
+ UInt notrace_until_limit =3D 0;
+ Segment* seg;
+ VexGuestExtents vge;
+
+ /* Indicates what arch and subarch we are running on. */
+ static VexArch vex_arch =3D VexArch_INVALID;
+ static VexSubArch vex_subarch =3D VexSubArch_INVALID;
+
+ /* Make sure Vex is initialised right. */
+ VexTranslateResult tres;
+ static Bool vex_init_done =3D False;
+
+ if (!vex_init_done) {
+ Bool ok =3D VGA_(getArchAndSubArch)( &vex_arch, &vex_subarch );
+ if (!ok) {
+ VG_(printf)("\n");
+ VG_(printf)("valgrind: fatal error: unsupported CPU.\n");
+ VG_(printf)(" Supported CPUs are:\n");
+ VG_(printf)(" * x86 with SSE state (Pentium II or above, "
+ "AMD Athlon or above)\n");
+ VG_(printf)("\n");
+ VG_(exit)(1);
+ }
+ if (VG_(clo_verbosity) > 2) {
+ VG_(message)(Vg_DebugMsg,=20
+ "Host CPU: arch =3D %s, subarch =3D %s",
+ LibVEX_ppVexArch ( vex_arch ),
+ LibVEX_ppVexSubArch( vex_subarch ) );
+ }
+
+ LibVEX_Init ( &failure_exit, &log_bytes,=20
+ 1, /* debug_paranoia */=20
+ False, /* valgrind support */
+ &VG_(clo_vex_control) );
+ vex_init_done =3D True;
+ }
+
+ /* profiling ... */
+ VGP_PUSHCC(VgpTranslate);
+
+ /* Look in the code redirect table to see if we should
+ translate an alternative address for orig_addr. */
+ redir =3D VG_(code_redirect)(orig_addr);
+
+ if (redir !=3D orig_addr && VG_(clo_verbosity) >=3D 2) {
+ Bool ok;
+ Char name1[64] =3D "";
+ Char name2[64] =3D "";
+ name1[0] =3D name2[0] =3D 0;
+ ok =3D VG_(get_fnname_w_offset)(orig_addr, name1, 64);
+ if (!ok) VG_(strcpy)(name1, "???");
+ ok =3D VG_(get_fnname_w_offset)(redir, name2, 64);
+ if (!ok) VG_(strcpy)(name2, "???");
+ VG_(message)(Vg_DebugMsg,=20
+ "TRANSLATE: 0x%llx (%s) redirected to 0x%llx (%s)",
+ orig_addr, name1,
+ redir, name2 );
+ }
+ orig_addr =3D redir;
+
+ /* If codegen tracing, don't start tracing until
+ notrace_until_limit blocks have gone by. This avoids printing
+ huge amounts of useless junk when all we want to see is the last
+ few blocks translated prior to a failure. Set
+ notrace_until_limit to be the number of translations to be made
+ before --trace-codegen=3D style printing takes effect. */
+ notrace_until_done
+ =3D VG_(get_bbs_translated)() >=3D notrace_until_limit;
+
+ seg =3D VG_(find_segment)(orig_addr);
+
+ if (!debugging_translation)
+ VG_TRACK( pre_mem_read, Vg_CoreTranslate, tid, "", orig_addr, 1 );
+
+ /* If doing any code printing, print a basic block start marker */
+ if (VG_(clo_trace_flags) || debugging_translation) {
+ Char fnname[64] =3D "";
+ VG_(get_fnname_w_offset)(orig_addr, fnname, 64);
+ VG_(printf)(
+ "=3D=3D=3D=3D BB %d %s(0x%llx) approx BBs exec'd %lld =3D=3D=
=3D=3D\n",
+ VG_(get_bbs_translated)(), fnname, orig_addr,=20
+ VG_(bbs_done));
+ }
+
+ if (seg =3D=3D NULL ||
+ !VG_(seg_contains)(seg, orig_addr, 1) ||=20
+ (seg->prot & (VKI_PROT_READ|VKI_PROT_EXEC)) =3D=3D 0) {
+ /* Code address is bad - deliver a signal instead */
+ vg_assert(!VG_(is_addressable)(orig_addr, 1,=20
+ VKI_PROT_READ|VKI_PROT_EXEC));
+
+ if (seg !=3D NULL && VG_(seg_contains)(seg, orig_addr, 1)) {
+ vg_assert((seg->prot & VKI_PROT_EXEC) =3D=3D 0);
+ VG_(synth_fault_perms)(tid, orig_addr);
+ } else
+ VG_(synth_fault_mapping)(tid, orig_addr);
+
+ return False;
+ } else
+ seg->flags |=3D SF_CODE; /* contains cached code */
+
+ /* True if a debug trans., or if bit N set in VG_(clo_trace_codegen).=
*/
+ verbosity =3D 0;
+ if (debugging_translation) {
+ verbosity =3D debugging_verbosity;
+ }
+ else
+ if ( (VG_(clo_trace_flags) > 0
+ && VG_(get_bbs_translated)() >=3D VG_(clo_trace_notbelow) )) {
+ verbosity =3D VG_(clo_trace_flags);
+ }
+
+ /* Actually do the translation. */
+ tl_assert2(VG_(tdict).tool_instrument,
+ "you forgot to set VgToolInterface function 'tool_instrume=
nt'");
+ tres =3D LibVEX_Translate (=20
+ vex_arch, vex_subarch,
+ vex_arch, vex_subarch,
+ (UChar*)ULong_to_Ptr(orig_addr),=20
+ (Addr64)orig_addr,=20
+ chase_into_ok,
+ &vge,
+ tmpbuf, N_TMPBUF, &tmpbuf_used,
+ VG_(tdict).tool_instrument,
+ need_to_handle_SP_assignment()
+ ? vg_SP_update_pass
+ : NULL,
+ True, /* cleanup after instrumentation */
+ NULL,
+ verbosity
+ );
+
+ vg_assert(tres =3D=3D VexTransOK);
+ vg_assert(tmpbuf_used <=3D N_TMPBUF);
+ vg_assert(tmpbuf_used > 0);
+
+#undef DECIDE_IF_PRINTING_CODEGEN
+
+ /* Copy data at trans_addr into the translation cache. */
+ vg_assert(tmpbuf_used > 0 && tmpbuf_used < 65536);
+
+ // If debugging, don't do anything with the translated block; we
+ // only did this for the debugging output produced along the way.
+ if (!debugging_translation) {
+ // Note that we use orig_addr0, not orig_addr, which might have be=
en
+ // changed by the redirection
+ VG_(add_to_trans_tab)( &vge,
+ orig_addr0,
+ (Addr)(&tmpbuf[0]),=20
+ tmpbuf_used );
+ }
+
+ VGP_POPCC(VgpTranslate);
+
+ return True;
+}
+
+/*--------------------------------------------------------------------*/
+/*--- end ---*/
+/*--------------------------------------------------------------------*/
+
Added: trunk/coregrind/pub_core_translate.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/pub_core_translate.h 2005-05-13 22:18:47 UTC (rev 369=
9)
+++ trunk/coregrind/pub_core_translate.h 2005-05-13 23:11:40 UTC (rev 370=
0)
@@ -0,0 +1,49 @@
+
+/*--------------------------------------------------------------------*/
+/*--- The JITter wrapper. pub_core_translate.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2000-2005 Julian Seward
+ js...@ac...
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __PUB_CORE_TRANSLATE_H
+#define __PUB_CORE_TRANSLATE_H
+
+//--------------------------------------------------------------------
+// PURPOSE: This module is Valgrind's interface to the JITter. It's
+// basically a wrapper around Vex.
+//--------------------------------------------------------------------
+
+extern=20
+Bool VG_(translate) ( ThreadId tid,=20
+ Addr64 orig_addr,
+ Bool debugging_translation,
+ Int debugging_verbosity );
+
+#endif // __PUB_CORE_TRANSLATE_H
+
+/*--------------------------------------------------------------------*/
+/*--- end ---*/
+/*--------------------------------------------------------------------*/
Modified: trunk/coregrind/vg_scheduler.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/vg_scheduler.c 2005-05-13 22:18:47 UTC (rev 3699)
+++ trunk/coregrind/vg_scheduler.c 2005-05-13 23:11:40 UTC (rev 3700)
@@ -66,6 +66,7 @@
#include "pub_core_stacktrace.h"
#include "pub_core_syscalls.h"
#include "pub_core_tooliface.h"
+#include "pub_core_translate.h"
#include "vki_unistd.h"
=20
/* ---------------------------------------------------------------------
Deleted: trunk/coregrind/vg_translate.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/vg_translate.c 2005-05-13 22:18:47 UTC (rev 3699)
+++ trunk/coregrind/vg_translate.c 2005-05-13 23:11:40 UTC (rev 3700)
@@ -1,513 +0,0 @@
-
-/*--------------------------------------------------------------------*/
-/*--- The JITter proper: register allocation & code improvement ---*/
-/*--- vg_translate.c ---*/
-/*--------------------------------------------------------------------*/
-
-/*
- This file is part of Valgrind, a dynamic binary instrumentation
- framework.
-
- Copyright (C) 2000-2005 Julian Seward=20
- js...@ac...
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307, USA.
-
- The GNU General Public License is contained in the file COPYING.
-*/
-
-#include "core.h"
-#include "pub_core_aspacemgr.h"
-#include "pub_core_tooliface.h"
-
-
-/*------------------------------------------------------------*/
-/*--- %SP-update pass ---*/
-/*------------------------------------------------------------*/
-
-/* NOTE: this comment is out of date */
-
-/* For tools that want to know about %ESP changes, this pass adds
- in the appropriate hooks. We have to do it after the tool's
- instrumentation, so the tool doesn't have to worry about the CCALLs
- it adds in, and we must do it before register allocation because
- spilled temps make it much harder to work out the %esp deltas.
- Thus we have it as an extra phase between the two.=20
- =20
- We look for "GETL %ESP, t_ESP", then track ADDs and SUBs of
- literal values to t_ESP, and the total delta of the ADDs/SUBs. Then =
if
- "PUTL t_ESP, %ESP" happens, we call the helper with the known delta. =
We
- also cope with "MOVL t_ESP, tX", making tX the new t_ESP. If any oth=
er
- instruction clobbers t_ESP, we don't track it anymore, and fall back =
to
- the delta-is-unknown case. That case is also used when the delta is =
not
- a nice small amount, or an unknown amount.
-*/
-
-static
-IRBB* vg_SP_update_pass ( IRBB* bb_in, VexGuestLayout* layout,=20
- IRType gWordTy, IRType hWordTy )
-{
- Int i, j, minoff_ST, maxoff_ST, sizeof_SP, offset_SP;
- IRDirty *dcall, *d;
- IRStmt* st;
- IRExpr* e;
- IRArray* descr;
- IRTemp curr;
- IRType typeof_SP;
- Long delta;
-
- /* Set up BB */
- IRBB* bb =3D emptyIRBB();
- bb->tyenv =3D dopyIRTypeEnv(bb_in->tyenv);
- bb->next =3D dopyIRExpr(bb_in->next);
- bb->jumpkind =3D bb_in->jumpkind;
-
- curr =3D IRTemp_INVALID;
- delta =3D 0;
-
- sizeof_SP =3D layout->sizeof_SP;
- offset_SP =3D layout->offset_SP;
- typeof_SP =3D sizeof_SP=3D=3D4 ? Ity_I32 : Ity_I64;
- vg_assert(sizeof_SP =3D=3D 4 || sizeof_SP =3D=3D 8);
-
-# define IS_ADD(op) (sizeof_SP=3D=3D4 ? ((op)=3D=3DIop_Add32) : ((op)=3D=
=3DIop_Add64))
-# define IS_SUB(op) (sizeof_SP=3D=3D4 ? ((op)=3D=3DIop_Sub32) : ((op)=3D=
=3DIop_Sub64))
-
-# define IS_ADD_OR_SUB(op) (IS_ADD(op) || IS_SUB(op))
-
-# define GET_CONST(con) =
\
- (sizeof_SP=3D=3D4 ? (Long)(Int)(con->Ico.U32) =
\
- : (Long)(con->Ico.U64))
-
-# define DO(kind, syze) =
\
- do { =
\
- if (!VG_(tdict).track_##kind##_mem_stack_##syze) \
- goto generic; =
\
- =
\
- /* I don't know if it's really necessary to say that the */ =
\
- /* call reads the stack pointer. But anyway, we do. */ =
\
- dcall =3D unsafeIRDirty_0_N( =
\
- 1/*regparms*/, =
\
- "track_" #kind "_mem_stack_" #syze, =
\
- VG_(tdict).track_##kind##_mem_stack_##syze, =
\
- mkIRExprVec_1(IRExpr_Tmp(curr)) =
\
- ); =
\
- dcall->nFxState =3D 1; =
\
- dcall->fxState[0].fx =3D Ifx_Read; =
\
- dcall->fxState[0].offset =3D layout->offset_SP; =
\
- dcall->fxState[0].size =3D layout->sizeof_SP; =
\
- =
\
- addStmtToIRBB( bb, IRStmt_Dirty(dcall) ); =
\
- } while (0)
-
- for (i =3D 0; i < bb_in->stmts_used; i++) {
-
- st =3D bb_in->stmts[i];
- if (!st)
- continue;
-
- /* t =3D Get(sp): curr =3D t, delta =3D 0 */
- if (st->tag !=3D Ist_Tmp) goto case2;
- e =3D st->Ist.Tmp.data;
- if (e->tag !=3D Iex_Get) goto case2;
- if (e->Iex.Get.offset !=3D offset_SP) goto case2;
- if (e->Iex.Get.ty !=3D typeof_SP) goto case2;
- curr =3D st->Ist.Tmp.tmp;
- delta =3D 0;
- addStmtToIRBB( bb, st );
- continue;
-
- case2:
- /* t' =3D curr +/- const: curr =3D t', delta +=3D/-=3D const */
- if (st->tag !=3D Ist_Tmp) goto case3;
- e =3D st->Ist.Tmp.data;
- if (e->tag !=3D Iex_Binop) goto case3;
- if (e->Iex.Binop.arg1->tag !=3D Iex_Tmp) goto case3;
- if (e->Iex.Binop.arg1->Iex.Tmp.tmp !=3D curr) goto case3;
- if (e->Iex.Binop.arg2->tag !=3D Iex_Const) goto case3;
- if (!IS_ADD_OR_SUB(e->Iex.Binop.op)) goto case3;
- curr =3D st->Ist.Tmp.tmp;
- if (IS_ADD(e->Iex.Binop.op))
- delta +=3D GET_CONST(e->Iex.Binop.arg2->Iex.Const.con);
- else
- delta -=3D GET_CONST(e->Iex.Binop.arg2->Iex.Const.con);
- addStmtToIRBB( bb, st );
- continue;
-
- case3:
- /* t' =3D curr: curr =3D t' */
- if (st->tag !=3D Ist_Tmp) goto case4;
- e =3D st->Ist.Tmp.data;
- if (e->tag !=3D Iex_Tmp) goto case4;
- if (e->Iex.Tmp.tmp !=3D curr) goto case4;
- curr =3D st->Ist.Tmp.tmp;
- addStmtToIRBB( bb, st );
- continue;
-
- case4:
- /* Put(sp) =3D curr */
- if (st->tag !=3D Ist_Put) goto case5;
- if (st->Ist.Put.offset !=3D offset_SP) goto case5;
- if (st->Ist.Put.data->tag !=3D Iex_Tmp) goto case5;
- if (st->Ist.Put.data->Iex.Tmp.tmp =3D=3D curr) {
- switch (delta) {
- case 0: addStmtToIRBB(bb,st); delta =3D 0; co=
ntinue;
- case 4: DO(die, 4); addStmtToIRBB(bb,st); delta =3D 0; co=
ntinue;
- case -4: DO(new, 4); addStmtToIRBB(bb,st); delta =3D 0; co=
ntinue;
- case 8: DO(die, 8); addStmtToIRBB(bb,st); delta =3D 0; co=
ntinue;
- case -8: DO(new, 8); addStmtToIRBB(bb,st); delta =3D 0; co=
ntinue;
- case 12: DO(die, 12); addStmtToIRBB(bb,st); delta =3D 0; co=
ntinue;
- case -12: DO(new, 12); addStmtToIRBB(bb,st); delta =3D 0; co=
ntinue;
- case 16: DO(die, 16); addStmtToIRBB(bb,st); delta =3D 0; co=
ntinue;
- case -16: DO(new, 16); addStmtToIRBB(bb,st); delta =3D 0; co=
ntinue;
- case 32: DO(die, 32); addStmtToIRBB(bb,st); delta =3D 0; co=
ntinue;
- case -32: DO(new, 32); addStmtToIRBB(bb,st); delta =3D 0; co=
ntinue;
- default: goto generic;
- }
- } else {
- IRTemp old_SP;
- generic:
- /* Pass both the old and new SP values to this helper. */
- old_SP =3D newIRTemp(bb->tyenv, typeof_SP);
- addStmtToIRBB(=20
- bb,
- IRStmt_Tmp( old_SP, IRExpr_Get(offset_SP, typeof_SP) )=20
- );
-
- dcall =3D unsafeIRDirty_0_N(=20
- 2/*regparms*/,=20
- "VG_(unknown_SP_update)", &VG_(unknown_SP_update),
- mkIRExprVec_2( IRExpr_Tmp(old_SP), st->Ist.Put.data =
)=20
- );
- addStmtToIRBB( bb, IRStmt_Dirty(dcall) );
-
- addStmtToIRBB( bb, st );
-
- curr =3D st->Ist.Put.data->Iex.Tmp.tmp;
- delta =3D 0;
- continue;
- }
-
- case5:
- /* PutI or Dirty call which overlaps SP: complain. We can't
- deal with SP changing in weird ways (well, we can, but not at
- this time of night). */
- if (st->tag =3D=3D Ist_PutI) {
- descr =3D st->Ist.PutI.descr;
- minoff_ST =3D descr->base;
- maxoff_ST =3D descr->base + descr->nElems * sizeofIRType(descr-=
>elemTy) - 1;
- if (!(offset_SP > maxoff_ST || (offset_SP + sizeof_SP - 1) < mi=
noff_ST))
- goto complain;
- }
- if (st->tag =3D=3D Ist_Dirty) {
- d =3D st->Ist.Dirty.details;
- for (j =3D 0; j < d->nFxState; j++) {
- minoff_ST =3D d->fxState[j].offset;
- maxoff_ST =3D d->fxState[j].offset + d->fxState[j].size - 1;
- if (d->fxState[j].fx =3D=3D Ifx_Read || d->fxState[j].fx =3D=
=3D Ifx_None)
- continue;
- if (!(offset_SP > maxoff_ST || (offset_SP + sizeof_SP - 1) <=
minoff_ST))
- goto complain;
- }
- }
-
- /* well, not interesting. Just copy and keep going. */
- addStmtToIRBB( bb, st );
-
- } /* for (i =3D 0; i < bb_in->stmts_used; i++) */
-
- return bb;
-
- complain:
- VG_(core_panic)("vg_SP_update_pass: PutI or Dirty which overlaps SP")=
;
-
-}
-
-
-
-#if 0
- for (i =3D 0; i < bb_in->stmts_used; i++) {
- st =3D bb_in->stmts[i];
- if (!st)
- continue;
- if (st->tag !=3D Ist_Put)=20
- goto boring;
- offP =3D st->Ist.Put.offset;
- if (offP !=3D layout->offset_SP)=20
- goto boring;
- szP =3D sizeofIRType(typeOfIRExpr(bb_in->tyenv, st->Ist.Put.data))=
;
- if (szP !=3D layout->sizeof_SP)
- goto boring;
- vg_assert(isAtom(st->Ist.Put.data));
-
- /* I don't know if it's really necessary to say that the call read=
s
- the stack pointer. But anyway, we do. */ =20
- dcall =3D unsafeIRDirty_0_N(=20
- mkIRCallee(1, "VG_(unknown_esp_update)",=20
- (HWord)&VG_(unknown_esp_update)),
- mkIRExprVec_1(st->Ist.Put.data)=20
- );
- dcall->nFxState =3D 1;
- dcall->fxState[0].fx =3D Ifx_Read;
- dcall->fxState[0].offset =3D layout->offset_SP;
- dcall->fxState[0].size =3D layout->sizeof_SP;
-
- addStmtToIRBB( bb, IRStmt_Dirty(dcall) );
-
- boring:
- addStmtToIRBB( bb, st );
- }
-#endif
-
-
-/*------------------------------------------------------------*/
-/*--- Main entry point for the JITter. ---*/
-/*------------------------------------------------------------*/
-
-/* Vex dumps the final code in here. Then we can copy it off
- wherever we like. */
-#define N_TMPBUF 20000
-static UChar tmpbuf[N_TMPBUF];
-
-/* Function pointers we must supply to LibVEX in order that it
- can bomb out and emit messages under Valgrind's control. */
-__attribute__ ((noreturn))
-static
-void failure_exit ( void )
-{
- LibVEX_ShowAllocStats();
- VG_(core_panic)("LibVEX called failure_exit().");
-}
-
-static
-void log_bytes ( HChar* bytes, Int nbytes )
-{
- Int i;
- for (i =3D 0; i < nbytes-3; i +=3D 4)
- VG_(printf)("%c%c%c%c", bytes[i], bytes[i+1], bytes[i+2], bytes[i+3=
]);
- for (; i < nbytes; i++)=20
- VG_(printf)("%c", bytes[i]);
-}
-
-/* Translate the basic block beginning at orig_addr, and add it to
- the translation cache & translation table. Unless 'debugging' is tru=
e,
- in which case the call is being done for debugging purposes, so
- (a) throw away the translation once it is made, and (b) produce a
- load of debugging output.=20
-
- 'tid' is the identity of the thread needing this block.
-*/
-
-/* This stops Vex from chasing into function entry points that we wish
- to redirect. Chasing across them obviously defeats the redirect
- mechanism, with bad effects for Memcheck, Addrcheck, and possibly
- others. */
-static Bool chase_into_ok ( Addr64 addr64 )
-{
- Addr addr =3D (Addr)addr64;
- if (addr !=3D VG_(code_redirect)(addr)) {
- if (0) VG_(printf)("not chasing into 0x%x\n", addr);
- return False;
- } else {
- return True; /* ok to chase into 'addr' */
- }
-}
-
-static Bool need_to_handle_SP_assignment(void)
-{
- return ( VG_(tdict).track_new_mem_stack_4 ||
- VG_(tdict).track_die_mem_stack_4 ||
- VG_(tdict).track_new_mem_stack_8 ||
- VG_(tdict).track_die_mem_stack_8 ||
- VG_(tdict).track_new_mem_stack_12 ||
- VG_(tdict).track_die_mem_stack_12 ||
- VG_(tdict).track_new_mem_stack_16 ||
- VG_(tdict).track_die_mem_stack_16 ||
- VG_(tdict).track_new_mem_stack_32 ||
- VG_(tdict).track_die_mem_stack_32 ||
- VG_(tdict).track_new_mem_stack ||
- VG_(tdict).track_die_mem_stack );
-}
-
-Bool VG_(translate) ( ThreadId tid,=20
- Addr64 orig_addr,
- Bool debugging_translation,
- Int debugging_verbosity )
-{
- Addr64 redir, orig_addr0 =3D orig_addr;
- Int tmpbuf_used, verbosity;
- Bool notrace_until_done;
- UInt notrace_until_limit =3D 0;
- Segment* seg;
- VexGuestExtents vge;
-
- /* Indicates what arch and subarch we are running on. */
- static VexArch vex_arch =3D VexArch_INVALID;
- static VexSubArch vex_subarch =3D VexSubArch_INVALID;
-
- /* Make sure Vex is initialised right. */
- VexTranslateResult tres;
- static Bool vex_init_done =3D False;
-
- if (!vex_init_done) {
- Bool ok =3D VGA_(getArchAndSubArch)( &vex_arch, &vex_subarch );
- if (!ok) {
- VG_(printf)("\n");
- VG_(printf)("valgrind: fatal error: unsupported CPU.\n");
- VG_(printf)(" Supported CPUs are:\n");
- VG_(printf)(" * x86 with SSE state (Pentium II or above, "
- "AMD Athlon or above)\n");
- VG_(printf)("\n");
- VG_(exit)(1);
- }
- if (VG_(clo_verbosity) > 2) {
- VG_(message)(Vg_DebugMsg,=20
- "Host CPU: arch =3D %s, subarch =3D %s",
- LibVEX_ppVexArch ( vex_arch ),
- LibVEX_ppVexSubArch( vex_subarch ) );
- }
-
- LibVEX_Init ( &failure_exit, &log_bytes,=20
- 1, /* debug_paranoia */=20
- False, /* valgrind support */
- &VG_(clo_vex_control) );
- vex_init_done =3D True;
- }
-
- /* profiling ... */
- VGP_PUSHCC(VgpTranslate);
-
- /* Look in the code redirect table to see if we should
- translate an alternative address for orig_addr. */
- redir =3D VG_(code_redirect)(orig_addr);
-
- if (redir !=3D orig_addr && VG_(clo_verbosity) >=3D 2) {
- Bool ok;
- Char name1[64] =3D "";
- Char name2[64] =3D "";
- name1[0] =3D name2[0] =3D 0;
- ok =3D VG_(get_fnname_w_offset)(orig_addr, name1, 64);
- if (!ok) VG_(strcpy)(name1, "???");
- ok =3D VG_(get_fnname_w_offset)(redir, name2, 64);
- if (!ok) VG_(strcpy)(name2, "???");
- VG_(message)(Vg_DebugMsg,=20
- "TRANSLATE: 0x%llx (%s) redirected to 0x%llx (%s)",
- orig_addr, name1,
- redir, name2 );
- }
- orig_addr =3D redir;
-
- /* If codegen tracing, don't start tracing until
- notrace_until_limit blocks have gone by. This avoids printing
- huge amounts of useless junk when all we want to see is the last
- few blocks translated prior to a failure. Set
- notrace_until_limit to be the number of translations to be made
- before --trace-codegen=3D style printing takes effect. */
- notrace_until_done
- =3D VG_(get_bbs_translated)() >=3D notrace_until_limit;
-
- seg =3D VG_(find_segment)(orig_addr);
-
- if (!debugging_translation)
- VG_TRACK( pre_mem_read, Vg_CoreTranslate, tid, "", orig_addr, 1 );
-
- /* If doing any code printing, print a basic block start marker */
- if (VG_(clo_trace_flags) || debugging_translation) {
- Char fnname[64] =3D "";
- VG_(get_fnname_w_offset)(orig_addr, fnname, 64);
- VG_(printf)(
- "=3D=3D=3D=3D BB %d %s(0x%llx) approx BBs exec'd %lld =3D=3D=
=3D=3D\n",
- VG_(get_bbs_translated)(), fnname, orig_addr,=20
- VG_(bbs_done));
- }
-
- if (seg =3D=3D NULL ||
- !VG_(seg_contains)(seg, orig_addr, 1) ||=20
- (seg->prot & (VKI_PROT_READ|VKI_PROT_EXEC)) =3D=3D 0) {
- /* Code address is bad - deliver a signal instead */
- vg_assert(!VG_(is_addressable)(orig_addr, 1,=20
- VKI_PROT_READ|VKI_PROT_EXEC));
-
- if (seg !=3D NULL && VG_(seg_contains)(seg, orig_addr, 1)) {
- vg_assert((seg->prot & VKI_PROT_EXEC) =3D=3D 0);
- VG_(synth_fault_perms)(tid, orig_addr);
- } else
- VG_(synth_fault_mapping)(tid, orig_addr);
-
- return False;
- } else
- seg->flags |=3D SF_CODE; /* contains cached code */
-
- /* True if a debug trans., or if bit N set in VG_(clo_trace_codegen).=
*/
- verbosity =3D 0;
- if (debugging_translation) {
- verbosity =3D debugging_verbosity;
- }
- else
- if ( (VG_(clo_trace_flags) > 0
- && VG_(get_bbs_translated)() >=3D VG_(clo_trace_notbelow) )) {
- verbosity =3D VG_(clo_trace_flags);
- }
-
- /* Actually do the translation. */
- tl_assert2(VG_(tdict).tool_instrument,
- "you forgot to set VgToolInterface function 'tool_instrume=
nt'");
- tres =3D LibVEX_Translate (=20
- vex_arch, vex_subarch,
- vex_arch, vex_subarch,
- (UChar*)ULong_to_Ptr(orig_addr),=20
- (Addr64)orig_addr,=20
- chase_into_ok,
- &vge,
- tmpbuf, N_TMPBUF, &tmpbuf_used,
- VG_(tdict).tool_instrument,
- need_to_handle_SP_assignment()
- ? vg_SP_update_pass
- : NULL,
- True, /* cleanup after instrumentation */
- NULL,
- verbosity
- );
-
- vg_assert(tres =3D=3D VexTransOK);
- vg_assert(tmpbuf_used <=3D N_TMPBUF);
- vg_assert(tmpbuf_used > 0);
-
-#undef DECIDE_IF_PRINTING_CODEGEN
-
- /* Copy data at trans_addr into the translation cache. */
- vg_assert(tmpbuf_used > 0 && tmpbuf_used < 65536);
-
- // If debugging, don't do anything with the translated block; we
- // only did this for the debugging output produced along the way.
- if (!debugging_translation) {
- // Note that we use orig_addr0, not orig_addr, which might have be=
en
- // changed by the redirection
- VG_(add_to_trans_tab)( &vge,
- orig_addr0,
- (Addr)(&tmpbuf[0]),=20
- tmpbuf_used );
- }
-
- VGP_POPCC(VgpTranslate);
-
- return True;
-}
-
-/*--------------------------------------------------------------------*/
-/*--- end vg_translate.c ---*/
-/*--------------------------------------------------------------------*/
-
Modified: trunk/coregrind/vg_transtab.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/vg_transtab.c 2005-05-13 22:18:47 UTC (rev 3699)
+++ trunk/coregrind/vg_transtab.c 2005-05-13 23:11:40 UTC (rev 3700)
@@ -31,6 +31,7 @@
=20
#include "core.h"
#include "pub_core_tooliface.h"
+#include "pub_core_translate.h"
=20
/* #define DEBUG_TRANSTAB */
=20
|