1 /* -*- mode: C; c-basic-offset: 3; -*- */ 2 /* 3 This file is part of drd, a thread error detector. 4 5 Copyright (C) 2006-2010 Bart Van Assche <bvanassche (at) acm.org>. 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_suppression.h" 27 #include "pub_drd_bitmap.h" 28 #include "pub_tool_libcassert.h" // tl_assert() 29 #include "pub_tool_stacktrace.h" // VG_(get_and_pp_StackTrace)() 30 #include "pub_tool_threadstate.h" // VG_(get_running_tid)() 31 #include "pub_tool_libcprint.h" // Vg_DebugMsg 32 33 34 /* Global variables. */ 35 36 Bool DRD_(g_any_address_traced) = False; 37 38 39 /* Local variables. */ 40 41 static struct bitmap* DRD_(s_suppressed); 42 static struct bitmap* DRD_(s_traced); 43 static Bool DRD_(s_trace_suppression); 44 45 46 /* Function definitions. */ 47 48 void DRD_(suppression_set_trace)(const Bool trace_suppression) 49 { 50 DRD_(s_trace_suppression) = trace_suppression; 51 } 52 53 void DRD_(suppression_init)(void) 54 { 55 tl_assert(DRD_(s_suppressed) == 0); 56 tl_assert(DRD_(s_traced) == 0); 57 DRD_(s_suppressed) = DRD_(bm_new)(); 58 DRD_(s_traced) = DRD_(bm_new)(); 59 tl_assert(DRD_(s_suppressed)); 60 tl_assert(DRD_(s_traced)); 61 } 62 63 void DRD_(start_suppression)(const Addr a1, const Addr a2, 64 const char* const reason) 65 { 66 if (DRD_(s_trace_suppression)) 67 { 68 VG_(message)(Vg_DebugMsg, "start suppression of 0x%lx sz %ld (%s)\n", 69 a1, a2 - a1, reason); 70 } 71 72 tl_assert(a1 <= a2); 73 DRD_(bm_access_range_store)(DRD_(s_suppressed), a1, a2); 74 } 75 76 void DRD_(finish_suppression)(const Addr a1, const Addr a2) 77 { 78 if (DRD_(s_trace_suppression)) 79 { 80 VG_(message)(Vg_DebugMsg, "finish suppression of 0x%lx sz %ld\n", 81 a1, a2 - a1); 82 VG_(get_and_pp_StackTrace)(VG_(get_running_tid)(), 12); 83 } 84 85 tl_assert(a1 <= a2); 86 DRD_(bm_clear_store)(DRD_(s_suppressed), a1, a2); 87 } 88 89 /** 90 * Return true if data race detection suppression has been requested for all 91 * bytes in the range a1 .. a2 - 1 inclusive. Return false in case the range 92 * is only partially suppressed or not suppressed at all. 93 */ 94 Bool DRD_(is_suppressed)(const Addr a1, const Addr a2) 95 { 96 return DRD_(bm_has)(DRD_(s_suppressed), a1, a2, eStore); 97 } 98 99 /** 100 * Return true if data race detection suppression has been requested for any 101 * of the bytes in the range a1 .. a2 - 1 inclusive. Return false in case none 102 * of the bytes in the specified range is suppressed. 103 */ 104 Bool DRD_(is_any_suppressed)(const Addr a1, const Addr a2) 105 { 106 return DRD_(bm_has_any_store)(DRD_(s_suppressed), a1, a2); 107 } 108 109 void DRD_(mark_hbvar)(const Addr a1) 110 { 111 DRD_(bm_access_range_load)(DRD_(s_suppressed), a1, a1 + 1); 112 } 113 114 Bool DRD_(range_contains_suppression_or_hbvar)(const Addr a1, const Addr a2) 115 { 116 return DRD_(bm_has_any_access)(DRD_(s_suppressed), a1, a2); 117 } 118 119 void DRD_(start_tracing_address_range)(const Addr a1, const Addr a2) 120 { 121 tl_assert(a1 <= a2); 122 123 DRD_(bm_access_range_load)(DRD_(s_traced), a1, a2); 124 if (! DRD_(g_any_address_traced)) 125 { 126 DRD_(g_any_address_traced) = True; 127 } 128 } 129 130 void DRD_(stop_tracing_address_range)(const Addr a1, const Addr a2) 131 { 132 tl_assert(a1 <= a2); 133 134 DRD_(bm_clear_load)(DRD_(s_traced), a1, a2); 135 if (DRD_(g_any_address_traced)) 136 { 137 DRD_(g_any_address_traced) 138 = DRD_(bm_has_any_load)(DRD_(s_traced), 0, ~(Addr)0); 139 } 140 } 141 142 Bool DRD_(is_any_traced)(const Addr a1, const Addr a2) 143 { 144 return DRD_(bm_has_any_load)(DRD_(s_traced), a1, a2); 145 } 146 147 void DRD_(suppression_stop_using_mem)(const Addr a1, const Addr a2) 148 { 149 if (DRD_(s_trace_suppression)) 150 { 151 Addr b; 152 for (b = a1; b < a2; b++) 153 { 154 if (DRD_(bm_has_1)(DRD_(s_suppressed), b, eStore)) 155 { 156 VG_(message)(Vg_DebugMsg, 157 "stop_using_mem(0x%lx, %ld) finish suppression of" 158 " 0x%lx\n", a1, a2 - a1, b); 159 } 160 } 161 } 162 tl_assert(a1); 163 tl_assert(a1 <= a2); 164 DRD_(bm_clear)(DRD_(s_suppressed), a1, a2); 165 DRD_(bm_clear)(DRD_(s_traced), a1, a2); 166 } 167