|
From: <sv...@va...> - 2005-12-28 00:55:08
|
Author: sewardj
Date: 2005-12-28 00:54:57 +0000 (Wed, 28 Dec 2005)
New Revision: 1518
Log:
x86 front end only: generalise the client-request idea so as to create
a whole family of "Special" instructions, which are no-ops when run
natively, but mean something special to the JIT.
Modified:
branches/FNWRAP/priv/guest-x86/toIR.c
Modified: branches/FNWRAP/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
--- branches/FNWRAP/priv/guest-x86/toIR.c 2005-12-27 16:39:36 UTC (rev 15=
17)
+++ branches/FNWRAP/priv/guest-x86/toIR.c 2005-12-28 00:54:57 UTC (rev 15=
18)
@@ -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. ---*/
@@ -7005,68 +7031,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
- /* Spot the even-more-magical "call-noredir *%eax" sequence, and
- treat it as a normal "call *%eax", except that the jump itself
- is marked NoRedir. */
- {
- UChar* code =3D (UChar*)(guest_code + delta);
- /* Spot this:
- C1C81C rorl $28, %eax
- C1C804 rorl $4, %eax
- C1C01A roll $26, %eax
- C1C006 roll $6, %eax
- C1C80C rorl $12, %eax
- C1C814 rorl $20, %eax
- FFD0 call *%eax
- */
- if (code[ 0] =3D=3D 0xC1 && code[ 1] =3D=3D 0xC8 && code[ 2] =3D=3D=
0x1C &&
- code[ 3] =3D=3D 0xC1 && code[ 4] =3D=3D 0xC8 && code[ 5] =3D=3D=
0x04 &&
- code[ 6] =3D=3D 0xC1 && code[ 7] =3D=3D 0xC0 && code[ 8] =3D=3D=
0x1A &&
- code[ 9] =3D=3D 0xC1 && code[10] =3D=3D 0xC0 && code[11] =3D=3D=
0x06 &&
- code[12] =3D=3D 0xC1 && code[13] =3D=3D 0xC8 && code[14] =3D=3D=
0x0C &&
- code[15] =3D=3D 0xC1 && code[16] =3D=3D 0xC8 && code[17] =3D=3D=
0x14 &&
- code[18] =3D=3D 0xFF && code[19] =3D=3D 0xD0
- ) {
- DIP("call-noredir *%%eax\n");
- delta +=3D 20;
- 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;
- }
- }
-
+ /* Deal with prefixes. */
/* Skip a LOCK prefix. */
/* 2005 Jan 06: the following insns are observed to sometimes
have a LOCK prefix:
|