blob: 26963ee194d69ebb21b51b1dccdc81e5004902bd [file] [log] [blame]
sewardjaf44c822007-11-25 14:01:38 +00001/*
2 This file is part of drd, a data race detector.
3
sewardj85642922008-01-14 11:54:56 +00004 Copyright (C) 2006-2008 Bart Van Assche
sewardjaf44c822007-11-25 14:01:38 +00005 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 "pub_tool_basics.h" // Addr, SizeT
27#include "pub_tool_debuginfo.h" // VG_(get_objname)()
28#include "pub_tool_libcassert.h" // tl_assert()
29#include "pub_tool_libcbase.h" // VG_(memset)
30#include "pub_tool_libcprint.h" // VG_(printf)
31#include "pub_tool_machine.h" // VG_(get_IP)()
32#include "pub_tool_mallocfree.h" // VG_(malloc), VG_(free)
33#include "pub_drd_bitmap.h"
34#include "drd_bitmap.h"
35#include "drd_error.h"
36#include "drd_suppression.h"
37
38
39// Local constants.
40
41static ULong s_bitmap_creation_count;
42
43
44// Local function declarations.
45
46static void bm2_merge(struct bitmap2* const bm2l,
47 const struct bitmap2* const bm2r);
48
49
50// Function definitions.
51
52struct bitmap* bm_new()
53{
bart3772a982008-03-15 08:11:03 +000054 struct bitmap* bm;
sewardjaf44c822007-11-25 14:01:38 +000055
bart3772a982008-03-15 08:11:03 +000056 // If this assert fails, fix the definition of BITS_PER_BITS_PER_UWORD
57 // in drd_bitmap.h.
58 tl_assert((1 << BITS_PER_BITS_PER_UWORD) == BITS_PER_UWORD);
sewardjaf44c822007-11-25 14:01:38 +000059
bart3772a982008-03-15 08:11:03 +000060 bm = VG_(malloc)(sizeof(*bm));
61 tl_assert(bm);
62 bm->oset = VG_(OSetGen_Create)(0, 0, VG_(malloc), VG_(free));
sewardjaf44c822007-11-25 14:01:38 +000063
bart3772a982008-03-15 08:11:03 +000064 s_bitmap_creation_count++;
sewardjaf44c822007-11-25 14:01:38 +000065
bart3772a982008-03-15 08:11:03 +000066 return bm;
sewardjaf44c822007-11-25 14:01:38 +000067}
68
69void bm_delete(struct bitmap* const bm)
70{
bart3772a982008-03-15 08:11:03 +000071 tl_assert(bm);
72 VG_(OSetGen_Destroy)(bm->oset);
73 VG_(free)(bm);
sewardjaf44c822007-11-25 14:01:38 +000074}
75
76/**
bart36556122008-03-13 19:24:30 +000077 * Record an access of type access_type at addresses a .. a + size - 1 in
sewardjaf44c822007-11-25 14:01:38 +000078 * bitmap bm.
79 */
barta79df6e2008-03-14 17:07:51 +000080static
sewardjaf44c822007-11-25 14:01:38 +000081void bm_access_range(struct bitmap* const bm,
bart9036dea2008-03-13 19:10:06 +000082 const Addr a1, const Addr a2,
bart0268dfa2008-03-11 20:10:21 +000083 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +000084{
bart3772a982008-03-15 08:11:03 +000085 Addr b, b_next;
bart36556122008-03-13 19:24:30 +000086
bart3772a982008-03-15 08:11:03 +000087 tl_assert(bm);
88 tl_assert(a1 < a2);
sewardjaf44c822007-11-25 14:01:38 +000089
bart3772a982008-03-15 08:11:03 +000090 for (b = a1; b < a2; b = b_next)
91 {
92 Addr b_start;
93 Addr b_end;
94 struct bitmap2* bm2;
95 SPLIT_ADDRESS(b);
bart36556122008-03-13 19:24:30 +000096
bart3772a982008-03-15 08:11:03 +000097 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
98 if (b_next > a2)
99 {
100 b_next = a2;
101 }
bart36556122008-03-13 19:24:30 +0000102
bart3772a982008-03-15 08:11:03 +0000103 bm2 = bm2_lookup_or_insert(bm, b1);
104 tl_assert(bm2);
bart36556122008-03-13 19:24:30 +0000105
bart3772a982008-03-15 08:11:03 +0000106 if ((bm2->addr << ADDR0_BITS) < a1)
107 b_start = a1;
108 else
109 if ((bm2->addr << ADDR0_BITS) < a2)
110 b_start = (bm2->addr << ADDR0_BITS);
bart36556122008-03-13 19:24:30 +0000111 else
bart3772a982008-03-15 08:11:03 +0000112 break;
113 tl_assert(a1 <= b_start && b_start <= a2);
bart36556122008-03-13 19:24:30 +0000114
bart3772a982008-03-15 08:11:03 +0000115 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
116 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
117 else
118 b_end = a2;
119 tl_assert(a1 <= b_end && b_end <= a2);
120 tl_assert(b_start < b_end);
121 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
bart36556122008-03-13 19:24:30 +0000122
bart3772a982008-03-15 08:11:03 +0000123 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end - 1) & ADDR0_MASK); b0++)
124 {
125 if (access_type == eLoad)
bart36556122008-03-13 19:24:30 +0000126 {
bart3772a982008-03-15 08:11:03 +0000127 bm0_set(bm2->bm1.bm0_r, b0);
sewardjaf44c822007-11-25 14:01:38 +0000128 }
bart3772a982008-03-15 08:11:03 +0000129 else
130 {
131 bm0_set(bm2->bm1.bm0_w, b0);
132 }
133 }
134 }
sewardjaf44c822007-11-25 14:01:38 +0000135}
136
barta79df6e2008-03-14 17:07:51 +0000137static inline
138void bm_access_aligned_load(struct bitmap* const bm,
bartf8bc71d2008-03-15 11:42:34 +0000139 const Addr a1, const SizeT size)
barta79df6e2008-03-14 17:07:51 +0000140{
bart3772a982008-03-15 08:11:03 +0000141 struct bitmap2* bm2;
barta79df6e2008-03-14 17:07:51 +0000142
bart3772a982008-03-15 08:11:03 +0000143 bm2 = bm2_lookup_or_insert(bm, a1 >> ADDR0_BITS);
bartf8bc71d2008-03-15 11:42:34 +0000144 bm0_set_range(bm2->bm1.bm0_r, a1 & ADDR0_MASK, size);
barta79df6e2008-03-14 17:07:51 +0000145}
146
147static inline
148void bm_access_aligned_store(struct bitmap* const bm,
bartf8bc71d2008-03-15 11:42:34 +0000149 const Addr a1, const SizeT size)
barta79df6e2008-03-14 17:07:51 +0000150{
bart3772a982008-03-15 08:11:03 +0000151 struct bitmap2* bm2;
barta79df6e2008-03-14 17:07:51 +0000152
bart3772a982008-03-15 08:11:03 +0000153 bm2 = bm2_lookup_or_insert(bm, a1 >> ADDR0_BITS);
bartf8bc71d2008-03-15 11:42:34 +0000154 bm0_set_range(bm2->bm1.bm0_w, a1 & ADDR0_MASK, size);
barta79df6e2008-03-14 17:07:51 +0000155}
156
bart36556122008-03-13 19:24:30 +0000157void bm_access_range_load(struct bitmap* const bm,
158 const Addr a1, const Addr a2)
159{
bart3772a982008-03-15 08:11:03 +0000160 bm_access_range(bm, a1, a2, eLoad);
bart36556122008-03-13 19:24:30 +0000161}
162
barta79df6e2008-03-14 17:07:51 +0000163void bm_access_load_1(struct bitmap* const bm, const Addr a1)
164{
bartf8bc71d2008-03-15 11:42:34 +0000165 bm_access_aligned_load(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000166}
167
168void bm_access_load_2(struct bitmap* const bm, const Addr a1)
169{
bart3772a982008-03-15 08:11:03 +0000170 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000171 bm_access_aligned_load(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000172 else
173 bm_access_range(bm, a1, a1 + 2, eLoad);
barta79df6e2008-03-14 17:07:51 +0000174}
175
176void bm_access_load_4(struct bitmap* const bm, const Addr a1)
177{
bart3772a982008-03-15 08:11:03 +0000178 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000179 bm_access_aligned_load(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000180 else
181 bm_access_range(bm, a1, a1 + 4, eLoad);
barta79df6e2008-03-14 17:07:51 +0000182}
183
184void bm_access_load_8(struct bitmap* const bm, const Addr a1)
185{
bart3772a982008-03-15 08:11:03 +0000186 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000187 bm_access_aligned_load(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000188 else if ((a1 & 3) == 0)
189 {
bartf8bc71d2008-03-15 11:42:34 +0000190 bm_access_aligned_load(bm, a1 + 0, 4);
191 bm_access_aligned_load(bm, a1 + 4, 4);
bart3772a982008-03-15 08:11:03 +0000192 }
193 else
194 bm_access_range(bm, a1, a1 + 8, eLoad);
barta79df6e2008-03-14 17:07:51 +0000195}
196
197void bm_access_store_1(struct bitmap* const bm, const Addr a1)
198{
bartf8bc71d2008-03-15 11:42:34 +0000199 bm_access_aligned_store(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000200}
201
202void bm_access_store_2(struct bitmap* const bm, const Addr a1)
203{
bart3772a982008-03-15 08:11:03 +0000204 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000205 bm_access_aligned_store(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000206 else
207 bm_access_range(bm, a1, a1 + 2, eStore);
barta79df6e2008-03-14 17:07:51 +0000208}
209
210void bm_access_store_4(struct bitmap* const bm, const Addr a1)
211{
bart3772a982008-03-15 08:11:03 +0000212 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000213 bm_access_aligned_store(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000214 else
215 bm_access_range(bm, a1, a1 + 4, eStore);
barta79df6e2008-03-14 17:07:51 +0000216}
217
218void bm_access_store_8(struct bitmap* const bm, const Addr a1)
219{
bart3772a982008-03-15 08:11:03 +0000220 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000221 bm_access_aligned_store(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000222 else if ((a1 & 3) == 0)
223 {
bartf8bc71d2008-03-15 11:42:34 +0000224 bm_access_aligned_store(bm, a1 + 0, 4);
225 bm_access_aligned_store(bm, a1 + 4, 4);
bart3772a982008-03-15 08:11:03 +0000226 }
227 else
228 bm_access_range(bm, a1, a1 + 8, eStore);
barta79df6e2008-03-14 17:07:51 +0000229}
230
bart36556122008-03-13 19:24:30 +0000231void bm_access_range_store(struct bitmap* const bm,
232 const Addr a1, const Addr a2)
233{
bart3772a982008-03-15 08:11:03 +0000234 bm_access_range(bm, a1, a2, eStore);
bart36556122008-03-13 19:24:30 +0000235}
236
237Bool bm_has(const struct bitmap* const bm, const Addr a1, const Addr a2,
sewardjaf44c822007-11-25 14:01:38 +0000238 const BmAccessTypeT access_type)
239{
bart3772a982008-03-15 08:11:03 +0000240 Addr b;
241 for (b = a1; b < a2; b++)
242 {
243 if (! bm_has_1(bm, b, access_type))
244 {
245 return False;
246 }
247 }
248 return True;
sewardjaf44c822007-11-25 14:01:38 +0000249}
250
251Bool bm_has_any(const struct bitmap* const bm,
bart36556122008-03-13 19:24:30 +0000252 const Addr a1, const Addr a2,
sewardjaf44c822007-11-25 14:01:38 +0000253 const BmAccessTypeT access_type)
254{
bart3772a982008-03-15 08:11:03 +0000255 Addr b;
sewardjaf44c822007-11-25 14:01:38 +0000256
bart3772a982008-03-15 08:11:03 +0000257 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000258
bart3772a982008-03-15 08:11:03 +0000259 for (b = a1; b < a2; b++)
260 {
261 if (bm_has_1(bm, b, access_type))
262 {
263 return True;
264 }
265 }
266 return False;
sewardjaf44c822007-11-25 14:01:38 +0000267}
268
269/* Return a non-zero value if there is a read access, write access or both */
270/* to any of the addresses in the range [ a1, a2 [ in bitmap bm. */
271UWord bm_has_any_access(const struct bitmap* const bm,
272 const Addr a1,
273 const Addr a2)
274{
bart3772a982008-03-15 08:11:03 +0000275 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000276
bart3772a982008-03-15 08:11:03 +0000277 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000278
bart3772a982008-03-15 08:11:03 +0000279 for (b = a1; b < a2; b = b_next)
280 {
281 struct bitmap2* bm2 = bm_lookup(bm, b);
sewardjaf44c822007-11-25 14:01:38 +0000282
bart3772a982008-03-15 08:11:03 +0000283 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
284 if (b_next > a2)
285 {
286 b_next = a2;
287 }
sewardjaf44c822007-11-25 14:01:38 +0000288
bart3772a982008-03-15 08:11:03 +0000289 if (bm2)
290 {
291 Addr b_start;
292 Addr b_end;
293 UWord b0;
294 const struct bitmap1* const p1 = &bm2->bm1;
sewardjaf44c822007-11-25 14:01:38 +0000295
bart3772a982008-03-15 08:11:03 +0000296 if ((bm2->addr << ADDR0_BITS) < a1)
297 b_start = a1;
298 else
299 if ((bm2->addr << ADDR0_BITS) < a2)
300 b_start = (bm2->addr << ADDR0_BITS);
301 else
302 break;
303 tl_assert(a1 <= b_start && b_start <= a2);
sewardjaf44c822007-11-25 14:01:38 +0000304
bart3772a982008-03-15 08:11:03 +0000305 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
306 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
307 else
308 b_end = a2;
309 tl_assert(a1 <= b_end && b_end <= a2);
310 tl_assert(b_start < b_end);
311 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
sewardjaf44c822007-11-25 14:01:38 +0000312
bart3772a982008-03-15 08:11:03 +0000313 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end-1) & ADDR0_MASK); b0++)
314 {
315 const UWord mask
316 = bm0_is_set(p1->bm0_r, b0) | bm0_is_set(p1->bm0_w, b0);
317 if (mask)
318 {
319 return mask;
320 }
sewardjaf44c822007-11-25 14:01:38 +0000321 }
bart3772a982008-03-15 08:11:03 +0000322 }
323 }
324 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000325}
326
327/**
328 * Report whether an access of type access_type at address a is recorded in
329 * bitmap bm.
330 * @return != 0 means true, and == 0 means false
331 */
332UWord bm_has_1(const struct bitmap* const bm,
333 const Addr a,
334 const BmAccessTypeT access_type)
335{
bart3772a982008-03-15 08:11:03 +0000336 struct bitmap2* p2;
337 struct bitmap1* p1;
338 UWord* p0;
339 const UWord a0 = a & ADDR0_MASK;
sewardjaf44c822007-11-25 14:01:38 +0000340
bart3772a982008-03-15 08:11:03 +0000341 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000342
bart3772a982008-03-15 08:11:03 +0000343 p2 = bm_lookup(bm, a);
344 if (p2)
345 {
346 p1 = &p2->bm1;
347 p0 = (access_type == eLoad) ? p1->bm0_r : p1->bm0_w;
348 return bm0_is_set(p0, a0);
349 }
350 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000351}
352
353static __inline__
354void bm1_clear(struct bitmap1* const bm1, const Addr a1, const Addr a2)
355{
bart3772a982008-03-15 08:11:03 +0000356 UWord idx;
357 UWord mask;
sewardjaf44c822007-11-25 14:01:38 +0000358
359#if 0
bart3772a982008-03-15 08:11:03 +0000360 /* Commented out the statements below because of performance reasons. */
361 tl_assert(a1);
362 tl_assert(a1 <= a2);
363 tl_assert(UWORD_MSB(a1) == UWORD_MSB(a2)
364 || UWORD_MSB(a1) == UWORD_MSB(a2 - 1));
sewardjaf44c822007-11-25 14:01:38 +0000365#endif
366
bart3772a982008-03-15 08:11:03 +0000367 idx = (a1 & ADDR0_MASK) >> BITS_PER_BITS_PER_UWORD;
368 /* mask: a contiguous series of one bits. The first bit set is bit */
369 /* UWORD_LSB(a2-1), and the last bit set is UWORD_LSB(a1). */
370 mask = UWORD_LSB(a2) ? bm0_mask(a2) - bm0_mask(a1) : - bm0_mask(a1);
371 bm1->bm0_r[idx] &= ~mask;
372 bm1->bm0_w[idx] &= ~mask;
sewardjaf44c822007-11-25 14:01:38 +0000373}
374
375void bm_clear_all(const struct bitmap* const bm)
376{
bart3772a982008-03-15 08:11:03 +0000377 struct bitmap2* bm2;
sewardjaf44c822007-11-25 14:01:38 +0000378
bart3772a982008-03-15 08:11:03 +0000379 VG_(OSetGen_ResetIter)(bm->oset);
sewardjaf44c822007-11-25 14:01:38 +0000380
bart3772a982008-03-15 08:11:03 +0000381 for ( ; (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0; )
382 {
383 struct bitmap1* const bm1 = &bm2->bm1;
384 tl_assert(bm1);
385 VG_(memset)(&bm1->bm0_r[0], 0, sizeof(bm1->bm0_r));
386 VG_(memset)(&bm1->bm0_w[0], 0, sizeof(bm1->bm0_w));
387 }
sewardjaf44c822007-11-25 14:01:38 +0000388}
389
sewardjaf44c822007-11-25 14:01:38 +0000390void bm_clear(const struct bitmap* const bm,
391 const Addr a1,
392 const Addr a2)
393{
bart3772a982008-03-15 08:11:03 +0000394 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000395
bart3772a982008-03-15 08:11:03 +0000396 tl_assert(bm);
397 tl_assert(a1);
398 tl_assert(a1 <= a2);
sewardjaf44c822007-11-25 14:01:38 +0000399
bart3772a982008-03-15 08:11:03 +0000400 for (b = a1; b < a2; b = b_next)
401 {
402 struct bitmap2* const p2 = bm_lookup(bm, b);
sewardjaf44c822007-11-25 14:01:38 +0000403
bart3772a982008-03-15 08:11:03 +0000404 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
405 if (b_next > a2)
406 {
407 b_next = a2;
408 }
409
410 if (p2)
411 {
412 Addr c = b;
413 if (UWORD_LSB(c))
sewardjaf44c822007-11-25 14:01:38 +0000414 {
bart3772a982008-03-15 08:11:03 +0000415 Addr c_next = UWORD_MSB(c) + BITS_PER_UWORD;
416 if (c_next > b_next)
417 c_next = b_next;
418 bm1_clear(&p2->bm1, c, c_next);
419 c = c_next;
sewardjaf44c822007-11-25 14:01:38 +0000420 }
bart3772a982008-03-15 08:11:03 +0000421 if (UWORD_LSB(c) == 0)
sewardjaf44c822007-11-25 14:01:38 +0000422 {
bart3772a982008-03-15 08:11:03 +0000423 const Addr c_next = UWORD_MSB(b_next);
424 tl_assert(UWORD_LSB(c) == 0);
425 tl_assert(UWORD_LSB(c_next) == 0);
426 tl_assert(c_next <= b_next);
427 tl_assert(c <= c_next);
428 if (c_next > c)
429 {
430 UWord idx = (c & ADDR0_MASK) >> BITS_PER_BITS_PER_UWORD;
431 VG_(memset)(&p2->bm1.bm0_r[idx], 0, (c_next - c) / 8);
432 VG_(memset)(&p2->bm1.bm0_w[idx], 0, (c_next - c) / 8);
433 c = c_next;
434 }
sewardjaf44c822007-11-25 14:01:38 +0000435 }
bart3772a982008-03-15 08:11:03 +0000436 if (c != b_next)
437 {
438 bm1_clear(&p2->bm1, c, b_next);
439 }
440 }
441 }
sewardjaf44c822007-11-25 14:01:38 +0000442}
sewardjaf44c822007-11-25 14:01:38 +0000443
bart36556122008-03-13 19:24:30 +0000444Bool bm_has_conflict_with(const struct bitmap* const bm,
445 const Addr a1, const Addr a2,
446 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000447{
bart3772a982008-03-15 08:11:03 +0000448 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000449
bart3772a982008-03-15 08:11:03 +0000450 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000451
bart3772a982008-03-15 08:11:03 +0000452 for (b = a1; b < a2; b = b_next)
453 {
454 struct bitmap2* bm2 = bm_lookup(bm, b);
bart36556122008-03-13 19:24:30 +0000455
bart3772a982008-03-15 08:11:03 +0000456 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
457 if (b_next > a2)
458 {
459 b_next = a2;
460 }
bart36556122008-03-13 19:24:30 +0000461
bart3772a982008-03-15 08:11:03 +0000462 if (bm2)
463 {
464 Addr b_start;
465 Addr b_end;
466 UWord b0;
467 const struct bitmap1* const p1 = &bm2->bm1;
bart36556122008-03-13 19:24:30 +0000468
bart3772a982008-03-15 08:11:03 +0000469 if ((bm2->addr << ADDR0_BITS) < a1)
470 b_start = a1;
471 else
472 if ((bm2->addr << ADDR0_BITS) < a2)
473 b_start = (bm2->addr << ADDR0_BITS);
474 else
475 break;
476 tl_assert(a1 <= b_start && b_start <= a2);
bart36556122008-03-13 19:24:30 +0000477
bart3772a982008-03-15 08:11:03 +0000478 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
479 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
480 else
481 b_end = a2;
482 tl_assert(a1 <= b_end && b_end <= a2);
483 tl_assert(b_start < b_end);
484 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
bart36556122008-03-13 19:24:30 +0000485
bart3772a982008-03-15 08:11:03 +0000486 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end-1) & ADDR0_MASK); b0++)
487 {
488 if (access_type == eLoad)
489 {
490 if (bm0_is_set(p1->bm0_w, b0))
491 {
492 return True;
493 }
494 }
495 else
496 {
497 tl_assert(access_type == eStore);
498 if (bm0_is_set(p1->bm0_r, b0)
499 | bm0_is_set(p1->bm0_w, b0))
500 {
501 return True;
502 }
503 }
sewardjaf44c822007-11-25 14:01:38 +0000504 }
bart3772a982008-03-15 08:11:03 +0000505 }
506 }
507 return False;
sewardjaf44c822007-11-25 14:01:38 +0000508}
509
barta79df6e2008-03-14 17:07:51 +0000510static inline
511Bool bm_aligned_load_has_conflict_with(const struct bitmap* const bm,
bartf8bc71d2008-03-15 11:42:34 +0000512 const Addr a1, const SizeT size)
barta79df6e2008-03-14 17:07:51 +0000513{
bart3772a982008-03-15 08:11:03 +0000514 struct bitmap2* bm2;
barta79df6e2008-03-14 17:07:51 +0000515
bart3772a982008-03-15 08:11:03 +0000516 bm2 = bm_lookup(bm, a1);
barta79df6e2008-03-14 17:07:51 +0000517
bartf8bc71d2008-03-15 11:42:34 +0000518 return (bm2 && bm0_is_any_set(bm2->bm1.bm0_w, a1 & ADDR0_MASK, size));
barta79df6e2008-03-14 17:07:51 +0000519}
520
521static inline
522Bool bm_aligned_store_has_conflict_with(const struct bitmap* const bm,
bartf8bc71d2008-03-15 11:42:34 +0000523 const Addr a1, const SizeT size)
barta79df6e2008-03-14 17:07:51 +0000524{
bart3772a982008-03-15 08:11:03 +0000525 struct bitmap2* bm2;
barta79df6e2008-03-14 17:07:51 +0000526
bart3772a982008-03-15 08:11:03 +0000527 bm2 = bm_lookup(bm, a1);
barta79df6e2008-03-14 17:07:51 +0000528
bart3772a982008-03-15 08:11:03 +0000529 if (bm2)
530 {
bartf8bc71d2008-03-15 11:42:34 +0000531 if (bm0_is_any_set(bm2->bm1.bm0_r, a1 & ADDR0_MASK, size)
532 | bm0_is_any_set(bm2->bm1.bm0_w, a1 & ADDR0_MASK, size))
bart3772a982008-03-15 08:11:03 +0000533 {
534 return True;
535 }
536 }
537 return False;
barta79df6e2008-03-14 17:07:51 +0000538}
539
bart36556122008-03-13 19:24:30 +0000540Bool bm_load_has_conflict_with(const struct bitmap* const bm,
541 const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000542{
bart3772a982008-03-15 08:11:03 +0000543 return bm_has_conflict_with(bm, a1, a2, eLoad);
bart36556122008-03-13 19:24:30 +0000544}
545
barta79df6e2008-03-14 17:07:51 +0000546Bool bm_load_1_has_conflict_with(const struct bitmap* const bm, const Addr a1)
547{
bartf8bc71d2008-03-15 11:42:34 +0000548 return bm_aligned_load_has_conflict_with(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000549}
550
551Bool bm_load_2_has_conflict_with(const struct bitmap* const bm, const Addr a1)
552{
bart3772a982008-03-15 08:11:03 +0000553 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000554 return bm_aligned_load_has_conflict_with(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000555 else
556 return bm_has_conflict_with(bm, a1, a1 + 2, eLoad);
barta79df6e2008-03-14 17:07:51 +0000557}
558
559Bool bm_load_4_has_conflict_with(const struct bitmap* const bm, const Addr a1)
560{
bart3772a982008-03-15 08:11:03 +0000561 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000562 return bm_aligned_load_has_conflict_with(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000563 else
564 return bm_has_conflict_with(bm, a1, a1 + 4, eLoad);
barta79df6e2008-03-14 17:07:51 +0000565}
566
567Bool bm_load_8_has_conflict_with(const struct bitmap* const bm, const Addr a1)
568{
bart3772a982008-03-15 08:11:03 +0000569 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000570 return bm_aligned_load_has_conflict_with(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000571 else
572 return bm_has_conflict_with(bm, a1, a1 + 8, eLoad);
barta79df6e2008-03-14 17:07:51 +0000573}
574
575Bool bm_store_1_has_conflict_with(const struct bitmap* const bm, const Addr a1)
576{
bartf8bc71d2008-03-15 11:42:34 +0000577 return bm_aligned_store_has_conflict_with(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000578}
579
580Bool bm_store_2_has_conflict_with(const struct bitmap* const bm, const Addr a1)
581{
bart3772a982008-03-15 08:11:03 +0000582 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000583 return bm_aligned_store_has_conflict_with(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000584 else
585 return bm_has_conflict_with(bm, a1, a1 + 2, eStore);
barta79df6e2008-03-14 17:07:51 +0000586}
587
588Bool bm_store_4_has_conflict_with(const struct bitmap* const bm, const Addr a1)
589{
bart3772a982008-03-15 08:11:03 +0000590 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000591 return bm_aligned_store_has_conflict_with(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000592 else
593 return bm_has_conflict_with(bm, a1, a1 + 4, eStore);
barta79df6e2008-03-14 17:07:51 +0000594}
595
596Bool bm_store_8_has_conflict_with(const struct bitmap* const bm, const Addr a1)
597{
bart3772a982008-03-15 08:11:03 +0000598 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000599 return bm_aligned_store_has_conflict_with(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000600 else
601 return bm_has_conflict_with(bm, a1, a1 + 8, eStore);
barta79df6e2008-03-14 17:07:51 +0000602}
603
bart36556122008-03-13 19:24:30 +0000604Bool bm_store_has_conflict_with(const struct bitmap* const bm,
605 const Addr a1, const Addr a2)
606{
bart3772a982008-03-15 08:11:03 +0000607 return bm_has_conflict_with(bm, a1, a2, eStore);
sewardjaf44c822007-11-25 14:01:38 +0000608}
609
610void bm_swap(struct bitmap* const bm1, struct bitmap* const bm2)
611{
bart3772a982008-03-15 08:11:03 +0000612 OSet* const tmp = bm1->oset;
613 bm1->oset = bm2->oset;
614 bm2->oset = tmp;
sewardjaf44c822007-11-25 14:01:38 +0000615}
616
617void bm_merge2(struct bitmap* const lhs,
618 const struct bitmap* const rhs)
619{
bart3772a982008-03-15 08:11:03 +0000620 struct bitmap2* bm2l;
621 const struct bitmap2* bm2r;
sewardjaf44c822007-11-25 14:01:38 +0000622
bart3772a982008-03-15 08:11:03 +0000623 // First step: allocate any missing bitmaps in *lhs.
624 VG_(OSetGen_ResetIter)(rhs->oset);
625 for ( ; (bm2r = VG_(OSetGen_Next)(rhs->oset)) != 0; )
626 {
627 bm2_lookup_or_insert(lhs, bm2r->addr);
628 }
sewardjaf44c822007-11-25 14:01:38 +0000629
bart3772a982008-03-15 08:11:03 +0000630 VG_(OSetGen_ResetIter)(lhs->oset);
631 VG_(OSetGen_ResetIter)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +0000632
bart3772a982008-03-15 08:11:03 +0000633 for ( ; (bm2r = VG_(OSetGen_Next)(rhs->oset)) != 0; )
634 {
635 do
636 {
637 bm2l = VG_(OSetGen_Next)(lhs->oset);
638 } while (bm2l->addr < bm2r->addr);
sewardjaf44c822007-11-25 14:01:38 +0000639
bart3772a982008-03-15 08:11:03 +0000640 tl_assert(bm2l->addr == bm2r->addr);
sewardjaf44c822007-11-25 14:01:38 +0000641
bart3772a982008-03-15 08:11:03 +0000642 bm2_merge(bm2l, bm2r);
643 }
sewardjaf44c822007-11-25 14:01:38 +0000644}
645
646/**
647 * Report whether there are any RW / WR / WW patterns in lhs and rhs.
648 * @param lhs First bitmap.
649 * @param rhs Bitmap to be compared with lhs.
650 * @return !=0 if there are data races, == 0 if there are none.
651 */
652int bm_has_races(const struct bitmap* const lhs,
653 const struct bitmap* const rhs)
654{
bart3772a982008-03-15 08:11:03 +0000655 VG_(OSetGen_ResetIter)(lhs->oset);
656 VG_(OSetGen_ResetIter)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +0000657
bart3772a982008-03-15 08:11:03 +0000658 for (;;)
659 {
660 const struct bitmap2* bm2l = VG_(OSetGen_Next)(lhs->oset);
661 const struct bitmap2* bm2r = VG_(OSetGen_Next)(rhs->oset);
662 const struct bitmap1* bm1l;
663 const struct bitmap1* bm1r;
664 unsigned k;
sewardjaf44c822007-11-25 14:01:38 +0000665
bart3772a982008-03-15 08:11:03 +0000666 while (bm2l && bm2r && bm2l->addr != bm2r->addr)
667 {
668 if (bm2l->addr < bm2r->addr)
669 bm2l = VG_(OSetGen_Next)(lhs->oset);
670 else
671 bm2r = VG_(OSetGen_Next)(rhs->oset);
672 }
673 if (bm2l == 0 || bm2r == 0)
674 break;
675
676 bm1l = &bm2l->bm1;
677 bm1r = &bm2r->bm1;
678
679 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
680 {
681 unsigned b;
682 for (b = 0; b < BITS_PER_UWORD; b++)
sewardjaf44c822007-11-25 14:01:38 +0000683 {
bart3772a982008-03-15 08:11:03 +0000684 UWord const access
685 = ((bm1l->bm0_r[k] & bm0_mask(b)) ? LHS_R : 0)
686 | ((bm1l->bm0_w[k] & bm0_mask(b)) ? LHS_W : 0)
687 | ((bm1r->bm0_r[k] & bm0_mask(b)) ? RHS_R : 0)
688 | ((bm1r->bm0_w[k] & bm0_mask(b)) ? RHS_W : 0);
689 Addr const a = MAKE_ADDRESS(bm2l->addr, k * BITS_PER_UWORD | b);
690 if (HAS_RACE(access) && ! drd_is_suppressed(a, a + 1))
691 {
692 return 1;
693 }
sewardjaf44c822007-11-25 14:01:38 +0000694 }
bart3772a982008-03-15 08:11:03 +0000695 }
696 }
697 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000698}
699
sewardjaf44c822007-11-25 14:01:38 +0000700void bm_print(const struct bitmap* const bm)
701{
bart3772a982008-03-15 08:11:03 +0000702 struct bitmap2* bm2;
sewardjaf44c822007-11-25 14:01:38 +0000703
bart3772a982008-03-15 08:11:03 +0000704 VG_(OSetGen_ResetIter)(bm->oset);
sewardjaf44c822007-11-25 14:01:38 +0000705
bart3772a982008-03-15 08:11:03 +0000706 for ( ; (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0; )
707 {
708 const struct bitmap1* const bm1 = &bm2->bm1;
709 unsigned k;
710 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
711 {
712 unsigned b;
713 for (b = 0; b < BITS_PER_UWORD; b++)
sewardjaf44c822007-11-25 14:01:38 +0000714 {
bart3772a982008-03-15 08:11:03 +0000715 int const r = bm1->bm0_r[k] & bm0_mask(b);
716 int const w = bm1->bm0_w[k] & bm0_mask(b);
717 Addr const a = MAKE_ADDRESS(bm2->addr, k * BITS_PER_UWORD | b);
718 if (r || w)
719 {
720 VG_(printf)("0x%08lx %c %c\n",
721 (Addr)(a),
722 w ? 'W' : ' ', r ? 'R' : ' ');
723 }
sewardjaf44c822007-11-25 14:01:38 +0000724 }
bart3772a982008-03-15 08:11:03 +0000725 }
726 }
sewardjaf44c822007-11-25 14:01:38 +0000727}
728
729ULong bm_get_bitmap_creation_count(void)
730{
bart3772a982008-03-15 08:11:03 +0000731 return s_bitmap_creation_count;
sewardjaf44c822007-11-25 14:01:38 +0000732}
733
734ULong bm_get_bitmap2_creation_count(void)
735{
bart3772a982008-03-15 08:11:03 +0000736 return s_bitmap2_creation_count;
sewardjaf44c822007-11-25 14:01:38 +0000737}
738
739static void bm2_merge(struct bitmap2* const bm2l,
740 const struct bitmap2* const bm2r)
741{
bart3772a982008-03-15 08:11:03 +0000742 unsigned k;
sewardjaf44c822007-11-25 14:01:38 +0000743
bart3772a982008-03-15 08:11:03 +0000744 tl_assert(bm2l->addr == bm2r->addr);
sewardjaf44c822007-11-25 14:01:38 +0000745
bart3772a982008-03-15 08:11:03 +0000746 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
747 {
748 bm2l->bm1.bm0_r[k] |= bm2r->bm1.bm0_r[k];
749 }
750 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
751 {
752 bm2l->bm1.bm0_w[k] |= bm2r->bm1.bm0_w[k];
753 }
sewardjaf44c822007-11-25 14:01:38 +0000754}
755
756#if 0
757
758/* Unit test */
759static
760struct { Addr address; SizeT size; BmAccessTypeT access_type; }
bart3772a982008-03-15 08:11:03 +0000761 s_args[] = {
762 { 0, 1, eLoad },
763 { 666, 4, eLoad },
764 { 667, 2, eStore },
765 { 1024, 1, eStore },
766 { 0x0000ffff, 1, eLoad },
767 { 0x0001ffff, 1, eLoad },
768 { 0x00ffffff, 1, eLoad },
769 { 0xffffffff, 1, eStore },
770 };
sewardjaf44c822007-11-25 14:01:38 +0000771
772void bm_test(void)
773{
bart3772a982008-03-15 08:11:03 +0000774 struct bitmap* bm;
775 struct bitmap* bm2;
776 int i, j;
sewardjaf44c822007-11-25 14:01:38 +0000777
bart3772a982008-03-15 08:11:03 +0000778 VG_(printf)("Start of DRD BM unit test.\n");
sewardjaf44c822007-11-25 14:01:38 +0000779
bart3772a982008-03-15 08:11:03 +0000780 bm = bm_new();
sewardjaf44c822007-11-25 14:01:38 +0000781
bart3772a982008-03-15 08:11:03 +0000782 for (i = 0; i < sizeof(s_args)/sizeof(s_args[0]); i++)
783 {
784 bm_access_range(bm,
785 s_args[i].address,
786 s_args[i].address + s_args[i].size,
787 s_args[i].access_type);
788 }
sewardjaf44c822007-11-25 14:01:38 +0000789
bart3772a982008-03-15 08:11:03 +0000790 VG_(printf)("Map contents -- should contain 10 addresses:\n");
791 bm_print(bm);
sewardjaf44c822007-11-25 14:01:38 +0000792
bart3772a982008-03-15 08:11:03 +0000793 for (i = 0; i < sizeof(s_args)/sizeof(s_args[0]); i++)
794 {
795 for (j = 0; j < s_args[i].size; j++)
796 {
797 tl_assert(bm_has_1(bm, s_args[i].address + j, s_args[i].access_type));
798 }
799 }
sewardjaf44c822007-11-25 14:01:38 +0000800
bart3772a982008-03-15 08:11:03 +0000801 VG_(printf)("Merge result:\n");
802 bm2 = bm_merge(bm, bm);
803 bm_print(bm);
sewardjaf44c822007-11-25 14:01:38 +0000804
bart3772a982008-03-15 08:11:03 +0000805 bm_delete(bm);
806 bm_delete(bm2);
sewardjaf44c822007-11-25 14:01:38 +0000807
bart3772a982008-03-15 08:11:03 +0000808 VG_(printf)("End of DRD BM unit test.\n");
sewardjaf44c822007-11-25 14:01:38 +0000809}
810#endif