2 /*--------------------------------------------------------------------*/
3 /*--- Stuff relating to tool data structures. ---*/
4 /*--- m_tooliface.c ---*/
5 /*--------------------------------------------------------------------*/
8 This file is part of Valgrind, a dynamic binary instrumentation
11 Copyright (C) 2000-2017 Nicholas Nethercote
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
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
),
50 VG_(tdict
).tool_post_clo_init
= post_clo_init
;
51 VG_(tdict
).tool_instrument
= instrument
;
52 VG_(tdict
).tool_fini
= fini
;
56 /*--------------------------------------------------------------------*/
59 /* Init with default values. */
60 VgDetails
VG_(details
) = {
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) \
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 /*--------------------------------------------------------------------*/
87 VgNeeds
VG_(needs
) = {
90 .libc_freeres
= False
,
92 .superblock_discards
= False
,
93 .command_line_options
= False
,
94 .client_requests
= False
,
95 .syscall_wrapper
= False
,
96 .sanity_checks
= False
,
98 .info_location
= False
,
100 .malloc_replacement
= False
,
102 .final_IR_tidy_pass
= False
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"; \
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
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";
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";
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";
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
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";
208 VG_(tdict
).any_die_mem_stack
209 = VG_(tdict
).track_die_mem_stack
|| any_die_mem_stack_N
;
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
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
*),
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
*),
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
,
286 VG_(ok_to_discard_translations
) = True
;
287 ret
= tool_handle_client_request_func(tid
, arg1
, arg2
);
288 VG_(ok_to_discard_translations
) = False
;
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
)(
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)) { \
387 #define DEF1(fn, args...) \
388 void VG_(fn)(VG_REGPARM(1) void(*f)(args)) { \
392 #define DEF2(fn, args...) \
393 void VG_(fn)(VG_REGPARM(2) void(*f)(args)) { \
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 /*--------------------------------------------------------------------*/
468 /*--------------------------------------------------------------------*/