blob: 2172c4716ec823db105d219867756d78115f626c [file] [log] [blame]
bartbedfd232009-03-26 19:07:15 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
bart09dc13f2009-02-14 15:13:31 +00002/*
bart86562bd2009-02-16 19:43:56 +00003 This file is part of drd, a thread error detector.
bart09dc13f2009-02-14 15:13:31 +00004
5 Copyright (C) 2006-2009 Bart Van Assche <bart.vanassche@gmail.com>.
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 02111-1307, USA.
21
22 The GNU General Public License is contained in the file COPYING.
23*/
24
25
26#include "drd_bitmap.h"
27#include "drd_thread_bitmap.h"
bart41b226c2009-02-14 16:55:19 +000028#include "drd_vc.h" /* DRD_(vc_snprint)() */
bart09dc13f2009-02-14 15:13:31 +000029
30/* Include several source files here in order to allow the compiler to */
31/* do more inlining. */
32#include "drd_bitmap.c"
33#include "drd_load_store.h"
34#include "drd_segment.c"
35#include "drd_thread.c"
36#include "drd_vc.c"
37#include "libvex_guest_offsets.h"
38
39
40/* STACK_POINTER_OFFSET: VEX register offset for the stack pointer register. */
41#if defined(VGA_x86)
42#define STACK_POINTER_OFFSET OFFSET_x86_ESP
43#elif defined(VGA_amd64)
44#define STACK_POINTER_OFFSET OFFSET_amd64_RSP
45#elif defined(VGA_ppc32)
46#define STACK_POINTER_OFFSET ((OFFSET_ppc32_GPR0 + OFFSET_ppc32_GPR2) / 2)
47#elif defined(VGA_ppc64)
48#define STACK_POINTER_OFFSET ((OFFSET_ppc64_GPR0 + OFFSET_ppc64_GPR2) / 2)
49#else
50#error Unknown architecture.
51#endif
52
53
54/* Local variables. */
55
bartf98a5692009-05-03 17:17:37 +000056static Bool s_check_stack_accesses = False;
57static Bool s_first_race_only = False;
bart09dc13f2009-02-14 15:13:31 +000058
59
60/* Function definitions. */
61
62Bool DRD_(get_check_stack_accesses)()
63{
bartf98a5692009-05-03 17:17:37 +000064 return s_check_stack_accesses;
bart09dc13f2009-02-14 15:13:31 +000065}
66
67void DRD_(set_check_stack_accesses)(const Bool c)
68{
bartbedfd232009-03-26 19:07:15 +000069 tl_assert(c == False || c == True);
bartf98a5692009-05-03 17:17:37 +000070 s_check_stack_accesses = c;
71}
72
73Bool DRD_(get_first_race_only)()
74{
75 return s_first_race_only;
76}
77
78void DRD_(set_first_race_only)(const Bool fro)
79{
80 tl_assert(fro == False || fro == True);
81 s_first_race_only = fro;
bart09dc13f2009-02-14 15:13:31 +000082}
83
bart1335ecc2009-02-14 16:10:53 +000084void DRD_(trace_mem_access)(const Addr addr, const SizeT size,
bartbedfd232009-03-26 19:07:15 +000085 const BmAccessTypeT access_type)
bart09dc13f2009-02-14 15:13:31 +000086{
bartbedfd232009-03-26 19:07:15 +000087 if (DRD_(is_any_traced)(addr, addr + size))
88 {
bart8f822af2009-06-08 18:20:42 +000089 char* vc;
90
91 vc = DRD_(vc_aprint)(DRD_(thread_get_vc)(DRD_(thread_get_running_tid)()));
bartbedfd232009-03-26 19:07:15 +000092 VG_(message)(Vg_UserMsg,
93 "%s 0x%lx size %ld (vg %d / drd %d / vc %s)",
94 access_type == eLoad
95 ? "load "
96 : access_type == eStore
97 ? "store"
98 : access_type == eStart
99 ? "start"
100 : access_type == eEnd
101 ? "end "
102 : "????",
103 addr,
104 size,
105 VG_(get_running_tid)(),
106 DRD_(thread_get_running_tid)(),
107 vc);
bart8f822af2009-06-08 18:20:42 +0000108 VG_(free)(vc);
bartbedfd232009-03-26 19:07:15 +0000109 VG_(get_and_pp_StackTrace)(VG_(get_running_tid)(),
110 VG_(clo_backtrace_size));
111 tl_assert(DRD_(DrdThreadIdToVgThreadId)(DRD_(thread_get_running_tid)())
112 == VG_(get_running_tid)());
113 }
bart09dc13f2009-02-14 15:13:31 +0000114}
115
116static VG_REGPARM(2) void drd_trace_mem_load(const Addr addr, const SizeT size)
117{
bartbedfd232009-03-26 19:07:15 +0000118 return DRD_(trace_mem_access)(addr, size, eLoad);
bart09dc13f2009-02-14 15:13:31 +0000119}
120
121static VG_REGPARM(2) void drd_trace_mem_store(const Addr addr,const SizeT size)
122{
bartbedfd232009-03-26 19:07:15 +0000123 return DRD_(trace_mem_access)(addr, size, eStore);
bart09dc13f2009-02-14 15:13:31 +0000124}
125
126static void drd_report_race(const Addr addr, const SizeT size,
127 const BmAccessTypeT access_type)
128{
bartbedfd232009-03-26 19:07:15 +0000129 DataRaceErrInfo drei;
bart09dc13f2009-02-14 15:13:31 +0000130
bartbedfd232009-03-26 19:07:15 +0000131 drei.tid = DRD_(thread_get_running_tid)();
132 drei.addr = addr;
133 drei.size = size;
134 drei.access_type = access_type;
135 VG_(maybe_record_error)(VG_(get_running_tid)(),
136 DataRaceErr,
137 VG_(get_IP)(VG_(get_running_tid)()),
138 "Conflicting accesses",
139 &drei);
bartf98a5692009-05-03 17:17:37 +0000140
141 if (s_first_race_only)
142 {
143 DRD_(start_suppression)(addr, addr + size, "first race only");
144 }
bart09dc13f2009-02-14 15:13:31 +0000145}
146
bart99edb292009-02-15 15:59:20 +0000147VG_REGPARM(2) void DRD_(trace_load)(Addr addr, SizeT size)
bart09dc13f2009-02-14 15:13:31 +0000148{
149#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bartbedfd232009-03-26 19:07:15 +0000150 /* The assert below has been commented out because of performance reasons.*/
151 tl_assert(thread_get_running_tid()
152 == VgThreadIdToDrdThreadId(VG_(get_running_tid())));
bart09dc13f2009-02-14 15:13:31 +0000153#endif
154
bartd45d9952009-05-31 18:53:54 +0000155 if (DRD_(running_thread_is_recording_loads)()
bartf98a5692009-05-03 17:17:37 +0000156 && (s_check_stack_accesses
bartbedfd232009-03-26 19:07:15 +0000157 || ! DRD_(thread_address_on_stack)(addr))
158 && bm_access_load_triggers_conflict(addr, addr + size)
159 && ! DRD_(is_suppressed)(addr, addr + size))
160 {
161 drd_report_race(addr, size, eLoad);
162 }
bart09dc13f2009-02-14 15:13:31 +0000163}
164
165static VG_REGPARM(1) void drd_trace_load_1(Addr addr)
166{
bartd45d9952009-05-31 18:53:54 +0000167 if (DRD_(running_thread_is_recording_loads)()
bartf98a5692009-05-03 17:17:37 +0000168 && (s_check_stack_accesses
bartbedfd232009-03-26 19:07:15 +0000169 || ! DRD_(thread_address_on_stack)(addr))
170 && bm_access_load_1_triggers_conflict(addr)
171 && ! DRD_(is_suppressed)(addr, addr + 1))
172 {
173 drd_report_race(addr, 1, eLoad);
174 }
bart09dc13f2009-02-14 15:13:31 +0000175}
176
177static VG_REGPARM(1) void drd_trace_load_2(Addr addr)
178{
bartd45d9952009-05-31 18:53:54 +0000179 if (DRD_(running_thread_is_recording_loads)()
bartf98a5692009-05-03 17:17:37 +0000180 && (s_check_stack_accesses
bartbedfd232009-03-26 19:07:15 +0000181 || ! DRD_(thread_address_on_stack)(addr))
182 && bm_access_load_2_triggers_conflict(addr)
183 && ! DRD_(is_suppressed)(addr, addr + 2))
184 {
185 drd_report_race(addr, 2, eLoad);
186 }
bart09dc13f2009-02-14 15:13:31 +0000187}
188
189static VG_REGPARM(1) void drd_trace_load_4(Addr addr)
190{
bartd45d9952009-05-31 18:53:54 +0000191 if (DRD_(running_thread_is_recording_loads)()
bartf98a5692009-05-03 17:17:37 +0000192 && (s_check_stack_accesses
bartbedfd232009-03-26 19:07:15 +0000193 || ! DRD_(thread_address_on_stack)(addr))
194 && bm_access_load_4_triggers_conflict(addr)
195 && ! DRD_(is_suppressed)(addr, addr + 4))
196 {
197 drd_report_race(addr, 4, eLoad);
198 }
bart09dc13f2009-02-14 15:13:31 +0000199}
200
201static VG_REGPARM(1) void drd_trace_load_8(Addr addr)
202{
bartd45d9952009-05-31 18:53:54 +0000203 if (DRD_(running_thread_is_recording_loads)()
bartf98a5692009-05-03 17:17:37 +0000204 && (s_check_stack_accesses
bartbedfd232009-03-26 19:07:15 +0000205 || ! DRD_(thread_address_on_stack)(addr))
206 && bm_access_load_8_triggers_conflict(addr)
207 && ! DRD_(is_suppressed)(addr, addr + 8))
208 {
209 drd_report_race(addr, 8, eLoad);
210 }
bart09dc13f2009-02-14 15:13:31 +0000211}
212
bart99edb292009-02-15 15:59:20 +0000213VG_REGPARM(2) void DRD_(trace_store)(Addr addr, SizeT size)
bart09dc13f2009-02-14 15:13:31 +0000214{
215#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bartbedfd232009-03-26 19:07:15 +0000216 /* The assert below has been commented out because of performance reasons.*/
217 tl_assert(thread_get_running_tid()
218 == VgThreadIdToDrdThreadId(VG_(get_running_tid())));
bart09dc13f2009-02-14 15:13:31 +0000219#endif
220
bartd45d9952009-05-31 18:53:54 +0000221 if (DRD_(running_thread_is_recording_stores)()
bartf98a5692009-05-03 17:17:37 +0000222 && (s_check_stack_accesses
bartbedfd232009-03-26 19:07:15 +0000223 || ! DRD_(thread_address_on_stack)(addr))
224 && bm_access_store_triggers_conflict(addr, addr + size)
225 && ! DRD_(is_suppressed)(addr, addr + size))
226 {
227 drd_report_race(addr, size, eStore);
228 }
bart09dc13f2009-02-14 15:13:31 +0000229}
230
231static VG_REGPARM(1) void drd_trace_store_1(Addr addr)
232{
bartd45d9952009-05-31 18:53:54 +0000233 if (DRD_(running_thread_is_recording_stores)()
bartf98a5692009-05-03 17:17:37 +0000234 && (s_check_stack_accesses
bartbedfd232009-03-26 19:07:15 +0000235 || ! DRD_(thread_address_on_stack)(addr))
236 && bm_access_store_1_triggers_conflict(addr)
237 && ! DRD_(is_suppressed)(addr, addr + 1))
238 {
239 drd_report_race(addr, 1, eStore);
240 }
bart09dc13f2009-02-14 15:13:31 +0000241}
242
243static VG_REGPARM(1) void drd_trace_store_2(Addr addr)
244{
bartd45d9952009-05-31 18:53:54 +0000245 if (DRD_(running_thread_is_recording_stores)()
bartf98a5692009-05-03 17:17:37 +0000246 && (s_check_stack_accesses
bartbedfd232009-03-26 19:07:15 +0000247 || ! DRD_(thread_address_on_stack)(addr))
248 && bm_access_store_2_triggers_conflict(addr)
249 && ! DRD_(is_suppressed)(addr, addr + 2))
250 {
251 drd_report_race(addr, 2, eStore);
252 }
bart09dc13f2009-02-14 15:13:31 +0000253}
254
255static VG_REGPARM(1) void drd_trace_store_4(Addr addr)
256{
bartd45d9952009-05-31 18:53:54 +0000257 if (DRD_(running_thread_is_recording_stores)()
bartf98a5692009-05-03 17:17:37 +0000258 && (s_check_stack_accesses
bartbedfd232009-03-26 19:07:15 +0000259 || ! DRD_(thread_address_on_stack)(addr))
260 && bm_access_store_4_triggers_conflict(addr)
261 && ! DRD_(is_suppressed)(addr, addr + 4))
262 {
263 drd_report_race(addr, 4, eStore);
264 }
bart09dc13f2009-02-14 15:13:31 +0000265}
266
267static VG_REGPARM(1) void drd_trace_store_8(Addr addr)
268{
bartd45d9952009-05-31 18:53:54 +0000269 if (DRD_(running_thread_is_recording_stores)()
bartf98a5692009-05-03 17:17:37 +0000270 && (s_check_stack_accesses
bartbedfd232009-03-26 19:07:15 +0000271 || ! DRD_(thread_address_on_stack)(addr))
272 && bm_access_store_8_triggers_conflict(addr)
273 && ! DRD_(is_suppressed)(addr, addr + 8))
274 {
275 drd_report_race(addr, 8, eStore);
276 }
bart09dc13f2009-02-14 15:13:31 +0000277}
278
279/**
280 * Return true if and only if addr_expr matches the pattern (SP) or
281 * <offset>(SP).
282 */
283static Bool is_stack_access(IRSB* const bb, IRExpr* const addr_expr)
284{
bartbedfd232009-03-26 19:07:15 +0000285 Bool result = False;
bart09dc13f2009-02-14 15:13:31 +0000286
bartbedfd232009-03-26 19:07:15 +0000287 if (addr_expr->tag == Iex_RdTmp)
288 {
289 int i;
290 for (i = 0; i < bb->stmts_size; i++)
bart09dc13f2009-02-14 15:13:31 +0000291 {
bartbedfd232009-03-26 19:07:15 +0000292 if (bb->stmts[i]
293 && bb->stmts[i]->tag == Ist_WrTmp
294 && bb->stmts[i]->Ist.WrTmp.tmp == addr_expr->Iex.RdTmp.tmp)
295 {
296 IRExpr* e = bb->stmts[i]->Ist.WrTmp.data;
297 if (e->tag == Iex_Get && e->Iex.Get.offset == STACK_POINTER_OFFSET)
298 {
299 result = True;
300 }
bart09dc13f2009-02-14 15:13:31 +0000301
bartbedfd232009-03-26 19:07:15 +0000302 //ppIRExpr(e);
303 //VG_(printf)(" (%s)\n", result ? "True" : "False");
304 break;
305 }
bart09dc13f2009-02-14 15:13:31 +0000306 }
bartbedfd232009-03-26 19:07:15 +0000307 }
308 return result;
bart09dc13f2009-02-14 15:13:31 +0000309}
310
311static void instrument_load(IRSB* const bb,
312 IRExpr* const addr_expr,
313 const HWord size)
314{
bartbedfd232009-03-26 19:07:15 +0000315 IRExpr* size_expr;
316 IRExpr** argv;
317 IRDirty* di;
bart09dc13f2009-02-14 15:13:31 +0000318
bartbedfd232009-03-26 19:07:15 +0000319 if (UNLIKELY(DRD_(any_address_is_traced)()))
320 {
321 addStmtToIRSB(bb,
322 IRStmt_Dirty(
323 unsafeIRDirty_0_N(/*regparms*/2,
324 "drd_trace_load",
325 VG_(fnptr_to_fnentry)
326 (drd_trace_mem_load),
327 mkIRExprVec_2(addr_expr,
328 mkIRExpr_HWord(size)))));
329 }
bart09dc13f2009-02-14 15:13:31 +0000330
bartf98a5692009-05-03 17:17:37 +0000331 if (! s_check_stack_accesses && is_stack_access(bb, addr_expr))
bartbedfd232009-03-26 19:07:15 +0000332 return;
bart09dc13f2009-02-14 15:13:31 +0000333
bartbedfd232009-03-26 19:07:15 +0000334 switch (size)
335 {
336 case 1:
337 argv = mkIRExprVec_1(addr_expr);
338 di = unsafeIRDirty_0_N(/*regparms*/1,
339 "drd_trace_load_1",
340 VG_(fnptr_to_fnentry)(drd_trace_load_1),
341 argv);
342 break;
343 case 2:
344 argv = mkIRExprVec_1(addr_expr);
345 di = unsafeIRDirty_0_N(/*regparms*/1,
346 "drd_trace_load_2",
347 VG_(fnptr_to_fnentry)(drd_trace_load_2),
348 argv);
349 break;
350 case 4:
351 argv = mkIRExprVec_1(addr_expr);
352 di = unsafeIRDirty_0_N(/*regparms*/1,
353 "drd_trace_load_4",
354 VG_(fnptr_to_fnentry)(drd_trace_load_4),
355 argv);
356 break;
357 case 8:
358 argv = mkIRExprVec_1(addr_expr);
359 di = unsafeIRDirty_0_N(/*regparms*/1,
360 "drd_trace_load_8",
361 VG_(fnptr_to_fnentry)(drd_trace_load_8),
362 argv);
363 break;
364 default:
365 size_expr = mkIRExpr_HWord(size);
366 argv = mkIRExprVec_2(addr_expr, size_expr);
367 di = unsafeIRDirty_0_N(/*regparms*/2,
368 "drd_trace_load",
369 VG_(fnptr_to_fnentry)(DRD_(trace_load)),
370 argv);
371 break;
372 }
373 addStmtToIRSB(bb, IRStmt_Dirty(di));
bart09dc13f2009-02-14 15:13:31 +0000374}
375
376static void instrument_store(IRSB* const bb,
377 IRExpr* const addr_expr,
378 const HWord size)
379{
bartbedfd232009-03-26 19:07:15 +0000380 IRExpr* size_expr;
381 IRExpr** argv;
382 IRDirty* di;
bart09dc13f2009-02-14 15:13:31 +0000383
bartbedfd232009-03-26 19:07:15 +0000384 if (UNLIKELY(DRD_(any_address_is_traced)()))
385 {
386 addStmtToIRSB(bb,
387 IRStmt_Dirty(
388 unsafeIRDirty_0_N(/*regparms*/2,
389 "drd_trace_store",
390 VG_(fnptr_to_fnentry)
391 (drd_trace_mem_store),
392 mkIRExprVec_2(addr_expr,
393 mkIRExpr_HWord(size)))));
394 }
bart09dc13f2009-02-14 15:13:31 +0000395
bartf98a5692009-05-03 17:17:37 +0000396 if (! s_check_stack_accesses && is_stack_access(bb, addr_expr))
bartbedfd232009-03-26 19:07:15 +0000397 return;
bart09dc13f2009-02-14 15:13:31 +0000398
bartbedfd232009-03-26 19:07:15 +0000399 switch (size)
400 {
401 case 1:
402 argv = mkIRExprVec_1(addr_expr);
403 di = unsafeIRDirty_0_N(/*regparms*/1,
404 "drd_trace_store_1",
405 VG_(fnptr_to_fnentry)(drd_trace_store_1),
406 argv);
407 break;
408 case 2:
409 argv = mkIRExprVec_1(addr_expr);
410 di = unsafeIRDirty_0_N(/*regparms*/1,
411 "drd_trace_store_2",
412 VG_(fnptr_to_fnentry)(drd_trace_store_2),
413 argv);
414 break;
415 case 4:
416 argv = mkIRExprVec_1(addr_expr);
417 di = unsafeIRDirty_0_N(/*regparms*/1,
418 "drd_trace_store_4",
419 VG_(fnptr_to_fnentry)(drd_trace_store_4),
420 argv);
421 break;
422 case 8:
423 argv = mkIRExprVec_1(addr_expr);
424 di = unsafeIRDirty_0_N(/*regparms*/1,
425 "drd_trace_store_8",
426 VG_(fnptr_to_fnentry)(drd_trace_store_8),
427 argv);
428 break;
429 default:
430 size_expr = mkIRExpr_HWord(size);
431 argv = mkIRExprVec_2(addr_expr, size_expr);
432 di = unsafeIRDirty_0_N(/*regparms*/2,
433 "drd_trace_store",
434 VG_(fnptr_to_fnentry)(DRD_(trace_store)),
435 argv);
436 break;
437 }
438 addStmtToIRSB(bb, IRStmt_Dirty(di));
bart09dc13f2009-02-14 15:13:31 +0000439}
440
bart1335ecc2009-02-14 16:10:53 +0000441IRSB* DRD_(instrument)(VgCallbackClosure* const closure,
bartbedfd232009-03-26 19:07:15 +0000442 IRSB* const bb_in,
443 VexGuestLayout* const layout,
444 VexGuestExtents* const vge,
445 IRType const gWordTy,
446 IRType const hWordTy)
bart09dc13f2009-02-14 15:13:31 +0000447{
bartbedfd232009-03-26 19:07:15 +0000448 IRDirty* di;
449 Int i;
450 IRSB* bb;
451 IRExpr** argv;
452 Bool instrument = True;
453 Bool bus_locked = False;
bart09dc13f2009-02-14 15:13:31 +0000454
bartbedfd232009-03-26 19:07:15 +0000455 /* Set up BB */
456 bb = emptyIRSB();
457 bb->tyenv = deepCopyIRTypeEnv(bb_in->tyenv);
458 bb->next = deepCopyIRExpr(bb_in->next);
459 bb->jumpkind = bb_in->jumpkind;
bart09dc13f2009-02-14 15:13:31 +0000460
bartbedfd232009-03-26 19:07:15 +0000461 for (i = 0; i < bb_in->stmts_used; i++)
462 {
463 IRStmt* const st = bb_in->stmts[i];
464 tl_assert(st);
465 if (st->tag == Ist_NoOp)
466 continue;
bart09dc13f2009-02-14 15:13:31 +0000467
bartbedfd232009-03-26 19:07:15 +0000468 switch (st->tag)
bart09dc13f2009-02-14 15:13:31 +0000469 {
bartbedfd232009-03-26 19:07:15 +0000470 /* Note: the code for not instrumenting the code in .plt */
471 /* sections is only necessary on CentOS 3.0 x86 (kernel 2.4.21 */
472 /* + glibc 2.3.2 + NPTL 0.60 + binutils 2.14.90.0.4). */
473 /* This is because on this platform dynamic library symbols are */
474 /* relocated in another way than by later binutils versions. The */
475 /* linker e.g. does not generate .got.plt sections on CentOS 3.0. */
476 case Ist_IMark:
477 instrument = VG_(seginfo_sect_kind)(NULL, 0, st->Ist.IMark.addr)
478 != Vg_SectPLT;
479 addStmtToIRSB(bb, st);
480 break;
481
482 case Ist_MBE:
483 switch (st->Ist.MBE.event)
484 {
485 case Imbe_Fence:
486 break; /* not interesting */
487 case Imbe_BusLock:
488 case Imbe_SnoopedStoreBegin:
489 tl_assert(! bus_locked);
490 bus_locked = True;
491 break;
492 case Imbe_BusUnlock:
493 case Imbe_SnoopedStoreEnd:
494 tl_assert(bus_locked);
495 bus_locked = False;
496 break;
497 default:
498 tl_assert(0);
499 }
500 addStmtToIRSB(bb, st);
501 break;
502
503 case Ist_Store:
504 if (instrument && ! bus_locked)
505 {
506 instrument_store(bb,
507 st->Ist.Store.addr,
508 sizeofIRType(typeOfIRExpr(bb->tyenv,
509 st->Ist.Store.data)));
510 }
511 addStmtToIRSB(bb, st);
512 break;
513
514 case Ist_WrTmp:
515 if (instrument)
516 {
517 const IRExpr* const data = st->Ist.WrTmp.data;
518 if (data->tag == Iex_Load)
519 {
520 instrument_load(bb,
521 data->Iex.Load.addr,
522 sizeofIRType(data->Iex.Load.ty));
523 }
524 }
525 addStmtToIRSB(bb, st);
526 break;
527
528 case Ist_Dirty:
529 if (instrument)
530 {
531 IRDirty* d = st->Ist.Dirty.details;
532 IREffect const mFx = d->mFx;
533 switch (mFx) {
534 case Ifx_None:
535 break;
536 case Ifx_Read:
537 case Ifx_Write:
538 case Ifx_Modify:
539 tl_assert(d->mAddr);
540 tl_assert(d->mSize > 0);
541 argv = mkIRExprVec_2(d->mAddr, mkIRExpr_HWord(d->mSize));
542 if (mFx == Ifx_Read || mFx == Ifx_Modify) {
543 di = unsafeIRDirty_0_N(
544 /*regparms*/2,
545 "drd_trace_load",
546 VG_(fnptr_to_fnentry)(DRD_(trace_load)),
547 argv);
548 addStmtToIRSB(bb, IRStmt_Dirty(di));
549 }
550 if ((mFx == Ifx_Write || mFx == Ifx_Modify)
551 && ! bus_locked)
552 {
553 di = unsafeIRDirty_0_N(
554 /*regparms*/2,
555 "drd_trace_store",
556 VG_(fnptr_to_fnentry)(DRD_(trace_store)),
557 argv);
558 addStmtToIRSB(bb, IRStmt_Dirty(di));
559 }
560 break;
561 default:
562 tl_assert(0);
563 }
564 }
565 addStmtToIRSB(bb, st);
566 break;
567
bart09dc13f2009-02-14 15:13:31 +0000568 default:
bartbedfd232009-03-26 19:07:15 +0000569 addStmtToIRSB(bb, st);
570 break;
bart09dc13f2009-02-14 15:13:31 +0000571 }
bartbedfd232009-03-26 19:07:15 +0000572 }
bart09dc13f2009-02-14 15:13:31 +0000573
bartbedfd232009-03-26 19:07:15 +0000574 tl_assert(! bus_locked);
bart09dc13f2009-02-14 15:13:31 +0000575
bartbedfd232009-03-26 19:07:15 +0000576 return bb;
bart09dc13f2009-02-14 15:13:31 +0000577}
578