1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This file is part of drd, a thread error detector. 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Copyright (C) 2006-2013 Bart Van Assche <bvanassche@acm.org>. 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is free software; you can redistribute it and/or 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modify it under the terms of the GNU General Public License as 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown published by the Free Software Foundation; either version 2 of the 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown License, or (at your option) any later version. 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is distributed in the hope that it will be useful, but 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WITHOUT ANY WARRANTY; without even the implied warranty of 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown General Public License for more details. 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown You should have received a copy of the GNU General Public License 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown along with this program; if not, write to the Free Software 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 02111-1307, USA. 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The GNU General Public License is contained in the file COPYING. 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_bitmap.h" 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_thread_bitmap.h" 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_vc.h" /* DRD_(vc_snprint)() */ 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Include several source files here in order to allow the compiler to */ 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* do more inlining. */ 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_bitmap.c" 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_load_store.h" 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_segment.c" 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_thread.c" 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_vc.c" 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex_guest_offsets.h" 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* STACK_POINTER_OFFSET: VEX register offset for the stack pointer register. */ 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGA_x86) 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define STACK_POINTER_OFFSET OFFSET_x86_ESP 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGA_amd64) 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define STACK_POINTER_OFFSET OFFSET_amd64_RSP 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGA_ppc32) 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define STACK_POINTER_OFFSET OFFSET_ppc32_GPR1 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGA_ppc64) 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define STACK_POINTER_OFFSET OFFSET_ppc64_GPR1 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGA_arm) 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define STACK_POINTER_OFFSET OFFSET_arm_R13 50436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined(VGA_arm64) 51436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define STACK_POINTER_OFFSET OFFSET_arm64_XSP 52b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGA_s390x) 53b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define STACK_POINTER_OFFSET OFFSET_s390x_r15 54663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#elif defined(VGA_mips32) 55663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define STACK_POINTER_OFFSET OFFSET_mips32_r29 56436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined(VGA_mips64) 57436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define STACK_POINTER_OFFSET OFFSET_mips64_r29 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#error Unknown architecture. 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Local variables. */ 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool s_check_stack_accesses = False; 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool s_first_race_only = False; 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Function definitions. */ 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool DRD_(get_check_stack_accesses)() 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return s_check_stack_accesses; 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid DRD_(set_check_stack_accesses)(const Bool c) 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(c == False || c == True); 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s_check_stack_accesses = c; 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool DRD_(get_first_race_only)() 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return s_first_race_only; 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid DRD_(set_first_race_only)(const Bool fro) 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(fro == False || fro == True); 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s_first_race_only = fro; 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid DRD_(trace_mem_access)(const Addr addr, const SizeT size, 94663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng const BmAccessTypeT access_type, 95663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng const HWord stored_value_hi, 96663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng const HWord stored_value_lo) 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DRD_(is_any_traced)(addr, addr + size)) 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 100436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HChar* vc; 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vc = DRD_(vc_aprint)(DRD_(thread_get_vc)(DRD_(thread_get_running_tid)())); 103663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (access_type == eStore && size <= sizeof(HWord)) { 104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DRD_(trace_msg_w_bt)("store 0x%lx size %ld val %ld/0x%lx (thread %d /" 105663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng " vc %s)", addr, size, stored_value_lo, 106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng stored_value_lo, DRD_(thread_get_running_tid)(), 107663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vc); 108663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else if (access_type == eStore && size > sizeof(HWord)) { 109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong sv; 110663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 111663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tl_assert(sizeof(HWord) == 4); 112663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng sv = ((ULong)stored_value_hi << 32) | stored_value_lo; 113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DRD_(trace_msg_w_bt)("store 0x%lx size %ld val %lld/0x%llx (thread %d" 114663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng " / vc %s)", addr, size, sv, sv, 115663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DRD_(thread_get_running_tid)(), vc); 116663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 117663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DRD_(trace_msg_w_bt)("%s 0x%lx size %ld (thread %d / vc %s)", 118663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng access_type == eLoad ? "load " 119663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : access_type == eStore ? "store" 120663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : access_type == eStart ? "start" 121663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : access_type == eEnd ? "end " : "????", 122663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addr, size, DRD_(thread_get_running_tid)(), vc); 123663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(free)(vc); 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(DRD_(DrdThreadIdToVgThreadId)(DRD_(thread_get_running_tid)()) 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown == VG_(get_running_tid)()); 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic VG_REGPARM(2) void drd_trace_mem_load(const Addr addr, const SizeT size) 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 132663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return DRD_(trace_mem_access)(addr, size, eLoad, 0, 0); 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 135663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic VG_REGPARM(3) void drd_trace_mem_store(const Addr addr,const SizeT size, 136663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng const HWord stored_value_hi, 137663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng const HWord stored_value_lo) 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 139663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return DRD_(trace_mem_access)(addr, size, eStore, stored_value_hi, 140663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng stored_value_lo); 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void drd_report_race(const Addr addr, const SizeT size, 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const BmAccessTypeT access_type) 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 146663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ThreadId vg_tid; 147663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 148663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vg_tid = VG_(get_running_tid)(); 149663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (!DRD_(get_check_stack_accesses)() 150663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && DRD_(thread_address_on_any_stack)(addr)) { 151663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if 0 152663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng GenericErrInfo GEI = { 153663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng .tid = DRD_(thread_get_running_tid)(), 154663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng .addr = addr, 155663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng }; 156663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(maybe_record_error)(vg_tid, GenericErr, VG_(get_IP)(vg_tid), 157663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "--check-stack-var=no skips checking stack" 158663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng " variables shared over threads", 159663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng &GEI); 160663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif 161663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 162663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DataRaceErrInfo drei = { 163663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng .tid = DRD_(thread_get_running_tid)(), 164663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng .addr = addr, 165663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng .size = size, 166663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng .access_type = access_type, 167663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng }; 168663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(maybe_record_error)(vg_tid, DataRaceErr, VG_(get_IP)(vg_tid), 169663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "Conflicting access", &drei); 170663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 171663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (s_first_race_only) 172663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DRD_(start_suppression)(addr, addr + size, "first race only"); 173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownVG_REGPARM(2) void DRD_(trace_load)(Addr addr, SizeT size) 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef ENABLE_DRD_CONSISTENCY_CHECKS 179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* The assert below has been commented out because of performance reasons.*/ 180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(DRD_(thread_get_running_tid)() 181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown == DRD_(VgThreadIdToDrdThreadId)(VG_(get_running_tid()))); 182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DRD_(running_thread_is_recording_loads)() 185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && (s_check_stack_accesses 186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || ! DRD_(thread_address_on_stack)(addr)) 187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && bm_access_load_triggers_conflict(addr, addr + size) 188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && ! DRD_(is_suppressed)(addr, addr + size)) 189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_report_race(addr, size, eLoad); 191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic VG_REGPARM(1) void drd_trace_load_1(Addr addr) 195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DRD_(running_thread_is_recording_loads)() 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && (s_check_stack_accesses 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || ! DRD_(thread_address_on_stack)(addr)) 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && bm_access_load_1_triggers_conflict(addr) 200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && ! DRD_(is_suppressed)(addr, addr + 1)) 201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_report_race(addr, 1, eLoad); 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic VG_REGPARM(1) void drd_trace_load_2(Addr addr) 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DRD_(running_thread_is_recording_loads)() 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && (s_check_stack_accesses 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || ! DRD_(thread_address_on_stack)(addr)) 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && bm_access_load_2_triggers_conflict(addr) 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && ! DRD_(is_suppressed)(addr, addr + 2)) 213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_report_race(addr, 2, eLoad); 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic VG_REGPARM(1) void drd_trace_load_4(Addr addr) 219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DRD_(running_thread_is_recording_loads)() 221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && (s_check_stack_accesses 222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || ! DRD_(thread_address_on_stack)(addr)) 223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && bm_access_load_4_triggers_conflict(addr) 224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && ! DRD_(is_suppressed)(addr, addr + 4)) 225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_report_race(addr, 4, eLoad); 227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic VG_REGPARM(1) void drd_trace_load_8(Addr addr) 231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DRD_(running_thread_is_recording_loads)() 233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && (s_check_stack_accesses 234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || ! DRD_(thread_address_on_stack)(addr)) 235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && bm_access_load_8_triggers_conflict(addr) 236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && ! DRD_(is_suppressed)(addr, addr + 8)) 237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_report_race(addr, 8, eLoad); 239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownVG_REGPARM(2) void DRD_(trace_store)(Addr addr, SizeT size) 243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef ENABLE_DRD_CONSISTENCY_CHECKS 245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* The assert below has been commented out because of performance reasons.*/ 246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(DRD_(thread_get_running_tid)() 247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown == DRD_(VgThreadIdToDrdThreadId)(VG_(get_running_tid()))); 248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DRD_(running_thread_is_recording_stores)() 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && (s_check_stack_accesses 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || ! DRD_(thread_address_on_stack)(addr)) 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && bm_access_store_triggers_conflict(addr, addr + size) 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && ! DRD_(is_suppressed)(addr, addr + size)) 255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_report_race(addr, size, eStore); 257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic VG_REGPARM(1) void drd_trace_store_1(Addr addr) 261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DRD_(running_thread_is_recording_stores)() 263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && (s_check_stack_accesses 264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || ! DRD_(thread_address_on_stack)(addr)) 265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && bm_access_store_1_triggers_conflict(addr) 266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && ! DRD_(is_suppressed)(addr, addr + 1)) 267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_report_race(addr, 1, eStore); 269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic VG_REGPARM(1) void drd_trace_store_2(Addr addr) 273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DRD_(running_thread_is_recording_stores)() 275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && (s_check_stack_accesses 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || ! DRD_(thread_address_on_stack)(addr)) 277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && bm_access_store_2_triggers_conflict(addr) 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && ! DRD_(is_suppressed)(addr, addr + 2)) 279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_report_race(addr, 2, eStore); 281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic VG_REGPARM(1) void drd_trace_store_4(Addr addr) 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DRD_(running_thread_is_recording_stores)() 287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && (s_check_stack_accesses 288663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || !DRD_(thread_address_on_stack)(addr)) 289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && bm_access_store_4_triggers_conflict(addr) 290663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && !DRD_(is_suppressed)(addr, addr + 4)) 291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_report_race(addr, 4, eStore); 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic VG_REGPARM(1) void drd_trace_store_8(Addr addr) 297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DRD_(running_thread_is_recording_stores)() 299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && (s_check_stack_accesses 300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || ! DRD_(thread_address_on_stack)(addr)) 301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && bm_access_store_8_triggers_conflict(addr) 302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && ! DRD_(is_suppressed)(addr, addr + 8)) 303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_report_race(addr, 8, eStore); 305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/** 309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Return true if and only if addr_expr matches the pattern (SP) or 310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * <offset>(SP). 311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool is_stack_access(IRSB* const bb, IRExpr* const addr_expr) 313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool result = False; 315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (addr_expr->tag == Iex_RdTmp) 317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int i; 319436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov for (i = 0; i < bb->stmts_used; i++) 320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (bb->stmts[i] 322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && bb->stmts[i]->tag == Ist_WrTmp 323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && bb->stmts[i]->Ist.WrTmp.tmp == addr_expr->Iex.RdTmp.tmp) 324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* e = bb->stmts[i]->Ist.WrTmp.data; 326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (e->tag == Iex_Get && e->Iex.Get.offset == STACK_POINTER_OFFSET) 327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown result = True; 329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //ppIRExpr(e); 332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //VG_(printf)(" (%s)\n", result ? "True" : "False"); 333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return result; 338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 340663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic const IROp u_widen_irop[5][9] = { 341663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng [Ity_I1 - Ity_I1] = { [4] = Iop_1Uto32, [8] = Iop_1Uto64 }, 342663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng [Ity_I8 - Ity_I1] = { [4] = Iop_8Uto32, [8] = Iop_8Uto64 }, 343663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng [Ity_I16 - Ity_I1] = { [4] = Iop_16Uto32, [8] = Iop_16Uto64 }, 344663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng [Ity_I32 - Ity_I1] = { [8] = Iop_32Uto64 }, 345663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}; 346663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 347663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/** 348663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * Instrument the client code to trace a memory load (--trace-addr). 349663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 350663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic IRExpr* instr_trace_mem_load(IRSB* const bb, IRExpr* addr_expr, 351436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HWord size, 352436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* const guard/* NULL => True */) 353663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 354663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRTemp tmp; 355663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 356663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tmp = newIRTemp(bb->tyenv, typeOfIRExpr(bb->tyenv, addr_expr)); 357663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addStmtToIRSB(bb, IRStmt_WrTmp(tmp, addr_expr)); 358663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addr_expr = IRExpr_RdTmp(tmp); 359436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRDirty* di 360436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov = unsafeIRDirty_0_N(/*regparms*/2, 361436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "drd_trace_mem_load", 362436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_(fnptr_to_fnentry) 363436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov (drd_trace_mem_load), 364436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mkIRExprVec_2(addr_expr, mkIRExpr_HWord(size))); 365436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (guard) di->guard = guard; 366436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addStmtToIRSB(bb, IRStmt_Dirty(di)); 367663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 368663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return addr_expr; 369663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 370663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 371663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/** 372663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * Instrument the client code to trace a memory store (--trace-addr). 373663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 374663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void instr_trace_mem_store(IRSB* const bb, IRExpr* const addr_expr, 375436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* data_expr_hi, IRExpr* data_expr_lo, 376436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* const guard/* NULL => True */) 377663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 378663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRType ty_data_expr; 379663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HWord size; 380663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 381663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tl_assert(sizeof(HWord) == 4 || sizeof(HWord) == 8); 382663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tl_assert(!data_expr_hi || typeOfIRExpr(bb->tyenv, data_expr_hi) == Ity_I32); 383663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 384663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ty_data_expr = typeOfIRExpr(bb->tyenv, data_expr_lo); 385663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size = sizeofIRType(ty_data_expr); 386663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 387663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if 0 388663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // Test code 389663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (ty_data_expr == Ity_I32) { 390663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRTemp tmp = newIRTemp(bb->tyenv, Ity_F32); 391663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng data_expr_lo = IRExpr_Unop(Iop_ReinterpI32asF32, data_expr_lo); 392663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addStmtToIRSB(bb, IRStmt_WrTmp(tmp, data_expr_lo)); 393663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng data_expr_lo = IRExpr_RdTmp(tmp); 394663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ty_data_expr = Ity_F32; 395663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else if (ty_data_expr == Ity_I64) { 396663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRTemp tmp = newIRTemp(bb->tyenv, Ity_F64); 397663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng data_expr_lo = IRExpr_Unop(Iop_ReinterpI64asF64, data_expr_lo); 398663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addStmtToIRSB(bb, IRStmt_WrTmp(tmp, data_expr_lo)); 399663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng data_expr_lo = IRExpr_RdTmp(tmp); 400663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ty_data_expr = Ity_F64; 401663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 402663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif 403663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 404663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (ty_data_expr == Ity_F32) { 405663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRTemp tmp = newIRTemp(bb->tyenv, Ity_I32); 406663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addStmtToIRSB(bb, IRStmt_WrTmp(tmp, IRExpr_Unop(Iop_ReinterpF32asI32, 407663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng data_expr_lo))); 408663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng data_expr_lo = IRExpr_RdTmp(tmp); 409663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ty_data_expr = Ity_I32; 410663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else if (ty_data_expr == Ity_F64) { 411663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRTemp tmp = newIRTemp(bb->tyenv, Ity_I64); 412663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addStmtToIRSB(bb, IRStmt_WrTmp(tmp, IRExpr_Unop(Iop_ReinterpF64asI64, 413663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng data_expr_lo))); 414663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng data_expr_lo = IRExpr_RdTmp(tmp); 415663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ty_data_expr = Ity_I64; 416663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 417663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 418663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (size == sizeof(HWord) 419663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && (ty_data_expr == Ity_I32 || ty_data_expr == Ity_I64)) 420663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng { 421663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* No conversion necessary */ 422663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 423663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IROp widen_op; 424663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 425663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (Ity_I1 <= ty_data_expr 426663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && ty_data_expr 427663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng < Ity_I1 + sizeof(u_widen_irop)/sizeof(u_widen_irop[0])) 428663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng { 429663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng widen_op = u_widen_irop[ty_data_expr - Ity_I1][sizeof(HWord)]; 430663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (!widen_op) 431663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng widen_op = Iop_INVALID; 432663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 433663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng widen_op = Iop_INVALID; 434663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 435663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (widen_op != Iop_INVALID) { 436663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRTemp tmp; 437663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 438663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Widen the integer expression to a HWord */ 439663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tmp = newIRTemp(bb->tyenv, sizeof(HWord) == 4 ? Ity_I32 : Ity_I64); 440663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addStmtToIRSB(bb, 441663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRStmt_WrTmp(tmp, IRExpr_Unop(widen_op, data_expr_lo))); 442663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng data_expr_lo = IRExpr_RdTmp(tmp); 443663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else if (size > sizeof(HWord) && !data_expr_hi 444663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && ty_data_expr == Ity_I64) { 445663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRTemp tmp; 446663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 447663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tl_assert(sizeof(HWord) == 4); 448663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tl_assert(size == 8); 449663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tmp = newIRTemp(bb->tyenv, Ity_I32); 450663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addStmtToIRSB(bb, 451663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRStmt_WrTmp(tmp, 452663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr_Unop(Iop_64HIto32, data_expr_lo))); 453663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng data_expr_hi = IRExpr_RdTmp(tmp); 454663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tmp = newIRTemp(bb->tyenv, Ity_I32); 455663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addStmtToIRSB(bb, IRStmt_WrTmp(tmp, 456663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr_Unop(Iop_64to32, data_expr_lo))); 457663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng data_expr_lo = IRExpr_RdTmp(tmp); 458663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 459663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng data_expr_lo = mkIRExpr_HWord(0); 460663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 461663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 462436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRDirty* di 463436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov = unsafeIRDirty_0_N(/*regparms*/3, 464436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "drd_trace_mem_store", 465436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_(fnptr_to_fnentry)(drd_trace_mem_store), 466436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mkIRExprVec_4(addr_expr, mkIRExpr_HWord(size), 467436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov data_expr_hi ? data_expr_hi 468436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov : mkIRExpr_HWord(0), data_expr_lo)); 469436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (guard) di->guard = guard; 470436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addStmtToIRSB(bb, IRStmt_Dirty(di) ); 471663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 472663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 473663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void instrument_load(IRSB* const bb, IRExpr* const addr_expr, 474436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HWord size, 475436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* const guard/* NULL => True */) 476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* size_expr; 478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr** argv; 479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRDirty* di; 480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 481663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (!s_check_stack_accesses && is_stack_access(bb, addr_expr)) 482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (size) 485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 1: 487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argv = mkIRExprVec_1(addr_expr); 488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown di = unsafeIRDirty_0_N(/*regparms*/1, 489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "drd_trace_load_1", 490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(fnptr_to_fnentry)(drd_trace_load_1), 491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argv); 492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 2: 494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argv = mkIRExprVec_1(addr_expr); 495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown di = unsafeIRDirty_0_N(/*regparms*/1, 496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "drd_trace_load_2", 497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(fnptr_to_fnentry)(drd_trace_load_2), 498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argv); 499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 4: 501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argv = mkIRExprVec_1(addr_expr); 502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown di = unsafeIRDirty_0_N(/*regparms*/1, 503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "drd_trace_load_4", 504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(fnptr_to_fnentry)(drd_trace_load_4), 505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argv); 506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 8: 508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argv = mkIRExprVec_1(addr_expr); 509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown di = unsafeIRDirty_0_N(/*regparms*/1, 510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "drd_trace_load_8", 511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(fnptr_to_fnentry)(drd_trace_load_8), 512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argv); 513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown size_expr = mkIRExpr_HWord(size); 516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argv = mkIRExprVec_2(addr_expr, size_expr); 517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown di = unsafeIRDirty_0_N(/*regparms*/2, 518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "drd_trace_load", 519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(fnptr_to_fnentry)(DRD_(trace_load)), 520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argv); 521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 523436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (guard) di->guard = guard; 524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, IRStmt_Dirty(di)); 525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 527663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void instrument_store(IRSB* const bb, IRExpr* addr_expr, 528436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* const data_expr, 529436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* const guard_expr/* NULL => True */) 530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* size_expr; 532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr** argv; 533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRDirty* di; 534663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HWord size; 535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 536663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size = sizeofIRType(typeOfIRExpr(bb->tyenv, data_expr)); 537663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 538663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (UNLIKELY(DRD_(any_address_is_traced)())) { 539663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRTemp tmp = newIRTemp(bb->tyenv, typeOfIRExpr(bb->tyenv, addr_expr)); 540663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addStmtToIRSB(bb, IRStmt_WrTmp(tmp, addr_expr)); 541663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addr_expr = IRExpr_RdTmp(tmp); 542436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov instr_trace_mem_store(bb, addr_expr, NULL, data_expr, guard_expr); 543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 545663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (!s_check_stack_accesses && is_stack_access(bb, addr_expr)) 546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (size) 549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 1: 551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argv = mkIRExprVec_1(addr_expr); 552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown di = unsafeIRDirty_0_N(/*regparms*/1, 553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "drd_trace_store_1", 554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(fnptr_to_fnentry)(drd_trace_store_1), 555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argv); 556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 2: 558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argv = mkIRExprVec_1(addr_expr); 559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown di = unsafeIRDirty_0_N(/*regparms*/1, 560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "drd_trace_store_2", 561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(fnptr_to_fnentry)(drd_trace_store_2), 562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argv); 563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 4: 565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argv = mkIRExprVec_1(addr_expr); 566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown di = unsafeIRDirty_0_N(/*regparms*/1, 567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "drd_trace_store_4", 568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(fnptr_to_fnentry)(drd_trace_store_4), 569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argv); 570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 8: 572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argv = mkIRExprVec_1(addr_expr); 573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown di = unsafeIRDirty_0_N(/*regparms*/1, 574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "drd_trace_store_8", 575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(fnptr_to_fnentry)(drd_trace_store_8), 576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argv); 577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown size_expr = mkIRExpr_HWord(size); 580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argv = mkIRExprVec_2(addr_expr, size_expr); 581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown di = unsafeIRDirty_0_N(/*regparms*/2, 582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "drd_trace_store", 583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(fnptr_to_fnentry)(DRD_(trace_store)), 584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argv); 585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 587436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (guard_expr) di->guard = guard_expr; 588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, IRStmt_Dirty(di)); 589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownIRSB* DRD_(instrument)(VgCallbackClosure* const closure, 592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRSB* const bb_in, 593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VexGuestLayout* const layout, 594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VexGuestExtents* const vge, 595436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VexArchInfo* archinfo_host, 596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRType const gWordTy, 597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRType const hWordTy) 598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRDirty* di; 600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRSB* bb; 602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr** argv; 603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool instrument = True; 604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Set up BB */ 606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb = emptyIRSB(); 607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb->tyenv = deepCopyIRTypeEnv(bb_in->tyenv); 608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb->next = deepCopyIRExpr(bb_in->next); 609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb->jumpkind = bb_in->jumpkind; 610663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng bb->offsIP = bb_in->offsIP; 611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < bb_in->stmts_used; i++) 613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmt* const st = bb_in->stmts[i]; 615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(st); 616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(isFlatIRStmt(st)); 617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (st->tag) 619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Note: the code for not instrumenting the code in .plt */ 621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* sections is only necessary on CentOS 3.0 x86 (kernel 2.4.21 */ 622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* + glibc 2.3.2 + NPTL 0.60 + binutils 2.14.90.0.4). */ 623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This is because on this platform dynamic library symbols are */ 624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* relocated in another way than by later binutils versions. The */ 625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* linker e.g. does not generate .got.plt sections on CentOS 3.0. */ 626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_IMark: 627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown instrument = VG_(DebugInfo_sect_kind)(NULL, 0, st->Ist.IMark.addr) 628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown != Vg_SectPLT; 629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, st); 630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_MBE: 633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (st->Ist.MBE.event) 634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Imbe_Fence: 636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; /* not interesting */ 637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(0); 639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, st); 641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Store: 644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (instrument) 645436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov instrument_store(bb, st->Ist.Store.addr, st->Ist.Store.data, 646436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov NULL/* no guard */); 647436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addStmtToIRSB(bb, st); 648436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 649436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 650436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Ist_StoreG: { 651436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRStoreG* sg = st->Ist.StoreG.details; 652436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* data = sg->data; 653436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* addr = sg->addr; 654436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (instrument) 655436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov instrument_store(bb, addr, data, sg->guard); 656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, st); 657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 658436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 659436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 660436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Ist_LoadG: { 661436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRLoadG* lg = st->Ist.LoadG.details; 662436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRType type = Ity_INVALID; /* loaded type */ 663436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRType typeWide = Ity_INVALID; /* after implicit widening */ 664436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* addr_expr = lg->addr; 665436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov typeOfIRLoadGOp(lg->cvt, &typeWide, &type); 666436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tl_assert(type != Ity_INVALID); 667436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (UNLIKELY(DRD_(any_address_is_traced)())) { 668436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addr_expr = instr_trace_mem_load(bb, addr_expr, 669436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sizeofIRType(type), lg->guard); 670436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 671436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov instrument_load(bb, lg->addr, 672436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sizeofIRType(type), lg->guard); 673436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addStmtToIRSB(bb, st); 674436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 675436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_WrTmp: 678663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (instrument) { 679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const IRExpr* const data = st->Ist.WrTmp.data; 680663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr* addr_expr = data->Iex.Load.addr; 681663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (data->tag == Iex_Load) { 682663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (UNLIKELY(DRD_(any_address_is_traced)())) { 683663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addr_expr = instr_trace_mem_load(bb, addr_expr, 684436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sizeofIRType(data->Iex.Load.ty), 685436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov NULL/* no guard */); 686663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 687436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov instrument_load(bb, addr_expr, sizeofIRType(data->Iex.Load.ty), 688436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov NULL/* no guard */); 689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, st); 692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Dirty: 695663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (instrument) { 696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRDirty* d = st->Ist.Dirty.details; 697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IREffect const mFx = d->mFx; 698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (mFx) { 699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ifx_None: 700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ifx_Read: 702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ifx_Write: 703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ifx_Modify: 704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(d->mAddr); 705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(d->mSize > 0); 706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argv = mkIRExprVec_2(d->mAddr, mkIRExpr_HWord(d->mSize)); 707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (mFx == Ifx_Read || mFx == Ifx_Modify) { 708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown di = unsafeIRDirty_0_N( 709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*regparms*/2, 710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "drd_trace_load", 711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(fnptr_to_fnentry)(DRD_(trace_load)), 712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argv); 713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, IRStmt_Dirty(di)); 714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (mFx == Ifx_Write || mFx == Ifx_Modify) 716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown di = unsafeIRDirty_0_N( 718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*regparms*/2, 719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "drd_trace_store", 720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(fnptr_to_fnentry)(DRD_(trace_store)), 721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argv); 722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, IRStmt_Dirty(di)); 723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(0); 727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, st); 730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_CAS: 733663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (instrument) { 734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Treat compare-and-swap as a read. By handling atomic 736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * instructions as read instructions no data races are reported 737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * between conflicting atomic operations nor between atomic 738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * operations and non-atomic reads. Conflicts between atomic 739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * operations and non-atomic write operations are still reported 740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * however. 741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int dataSize; 743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRCAS* cas = st->Ist.CAS.details; 744663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(cas->addr != NULL); 746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(cas->dataLo != NULL); 747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dataSize = sizeofIRType(typeOfIRExpr(bb->tyenv, cas->dataLo)); 748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (cas->dataHi != NULL) 749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dataSize *= 2; /* since it's a doubleword-CAS */ 750663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 751663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (UNLIKELY(DRD_(any_address_is_traced)())) 752436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov instr_trace_mem_store(bb, cas->addr, cas->dataHi, cas->dataLo, 753436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov NULL/* no guard */); 754663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 755436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov instrument_load(bb, cas->addr, dataSize, NULL/*no guard*/); 756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, st); 758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_LLSC: { 761663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* 762663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * Ignore store-conditionals (except for tracing), and handle 763663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * load-linked's exactly like normal loads. 764663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRType dataTy; 766663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 767663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (st->Ist.LLSC.storedata == NULL) { 768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* LL */ 769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dataTy = typeOfIRTemp(bb_in->tyenv, st->Ist.LLSC.result); 770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (instrument) { 771663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr* addr_expr = st->Ist.LLSC.addr; 772663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (UNLIKELY(DRD_(any_address_is_traced)())) 773663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addr_expr = instr_trace_mem_load(bb, addr_expr, 774436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sizeofIRType(dataTy), 775436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov NULL /* no guard */); 776663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 777436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov instrument_load(bb, addr_expr, sizeofIRType(dataTy), 778436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov NULL/*no guard*/); 779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 780663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* SC */ 782663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng instr_trace_mem_store(bb, st->Ist.LLSC.addr, NULL, 783436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov st->Ist.LLSC.storedata, 784436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov NULL/* no guard */); 785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, st); 787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_NoOp: 791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_AbiHint: 792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Put: 793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_PutI: 794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Exit: 795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* None of these can contain any memory references. */ 796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, st); 797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt(st); 801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(0); 802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return bb; 806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 808