|
From: <sv...@va...> - 2006-01-20 14:19:36
|
Author: sewardj
Date: 2006-01-20 14:19:25 +0000 (Fri, 20 Jan 2006)
New Revision: 1543
Log:
More ppc64-only function wrapping hacks:=20
- increase size of redirect stack from 8 to 16 elems
- augment the _NRADDR pseudo-register with _NRADDR_GPR2,
which is the value of R2 at the most recent divert point.
This is needed in the ELF ppc64 ABI in order to safely run
the function being wrapped.
- add pseudo-instruction to read get _NRADDR_GPR2 into _GPR3.
- related change: always keep R2 up to date wrt possible memory
exceptions (no specific reason, just being conservative)
Modified:
trunk/priv/guest-ppc/ghelpers.c
trunk/priv/guest-ppc/toIR.c
trunk/priv/host-ppc/isel.c
trunk/pub/libvex_guest_ppc64.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-20 14:13:55 UTC (rev 1542)
+++ trunk/priv/guest-ppc/ghelpers.c 2006-01-20 14:19:25 UTC (rev 1543)
@@ -615,6 +615,7 @@
vex_state->guest_TILEN =3D 0;
=20
vex_state->guest_NRADDR =3D 0;
+ vex_state->guest_NRADDR_GPR2 =3D 0;
=20
vex_state->guest_REDIR_SP =3D -1;
for (i =3D 0; i < VEX_GUEST_PPC64_REDIR_STACK_SIZE; i++)
@@ -671,10 +672,16 @@
Bool guest_ppc64_state_requires_precise_mem_exns ( Int minoff,=20
Int maxoff )
{
+ /* Given that R2 is a Big Deal in the ELF ppc64 ABI, it seems
+ prudent to be conservative with it, even though thus far there
+ is no evidence to suggest that it actually needs to be kept up
+ to date wrt possible exceptions. */
Int lr_min =3D offsetof(VexGuestPPC64State, guest_LR);
Int lr_max =3D lr_min + 8 - 1;
Int r1_min =3D offsetof(VexGuestPPC64State, guest_GPR1);
Int r1_max =3D r1_min + 8 - 1;
+ Int r2_min =3D offsetof(VexGuestPPC64State, guest_GPR2);
+ Int r2_max =3D r2_min + 8 - 1;
Int cia_min =3D offsetof(VexGuestPPC64State, guest_CIA);
Int cia_max =3D cia_min + 8 - 1;
=20
@@ -690,6 +697,12 @@
return True;
}
=20
+ if (maxoff < r2_min || minoff > r2_max) {
+ /* no overlap with R2 */
+ } else {
+ return True;
+ }
+
if (maxoff < cia_min || minoff > cia_max) {
/* no overlap with CIA */
} else {
@@ -754,7 +767,7 @@
=20
/* Describe any sections to be regarded by Memcheck as
'always-defined'. */
- .n_alwaysDefd =3D 10,
+ .n_alwaysDefd =3D 11,
=20
.alwaysDefd=20
=3D { /* 0 */ ALWAYSDEFD64(guest_CIA),
@@ -765,8 +778,9 @@
/* 5 */ ALWAYSDEFD64(guest_FPROUND),
/* 6 */ ALWAYSDEFD64(guest_RESVN),
/* 7 */ ALWAYSDEFD64(guest_NRADDR),
- /* 8 */ ALWAYSDEFD64(guest_REDIR_SP),
- /* 9 */ ALWAYSDEFD64(guest_REDIR_STACK)
+ /* 8 */ ALWAYSDEFD64(guest_NRADDR_GPR2),
+ /* 9 */ ALWAYSDEFD64(guest_REDIR_SP),
+ /* 10 */ ALWAYSDEFD64(guest_REDIR_STACK)
}
};
=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-20 14:13:55 UTC (rev 1542)
+++ trunk/priv/guest-ppc/toIR.c 2006-01-20 14:19:25 UTC (rev 1543)
@@ -109,6 +109,7 @@
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
+ 7C842378 (or 4,4,4) %R3 =3D guest_NRADDR_GPR2 (64-bit mode only)
=20
Any other bytes following the 16-byte preamble are illegal and
constitute a failure in instruction decoding. This all assumes
@@ -235,7 +236,11 @@
#define OFFB_RESVN offsetofPPCGuestState(guest_RESVN)
#define OFFB_NRADDR offsetofPPCGuestState(guest_NRADDR)
=20
+/* This only exists in the 64-bit guest state */
+#define OFFB64_NRADDR_GPR2 \
+ offsetof(VexGuestPPC64State,guest_NRADDR_GPR2)
=20
+
/*------------------------------------------------------------*/
/*--- Extract instruction fields --- */
/*------------------------------------------------------------*/
@@ -2248,7 +2253,7 @@
- Non-IEEE Mode
*/
if (mask & 0xFC) { // Exception Control, Non-IEE mode
- VexEmWarn ew =3D EmWarn_PPC32exns;
+ VexEmWarn ew =3D EmWarn_PPCexns;
=20
/* If any of the src::exception_control bits are actually set,
side-exit to the next insn, reporting the warning,
@@ -8465,6 +8470,17 @@
dres.whatNext =3D Dis_StopHere;
goto decode_success;
}
+ else
+ if (mode64=20
+ && getUIntBigendianly(code+16) =3D=3D 0x7C842378 /* or 4,4,=
4 */) {
+ /* %R3 =3D guest_NRADDR_GPR2 */
+ DIP("r3 =3D guest_NRADDR_GPR2\n");
+ delta +=3D 20;
+ dres.len =3D 20;
+ vassert(ty =3D=3D Ity_I64);
+ putIReg(3, IRExpr_Get( OFFB64_NRADDR_GPR2, ty ));
+ 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);
Modified: trunk/priv/host-ppc/isel.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/isel.c 2006-01-20 14:13:55 UTC (rev 1542)
+++ trunk/priv/host-ppc/isel.c 2006-01-20 14:19:25 UTC (rev 1543)
@@ -752,7 +752,7 @@
/* Throw out any cases we don't need. In theory there might be a
day where we need to handle others, but not today. */
=20
- if (nElems !=3D 16)
+ if (nElems !=3D 16 && nElems !=3D 32)
vpanic("genGuestArrayOffset(ppc64 host)(1)");
=20
switch (elemSz) {
@@ -768,7 +768,7 @@
/* Compute off into a reg, %off. Then return:
=20
addi %tmp, %off, bias (if bias !=3D 0)
- andi %tmp, 15
+ andi %tmp, nElems-1
sldi %tmp, shift
addi %tmp, %tmp, base
... Baseblockptr + %tmp ...
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-20 14:13:55 UTC (rev 1542)
+++ trunk/pub/libvex_guest_ppc64.h 2006-01-20 14:19:25 UTC (rev 1543)
@@ -93,7 +93,7 @@
/*--- Vex's representation of the PPC64 CPU state ---*/
/*---------------------------------------------------------------*/
=20
-#define VEX_GUEST_PPC64_REDIR_STACK_SIZE 16
+#define VEX_GUEST_PPC64_REDIR_STACK_SIZE (16/*entries*/ * 2/*words per e=
ntry*/)
=20
typedef
struct {
@@ -257,13 +257,14 @@
Note, this is only set for wrap-style redirects, not for
replace-style ones. */
/* 1112 */ ULong guest_NRADDR;
+ /* 1120 */ ULong guest_NRADDR_GPR2;
=20
/* A grows-upwards stack for hidden saves/restores of LR and R2
needed for function interception and wrapping on ppc64-linux.
A horrible hack. REDIR_SP points to the highest live entry,
and so starts at -1. */
- /* 1120 */ ULong guest_REDIR_SP;
- /* 1128 */ ULong guest_REDIR_STACK[VEX_GUEST_PPC64_REDIR_STACK_SIZ=
E];
+ /* 1128 */ ULong guest_REDIR_SP;
+ /* 1136 */ ULong guest_REDIR_STACK[VEX_GUEST_PPC64_REDIR_STACK_SIZ=
E];
=20
/* Padding to make it have an 8-aligned size */
/* UInt padding; */
|