Author: sewardj
Date: 2006-01-12 12:27:58 +0000 (Thu, 12 Jan 2006)
New Revision: 1536
Log:
Merge in function wrapping support from the FNWRAP branch. That
branch hereby becomes inactive.
Modified:
trunk/priv/guest-amd64/ghelpers.c
trunk/priv/guest-amd64/toIR.c
trunk/priv/guest-generic/bb_to_IR.c
trunk/priv/guest-generic/bb_to_IR.h
trunk/priv/guest-ppc/ghelpers.c
trunk/priv/guest-ppc/toIR.c
trunk/priv/guest-x86/ghelpers.c
trunk/priv/guest-x86/toIR.c
trunk/priv/host-amd64/hdefs.c
trunk/priv/host-ppc/hdefs.c
trunk/priv/host-x86/hdefs.c
trunk/priv/ir/irdefs.c
trunk/priv/main/vex_main.c
trunk/pub/libvex.h
trunk/pub/libvex_guest_amd64.h
trunk/pub/libvex_guest_ppc32.h
trunk/pub/libvex_guest_ppc64.h
trunk/pub/libvex_guest_x86.h
trunk/pub/libvex_ir.h
trunk/pub/libvex_trc_values.h
trunk/test_main.c
Modified: trunk/priv/guest-amd64/ghelpers.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/priv/guest-amd64/ghelpers.c 2006-01-10 20:39:03 UTC (rev 1535)
+++ trunk/priv/guest-amd64/ghelpers.c 2006-01-12 12:27:58 UTC (rev 1536)
@@ -1965,6 +1965,8 @@
initialise them anyway. */
vex_state->guest_TISTART =3D 0;
vex_state->guest_TILEN =3D 0;
+
+ vex_state->guest_NRADDR =3D 0;
}
=20
=20
Modified: trunk/priv/guest-amd64/toIR.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/priv/guest-amd64/toIR.c 2006-01-10 20:39:03 UTC (rev 1535)
+++ trunk/priv/guest-amd64/toIR.c 2006-01-12 12:27:58 UTC (rev 1536)
@@ -122,6 +122,28 @@
sto{s,sb,sw,sd,sq}
xlat{,b} */
=20
+/* "Special" instructions.
+
+ This instruction decoder can decode three special instructions
+ which mean nothing natively (are no-ops as far as regs/mem are
+ concerned) but have meaning for supporting Valgrind. A special
+ instruction is flagged by the 16-byte preamble 48C1C703 48C1C70D
+ 48C1C73D 48C1C733 (in the standard interpretation, that means: rolq
+ $3, %rdi; rolq $13, %rdi; rolq $61, %rdi; rolq $51, %rdi).
+ Following that, one of the following 3 are allowed (standard
+ interpretation in parentheses):
+
+ 4887DB (xchgq %rbx,%rbx) %RDX =3D client_request ( %RAX )
+ 4887C9 (xchgq %rcx,%rcx) %RAX =3D guest_NRADDR
+ 4887D2 (xchgq %rdx,%rdx) call-noredir *%RAX
+
+ Any other bytes following the 16-byte preamble are illegal and
+ constitute a failure in instruction decoding. This all assumes
+ that the preamble will never occur except in specific code
+ fragments designed for Valgrind to catch.
+
+ No prefixes may precede a "Special" instruction. */
+
/* Translates AMD64 code to IR. */
=20
#include "libvex_basictypes.h"
@@ -398,7 +420,9 @@
#define OFFB_TISTART offsetof(VexGuestAMD64State,guest_TISTART)
#define OFFB_TILEN offsetof(VexGuestAMD64State,guest_TILEN)
=20
+#define OFFB_NRADDR offsetof(VexGuestAMD64State,guest_NRADDR)
=20
+
/*------------------------------------------------------------*/
/*--- Helper bits and pieces for deconstructing the ---*/
/*--- amd64 insn stream. ---*/
@@ -7949,29 +7973,61 @@
if (put_IP)
stmt( IRStmt_Put( OFFB_RIP, mkU64(guest_RIP_curr_instr)) );
=20
- /* Spot the client-request magic sequence. */
+ /* Spot "Special" instructions (see comment at top of file). */
{
UChar* code =3D (UChar*)(guest_code + delta);
- /* Spot this:
- C1C01D roll $29, %eax
- C1C003 roll $3, %eax
- C1C81B rorl $27, %eax
- C1C805 rorl $5, %eax
- C1C00D roll $13, %eax
- C1C013 roll $19, %eax =20
+ /* Spot the 16-byte preamble:
+ 48C1C703 rolq $3, %rdi
+ 48C1C70D rolq $13, %rdi
+ 48C1C73D rolq $61, %rdi
+ 48C1C733 rolq $51, %rdi
*/
- if (code[ 0] =3D=3D 0xC1 && code[ 1] =3D=3D 0xC0 && code[ 2] =3D=3D=
0x1D &&
- code[ 3] =3D=3D 0xC1 && code[ 4] =3D=3D 0xC0 && code[ 5] =3D=3D=
0x03 &&
- code[ 6] =3D=3D 0xC1 && code[ 7] =3D=3D 0xC8 && code[ 8] =3D=3D=
0x1B &&
- code[ 9] =3D=3D 0xC1 && code[10] =3D=3D 0xC8 && code[11] =3D=3D=
0x05 &&
- code[12] =3D=3D 0xC1 && code[13] =3D=3D 0xC0 && code[14] =3D=3D=
0x0D &&
- code[15] =3D=3D 0xC1 && code[16] =3D=3D 0xC0 && code[17] =3D=3D=
0x13
- ) {
- DIP("%%edx =3D client_request ( %%eax )\n"); =20
- delta +=3D 18;
- jmp_lit(Ijk_ClientReq, guest_RIP_bbstart+delta);
- dres.whatNext =3D Dis_StopHere;
- goto decode_success;
+ if (code[ 0] =3D=3D 0x48 && code[ 1] =3D=3D 0xC1 && code[ 2] =3D=3D=
0xC7=20
+ && code[ 3] =3D=3D 0x03 &=
&
+ code[ 4] =3D=3D 0x48 && code[ 5] =3D=3D 0xC1 && code[ 6] =3D=3D=
0xC7=20
+ && code[ 7] =3D=3D 0x0D &=
&
+ code[ 8] =3D=3D 0x48 && code[ 9] =3D=3D 0xC1 && code[10] =3D=3D=
0xC7=20
+ && code[11] =3D=3D 0x3D &=
&
+ code[12] =3D=3D 0x48 && code[13] =3D=3D 0xC1 && code[14] =3D=3D=
0xC7=20
+ && code[15] =3D=3D 0x33) =
{
+ /* Got a "Special" instruction preamble. Which one is it? */
+ if (code[16] =3D=3D 0x48 && code[17] =3D=3D 0x87=20
+ && code[18] =3D=3D 0xDB /* xchgq %rbx,%rbx=
*/) {
+ /* %RDX =3D client_request ( %RAX ) */
+ DIP("%%rdx =3D client_request ( %%rax )\n");
+ delta +=3D 19;
+ jmp_lit(Ijk_ClientReq, guest_RIP_bbstart+delta);
+ dres.whatNext =3D Dis_StopHere;
+ goto decode_success;
+ }
+ else
+ if (code[16] =3D=3D 0x48 && code[17] =3D=3D 0x87=20
+ && code[18] =3D=3D 0xC9 /* xchgq %rcx,%rcx=
*/) {
+ /* %RAX =3D guest_NRADDR */
+ DIP("%%rax =3D guest_NRADDR\n");
+ delta +=3D 19;
+ putIRegRAX(8, IRExpr_Get( OFFB_NRADDR, Ity_I64 ));
+ goto decode_success;
+ }
+ else
+ if (code[16] =3D=3D 0x48 && code[17] =3D=3D 0x87=20
+ && code[18] =3D=3D 0xD2 /* xchgq %rdx,%rdx=
*/) {
+ /* call-noredir *%RAX */
+ DIP("call-noredir *%%rax\n");
+ delta +=3D 19;
+ t1 =3D newTemp(Ity_I64);
+ assign(t1, getIRegRAX(8));
+ t2 =3D newTemp(Ity_I64);
+ assign(t2, binop(Iop_Sub64, getIReg64(R_RSP), mkU64(8)));
+ putIReg64(R_RSP, mkexpr(t2));
+ storeLE( mkexpr(t2), mkU64(guest_RIP_bbstart+delta));
+ jmp_treg(Ijk_NoRedir,t1);
+ dres.whatNext =3D Dis_StopHere;
+ goto decode_success;
+ }
+ /* We don't know what it is. */
+ goto decode_failure;
+ /*NOTREACHED*/
}
}
=20
Modified: trunk/priv/guest-generic/bb_to_IR.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/priv/guest-generic/bb_to_IR.c 2006-01-10 20:39:03 UTC (rev 1535=
)
+++ trunk/priv/guest-generic/bb_to_IR.c 2006-01-12 12:27:58 UTC (rev 1536=
)
@@ -56,8 +56,10 @@
__attribute((regparm(2)))
static UInt genericg_compute_adler32 ( HWord addr, HWord len );
=20
+/* Small helpers */
+static Bool const_False ( Addr64 a ) { return False; }
=20
-/* Disassemble a complete basic block, starting at guest_IP_bbstart,=20
+/* Disassemble a complete basic block, starting at guest_IP_start,=20
returning a new IRBB. The disassembler may chase across basic
block boundaries if it wishes and if chase_into_ok allows it.
The precise guest address ranges from which code has been taken
@@ -71,24 +73,29 @@
do_self_check indicates that the caller needs a self-checking
translation.
=20
- offB_TIADDR and offB_TILEN are the offsets of guest_TIADDR and
- guest_TILEN. Since this routine has to work for any guest state,
- without knowing what it is, those offsets have to passed in.
+ do_set_NRADDR indicates that the unredirected guest address for
+ this BB should be written to the guest's NRADDR pseudo-register.
+
+ offB_TIADDR, offB_TILEN and offB_NRADDR are the offsets of
+ guest_TIADDR, guest_TILEN and guest_NRADDR. Since this routine has
+ to work for any guest state, without knowing what it is, those
+ offsets have to passed in.
*/
=20
-static Bool const_False ( Addr64 a ) { return False; }
-
IRBB* bb_to_IR ( /*OUT*/VexGuestExtents* vge,
/*IN*/ DisOneInstrFn dis_instr_fn,
/*IN*/ UChar* guest_code,
/*IN*/ Addr64 guest_IP_bbstart,
+ /*IN*/ Addr64 guest_IP_bbstart_noredir,
/*IN*/ Bool (*chase_into_ok)(Addr64),
/*IN*/ Bool host_bigendian,
/*IN*/ VexArchInfo* archinfo_guest,
/*IN*/ IRType guest_word_type,
/*IN*/ Bool do_self_check,
+ /*IN*/ Bool do_set_NRADDR,
/*IN*/ Int offB_TISTART,
- /*IN*/ Int offB_TILEN )
+ /*IN*/ Int offB_TILEN,
+ /*IN*/ Int offB_NRADDR )
{
Long delta;
Int i, n_instrs, first_stmt_idx;
@@ -100,6 +107,8 @@
Int selfcheck_idx =3D 0;
IRBB* irbb;
Addr64 guest_IP_curr_instr;
+ IRConst* guest_IP_bbstart_IRConst =3D NULL;
+ IRConst* guest_IP_bbstart_noredir_IRConst =3D NULL;
=20
Bool (*resteerOKfn)(Addr64) =3D NULL;
=20
@@ -131,7 +140,23 @@
delta =3D 0;
n_instrs =3D 0;
=20
- /* If asked to make a self-checking translation, leave a 5 spaces
+ /* Guest addresses as IRConsts. Used in the two self-checks
+ generated. */
+ if (do_self_check) {
+ guest_IP_bbstart_IRConst
+ =3D guest_word_type=3D=3DIty_I32=20
+ ? IRConst_U32(toUInt(guest_IP_bbstart))
+ : IRConst_U64(guest_IP_bbstart);
+ }
+
+ if (do_set_NRADDR) {
+ guest_IP_bbstart_noredir_IRConst
+ =3D guest_word_type=3D=3DIty_I32=20
+ ? IRConst_U32(toUInt(guest_IP_bbstart_noredir))
+ : IRConst_U64(guest_IP_bbstart_noredir);
+ }
+
+ /* If asked to make a self-checking translation, leave 5 spaces
in which to put the check statements. We'll fill them in later
when we know the length and adler32 of the area to check. */
if (do_self_check) {
@@ -143,6 +168,18 @@
addStmtToIRBB( irbb, IRStmt_NoOp() );
}
=20
+ /* Set guest_NRADDR if asked to. This records the unredirected
+ guest address of this bb, so that it can later be read (and so
+ used by a function wrapper to get to the function itself. */
+ if (do_set_NRADDR) {
+ /* set guest_NRADDR to guest_IP_bbstart_noredir */
+ addStmtToIRBB(=20
+ irbb,
+ IRStmt_Put( offB_NRADDR,=20
+ IRExpr_Const(guest_IP_bbstart_noredir_IRConst))
+ );
+ }
+
/* Process instructions. */
while (True) {
vassert(n_instrs < vex_control.guest_max_insns);
@@ -197,7 +234,7 @@
vassert(dres.whatNext =3D=3D Dis_StopHere
|| dres.whatNext =3D=3D Dis_Continue
|| dres.whatNext =3D=3D Dis_Resteer);
- vassert(dres.len >=3D 0 && dres.len <=3D 18);
+ vassert(dres.len >=3D 0 && dres.len <=3D 20);
if (dres.whatNext !=3D Dis_Resteer)
vassert(dres.continueAt =3D=3D 0);
=20
@@ -298,7 +335,6 @@
if (do_self_check) {
=20
UInt len2check, adler32;
- IRConst* guest_IP_bbstart_IRConst;
IRTemp tistart_tmp, tilen_tmp;
=20
vassert(vge->n_used =3D=3D 1);
@@ -308,11 +344,6 @@
=20
adler32 =3D genericg_compute_adler32( (HWord)guest_code, len2check =
);
=20
- guest_IP_bbstart_IRConst
- =3D guest_word_type=3D=3DIty_I32=20
- ? IRConst_U32(toUInt(guest_IP_bbstart))
- : IRConst_U64(guest_IP_bbstart);
-
/* Set TISTART and TILEN. These will describe to the despatcher
the area of guest code to invalidate should we exit with a
self-check failure. */
Modified: trunk/priv/guest-generic/bb_to_IR.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/priv/guest-generic/bb_to_IR.h 2006-01-10 20:39:03 UTC (rev 1535=
)
+++ trunk/priv/guest-generic/bb_to_IR.h 2006-01-12 12:27:58 UTC (rev 1536=
)
@@ -154,13 +154,16 @@
/*IN*/ DisOneInstrFn dis_instr_fn,
/*IN*/ UChar* guest_code,
/*IN*/ Addr64 guest_IP_bbstart,
+ /*IN*/ Addr64 guest_IP_bbstart_noredir,
/*IN*/ Bool (*chase_into_ok)(Addr64),
/*IN*/ Bool host_bigendian,
/*IN*/ VexArchInfo* archinfo_guest,
/*IN*/ IRType guest_word_type,
/*IN*/ Bool do_self_check,
+ /*IN*/ Bool do_set_NRADDR,
/*IN*/ Int offB_TISTART,
- /*IN*/ Int offB_TILEN );
+ /*IN*/ Int offB_TILEN,
+ /*IN*/ Int offB_NRADDR );
=20
=20
#endif /* ndef GENERIC_BB_TO_IR_H */
Modified: trunk/priv/guest-ppc/ghelpers.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/priv/guest-ppc/ghelpers.c 2006-01-10 20:39:03 UTC (rev 1535)
+++ trunk/priv/guest-ppc/ghelpers.c 2006-01-12 12:27:58 UTC (rev 1536)
@@ -458,10 +458,12 @@
=20
vex_state->guest_EMWARN =3D EmWarn_NONE;
=20
+ vex_state->guest_RESVN =3D 0;
+
vex_state->guest_TISTART =3D 0;
vex_state->guest_TILEN =3D 0;
=20
- vex_state->guest_RESVN =3D 0;
+ vex_state->guest_NRADDR =3D 0;
}
=20
=20
@@ -606,10 +608,12 @@
=20
vex_state->guest_EMWARN =3D EmWarn_NONE;
=20
+ vex_state->guest_RESVN =3D 0;
+
vex_state->guest_TISTART =3D 0;
vex_state->guest_TILEN =3D 0;
=20
- vex_state->guest_RESVN =3D 0;
+ vex_state->guest_NRADDR =3D 0;
}
=20
=20
Modified: trunk/priv/guest-ppc/toIR.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/priv/guest-ppc/toIR.c 2006-01-10 20:39:03 UTC (rev 1535)
+++ trunk/priv/guest-ppc/toIR.c 2006-01-12 12:27:58 UTC (rev 1536)
@@ -83,7 +83,28 @@
results would then be zeroed, too.
*/
=20
+/* "Special" instructions.
=20
+ This instruction decoder can decode three special instructions
+ which mean nothing natively (are no-ops as far as regs/mem are
+ concerned) but have meaning for supporting Valgrind. A special
+ instruction is flagged by the 16-byte preamble 54001800 54006800
+ 5400E800 54009800 (in the standard interpretation, that means:
+ rlwinm 0,0,3,0,0; rlwinm 0,0,13,0,0; rlwinm 0,0,29,0,0; rlwinm
+ 0,0,19,0,0). Following that, one of the following 3 are allowed
+ (standard interpretation in parentheses):
+
+ 7C210B78 (or 1,1,1) %R3 =3D client_request ( %R4 )
+ 7C421378 (or 2,2,2) %R3 =3D guest_NRADDR
+ 7C631B78 (or 3,3,3) branch-and-link-to-noredir %R11
+
+ Any other bytes following the 16-byte preamble are illegal and
+ constitute a failure in instruction decoding. This all assumes
+ that the preamble will never occur except in specific code
+ fragments designed for Valgrind to catch.
+*/
+
+
/* Translates PPC32/64 code to IR. */
=20
/* References
@@ -200,9 +221,9 @@
#define OFFB_TISTART offsetofPPCGuestState(guest_TISTART)
#define OFFB_TILEN offsetofPPCGuestState(guest_TILEN)
#define OFFB_RESVN offsetofPPCGuestState(guest_RESVN)
+#define OFFB_NRADDR offsetofPPCGuestState(guest_NRADDR)
=20
=20
-
/*------------------------------------------------------------*/
/*--- Extract instruction fields --- */
/*------------------------------------------------------------*/
@@ -8358,8 +8379,7 @@
if (put_IP)
putGST( PPC_GST_CIA, mkSzImm(ty, guest_CIA_curr_instr) );
=20
- /* Spot the client-request magic sequence. */
- // Essentially a v. unlikely sequence of noops that we can catch
+ /* Spot "Special" instructions (see comment at top of file). */
if (mode64) {
/* Spot the magic sequence, 64-bit mode */
UChar* code =3D (UChar*)(&guest_code[delta]);
@@ -8388,31 +8408,54 @@
goto decode_success;
}
} else {
- /* Spot the magic sequence, 32-bit mode */
- UChar* code =3D (UChar*)(&guest_code[delta]);
-
- /* Spot this: =20
- 0x7C03D808 tw 0,3,27 =3D> trap word if (0) =3D> no=
p
- 0x5400E800 rlwinm 0,0,29,0,0 =3D> r0 =3D rotl(r0,29)
- 0x54001800 rlwinm 0,0, 3,0,0 =3D> r0 =3D rotl(r0, 3)
- 0x54006800 rlwinm 0,0,13,0,0 =3D> r0 =3D rotl(r0,13)
- 0x54009800 rlwinm 0,0,19,0,0 =3D> r0 =3D rotl(r0,19)
- 0x60000000 nop
+ UChar* code =3D (UChar*)(guest_code + delta);
+ /* Spot the 16-byte preamble:
+ 54001800 rlwinm 0,0,3,0,0
+ 54006800 rlwinm 0,0,13,0,0
+ 5400E800 rlwinm 0,0,29,0,0
+ 54009800 rlwinm 0,0,19,0,0
*/
- if (getUIntBigendianly(code+ 0) =3D=3D 0x7C03D808 &&
- getUIntBigendianly(code+ 4) =3D=3D 0x5400E800 &&
- getUIntBigendianly(code+ 8) =3D=3D 0x54001800 &&
- getUIntBigendianly(code+12) =3D=3D 0x54006800 &&
- getUIntBigendianly(code+16) =3D=3D 0x54009800 &&
- getUIntBigendianly(code+20) =3D=3D 0x60000000) {
- DIP("%%r3 =3D client_request ( %%r31 )\n");
- dres.len =3D 24;
- delta +=3D 24;
-
- irbb->next =3D mkSzImm( ty, guest_CIA_bbstart + delta );
- irbb->jumpkind =3D Ijk_ClientReq;
- dres.whatNext =3D Dis_StopHere;
- goto decode_success;
+ if (getUIntBigendianly(code+ 0) =3D=3D 0x54001800 &&
+ getUIntBigendianly(code+ 4) =3D=3D 0x54006800 &&
+ getUIntBigendianly(code+ 8) =3D=3D 0x5400E800 &&
+ getUIntBigendianly(code+12) =3D=3D 0x54009800) {
+ /* Got a "Special" instruction preamble. Which one is it? */
+ if (getUIntBigendianly(code+16) =3D=3D 0x7C210B78 /* or 1,1,1 *=
/) {
+ /* %R3 =3D client_request ( %R4 ) */
+ DIP("r3 =3D client_request ( %%r4 )\n");
+ delta +=3D 20;
+ irbb->next =3D mkSzImm( ty, guest_CIA_bbstart + delta );
+ irbb->jumpkind =3D Ijk_ClientReq;
+ dres.whatNext =3D Dis_StopHere;
+ goto decode_success;
+ }
+ else
+ if (getUIntBigendianly(code+16) =3D=3D 0x7C421378 /* or 2,2,2 *=
/) {
+ /* %R3 =3D guest_NRADDR */
+ DIP("r3 =3D guest_NRADDR\n");
+ delta +=3D 20;
+ dres.len =3D 20;
+ putIReg(3, IRExpr_Get( OFFB_NRADDR, ty ));
+ goto decode_success;
+ }
+ else
+ if (getUIntBigendianly(code+16) =3D=3D 0x7C631B78 /* or 3,3,3 *=
/) {
+ /* branch-and-link-to-noredir %R11 */
+ DIP("branch-and-link-to-noredir r11\n");
+ delta +=3D 20;
+ putGST( PPC_GST_LR, mkSzImm(ty, guest_CIA_bbstart + delta) )=
;
+ irbb->next =3D getIReg(11);
+ irbb->jumpkind =3D Ijk_NoRedir;
+ dres.whatNext =3D Dis_StopHere;
+ goto decode_success;
+ }
+ /* We don't know what it is. Set opc1/opc2 so decode_failure
+ can print the insn following the Special-insn preamble. */
+ theInstr =3D getUIntBigendianly(code+16);
+ opc1 =3D ifieldOPC(theInstr);
+ opc2 =3D ifieldOPClo10(theInstr);
+ goto decode_failure;
+ /*NOTREACHED*/
}
}
=20
@@ -9007,7 +9050,11 @@
/* All decode successes end up here. */
DIP("\n");
=20
- dres.len =3D 4;
+ if (dres.len =3D=3D 0) {
+ dres.len =3D 4;
+ } else {
+ vassert(dres.len =3D=3D 20);
+ }
return dres;
}
=20
Modified: trunk/priv/guest-x86/ghelpers.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/priv/guest-x86/ghelpers.c 2006-01-10 20:39:03 UTC (rev 1535)
+++ trunk/priv/guest-x86/ghelpers.c 2006-01-12 12:27:58 UTC (rev 1536)
@@ -2225,6 +2225,8 @@
/* SSE2 has a 'clflush' cache-line-invalidator which uses these. */
vex_state->guest_TISTART =3D 0;
vex_state->guest_TILEN =3D 0;
+
+ vex_state->guest_NRADDR =3D 0;
}
=20
=20
Modified: trunk/priv/guest-x86/toIR.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/priv/guest-x86/toIR.c 2006-01-10 20:39:03 UTC (rev 1535)
+++ trunk/priv/guest-x86/toIR.c 2006-01-12 12:27:58 UTC (rev 1536)
@@ -122,6 +122,30 @@
way through bbs as usual.
*/
=20
+/* "Special" instructions.
+
+ This instruction decoder can decode three special instructions
+ which mean nothing natively (are no-ops as far as regs/mem are
+ concerned) but have meaning for supporting Valgrind. A special
+ instruction is flagged by the 12-byte preamble C1C703 C1C70D C1C71D
+ C1C713 (in the standard interpretation, that means: roll $3, %edi;
+ roll $13, %edi; roll $29, %edi; roll $19, %edi). Following that,
+ one of the following 3 are allowed (standard interpretation in
+ parentheses):
+
+ 87DB (xchgl %ebx,%ebx) %EDX =3D client_request ( %EAX )
+ 87C9 (xchgl %ecx,%ecx) %EAX =3D guest_NRADDR
+ 87D2 (xchgl %edx,%edx) call-noredir *%EAX
+
+ Any other bytes following the 12-byte preamble are illegal and
+ constitute a failure in instruction decoding. This all assumes
+ that the preamble will never occur except in specific code
+ fragments designed for Valgrind to catch.
+
+ No prefixes may precede a "Special" instruction.
+*/
+
+
/* Translates x86 code to IR. */
=20
#include "libvex_basictypes.h"
@@ -227,7 +251,9 @@
=20
#define OFFB_TISTART offsetof(VexGuestX86State,guest_TISTART)
#define OFFB_TILEN offsetof(VexGuestX86State,guest_TILEN)
+#define OFFB_NRADDR offsetof(VexGuestX86State,guest_NRADDR)
=20
+
/*------------------------------------------------------------*/
/*--- Helper bits and pieces for deconstructing the ---*/
/*--- x86 insn stream. ---*/
@@ -7012,32 +7038,58 @@
if (put_IP)
stmt( IRStmt_Put( OFFB_EIP, mkU32(guest_EIP_curr_instr)) );
=20
- /* Spot the client-request magic sequence. */
+ /* Spot "Special" instructions (see comment at top of file). */
{
UChar* code =3D (UChar*)(guest_code + delta);
- /* Spot this:
- C1C01D roll $29, %eax
- C1C003 roll $3, %eax
- C1C81B rorl $27, %eax
- C1C805 rorl $5, %eax
- C1C00D roll $13, %eax
- C1C013 roll $19, %eax =20
+ /* Spot the 12-byte preamble:
+ C1C703 roll $3, %edi
+ C1C70D roll $13, %edi
+ C1C71D roll $29, %edi
+ C1C713 roll $19, %edi
*/
- if (code[ 0] =3D=3D 0xC1 && code[ 1] =3D=3D 0xC0 && code[ 2] =3D=3D=
0x1D &&
- code[ 3] =3D=3D 0xC1 && code[ 4] =3D=3D 0xC0 && code[ 5] =3D=3D=
0x03 &&
- code[ 6] =3D=3D 0xC1 && code[ 7] =3D=3D 0xC8 && code[ 8] =3D=3D=
0x1B &&
- code[ 9] =3D=3D 0xC1 && code[10] =3D=3D 0xC8 && code[11] =3D=3D=
0x05 &&
- code[12] =3D=3D 0xC1 && code[13] =3D=3D 0xC0 && code[14] =3D=3D=
0x0D &&
- code[15] =3D=3D 0xC1 && code[16] =3D=3D 0xC0 && code[17] =3D=3D=
0x13
- ) {
- DIP("%%edx =3D client_request ( %%eax )\n"); =20
- delta +=3D 18;
- jmp_lit(Ijk_ClientReq, guest_EIP_bbstart+delta);
- dres.whatNext =3D Dis_StopHere;
- goto decode_success;
+ if (code[ 0] =3D=3D 0xC1 && code[ 1] =3D=3D 0xC7 && code[ 2] =3D=3D=
0x03 &&
+ code[ 3] =3D=3D 0xC1 && code[ 4] =3D=3D 0xC7 && code[ 5] =3D=3D=
0x0D &&
+ code[ 6] =3D=3D 0xC1 && code[ 7] =3D=3D 0xC7 && code[ 8] =3D=3D=
0x1D &&
+ code[ 9] =3D=3D 0xC1 && code[10] =3D=3D 0xC7 && code[11] =3D=3D=
0x13) {
+ /* Got a "Special" instruction preamble. Which one is it? */
+ if (code[12] =3D=3D 0x87 && code[13] =3D=3D 0xDB /* xchgl %ebx,=
%ebx */) {
+ /* %EDX =3D client_request ( %EAX ) */
+ DIP("%%edx =3D client_request ( %%eax )\n");
+ delta +=3D 14;
+ jmp_lit(Ijk_ClientReq, guest_EIP_bbstart+delta);
+ dres.whatNext =3D Dis_StopHere;
+ goto decode_success;
+ }
+ else
+ if (code[12] =3D=3D 0x87 && code[13] =3D=3D 0xC9 /* xchgl %ecx,=
%ecx */) {
+ /* %EAX =3D guest_NRADDR */
+ DIP("%%eax =3D guest_NRADDR\n");
+ delta +=3D 14;
+ putIReg(4, R_EAX, IRExpr_Get( OFFB_NRADDR, Ity_I32 ));
+ goto decode_success;
+ }
+ else
+ if (code[12] =3D=3D 0x87 && code[13] =3D=3D 0xD2 /* xchgl %edx,=
%edx */) {
+ /* call-noredir *%EAX */
+ DIP("call-noredir *%%eax\n");
+ delta +=3D 14;
+ t1 =3D newTemp(Ity_I32);
+ assign(t1, getIReg(4,R_EAX));
+ t2 =3D newTemp(Ity_I32);
+ assign(t2, binop(Iop_Sub32, getIReg(4,R_ESP), mkU32(4)));
+ putIReg(4, R_ESP, mkexpr(t2));
+ storeLE( mkexpr(t2), mkU32(guest_EIP_bbstart+delta));
+ jmp_treg(Ijk_NoRedir,t1);
+ dres.whatNext =3D Dis_StopHere;
+ goto decode_success;
+ }
+ /* We don't know what it is. */
+ goto decode_failure;
+ /*NOTREACHED*/
}
}
=20
+ /* Deal with prefixes. */
/* Skip a LOCK prefix. */
/* 2005 Jan 06: the following insns are observed to sometimes
have a LOCK prefix:
Modified: trunk/priv/host-amd64/hdefs.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/priv/host-amd64/hdefs.c 2006-01-10 20:39:03 UTC (rev 1535)
+++ trunk/priv/host-amd64/hdefs.c 2006-01-12 12:27:58 UTC (rev 1536)
@@ -2620,6 +2620,9 @@
case Ijk_TInval:
*p++ =3D 0xBD;
p =3D emit32(p, VEX_TRC_JMP_TINVAL); break;
+ case Ijk_NoRedir:
+ *p++ =3D 0xBD;
+ p =3D emit32(p, VEX_TRC_JMP_NOREDIR); break;
case Ijk_Ret:
case Ijk_Call:
case Ijk_Boring:
Modified: trunk/priv/host-ppc/hdefs.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/priv/host-ppc/hdefs.c 2006-01-10 20:39:03 UTC (rev 1535)
+++ trunk/priv/host-ppc/hdefs.c 2006-01-12 12:27:58 UTC (rev 1536)
@@ -2942,6 +2942,7 @@
case Ijk_MapFail: trc =3D VEX_TRC_JMP_MAPFAIL; break;
case Ijk_NoDecode: trc =3D VEX_TRC_JMP_NODECODE; break;
case Ijk_TInval: trc =3D VEX_TRC_JMP_TINVAL; break;
+ case Ijk_NoRedir: trc =3D VEX_TRC_JMP_NOREDIR; break;
case Ijk_Ret:
case Ijk_Call:
case Ijk_Boring:
Modified: trunk/priv/host-x86/hdefs.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/priv/host-x86/hdefs.c 2006-01-10 20:39:03 UTC (rev 1535)
+++ trunk/priv/host-x86/hdefs.c 2006-01-12 12:27:58 UTC (rev 1536)
@@ -2179,6 +2179,9 @@
case Ijk_TInval:
*p++ =3D 0xBD;
p =3D emit32(p, VEX_TRC_JMP_TINVAL); break;
+ case Ijk_NoRedir:
+ *p++ =3D 0xBD;
+ p =3D emit32(p, VEX_TRC_JMP_NOREDIR); break;
case Ijk_Sys_sysenter:
*p++ =3D 0xBD;
p =3D emit32(p, VEX_TRC_JMP_SYS_SYSENTER); break;
Modified: trunk/priv/ir/irdefs.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/priv/ir/irdefs.c 2006-01-10 20:39:03 UTC (rev 1535)
+++ trunk/priv/ir/irdefs.c 2006-01-12 12:27:58 UTC (rev 1536)
@@ -684,6 +684,7 @@
case Ijk_NoDecode: vex_printf("NoDecode"); break;
case Ijk_MapFail: vex_printf("MapFail"); break;
case Ijk_TInval: vex_printf("Invalidate"); break;
+ case Ijk_NoRedir: vex_printf("NoRedir"); break;
case Ijk_Sys_syscall: vex_printf("Sys_syscall"); break;
case Ijk_Sys_int32: vex_printf("Sys_int32"); break;
case Ijk_Sys_int128: vex_printf("Sys_int128"); break;
Modified: trunk/priv/main/vex_main.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/priv/main/vex_main.c 2006-01-10 20:39:03 UTC (rev 1535)
+++ trunk/priv/main/vex_main.c 2006-01-12 12:27:58 UTC (rev 1536)
@@ -200,7 +200,7 @@
HInstrArray* vcode;
HInstrArray* rcode;
Int i, j, k, out_used, guest_sizeB;
- Int offB_TISTART, offB_TILEN;
+ Int offB_TISTART, offB_TILEN, offB_NRADDR;
UChar insn_bytes[32];
IRType guest_word_type;
IRType host_word_type;
@@ -226,6 +226,7 @@
offB_TISTART =3D 0;
offB_TILEN =3D 0;
mode64 =3D False;
+ offB_NRADDR =3D 0;
=20
vex_traceflags =3D vta->traceflags;
=20
@@ -335,12 +336,14 @@
guest_layout =3D &x86guest_layout;
offB_TISTART =3D offsetof(VexGuestX86State,guest_TISTART);
offB_TILEN =3D offsetof(VexGuestX86State,guest_TILEN);
+ offB_NRADDR =3D offsetof(VexGuestX86State,guest_NRADDR);
vassert(vta->archinfo_guest.subarch =3D=3D VexSubArchX86_sse0
|| vta->archinfo_guest.subarch =3D=3D VexSubArchX86_sse=
1
|| vta->archinfo_guest.subarch =3D=3D VexSubArchX86_sse=
2);
vassert(0 =3D=3D sizeof(VexGuestX86State) % 8);
- vassert(sizeof( ((VexGuestX86State*)0)->guest_TISTART ) =3D=3D =
4);
- vassert(sizeof( ((VexGuestX86State*)0)->guest_TILEN ) =3D=3D 4)=
;
+ vassert(sizeof( ((VexGuestX86State*)0)->guest_TISTART) =3D=3D 4=
);
+ vassert(sizeof( ((VexGuestX86State*)0)->guest_TILEN ) =3D=3D 4=
);
+ vassert(sizeof( ((VexGuestX86State*)0)->guest_NRADDR ) =3D=3D 4=
);
break;
=20
case VexArchAMD64:
@@ -352,10 +355,12 @@
guest_layout =3D &amd64guest_layout;
offB_TISTART =3D offsetof(VexGuestAMD64State,guest_TISTART)=
;
offB_TILEN =3D offsetof(VexGuestAMD64State,guest_TILEN);
+ offB_NRADDR =3D offsetof(VexGuestAMD64State,guest_NRADDR);
vassert(vta->archinfo_guest.subarch =3D=3D VexSubArch_NONE);
vassert(0 =3D=3D sizeof(VexGuestAMD64State) % 8);
vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TISTART ) =3D=3D=
8);
- vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TILEN ) =3D=3D =
8);
+ vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TILEN ) =3D=3D=
8);
+ vassert(sizeof( ((VexGuestAMD64State*)0)->guest_NRADDR ) =3D=3D=
8);
break;
=20
case VexArchARM:
@@ -367,6 +372,7 @@
guest_layout =3D &armGuest_layout;
offB_TISTART =3D 0; /* hack ... arm has bitrot */
offB_TILEN =3D 0; /* hack ... arm has bitrot */
+ offB_NRADDR =3D 0; /* hack ... arm has bitrot */
vassert(vta->archinfo_guest.subarch =3D=3D VexSubArchARM_v4);
break;
=20
@@ -379,12 +385,14 @@
guest_layout =3D &ppc32Guest_layout;
offB_TISTART =3D offsetof(VexGuestPPC32State,guest_TISTART)=
;
offB_TILEN =3D offsetof(VexGuestPPC32State,guest_TILEN);
+ offB_NRADDR =3D offsetof(VexGuestPPC32State,guest_NRADDR);
vassert(vta->archinfo_guest.subarch =3D=3D VexSubArchPPC32_I
|| vta->archinfo_guest.subarch =3D=3D VexSubArchPPC32_F=
I
|| vta->archinfo_guest.subarch =3D=3D VexSubArchPPC32_V=
FI);
vassert(0 =3D=3D sizeof(VexGuestPPC32State) % 8);
vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TISTART ) =3D=3D=
4);
- vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TILEN ) =3D=3D =
4);
+ vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TILEN ) =3D=3D=
4);
+ vassert(sizeof( ((VexGuestPPC32State*)0)->guest_NRADDR ) =3D=3D=
4);
break;
=20
case VexArchPPC64:
@@ -426,13 +434,16 @@
disInstrFn,
vta->guest_bytes,=20
vta->guest_bytes_addr,
+ vta->guest_bytes_addr_noredir,
vta->chase_into_ok,
host_is_bigendian,
&vta->archinfo_guest,
guest_word_type,
vta->do_self_check,
+ vta->do_set_NRADDR,
offB_TISTART,
- offB_TILEN );
+ offB_TILEN,
+ offB_NRADDR );
=20
vexAllocSanityCheck();
=20
Modified: trunk/pub/libvex.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/pub/libvex.h 2006-01-10 20:39:03 UTC (rev 1535)
+++ trunk/pub/libvex.h 2006-01-12 12:27:58 UTC (rev 1536)
@@ -345,6 +345,9 @@
=20
/* IN: should this translation be self-checking? default: False *=
/
Bool do_self_check;
+ /* IN: should this translation set guest_NRADDR? */
+ Bool do_set_NRADDR;
+
/* IN: debug: trace vex activity at various points */
Int traceflags;
=20
@@ -383,7 +386,6 @@
extern=20
VexTranslateResult LibVEX_Translate ( VexTranslateArgs* );
=20
-
/* A subtlety re interaction between self-checking translations and
bb-chasing. The supplied chase_into_ok function should say NO
(False) when presented with any address for which you might want to
@@ -456,11 +458,19 @@
=20
ALL GUEST ARCHITECTURES
~~~~~~~~~~~~~~~~~~~~~~~
- The architecture must contain two pseudo-registers, guest_TISTART
+ The guest state must contain two pseudo-registers, guest_TISTART
and guest_TILEN. These are used to pass the address of areas of
guest code, translations of which are to be invalidated, back to
the despatcher. Both pseudo-regs must have size equal to the guest
word size.
+
+ The architecture must a third pseudo-register, guest_NRADDR, also
+ guest-word-sized. This is used to record the unredirected guest
+ address at the start of a translation whose start has been
+ redirected. By reading this pseudo-register shortly afterwards,
+ the translation can find out what the corresponding no-redirection
+ address was. Note, this is only set for wrap-style redirects, not
+ for replace-style ones.
*/
#endif /* ndef __LIBVEX_H */
=20
Modified: trunk/pub/libvex_guest_amd64.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/pub/libvex_guest_amd64.h 2006-01-10 20:39:03 UTC (rev 1535)
+++ trunk/pub/libvex_guest_amd64.h 2006-01-12 12:27:58 UTC (rev 1536)
@@ -145,6 +145,14 @@
ULong guest_TISTART;
ULong guest_TILEN;
=20
+ /* Used to record the unredirected guest address at the start of
+ a translation whose start has been redirected. By reading
+ this pseudo-register shortly afterwards, the translation can
+ find out what the corresponding no-redirection address was.
+ Note, this is only set for wrap-style redirects, not for
+ replace-style ones. */
+ ULong guest_NRADDR;
+
/* Padding to make it have an 8-aligned size */
/* UInt padding; */
}
Modified: trunk/pub/libvex_guest_ppc32.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/pub/libvex_guest_ppc32.h 2006-01-10 20:39:03 UTC (rev 1535)
+++ trunk/pub/libvex_guest_ppc32.h 2006-01-12 12:27:58 UTC (rev 1536)
@@ -199,14 +199,22 @@
/* Emulation warnings */
/* 940 */ UInt guest_EMWARN;
=20
- /* For icbi: record start and length of area to invalidate */
- /* 944 */ UInt guest_TISTART;
- /* 948 */ UInt guest_TILEN;
-
/* For lwarx/stwcx.: 0 =3D=3D no reservation exists, non-0 =3D=3D =
a
reservation exists. */
- /* 952 */ UInt guest_RESVN;
+ /* 944 */ UInt guest_RESVN;
=20
+ /* For icbi: record start and length of area to invalidate */
+ /* 948 */ UInt guest_TISTART;
+ /* 952 */ UInt guest_TILEN;
+
+ /* Used to record the unredirected guest address at the start of
+ a translation whose start has been redirected. By reading
+ this pseudo-register shortly afterwards, the translation can
+ find out what the corresponding no-redirection address was.
+ Note, this is only set for wrap-style redirects, not for
+ replace-style ones. */
+ /* 956 */ UInt guest_NRADDR;
+
/* Padding to make it have an 8-aligned size */
/* 956 */ UInt padding;
/* 960 */
Modified: trunk/pub/libvex_guest_ppc64.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/pub/libvex_guest_ppc64.h 2006-01-10 20:39:03 UTC (rev 1535)
+++ trunk/pub/libvex_guest_ppc64.h 2006-01-12 12:27:58 UTC (rev 1536)
@@ -248,9 +248,16 @@
reservation exists. */
/* 1104 */ ULong guest_RESVN;
=20
- /* Padding to make it have an 16-aligned size */
- /* 1112 */ ULong padding2;
- /* 1120 */
+ /* Used to record the unredirected guest address at the start of
+ a translation whose start has been redirected. By reading
+ this pseudo-register shortly afterwards, the translation can
+ find out what the corresponding no-redirection address was.
+ Note, this is only set for wrap-style redirects, not for
+ replace-style ones. */
+ /* 1112 */ ULong guest_NRADDR;
+
+ /* Padding to make it have an 8-aligned size */
+ /* UInt padding; */
}
VexGuestPPC64State;
=20
Modified: trunk/pub/libvex_guest_x86.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/pub/libvex_guest_x86.h 2006-01-10 20:39:03 UTC (rev 1535)
+++ trunk/pub/libvex_guest_x86.h 2006-01-12 12:27:58 UTC (rev 1536)
@@ -208,18 +208,20 @@
/* Emulation warnings */
UInt guest_EMWARN;
=20
- /* Translation-invalidation area description. Not used on x86
- (there is no invalidate-icache insn), but needed so as to
- allow users of the library to uniformly assume that the guest
- state contains these two fields -- otherwise there is
- compilation breakage. On x86, these two fields are set to
- zero by LibVEX_GuestX86_initialise and then should be ignored
- forever thereafter. */
+ /* For clflush: record start and length of area to invalidate */
UInt guest_TISTART;
UInt guest_TILEN;
=20
+ /* Used to record the unredirected guest address at the start of
+ a translation whose start has been redirected. By reading
+ this pseudo-register shortly afterwards, the translation can
+ find out what the corresponding no-redirection address was.
+ Note, this is only set for wrap-style redirects, not for
+ replace-style ones. */
+ UInt guest_NRADDR;
+
/* Padding to make it have an 8-aligned size */
- /* UInt padding; */
+ UInt padding;
}
VexGuestX86State;
=20
Modified: trunk/pub/libvex_ir.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/pub/libvex_ir.h 2006-01-10 20:39:03 UTC (rev 1535)
+++ trunk/pub/libvex_ir.h 2006-01-12 12:27:58 UTC (rev 1536)
@@ -855,6 +855,7 @@
Ijk_NoDecode, /* next instruction cannot be decoded */
Ijk_MapFail, /* Vex-provided address translation failed */
Ijk_TInval, /* Invalidate translations before continuing. =
*/
+ Ijk_NoRedir, /* Jump to un-redirected guest addr */
/* Unfortunately, various guest-dependent syscall kinds. They
all mean: do a syscall before continuing. */
Ijk_Sys_syscall, /* amd64 'syscall', ppc 'sc' */
Modified: trunk/pub/libvex_trc_values.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/pub/libvex_trc_values.h 2006-01-10 20:39:03 UTC (rev 1535)
+++ trunk/pub/libvex_trc_values.h 2006-01-12 12:27:58 UTC (rev 1536)
@@ -58,6 +58,7 @@
=20
#define VEX_TRC_JMP_TINVAL 61 /* invalidate translations before
continuing */
+#define VEX_TRC_JMP_NOREDIR 81 /* jump to undirected guest addr */
#define VEX_TRC_JMP_EMWARN 63 /* deliver emulation warning before
continuing */
#define VEX_TRC_JMP_CLIENTREQ 65 /* do a client req before continuing =
*/
Modified: trunk/test_main.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/test_main.c 2006-01-10 20:39:03 UTC (rev 1535)
+++ trunk/test_main.c 2006-01-12 12:27:58 UTC (rev 1536)
@@ -174,6 +174,7 @@
vta.instrument2 =3D NULL;
#endif
vta.do_self_check =3D False;
+ vta.do_set_NRADDR =3D False;
vta.traceflags =3D TEST_FLAGS;
#if 1 /* x86, amd64 hosts */
vta.dispatch =3D (void*)0x12345678;
|