]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
arm(32)-linux: add support for the TPIDRURW system register. Fixes #386425.
authorJulian Seward <jseward@acm.org>
Mon, 20 Nov 2017 10:43:55 +0000 (11:43 +0100)
committerJulian Seward <jseward@acm.org>
Mon, 20 Nov 2017 10:43:55 +0000 (11:43 +0100)
VEX/priv/guest_arm_helpers.c
VEX/priv/guest_arm_toIR.c
VEX/pub/libvex_guest_arm.h
memcheck/mc_machine.c

index 0ef26b6452721202b109b88c576fc7dc31a7bed3..8a028736eeffa88ff9bbeb01da9a25013ec821aa 100644 (file)
@@ -1334,11 +1334,10 @@ void LibVEX_GuestARM_initialise ( /*OUT*/VexGuestARMState* vex_state )
    vex_state->guest_FPSCR = 0;
 
    vex_state->guest_TPIDRURO = 0;
+   vex_state->guest_TPIDRURW = 0;
 
    /* Not in a Thumb IT block. */
    vex_state->guest_ITSTATE = 0;
-
-   vex_state->padding1 = 0;
 }
 
 
index b26393ac8e27d620296fb0aabd52196bce66835d..26c5174647aa5c09e2ae08167aaaf9774470e611 100644 (file)
@@ -486,6 +486,7 @@ static IRExpr* align4if ( IRExpr* e, Bool b )
 
 #define OFFB_FPSCR    offsetof(VexGuestARMState,guest_FPSCR)
 #define OFFB_TPIDRURO offsetof(VexGuestARMState,guest_TPIDRURO)
+#define OFFB_TPIDRURW offsetof(VexGuestARMState,guest_TPIDRURW)
 #define OFFB_ITSTATE  offsetof(VexGuestARMState,guest_ITSTATE)
 #define OFFB_QFLAG32  offsetof(VexGuestARMState,guest_QFLAG32)
 #define OFFB_GEFLAG0  offsetof(VexGuestARMState,guest_GEFLAG0)
@@ -935,6 +936,7 @@ static void putMiscReg32 ( UInt    gsoffset,
       case OFFB_GEFLAG1: break;
       case OFFB_GEFLAG2: break;
       case OFFB_GEFLAG3: break;
+      case OFFB_TPIDRURW: break;
       default: vassert(0); /* awaiting more cases */
    }
    vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I32);
@@ -18702,6 +18704,35 @@ DisResult disInstr_ARM_WRK (
       /* fall through */
    }
 
+   /* ------------ read/write CP15 TPIDRURW register ----------- */
+   /* mcr     p15, 0, r0,  c13, c0, 2 (r->cr xfer)  up to
+      mcr     p15, 0, r14, c13, c0, 2
+
+      mrc     p15, 0, r0,  c13, c0, 2 (rc->r xfer)  up to
+      mrc     p15, 0, r14, c13, c0, 2
+   */
+   if (0x0E0D0F50 == (insn & 0x0FFF0FFF)) { // MCR
+      UInt rS = INSN(15,12);
+      if (rS <= 14) {
+         /* skip r15, that's too stupid to handle */
+         putMiscReg32(OFFB_TPIDRURW, getIRegA(rS), condT);
+         DIP("mcr%s p15,0, r%u, c13, c0, 2\n", nCC(INSN_COND), rS);
+         goto decode_success;
+      }
+      /* fall through */
+   }
+   if (0x0E1D0F50 == (insn & 0x0FFF0FFF)) { // MRC
+      UInt rD = INSN(15,12);
+      if (rD <= 14) {
+         /* skip r15, that's too stupid to handle */
+         putIRegA(rD, IRExpr_Get(OFFB_TPIDRURW, Ity_I32),
+                      condT, Ijk_Boring);
+         DIP("mrc%s p15,0, r%u, c13, c0, 2\n", nCC(INSN_COND), rD);
+         goto decode_success;
+      }
+      /* fall through */
+   }
+
    /* -------------- read CP15 PMUSRENR register ------------- */
    /* mrc     p15, 0, r0,  c9, c14, 0  up to
       mrc     p15, 0, r14, c9, c14, 0
@@ -23121,6 +23152,32 @@ DisResult disInstr_THUMB_WRK (
       /* fall through */
    }
 
+   /* ------------ read/write CP15 TPIDRURW register ----------- */
+   /* mcr     p15, 0, r0,  c13, c0, 2 (r->cr xfer)  up to
+      mcr     p15, 0, r14, c13, c0, 2
+
+      mrc     p15, 0, r0,  c13, c0, 2 (rc->r xfer)  up to
+      mrc     p15, 0, r14, c13, c0, 2
+   */
+   if ((INSN0(15,0) == 0xEE0D) && (INSN1(11,0) == 0x0F50)) {
+      UInt rS = INSN1(15,12);
+      if (!isBadRegT(rS)) {
+         putMiscReg32(OFFB_TPIDRURW, getIRegT(rS), condT);
+         DIP("mcr p15,0, r%u, c13, c0, 2\n", rS);
+         goto decode_success;
+      }
+      /* fall through */
+   }
+   if ((INSN0(15,0) == 0xEE1D) && (INSN1(11,0) == 0x0F50)) {
+      UInt rD = INSN1(15,12);
+      if (!isBadRegT(rD)) {
+         putIRegT(rD, IRExpr_Get(OFFB_TPIDRURW, Ity_I32), condT);
+         DIP("mrc p15,0, r%u, c13, c0, 2\n", rD);
+         goto decode_success;
+      }
+      /* fall through */
+   }
+
    /* -------------- read CP15 PMUSRENR register ------------- */
    /* mrc     p15, 0, r0,  c9, c14, 0  up to
       mrc     p15, 0, r14, c9, c14, 0
index 029441f463d99ad29d864b21103305a43c701c82..5dbe59c41a9c4e0af9e3b22fce3e9c5c7ed149e8 100644 (file)
@@ -158,6 +158,11 @@ typedef
          thread-related syscalls. */
       UInt guest_TPIDRURO;
 
+      /* TPIDRURW is also apparently used as a thread register, but one
+         controlled entirely by, and writable from, user space.  We model
+         it as a completely vanilla piece of integer state. */
+      UInt guest_TPIDRURW;
+
       /* Representation of the Thumb IT state.  ITSTATE is a 32-bit
          value with 4 8-bit lanes.  [7:0] pertain to the next insn to
          execute, [15:8] for the one after that, etc.  The per-insn
@@ -192,9 +197,6 @@ typedef
          to the top 24 bits of ITSTATE being zero.
       */
       UInt guest_ITSTATE;
-
-      /* Padding to make it have an 16-aligned size */
-      UInt padding1;
    }
    VexGuestARMState;
 
index 2f2afada448a1f751e266c3757b9eb012b35a068..d05125a9a8ee459ba87c18ff35427e743d2b1223 100644 (file)
@@ -873,6 +873,7 @@ static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB )
 
    if (o == GOF(FPSCR)    && sz == 4) return -1;
    if (o == GOF(TPIDRURO) && sz == 4) return -1;
+   if (o == GOF(TPIDRURW) && sz == 4) return -1;
    if (o == GOF(ITSTATE)  && sz == 4) return -1;
 
    /* Accesses to F or D registers */