|
From: <sv...@va...> - 2006-01-10 20:39:11
|
Author: sewardj
Date: 2006-01-10 20:39:03 +0000 (Tue, 10 Jan 2006)
New Revision: 1535
Log:
Make function wrapping work on ppc32-linux.
Modified:
branches/FNWRAP/priv/guest-ppc32/toIR.c
branches/FNWRAP/priv/host-ppc32/hdefs.c
Modified: branches/FNWRAP/priv/guest-ppc32/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-ppc32/toIR.c 2006-01-10 08:01:07 UTC (rev =
1534)
+++ branches/FNWRAP/priv/guest-ppc32/toIR.c 2006-01-10 20:39:03 UTC (rev =
1535)
@@ -77,7 +77,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 & PPC64 code to IR. */
=20
/* References
@@ -199,7 +220,9 @@
#define OFFB64_TILEN offsetof(VexGuestPPC64State,guest_TILEN)
=20
#define OFFB64_RESVN offsetof(VexGuestPPC64State,guest_RESVN)
+#define OFFB64_NRADDR offsetof(VexGuestPPC64State,guest_NRADDR)
=20
+
// 32-bit offsets
#define OFFB32_CIA offsetof(VexGuestPPC32State,guest_CIA)
#define OFFB32_LR offsetof(VexGuestPPC32State,guest_LR)
@@ -221,6 +244,7 @@
#define OFFB32_TILEN offsetof(VexGuestPPC32State,guest_TILEN)
=20
#define OFFB32_RESVN offsetof(VexGuestPPC32State,guest_RESVN)
+#define OFFB32_NRADDR offsetof(VexGuestPPC32State,guest_NRADDR)
=20
=20
/*------------------------------------------------------------*/
@@ -7867,33 +7891,56 @@
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). */
{
- 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( mode64 ? OFFB64_NRADDR : OFFB32_NRADD=
R, 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
@@ -8420,7 +8467,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: branches/FNWRAP/priv/host-ppc32/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
--- branches/FNWRAP/priv/host-ppc32/hdefs.c 2006-01-10 08:01:07 UTC (rev =
1534)
+++ branches/FNWRAP/priv/host-ppc32/hdefs.c 2006-01-10 20:39:03 UTC (rev =
1535)
@@ -2591,6 +2591,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:
|