]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
More ppc64-only function wrapping hacks:
authorJulian Seward <jseward@acm.org>
Fri, 20 Jan 2006 14:19:25 +0000 (14:19 +0000)
committerJulian Seward <jseward@acm.org>
Fri, 20 Jan 2006 14:19:25 +0000 (14:19 +0000)
- 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)

git-svn-id: svn://svn.valgrind.org/vex/trunk@1543

VEX/priv/guest-ppc/ghelpers.c
VEX/priv/guest-ppc/toIR.c
VEX/priv/host-ppc/isel.c
VEX/pub/libvex_guest_ppc64.h

index a070c91d36d7c51ab82462841e1698905ace862b..bb3349c32c29b15ddade0e8eabf0176560539771 100644 (file)
@@ -615,6 +615,7 @@ void LibVEX_GuestPPC64_initialise ( /*OUT*/VexGuestPPC64State* vex_state )
    vex_state->guest_TILEN   = 0;
 
    vex_state->guest_NRADDR = 0;
+   vex_state->guest_NRADDR_GPR2 = 0;
 
    vex_state->guest_REDIR_SP = -1;
    for (i = 0; i < VEX_GUEST_PPC64_REDIR_STACK_SIZE; i++)
@@ -671,10 +672,16 @@ Bool guest_ppc32_state_requires_precise_mem_exns ( Int minoff,
 Bool guest_ppc64_state_requires_precise_mem_exns ( Int minoff, 
                                                    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  = offsetof(VexGuestPPC64State, guest_LR);
    Int lr_max  = lr_min + 8 - 1;
    Int r1_min  = offsetof(VexGuestPPC64State, guest_GPR1);
    Int r1_max  = r1_min + 8 - 1;
+   Int r2_min  = offsetof(VexGuestPPC64State, guest_GPR2);
+   Int r2_max  = r2_min + 8 - 1;
    Int cia_min = offsetof(VexGuestPPC64State, guest_CIA);
    Int cia_max = cia_min + 8 - 1;
 
@@ -690,6 +697,12 @@ Bool guest_ppc64_state_requires_precise_mem_exns ( Int minoff,
       return True;
    }
 
+   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 @@ VexGuestLayout
 
           /* Describe any sections to be regarded by Memcheck as
              'always-defined'. */
-          .n_alwaysDefd = 10,
+          .n_alwaysDefd = 11,
 
           .alwaysDefd 
          = { /*  0 */ ALWAYSDEFD64(guest_CIA),
@@ -765,8 +778,9 @@ VexGuestLayout
              /*  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)
             }
         };
 
index 5ce26b72a1679596474facc6072a0e849dbad706..567215cc982a2aa35c2dd04be3711281eed89d58 100644 (file)
       7C210B78 (or 1,1,1)   %R3 = client_request ( %R4 )
       7C421378 (or 2,2,2)   %R3 = guest_NRADDR
       7C631B78 (or 3,3,3)   branch-and-link-to-noredir %R11
+      7C842378 (or 4,4,4)   %R3 = guest_NRADDR_GPR2 (64-bit mode only)
 
    Any other bytes following the 16-byte preamble are illegal and
    constitute a failure in instruction decoding.  This all assumes
@@ -235,6 +236,10 @@ static void* fnptr_to_fnentry( void* f )
 #define OFFB_RESVN      offsetofPPCGuestState(guest_RESVN)
 #define OFFB_NRADDR     offsetofPPCGuestState(guest_NRADDR)
 
+/* This only exists in the 64-bit guest state */
+#define OFFB64_NRADDR_GPR2 \
+                        offsetof(VexGuestPPC64State,guest_NRADDR_GPR2)
+
 
 /*------------------------------------------------------------*/
 /*--- Extract instruction fields                          --- */
@@ -2248,7 +2253,7 @@ static void putGST_masked ( PPC_GST reg, IRExpr* src, UInt mask )
          - Non-IEEE Mode
       */
       if (mask & 0xFC) {  // Exception Control, Non-IEE mode
-         VexEmWarn ew = EmWarn_PPC32exns;
+         VexEmWarn ew = EmWarn_PPCexns;
 
          /* If any of the src::exception_control bits are actually set,
             side-exit to the next insn, reporting the warning,
@@ -8465,6 +8470,17 @@ DisResult disInstr_PPC_WRK (
             dres.whatNext  = Dis_StopHere;
             goto decode_success;
          }
+         else
+         if (mode64 
+             && getUIntBigendianly(code+16) == 0x7C842378 /* or 4,4,4 */) {
+            /* %R3 = guest_NRADDR_GPR2 */
+            DIP("r3 = guest_NRADDR_GPR2\n");
+            delta += 20;
+            dres.len = 20;
+            vassert(ty == 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 = getUIntBigendianly(code+16);
index 66ab534f824f02cf364513f4168be36dcde4d28d..516f3c81364b8afde4b31bb4008a6897b80a2c56 100644 (file)
@@ -752,7 +752,7 @@ PPCAMode* genGuestArrayOffset ( ISelEnv* env, IRArray* descr,
    /* Throw out any cases we don't need.  In theory there might be a
       day where we need to handle others, but not today. */
 
-   if (nElems != 16)
+   if (nElems != 16 && nElems != 32)
       vpanic("genGuestArrayOffset(ppc64 host)(1)");
 
    switch (elemSz) {
@@ -768,7 +768,7 @@ PPCAMode* genGuestArrayOffset ( ISelEnv* env, IRArray* descr,
    /* Compute off into a reg, %off.  Then return:
 
          addi %tmp, %off, bias (if bias != 0)
-         andi %tmp, 15
+         andi %tmp, nElems-1
          sldi %tmp, shift
          addi %tmp, %tmp, base
          ... Baseblockptr + %tmp ...
index b03db616d39c253b8ddc546d11f059d6e085f225..e2d6b97c109c1a0f9de9be683f104dd4fb192a43 100644 (file)
@@ -93,7 +93,7 @@ vrsave    Non-volatile 32-bit register
 /*--- Vex's representation of the PPC64 CPU state             ---*/
 /*---------------------------------------------------------------*/
 
-#define VEX_GUEST_PPC64_REDIR_STACK_SIZE 16
+#define VEX_GUEST_PPC64_REDIR_STACK_SIZE (16/*entries*/ * 2/*words per entry*/)
 
 typedef
    struct {
@@ -257,13 +257,14 @@ typedef
          Note, this is only set for wrap-style redirects, not for
          replace-style ones. */
       /* 1112 */ ULong guest_NRADDR;
+      /* 1120 */ ULong guest_NRADDR_GPR2;
 
      /* 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_SIZE];
+      /* 1128 */ ULong guest_REDIR_SP;
+      /* 1136 */ ULong guest_REDIR_STACK[VEX_GUEST_PPC64_REDIR_STACK_SIZE];
 
       /* Padding to make it have an 8-aligned size */
       /* UInt  padding; */