diff --git a/addrcheck/ac_main.c b/addrcheck/ac_main.c index 7eb355db9..984cc15a0 100644 --- a/addrcheck/ac_main.c +++ b/addrcheck/ac_main.c @@ -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 diff --git a/cachegrind/cg_main.c b/cachegrind/cg_main.c index c28864794..7a93fc292 100644 --- a/cachegrind/cg_main.c +++ b/cachegrind/cg_main.c @@ -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 diff --git a/coregrind/vg_from_ucode.c b/coregrind/vg_from_ucode.c index d08c5051a..769785dc3 100644 --- a/coregrind/vg_from_ucode.c +++ b/coregrind/vg_from_ucode.c @@ -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 diff --git a/coregrind/vg_to_ucode.c b/coregrind/vg_to_ucode.c index 491258800..99bf7b124 100644 --- a/coregrind/vg_to_ucode.c +++ b/coregrind/vg_to_ucode.c @@ -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++; } diff --git a/coregrind/vg_translate.c b/coregrind/vg_translate.c index 71fbb11da..0b6175ab2 100644 --- a/coregrind/vg_translate.c +++ b/coregrind/vg_translate.c @@ -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: diff --git a/helgrind/hg_main.c b/helgrind/hg_main.c index 85dcc80d7..b9b539b3d 100644 --- a/helgrind/hg_main.c +++ b/helgrind/hg_main.c @@ -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; diff --git a/include/vg_skin.h b/include/vg_skin.h index 540fe5f90..10f70e725 100644 --- a/include/vg_skin.h +++ b/include/vg_skin.h @@ -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 */ diff --git a/lackey/lk_main.c b/lackey/lk_main.c index 896dc188b..4b79d9a1e 100644 --- a/lackey/lk_main.c +++ b/lackey/lk_main.c @@ -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: diff --git a/memcheck/mc_translate.c b/memcheck/mc_translate.c index f81bde39d..657b99801 100644 --- a/memcheck/mc_translate.c +++ b/memcheck/mc_translate.c @@ -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;