]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Merge patch from JeremyF:
authorJulian Seward <jseward@acm.org>
Wed, 13 Nov 2002 22:42:13 +0000 (22:42 +0000)
committerJulian Seward <jseward@acm.org>
Wed, 13 Nov 2002 22:42:13 +0000 (22:42 +0000)
39-lock-prefix

Add a new UInstr LOCK to represent a "lock" prefix in the instruction
stream. This has the same semantics as NOP, but allows a skin to tell
whether a group of UInstrs associated with an x86 instruction are
meant to be locked.

HELGRIND: uses the LOCK UInstr to automatically take and release a
special __BUS_HARDWARE_LOCK__ around locked instructions. This only
works properly if all instructions touching a given address are locked
(even reads).

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@1310

addrcheck/ac_main.c
cachegrind/cg_main.c
coregrind/vg_from_ucode.c
coregrind/vg_to_ucode.c
coregrind/vg_translate.c
helgrind/hg_main.c
include/vg_skin.h
lackey/lk_main.c
memcheck/mc_translate.c

index 7eb355db9c96fdca64ff5cd38d842c17b3359e0b..984cc15a01a4d144a3787b944c1dffe4ff122307 100644 (file)
@@ -1752,7 +1752,7 @@ UCodeBlock* SK_(instrument)(UCodeBlock* cb_in, Addr orig_addr)
       u_in = &cb_in->instrs[i];
 
       switch (u_in->opcode) {
-         case NOP:  case CALLM_E:  case CALLM_S:
+         case NOP:  case LOCK:  case CALLM_E:  case CALLM_S:
             break;
 
          /* For memory-ref instrs, copy the data_addr into a temporary to be
index c288647942cbd8ac01f585c5b233faa80e50eb77..7a93fc29294a3b3363b01efec981500a9fb205db 100644 (file)
@@ -731,7 +731,7 @@ UCodeBlock* SK_(instrument)(UCodeBlock* cb_in, Addr orig_addr)
       if (instrumented_Jcond) sk_assert(u_in->opcode == JMP);
 
       switch (u_in->opcode) {
-         case NOP:  case CALLM_E:  case CALLM_S:
+         case NOP:  case LOCK:  case CALLM_E:  case CALLM_S:
             break;
 
          /* For memory-ref instrs, copy the data_addr into a temporary to be
index d08c5051a6ccc9f0a85e3e61c70b2d93b129e9cc..769785dc350527391de4fee7dbbf8eb57669d336 100644 (file)
@@ -1981,7 +1981,7 @@ static void emitUInstr ( UCodeBlock* cb, Int i, RRegSet regs_live_before )
    old_emitted_code_used = emitted_code_used;
    
    switch (u->opcode) {
-      case NOP: case CALLM_S: case CALLM_E: break;
+      case NOP: case LOCK: case CALLM_S: case CALLM_E: break;
 
       case INCEIP: {
         /* Note: Redundant INCEIP merging.  A potentially useful
index 4912588001a3fcf33764e7bece9a8ac7e22cf194..99bf7b124b2b8a4a035f1c5faaadac6ca52dfaea 100644 (file)
@@ -3254,6 +3254,7 @@ static Addr disInstr ( UCodeBlock* cb, Addr eip, Bool* isEnd )
    /* Skip a LOCK prefix. */
    if (getUChar(eip) == 0xF0) { 
       /* VG_(printf)("LOCK LOCK LOCK LOCK LOCK \n"); */
+      uInstr0(cb, LOCK, 0);
       eip++;
    }
 
index 71fbb11daf12bf25be8e582e7f3b322a49760980..0b6175ab216b505497ffba499d94dca227147b78 100644 (file)
@@ -476,6 +476,7 @@ Bool VG_(saneUInstr) ( Bool beforeRA, Bool beforeLiveness, UInstr* u )
    case GETSEG: return LIT0 && SZ2  && CC0 &&  Se1 && TR2 &&  N3 && XOTHER;
    case USESEG: return LIT0 && SZ0  && CC0 &&  TR1 && TR2 &&  N3 && XOTHER;
    case NOP:    return LIT0 && SZ0  && CC0 &&   N1 &&  N2 &&  N3 && XOTHER;
+   case LOCK:   return LIT0 && SZ0  && CC0 &&   N1 &&  N2 &&  N3 && XOTHER;
    case GETF:   return LIT0 && SZ42 && CCr &&  TR1 &&  N2 &&  N3 && XOTHER;
    case PUTF:   return LIT0 && SZ42 && CCw &&  TR1 &&  N2 &&  N3 && XOTHER;
    case GET:    return LIT0 && SZi  && CC0 &&  AS1 && TR2 &&  N3 && XOTHER;
@@ -799,6 +800,7 @@ Char* VG_(name_UOpcode) ( Bool upper, Opcode opc )
       case LEA1:    return "LEA1";
       case LEA2:    return "LEA2";
       case NOP:     return "NOP";
+      case LOCK:    return "LOCK";
       case GET:     return "GET";
       case PUT:     return "PUT";
       case GETF:    return "GETF";
@@ -919,7 +921,7 @@ void pp_UInstrWorker ( Int instrNo, UInstr* u, Bool ppRegsLiveness )
          VG_(pp_UOperand)(u, 2, 4, False);
          break;
 
-      case NOP:
+      case NOP: case LOCK:
          break;
 
       case FPU_W:
@@ -1092,7 +1094,7 @@ Int VG_(get_reg_usage) ( UInstr* u, Tag tag, RegUse* arr )
       case LEA2: RD(1); RD(2); WR(3); break;
 
       case NOP:   case FPU:   case INCEIP: case CALLM_S: case CALLM_E:
-      case CLEAR: case CALLM: break;
+      case CLEAR: case CALLM: case LOCK: break;
 
       case CCALL:
          if (u->argc > 0)    RD(1); 
@@ -1225,6 +1227,7 @@ Int maybe_uinstrReadsArchReg ( UInstr* u )
       case LEA1:
       case LEA2:
       case NOP:
+      case LOCK:
       case PUT:
       case LOAD:
       case STORE:
index 85dcc80d70b9a2c57e5f132426a3a93608b79ec6..b9b539b3d21174657d67370a1a864a5865c14c57 100644 (file)
@@ -1732,6 +1732,9 @@ static void eraser_mem_help_write_2(Addr a, UInt val) REGPARM(2);
 static void eraser_mem_help_write_4(Addr a, UInt val) REGPARM(2);
 static void eraser_mem_help_write_N(Addr a, UInt size) REGPARM(2);
 
+static void bus_lock(void);
+static void bus_unlock(void);
+
 static
 void eraser_pre_mem_read(CorePart part, ThreadState* tst,
                          Char* s, UInt base, UInt size )
@@ -1863,6 +1866,7 @@ UCodeBlock* SK_(instrument) ( UCodeBlock* cb_in, Addr not_used )
    Int         t_size = INVALID_TEMPREG;
    Int        ntemps;
    Bool               *stackref = NULL;
+   Bool        locked = False; /* lock prefix */
 
    cb = VG_(alloc_UCodeBlock)();
    cb->nextTemp = cb_in->nextTemp;
@@ -1883,6 +1887,21 @@ UCodeBlock* SK_(instrument) ( UCodeBlock* cb_in, Addr not_used )
          case NOP: case CALLM_S: case CALLM_E:
             break;
     
+         case LOCK:
+           locked = True;
+           uInstr0(cb, CCALL, 0);
+           uCCall(cb, (Addr)bus_lock, 0, 0, False);
+           break;
+
+         case JMP: case INCEIP:
+           if (locked) {
+              uInstr0(cb, CCALL, 0);
+              uCCall(cb, (Addr)bus_unlock, 0, 0, False);
+           }
+           locked = False;
+           VG_(copy_UInstr)(cb, u_in);
+           break;
+
          case GET:
            sk_assert(u_in->tag1 == ArchReg);
            sk_assert(u_in->tag2 == TempReg);
@@ -2935,6 +2954,21 @@ static void hg_thread_join(ThreadId joiner, ThreadId joinee)
    clearTLS(joinee);
 }
 
+static Int __BUS_HARDWARE_LOCK__;
+
+static void bus_lock(void)
+{
+   ThreadId tid = VG_(get_current_tid)();
+   eraser_pre_mutex_lock(tid, &__BUS_HARDWARE_LOCK__);
+   eraser_post_mutex_lock(tid, &__BUS_HARDWARE_LOCK__);
+}
+
+static void bus_unlock(void)
+{
+   ThreadId tid = VG_(get_current_tid)();
+   eraser_post_mutex_unlock(tid, &__BUS_HARDWARE_LOCK__);
+}
+
 /*--------------------------------------------------------------------*/
 /*--- Client requests                                              ---*/
 /*--------------------------------------------------------------------*/
@@ -3030,6 +3064,9 @@ void SK_(pre_clo_init)(VgDetails* details, VgNeeds* needs, VgTrackEvents* track)
    VG_(register_compact_helper)((Addr) & eraser_mem_help_write_4);
    VG_(register_noncompact_helper)((Addr) & eraser_mem_help_write_N);
 
+   VG_(register_noncompact_helper)((Addr) & bus_lock);
+   VG_(register_noncompact_helper)((Addr) & bus_unlock);
+
    for(i = 0; i < LOCKSET_HASH_SZ; i++)
       lockset_hash[i] = NULL;
 
index 540fe5f90abfed598aea735a692d64a4e0837832..10f70e7253d5c634647eb6f5068f8b6e0e89c727 100644 (file)
@@ -492,6 +492,8 @@ typedef
    enum {
       NOP,         /* Null op */
 
+      LOCK,       /* Indicate the existance of a LOCK prefix (functionally NOP) */
+
       /* Moving values around */
       GET,  PUT,   /* simulated register <--> TempReg */
       GETF, PUTF,  /* simulated %eflags  <--> TempReg */
index 896dc188b8239a899408db86b0bd1e064ba927a1..4b79d9a1e6d992b9055ae43182788cc9c74a42cf 100644 (file)
@@ -162,7 +162,7 @@ UCodeBlock* SK_(instrument)(UCodeBlock* cb_in, Addr orig_addr)
       u = &cb_in->instrs[i];
 
       switch (u->opcode) {
-         case NOP: case CALLM_S: case CALLM_E:
+         case NOP: case LOCK: case CALLM_S: case CALLM_E:
             break;
    
          case INCEIP:
index f81bde39d1178223f4c8a450b28965682cf2982f..657b99801cfd072466cd651ebc8af1696a6a6e10 100644 (file)
@@ -541,6 +541,7 @@ static UCodeBlock* memcheck_instrument ( UCodeBlock* cb_in )
 
       switch (u_in->opcode) {
 
+         case LOCK:
          case NOP:
             break;
 
@@ -1260,6 +1261,7 @@ static void vg_propagate_definedness ( UCodeBlock* cb )
 
          /* Deal with these quickly. */
          case NOP:
+         case LOCK:
          case INCEIP:
             break;