1
2 /*--------------------------------------------------------------------*/
3 /*--- Stuff relating to tool data structures. ---*/
4 /*--- m_tooliface.c ---*/
5 /*--------------------------------------------------------------------*/
6
7 /*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
11 Copyright (C) 2000-2013 Nicholas Nethercote
12 njn@valgrind.org
13
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.
18
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.
23
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.
28
29 The GNU General Public License is contained in the file COPYING.
30 */
31
32 #include "pub_core_basics.h"
33 #include "pub_core_tooliface.h"
34
35 // The core/tool dictionary of functions (initially zeroed, as we want it)
36 VgToolInterface VG_(tdict);
37
38 /*--------------------------------------------------------------------*/
39 /* Setting basic functions */
40
VG_(basic_tool_funcs)41 void VG_(basic_tool_funcs)(
42 void(*post_clo_init)(void),
43 IRSB*(*instrument)(VgCallbackClosure*, IRSB*,
44 VexGuestLayout*, VexGuestExtents*, VexArchInfo*,
45 IRType, IRType),
46 void(*fini)(Int)
47 )
48 {
49 VG_(tdict).tool_post_clo_init = post_clo_init;
50 VG_(tdict).tool_instrument = instrument;
51 VG_(tdict).tool_fini = fini;
52 }
53
54
55 /*--------------------------------------------------------------------*/
56 /* Setting details */
57
58 /* Init with default values. */
59 VgDetails VG_(details) = {
60 .name = NULL,
61 .version = NULL,
62 .description = NULL,
63 .copyright_author = NULL,
64 .bug_reports_to = NULL,
65 .avg_translation_sizeB = VG_DEFAULT_TRANS_SIZEB,
66 };
67
68 /* Use macro because they're so repetitive */
69 #define DETAILS(type, detail) \
70 extern void VG_(details_##detail)(type detail) \
71 { \
72 VG_(details).detail = detail; \
73 }
74
75 DETAILS(const HChar*, name)
76 DETAILS(const HChar*, version)
77 DETAILS(const HChar*, description)
78 DETAILS(const HChar*, copyright_author)
79 DETAILS(const HChar*, bug_reports_to)
80 DETAILS(UInt, avg_translation_sizeB)
81
82
83 /*--------------------------------------------------------------------*/
84 /* Setting needs */
85
86 VgNeeds VG_(needs) = {
87 .core_errors = False,
88 .tool_errors = False,
89 .libc_freeres = False,
90 .superblock_discards = False,
91 .command_line_options = False,
92 .client_requests = False,
93 .syscall_wrapper = False,
94 .sanity_checks = False,
95 .print_stats = False,
96 .info_location = False,
97 .var_info = False,
98 .malloc_replacement = False,
99 .xml_output = False,
100 .final_IR_tidy_pass = False
101 };
102
103 /* static */
VG_(sanity_check_needs)104 Bool VG_(sanity_check_needs)(const HChar** failmsg)
105 {
106 Bool any_new_mem_stack_N, any_new_mem_stack_N_w_ECU;
107 Bool any_new_mem_stack_w_conflicting_otags;
108 Bool any_die_mem_stack_N;
109
110 #define CHECK_NOT(var, value) \
111 if ((var)==(value)) { \
112 *failmsg = "Tool error: '" #var "' not initialised\n"; \
113 return False; \
114 }
115
116 /* Ones that must be set */
117 CHECK_NOT(VG_(details).name, NULL);
118 /* Nb: .version can be NULL */
119 CHECK_NOT(VG_(details).description, NULL);
120 CHECK_NOT(VG_(details).copyright_author, NULL);
121 CHECK_NOT(VG_(details).bug_reports_to, NULL);
122
123 /* Check that new_mem_stack is defined if any new_mem_stack_N
124 are. */
125 any_new_mem_stack_N
126 = VG_(tdict).track_new_mem_stack_4 ||
127 VG_(tdict).track_new_mem_stack_8 ||
128 VG_(tdict).track_new_mem_stack_12 ||
129 VG_(tdict).track_new_mem_stack_16 ||
130 VG_(tdict).track_new_mem_stack_32 ||
131 VG_(tdict).track_new_mem_stack_112 ||
132 VG_(tdict).track_new_mem_stack_128 ||
133 VG_(tdict).track_new_mem_stack_144 ||
134 VG_(tdict).track_new_mem_stack_160;
135
136 if (any_new_mem_stack_N && ! VG_(tdict).track_new_mem_stack) {
137 *failmsg = "Tool error: one of the specialised 'new_mem_stack_N'\n"
138 " events tracked, but not the generic 'new_mem_stack' one.\n"
139 " 'new_mem_stack' should be defined\n";
140 return False;
141 }
142
143 /* Check that new_mem_stack_w_ECU is defined if any
144 new_mem_stack_N_w_ECU are. */
145 any_new_mem_stack_N_w_ECU
146 = VG_(tdict).track_new_mem_stack_4_w_ECU ||
147 VG_(tdict).track_new_mem_stack_8_w_ECU ||
148 VG_(tdict).track_new_mem_stack_12_w_ECU ||
149 VG_(tdict).track_new_mem_stack_16_w_ECU ||
150 VG_(tdict).track_new_mem_stack_32_w_ECU ||
151 VG_(tdict).track_new_mem_stack_112_w_ECU ||
152 VG_(tdict).track_new_mem_stack_128_w_ECU ||
153 VG_(tdict).track_new_mem_stack_144_w_ECU ||
154 VG_(tdict).track_new_mem_stack_160_w_ECU;
155
156 if (any_new_mem_stack_N_w_ECU && ! VG_(tdict).track_new_mem_stack_w_ECU) {
157 *failmsg = "Tool error: one of the specialised 'new_mem_stack_N_w_ECU'\n"
158 " events tracked, but not the generic 'new_mem_stack_w_ECU' one.\n"
159 " 'new_mem_stack_w_ECU' should be defined\n";
160 return False;
161 }
162
163 /* Check that in no cases are both with- and without-otag versions of the
164 same new_mem_stack_ function defined. */
165 any_new_mem_stack_w_conflicting_otags
166 = (VG_(tdict).track_new_mem_stack_4 && VG_(tdict).track_new_mem_stack_4_w_ECU) ||
167 (VG_(tdict).track_new_mem_stack_8 && VG_(tdict).track_new_mem_stack_8_w_ECU) ||
168 (VG_(tdict).track_new_mem_stack_12 && VG_(tdict).track_new_mem_stack_12_w_ECU) ||
169 (VG_(tdict).track_new_mem_stack_16 && VG_(tdict).track_new_mem_stack_16_w_ECU) ||
170 (VG_(tdict).track_new_mem_stack_32 && VG_(tdict).track_new_mem_stack_32_w_ECU) ||
171 (VG_(tdict).track_new_mem_stack_112 && VG_(tdict).track_new_mem_stack_112_w_ECU) ||
172 (VG_(tdict).track_new_mem_stack_128 && VG_(tdict).track_new_mem_stack_128_w_ECU) ||
173 (VG_(tdict).track_new_mem_stack_144 && VG_(tdict).track_new_mem_stack_144_w_ECU) ||
174 (VG_(tdict).track_new_mem_stack_160 && VG_(tdict).track_new_mem_stack_160_w_ECU) ||
175 (VG_(tdict).track_new_mem_stack && VG_(tdict).track_new_mem_stack_w_ECU);
176
177 if (any_new_mem_stack_w_conflicting_otags) {
178 *failmsg = "Tool error: tool supplies both a 'new_mem_stack_N' and a\n"
179 " 'new_mem_stack_N_w_ECU' function for some N (or none),\n"
180 " but you can only have one or the other (not both)\n";
181 return False;
182 }
183
184 /* Check that die_mem_stack is defined if any die_mem_stack_N
185 are. */
186 any_die_mem_stack_N
187 = VG_(tdict).track_die_mem_stack_4 ||
188 VG_(tdict).track_die_mem_stack_8 ||
189 VG_(tdict).track_die_mem_stack_12 ||
190 VG_(tdict).track_die_mem_stack_16 ||
191 VG_(tdict).track_die_mem_stack_32 ||
192 VG_(tdict).track_die_mem_stack_112 ||
193 VG_(tdict).track_die_mem_stack_128 ||
194 VG_(tdict).track_die_mem_stack_144 ||
195 VG_(tdict).track_die_mem_stack_160;
196
197 if (any_die_mem_stack_N && ! VG_(tdict).track_die_mem_stack) {
198 *failmsg = "Tool error: one of the specialised 'die_mem_stack_N'\n"
199 " events tracked, but not the generic 'die_mem_stack' one.\n"
200 " 'die_mem_stack' should be defined\n";
201 return False;
202 }
203
204 return True;
205
206 #undef CHECK_NOT
207 }
208
209 /* Use macro because they're so repetitive */
210 #define NEEDS(need) \
211 extern void VG_(needs_##need)(void) \
212 { \
213 VG_(needs).need = True; \
214 }
215
216 // These ones don't require any tool-supplied functions
217 NEEDS(libc_freeres)
NEEDS(core_errors)218 NEEDS(core_errors)
219 NEEDS(var_info)
220
221 void VG_(needs_superblock_discards)(
222 void (*discard)(Addr64, VexGuestExtents)
223 )
224 {
225 VG_(needs).superblock_discards = True;
226 VG_(tdict).tool_discard_superblock_info = discard;
227 }
228
VG_(needs_tool_errors)229 void VG_(needs_tool_errors)(
230 Bool (*eq) (VgRes, Error*, Error*),
231 void (*before_pp) (Error*),
232 void (*pp) (Error*),
233 Bool show_TIDs,
234 UInt (*update) (Error*),
235 Bool (*recog) (const HChar*, Supp*),
236 Bool (*read_extra) (Int, HChar**, SizeT*, Int*, Supp*),
237 Bool (*matches) (Error*, Supp*),
238 const HChar* (*name) (Error*),
239 Bool (*get_xtra_si)(Error*,/*OUT*/HChar*,Int),
240 Bool (*print_xtra_su)(Supp*,/*OUT*/HChar*,Int),
241 void (*update_xtra_su)(Error*, Supp*)
242 )
243 {
244 VG_(needs).tool_errors = True;
245 VG_(tdict).tool_eq_Error = eq;
246 VG_(tdict).tool_before_pp_Error = before_pp;
247 VG_(tdict).tool_pp_Error = pp;
248 VG_(tdict).tool_show_ThreadIDs_for_errors = show_TIDs;
249 VG_(tdict).tool_update_extra = update;
250 VG_(tdict).tool_recognised_suppression = recog;
251 VG_(tdict).tool_read_extra_suppression_info = read_extra;
252 VG_(tdict).tool_error_matches_suppression = matches;
253 VG_(tdict).tool_get_error_name = name;
254 VG_(tdict).tool_get_extra_suppression_info = get_xtra_si;
255 VG_(tdict).tool_print_extra_suppression_use = print_xtra_su;
256 VG_(tdict).tool_update_extra_suppression_use = update_xtra_su;
257 }
258
VG_(needs_command_line_options)259 void VG_(needs_command_line_options)(
260 Bool (*process)(const HChar*),
261 void (*usage)(void),
262 void (*debug_usage)(void)
263 )
264 {
265 VG_(needs).command_line_options = True;
266 VG_(tdict).tool_process_cmd_line_option = process;
267 VG_(tdict).tool_print_usage = usage;
268 VG_(tdict).tool_print_debug_usage = debug_usage;
269 }
270
VG_(needs_client_requests)271 void VG_(needs_client_requests)(
272 Bool (*handle)(ThreadId, UWord*, UWord*)
273 )
274 {
275 VG_(needs).client_requests = True;
276 VG_(tdict).tool_handle_client_request = handle;
277 }
278
VG_(needs_syscall_wrapper)279 void VG_(needs_syscall_wrapper)(
280 void(*pre) (ThreadId, UInt, UWord*, UInt),
281 void(*post)(ThreadId, UInt, UWord*, UInt, SysRes res)
282 )
283 {
284 VG_(needs).syscall_wrapper = True;
285 VG_(tdict).tool_pre_syscall = pre;
286 VG_(tdict).tool_post_syscall = post;
287 }
288
VG_(needs_sanity_checks)289 void VG_(needs_sanity_checks)(
290 Bool(*cheap)(void),
291 Bool(*expen)(void)
292 )
293 {
294 VG_(needs).sanity_checks = True;
295 VG_(tdict).tool_cheap_sanity_check = cheap;
296 VG_(tdict).tool_expensive_sanity_check = expen;
297 }
298
VG_(needs_print_stats)299 void VG_(needs_print_stats) (
300 void (*print_stats)(void)
301 )
302 {
303 VG_(needs).print_stats = True;
304 VG_(tdict).tool_print_stats = print_stats;
305 }
306
VG_(needs_info_location)307 void VG_(needs_info_location) (
308 void (*info_location)(Addr)
309 )
310 {
311 VG_(needs).info_location = True;
312 VG_(tdict).tool_info_location = info_location;
313 }
314
VG_(needs_malloc_replacement)315 void VG_(needs_malloc_replacement)(
316 void* (*malloc) ( ThreadId, SizeT ),
317 void* (*__builtin_new) ( ThreadId, SizeT ),
318 void* (*__builtin_vec_new) ( ThreadId, SizeT ),
319 void* (*memalign) ( ThreadId, SizeT, SizeT ),
320 void* (*calloc) ( ThreadId, SizeT, SizeT ),
321 void (*free) ( ThreadId, void* ),
322 void (*__builtin_delete) ( ThreadId, void* ),
323 void (*__builtin_vec_delete) ( ThreadId, void* ),
324 void* (*realloc) ( ThreadId, void*, SizeT ),
325 SizeT (*malloc_usable_size) ( ThreadId, void* ),
326 SizeT client_malloc_redzone_szB
327 )
328 {
329 VG_(needs).malloc_replacement = True;
330 VG_(tdict).tool_malloc = malloc;
331 VG_(tdict).tool___builtin_new = __builtin_new;
332 VG_(tdict).tool___builtin_vec_new = __builtin_vec_new;
333 VG_(tdict).tool_memalign = memalign;
334 VG_(tdict).tool_calloc = calloc;
335 VG_(tdict).tool_free = free;
336 VG_(tdict).tool___builtin_delete = __builtin_delete;
337 VG_(tdict).tool___builtin_vec_delete = __builtin_vec_delete;
338 VG_(tdict).tool_realloc = realloc;
339 VG_(tdict).tool_malloc_usable_size = malloc_usable_size;
340 VG_(tdict).tool_client_redzone_szB = client_malloc_redzone_szB;
341 }
342
VG_(needs_xml_output)343 void VG_(needs_xml_output)( void )
344 {
345 VG_(needs).xml_output = True;
346 }
347
VG_(needs_final_IR_tidy_pass)348 void VG_(needs_final_IR_tidy_pass)(
349 IRSB*(*final_tidy)(IRSB*)
350 )
351 {
352 VG_(needs).final_IR_tidy_pass = True;
353 VG_(tdict).tool_final_IR_tidy_pass = final_tidy;
354 }
355
356 /*--------------------------------------------------------------------*/
357 /* Tracked events. Digit 'n' on DEFn is the REGPARMness. */
358
359 #define DEF0(fn, args...) \
360 void VG_(fn)(void(*f)(args)) { \
361 VG_(tdict).fn = f; \
362 }
363
364 #define DEF1(fn, args...) \
365 void VG_(fn)(VG_REGPARM(1) void(*f)(args)) { \
366 VG_(tdict).fn = f; \
367 }
368
369 #define DEF2(fn, args...) \
370 void VG_(fn)(VG_REGPARM(2) void(*f)(args)) { \
371 VG_(tdict).fn = f; \
372 }
373
374 DEF0(track_new_mem_startup, Addr, SizeT, Bool, Bool, Bool, ULong)
375 DEF0(track_new_mem_stack_signal, Addr, SizeT, UInt)
376 DEF0(track_new_mem_brk, Addr, SizeT, UInt)
377 DEF0(track_new_mem_mmap, Addr, SizeT, Bool, Bool, Bool, ULong)
378
379 DEF0(track_copy_mem_remap, Addr, Addr, SizeT)
380 DEF0(track_change_mem_mprotect, Addr, SizeT, Bool, Bool, Bool)
381 DEF0(track_die_mem_stack_signal, Addr, SizeT)
382 DEF0(track_die_mem_brk, Addr, SizeT)
383 DEF0(track_die_mem_munmap, Addr, SizeT)
384
385 DEF2(track_new_mem_stack_4_w_ECU, Addr, UInt)
386 DEF2(track_new_mem_stack_8_w_ECU, Addr, UInt)
387 DEF2(track_new_mem_stack_12_w_ECU, Addr, UInt)
388 DEF2(track_new_mem_stack_16_w_ECU, Addr, UInt)
389 DEF2(track_new_mem_stack_32_w_ECU, Addr, UInt)
390 DEF2(track_new_mem_stack_112_w_ECU, Addr, UInt)
391 DEF2(track_new_mem_stack_128_w_ECU, Addr, UInt)
392 DEF2(track_new_mem_stack_144_w_ECU, Addr, UInt)
393 DEF2(track_new_mem_stack_160_w_ECU, Addr, UInt)
394 DEF0(track_new_mem_stack_w_ECU, Addr, SizeT, UInt)
395
396 DEF1(track_new_mem_stack_4, Addr)
397 DEF1(track_new_mem_stack_8, Addr)
398 DEF1(track_new_mem_stack_12, Addr)
399 DEF1(track_new_mem_stack_16, Addr)
400 DEF1(track_new_mem_stack_32, Addr)
401 DEF1(track_new_mem_stack_112, Addr)
402 DEF1(track_new_mem_stack_128, Addr)
403 DEF1(track_new_mem_stack_144, Addr)
404 DEF1(track_new_mem_stack_160, Addr)
405 DEF0(track_new_mem_stack, Addr, SizeT)
406
407 DEF1(track_die_mem_stack_4, Addr)
408 DEF1(track_die_mem_stack_8, Addr)
409 DEF1(track_die_mem_stack_12, Addr)
410 DEF1(track_die_mem_stack_16, Addr)
411 DEF1(track_die_mem_stack_32, Addr)
412 DEF1(track_die_mem_stack_112, Addr)
413 DEF1(track_die_mem_stack_128, Addr)
414 DEF1(track_die_mem_stack_144, Addr)
415 DEF1(track_die_mem_stack_160, Addr)
416 DEF0(track_die_mem_stack, Addr, SizeT)
417
418 DEF0(track_ban_mem_stack, Addr, SizeT)
419
420 DEF0(track_pre_mem_read, CorePart, ThreadId, const HChar*, Addr, SizeT)
421 DEF0(track_pre_mem_read_asciiz, CorePart, ThreadId, const HChar*, Addr)
422 DEF0(track_pre_mem_write, CorePart, ThreadId, const HChar*, Addr, SizeT)
423 DEF0(track_post_mem_write, CorePart, ThreadId, Addr, SizeT)
424
425 DEF0(track_pre_reg_read, CorePart, ThreadId, const HChar*, PtrdiffT, SizeT)
426 DEF0(track_post_reg_write, CorePart, ThreadId, PtrdiffT, SizeT)
427
428 DEF0(track_post_reg_write_clientcall_return, ThreadId, PtrdiffT, SizeT, Addr)
429
430 DEF0(track_start_client_code, ThreadId, ULong)
431 DEF0(track_stop_client_code, ThreadId, ULong)
432
433 DEF0(track_pre_thread_ll_create, ThreadId, ThreadId)
434 DEF0(track_pre_thread_first_insn, ThreadId)
435 DEF0(track_pre_thread_ll_exit, ThreadId)
436
437 DEF0(track_pre_deliver_signal, ThreadId, Int sigNo, Bool)
438 DEF0(track_post_deliver_signal, ThreadId, Int sigNo)
439
440 /*--------------------------------------------------------------------*/
441 /*--- end ---*/
442 /*--------------------------------------------------------------------*/
443