Add DRD suppression patterns for races triggered by std::ostream
[valgrind.git] / coregrind / m_tooliface.c
blobdcb233f02ff76df679b160ccd08fe88097472e4c
2 /*--------------------------------------------------------------------*/
3 /*--- Stuff relating to tool data structures. ---*/
4 /*--- m_tooliface.c ---*/
5 /*--------------------------------------------------------------------*/
7 /*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
11 Copyright (C) 2000-2017 Nicholas Nethercote
12 njn@valgrind.org
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
29 The GNU General Public License is contained in the file COPYING.
32 #include "pub_core_basics.h"
33 #include "pub_core_tooliface.h"
34 #include "pub_core_transtab.h" /* VG_(ok_to_discard_translations) */
36 // The core/tool dictionary of functions (initially zeroed, as we want it)
37 VgToolInterface VG_(tdict);
39 /*--------------------------------------------------------------------*/
40 /* Setting basic functions */
42 void VG_(basic_tool_funcs)(
43 void(*post_clo_init)(void),
44 IRSB*(*instrument)(VgCallbackClosure*, IRSB*,
45 const VexGuestLayout*, const VexGuestExtents*,
46 const VexArchInfo*, IRType, IRType),
47 void(*fini)(Int)
50 VG_(tdict).tool_post_clo_init = post_clo_init;
51 VG_(tdict).tool_instrument = instrument;
52 VG_(tdict).tool_fini = fini;
56 /*--------------------------------------------------------------------*/
57 /* Setting details */
59 /* Init with default values. */
60 VgDetails VG_(details) = {
61 .name = NULL,
62 .version = NULL,
63 .description = NULL,
64 .copyright_author = NULL,
65 .bug_reports_to = NULL,
66 .avg_translation_sizeB = VG_DEFAULT_TRANS_SIZEB,
69 /* Use macro because they're so repetitive */
70 #define DETAILS(type, detail) \
71 extern void VG_(details_##detail)(type detail) \
72 { \
73 VG_(details).detail = detail; \
76 DETAILS(const HChar*, name)
77 DETAILS(const HChar*, version)
78 DETAILS(const HChar*, description)
79 DETAILS(const HChar*, copyright_author)
80 DETAILS(const HChar*, bug_reports_to)
81 DETAILS(UInt, avg_translation_sizeB)
84 /*--------------------------------------------------------------------*/
85 /* Setting needs */
87 VgNeeds VG_(needs) = {
88 .core_errors = False,
89 .tool_errors = False,
90 .libc_freeres = False,
91 .cxx_freeres = False,
92 .superblock_discards = False,
93 .command_line_options = False,
94 .client_requests = False,
95 .syscall_wrapper = False,
96 .sanity_checks = False,
97 .print_stats = False,
98 .info_location = False,
99 .var_info = False,
100 .malloc_replacement = False,
101 .xml_output = False,
102 .final_IR_tidy_pass = False
105 /* static */
106 Bool VG_(finish_needs_init)(const HChar** failmsg)
108 Bool any_new_mem_stack_N, any_new_mem_stack_N_w_ECU;
109 Bool any_new_mem_stack_w_conflicting_otags;
110 Bool any_die_mem_stack_N;
112 #define CHECK_NOT(var, value) \
113 if ((var)==(value)) { \
114 *failmsg = "Tool error: '" #var "' not initialised\n"; \
115 return False; \
118 /* Ones that must be set */
119 CHECK_NOT(VG_(details).name, NULL);
120 /* Nb: .version can be NULL */
121 CHECK_NOT(VG_(details).description, NULL);
122 CHECK_NOT(VG_(details).copyright_author, NULL);
123 CHECK_NOT(VG_(details).bug_reports_to, NULL);
125 /* Check that new_mem_stack is defined if any new_mem_stack_N
126 are. */
127 any_new_mem_stack_N
128 = VG_(tdict).track_new_mem_stack_4 ||
129 VG_(tdict).track_new_mem_stack_8 ||
130 VG_(tdict).track_new_mem_stack_12 ||
131 VG_(tdict).track_new_mem_stack_16 ||
132 VG_(tdict).track_new_mem_stack_32 ||
133 VG_(tdict).track_new_mem_stack_112 ||
134 VG_(tdict).track_new_mem_stack_128 ||
135 VG_(tdict).track_new_mem_stack_144 ||
136 VG_(tdict).track_new_mem_stack_160;
138 if (any_new_mem_stack_N && ! VG_(tdict).track_new_mem_stack) {
139 *failmsg = "Tool error: one of the specialised 'new_mem_stack_N'\n"
140 " events tracked, but not the generic 'new_mem_stack' one.\n"
141 " 'new_mem_stack' should be defined\n";
142 return False;
145 /* Check that new_mem_stack_w_ECU is defined if any
146 new_mem_stack_N_w_ECU are. */
147 any_new_mem_stack_N_w_ECU
148 = VG_(tdict).track_new_mem_stack_4_w_ECU ||
149 VG_(tdict).track_new_mem_stack_8_w_ECU ||
150 VG_(tdict).track_new_mem_stack_12_w_ECU ||
151 VG_(tdict).track_new_mem_stack_16_w_ECU ||
152 VG_(tdict).track_new_mem_stack_32_w_ECU ||
153 VG_(tdict).track_new_mem_stack_112_w_ECU ||
154 VG_(tdict).track_new_mem_stack_128_w_ECU ||
155 VG_(tdict).track_new_mem_stack_144_w_ECU ||
156 VG_(tdict).track_new_mem_stack_160_w_ECU;
158 if (any_new_mem_stack_N_w_ECU && ! VG_(tdict).track_new_mem_stack_w_ECU) {
159 *failmsg = "Tool error: one of the specialised 'new_mem_stack_N_w_ECU'\n"
160 " events tracked, but not the generic 'new_mem_stack_w_ECU' one.\n"
161 " 'new_mem_stack_w_ECU' should be defined\n";
162 return False;
165 /* Check that in no cases are both with- and without-otag versions of the
166 same new_mem_stack_ function defined. */
167 any_new_mem_stack_w_conflicting_otags
168 = (VG_(tdict).track_new_mem_stack_4 && VG_(tdict).track_new_mem_stack_4_w_ECU) ||
169 (VG_(tdict).track_new_mem_stack_8 && VG_(tdict).track_new_mem_stack_8_w_ECU) ||
170 (VG_(tdict).track_new_mem_stack_12 && VG_(tdict).track_new_mem_stack_12_w_ECU) ||
171 (VG_(tdict).track_new_mem_stack_16 && VG_(tdict).track_new_mem_stack_16_w_ECU) ||
172 (VG_(tdict).track_new_mem_stack_32 && VG_(tdict).track_new_mem_stack_32_w_ECU) ||
173 (VG_(tdict).track_new_mem_stack_112 && VG_(tdict).track_new_mem_stack_112_w_ECU) ||
174 (VG_(tdict).track_new_mem_stack_128 && VG_(tdict).track_new_mem_stack_128_w_ECU) ||
175 (VG_(tdict).track_new_mem_stack_144 && VG_(tdict).track_new_mem_stack_144_w_ECU) ||
176 (VG_(tdict).track_new_mem_stack_160 && VG_(tdict).track_new_mem_stack_160_w_ECU) ||
177 (VG_(tdict).track_new_mem_stack && VG_(tdict).track_new_mem_stack_w_ECU);
179 if (any_new_mem_stack_w_conflicting_otags) {
180 *failmsg = "Tool error: tool supplies both a 'new_mem_stack_N' and a\n"
181 " 'new_mem_stack_N_w_ECU' function for some N (or none),\n"
182 " but you can only have one or the other (not both)\n";
183 return False;
185 VG_(tdict).any_new_mem_stack
186 = VG_(tdict).track_new_mem_stack || VG_(tdict).track_new_mem_stack_w_ECU
187 || any_new_mem_stack_N || any_new_mem_stack_N_w_ECU;
189 /* Check that die_mem_stack is defined if any die_mem_stack_N
190 are. */
191 any_die_mem_stack_N
192 = VG_(tdict).track_die_mem_stack_4 ||
193 VG_(tdict).track_die_mem_stack_8 ||
194 VG_(tdict).track_die_mem_stack_12 ||
195 VG_(tdict).track_die_mem_stack_16 ||
196 VG_(tdict).track_die_mem_stack_32 ||
197 VG_(tdict).track_die_mem_stack_112 ||
198 VG_(tdict).track_die_mem_stack_128 ||
199 VG_(tdict).track_die_mem_stack_144 ||
200 VG_(tdict).track_die_mem_stack_160;
202 if (any_die_mem_stack_N && ! VG_(tdict).track_die_mem_stack) {
203 *failmsg = "Tool error: one of the specialised 'die_mem_stack_N'\n"
204 " events tracked, but not the generic 'die_mem_stack' one.\n"
205 " 'die_mem_stack' should be defined\n";
206 return False;
208 VG_(tdict).any_die_mem_stack
209 = VG_(tdict).track_die_mem_stack || any_die_mem_stack_N;
211 return True;
213 #undef CHECK_NOT
216 /* Use macro because they're so repetitive */
217 #define NEEDS(need) \
218 extern void VG_(needs_##need)(void) \
220 VG_(needs).need = True; \
223 // These ones don't require any tool-supplied functions
224 NEEDS(libc_freeres)
225 NEEDS(cxx_freeres)
226 NEEDS(core_errors)
227 NEEDS(var_info)
229 void VG_(needs_superblock_discards)(
230 void (*discard)(Addr, VexGuestExtents)
233 VG_(needs).superblock_discards = True;
234 VG_(tdict).tool_discard_superblock_info = discard;
237 void VG_(needs_tool_errors)(
238 Bool (*eq) (VgRes, const Error*, const Error*),
239 void (*before_pp) (const Error*),
240 void (*pp) (const Error*),
241 Bool show_TIDs,
242 UInt (*update) (const Error*),
243 Bool (*recog) (const HChar*, Supp*),
244 Bool (*read_extra) (Int, HChar**, SizeT*, Int*, Supp*),
245 Bool (*matches) (const Error*, const Supp*),
246 const HChar* (*name) (const Error*),
247 SizeT (*get_xtra_si)(const Error*,/*OUT*/HChar*,Int),
248 SizeT (*print_xtra_su)(const Supp*,/*OUT*/HChar*,Int),
249 void (*update_xtra_su)(const Error*, const Supp*)
252 VG_(needs).tool_errors = True;
253 VG_(tdict).tool_eq_Error = eq;
254 VG_(tdict).tool_before_pp_Error = before_pp;
255 VG_(tdict).tool_pp_Error = pp;
256 VG_(tdict).tool_show_ThreadIDs_for_errors = show_TIDs;
257 VG_(tdict).tool_update_extra = update;
258 VG_(tdict).tool_recognised_suppression = recog;
259 VG_(tdict).tool_read_extra_suppression_info = read_extra;
260 VG_(tdict).tool_error_matches_suppression = matches;
261 VG_(tdict).tool_get_error_name = name;
262 VG_(tdict).tool_get_extra_suppression_info = get_xtra_si;
263 VG_(tdict).tool_print_extra_suppression_use = print_xtra_su;
264 VG_(tdict).tool_update_extra_suppression_use = update_xtra_su;
267 void VG_(needs_command_line_options)(
268 Bool (*process)(const HChar*),
269 void (*usage)(void),
270 void (*debug_usage)(void)
273 VG_(needs).command_line_options = True;
274 VG_(tdict).tool_process_cmd_line_option = process;
275 VG_(tdict).tool_print_usage = usage;
276 VG_(tdict).tool_print_debug_usage = debug_usage;
279 /* The tool's function for handling client requests. */
280 static Bool (*tool_handle_client_request_func)(ThreadId, UWord *, UWord *);
282 static Bool wrap_tool_handle_client_request(ThreadId tid, UWord *arg1,
283 UWord *arg2)
285 Bool ret;
286 VG_(ok_to_discard_translations) = True;
287 ret = tool_handle_client_request_func(tid, arg1, arg2);
288 VG_(ok_to_discard_translations) = False;
289 return ret;
292 void VG_(needs_client_requests)(
293 Bool (*handle)(ThreadId, UWord*, UWord*)
296 VG_(needs).client_requests = True;
297 tool_handle_client_request_func = handle; /* Stash away */
298 /* Register the wrapper function */
299 VG_(tdict).tool_handle_client_request = wrap_tool_handle_client_request;
302 void VG_(needs_syscall_wrapper)(
303 void(*pre) (ThreadId, UInt, UWord*, UInt),
304 void(*post)(ThreadId, UInt, UWord*, UInt, SysRes res)
307 VG_(needs).syscall_wrapper = True;
308 VG_(tdict).tool_pre_syscall = pre;
309 VG_(tdict).tool_post_syscall = post;
312 void VG_(needs_sanity_checks)(
313 Bool(*cheap)(void),
314 Bool(*expen)(void)
317 VG_(needs).sanity_checks = True;
318 VG_(tdict).tool_cheap_sanity_check = cheap;
319 VG_(tdict).tool_expensive_sanity_check = expen;
322 void VG_(needs_print_stats) (
323 void (*print_stats)(void)
326 VG_(needs).print_stats = True;
327 VG_(tdict).tool_print_stats = print_stats;
330 void VG_(needs_info_location) (
331 void (*info_location)(DiEpoch, Addr)
334 VG_(needs).info_location = True;
335 VG_(tdict).tool_info_location = info_location;
338 void VG_(needs_malloc_replacement)(
339 void* (*malloc) ( ThreadId, SizeT ),
340 void* (*__builtin_new) ( ThreadId, SizeT ),
341 void* (*__builtin_vec_new) ( ThreadId, SizeT ),
342 void* (*memalign) ( ThreadId, SizeT, SizeT ),
343 void* (*calloc) ( ThreadId, SizeT, SizeT ),
344 void (*free) ( ThreadId, void* ),
345 void (*__builtin_delete) ( ThreadId, void* ),
346 void (*__builtin_vec_delete) ( ThreadId, void* ),
347 void* (*realloc) ( ThreadId, void*, SizeT ),
348 SizeT (*malloc_usable_size) ( ThreadId, void* ),
349 SizeT client_malloc_redzone_szB
352 VG_(needs).malloc_replacement = True;
353 VG_(tdict).tool_malloc = malloc;
354 VG_(tdict).tool___builtin_new = __builtin_new;
355 VG_(tdict).tool___builtin_vec_new = __builtin_vec_new;
356 VG_(tdict).tool_memalign = memalign;
357 VG_(tdict).tool_calloc = calloc;
358 VG_(tdict).tool_free = free;
359 VG_(tdict).tool___builtin_delete = __builtin_delete;
360 VG_(tdict).tool___builtin_vec_delete = __builtin_vec_delete;
361 VG_(tdict).tool_realloc = realloc;
362 VG_(tdict).tool_malloc_usable_size = malloc_usable_size;
363 VG_(tdict).tool_client_redzone_szB = client_malloc_redzone_szB;
366 void VG_(needs_xml_output)( void )
368 VG_(needs).xml_output = True;
371 void VG_(needs_final_IR_tidy_pass)(
372 IRSB*(*final_tidy)(IRSB*)
375 VG_(needs).final_IR_tidy_pass = True;
376 VG_(tdict).tool_final_IR_tidy_pass = final_tidy;
379 /*--------------------------------------------------------------------*/
380 /* Tracked events. Digit 'n' on DEFn is the REGPARMness. */
382 #define DEF0(fn, args...) \
383 void VG_(fn)(void(*f)(args)) { \
384 VG_(tdict).fn = f; \
387 #define DEF1(fn, args...) \
388 void VG_(fn)(VG_REGPARM(1) void(*f)(args)) { \
389 VG_(tdict).fn = f; \
392 #define DEF2(fn, args...) \
393 void VG_(fn)(VG_REGPARM(2) void(*f)(args)) { \
394 VG_(tdict).fn = f; \
397 DEF0(track_new_mem_startup, Addr, SizeT, Bool, Bool, Bool, ULong)
398 DEF0(track_new_mem_stack_signal, Addr, SizeT, UInt)
399 DEF0(track_new_mem_brk, Addr, SizeT, UInt)
400 DEF0(track_new_mem_mmap, Addr, SizeT, Bool, Bool, Bool, ULong)
402 DEF0(track_copy_mem_remap, Addr, Addr, SizeT)
403 DEF0(track_change_mem_mprotect, Addr, SizeT, Bool, Bool, Bool)
404 DEF0(track_die_mem_stack_signal, Addr, SizeT)
405 DEF0(track_die_mem_brk, Addr, SizeT)
406 DEF0(track_die_mem_munmap, Addr, SizeT)
408 DEF2(track_new_mem_stack_4_w_ECU, Addr, UInt)
409 DEF2(track_new_mem_stack_8_w_ECU, Addr, UInt)
410 DEF2(track_new_mem_stack_12_w_ECU, Addr, UInt)
411 DEF2(track_new_mem_stack_16_w_ECU, Addr, UInt)
412 DEF2(track_new_mem_stack_32_w_ECU, Addr, UInt)
413 DEF2(track_new_mem_stack_112_w_ECU, Addr, UInt)
414 DEF2(track_new_mem_stack_128_w_ECU, Addr, UInt)
415 DEF2(track_new_mem_stack_144_w_ECU, Addr, UInt)
416 DEF2(track_new_mem_stack_160_w_ECU, Addr, UInt)
417 DEF0(track_new_mem_stack_w_ECU, Addr, SizeT, UInt)
419 DEF1(track_new_mem_stack_4, Addr)
420 DEF1(track_new_mem_stack_8, Addr)
421 DEF1(track_new_mem_stack_12, Addr)
422 DEF1(track_new_mem_stack_16, Addr)
423 DEF1(track_new_mem_stack_32, Addr)
424 DEF1(track_new_mem_stack_112, Addr)
425 DEF1(track_new_mem_stack_128, Addr)
426 DEF1(track_new_mem_stack_144, Addr)
427 DEF1(track_new_mem_stack_160, Addr)
428 DEF0(track_new_mem_stack, Addr, SizeT)
430 DEF1(track_die_mem_stack_4, Addr)
431 DEF1(track_die_mem_stack_8, Addr)
432 DEF1(track_die_mem_stack_12, Addr)
433 DEF1(track_die_mem_stack_16, Addr)
434 DEF1(track_die_mem_stack_32, Addr)
435 DEF1(track_die_mem_stack_112, Addr)
436 DEF1(track_die_mem_stack_128, Addr)
437 DEF1(track_die_mem_stack_144, Addr)
438 DEF1(track_die_mem_stack_160, Addr)
439 DEF0(track_die_mem_stack, Addr, SizeT)
441 DEF0(track_ban_mem_stack, Addr, SizeT)
443 DEF0(track_pre_mem_read, CorePart, ThreadId, const HChar*, Addr, SizeT)
444 DEF0(track_pre_mem_read_asciiz, CorePart, ThreadId, const HChar*, Addr)
445 DEF0(track_pre_mem_write, CorePart, ThreadId, const HChar*, Addr, SizeT)
446 DEF0(track_post_mem_write, CorePart, ThreadId, Addr, SizeT)
448 DEF0(track_pre_reg_read, CorePart, ThreadId, const HChar*, PtrdiffT, SizeT)
449 DEF0(track_post_reg_write, CorePart, ThreadId, PtrdiffT, SizeT)
451 DEF0(track_copy_mem_to_reg, CorePart, ThreadId, Addr, PtrdiffT, SizeT)
452 DEF0(track_copy_reg_to_mem, CorePart, ThreadId, PtrdiffT, Addr, SizeT)
454 DEF0(track_post_reg_write_clientcall_return, ThreadId, PtrdiffT, SizeT, Addr)
456 DEF0(track_start_client_code, ThreadId, ULong)
457 DEF0(track_stop_client_code, ThreadId, ULong)
459 DEF0(track_pre_thread_ll_create, ThreadId, ThreadId)
460 DEF0(track_pre_thread_first_insn, ThreadId)
461 DEF0(track_pre_thread_ll_exit, ThreadId)
463 DEF0(track_pre_deliver_signal, ThreadId, Int sigNo, Bool)
464 DEF0(track_post_deliver_signal, ThreadId, Int sigNo)
466 /*--------------------------------------------------------------------*/
467 /*--- end ---*/
468 /*--------------------------------------------------------------------*/