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-2013 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"
35 // The core/tool dictionary of functions (initially zeroed, as we want it)
36 VgToolInterface
VG_(tdict
);
38 /*--------------------------------------------------------------------*/
39 /* Setting basic functions */
41 void VG_(basic_tool_funcs
)(
42 void(*post_clo_init
)(void),
43 IRSB
*(*instrument
)(VgCallbackClosure
*, IRSB
*,
44 const VexGuestLayout
*, const VexGuestExtents
*,
45 const VexArchInfo
*, IRType
, IRType
),
49 VG_(tdict
).tool_post_clo_init
= post_clo_init
;
50 VG_(tdict
).tool_instrument
= instrument
;
51 VG_(tdict
).tool_fini
= fini
;
55 /*--------------------------------------------------------------------*/
58 /* Init with default values. */
59 VgDetails
VG_(details
) = {
63 .copyright_author
= NULL
,
64 .bug_reports_to
= NULL
,
65 .avg_translation_sizeB
= VG_DEFAULT_TRANS_SIZEB
,
68 /* Use macro because they're so repetitive */
69 #define DETAILS(type, detail) \
70 extern void VG_(details_##detail)(type detail) \
72 VG_(details).detail = detail; \
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
)
83 /*--------------------------------------------------------------------*/
86 VgNeeds
VG_(needs
) = {
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
,
96 .info_location
= False
,
98 .malloc_replacement
= False
,
100 .final_IR_tidy_pass
= False
104 Bool
VG_(sanity_check_needs
)(const HChar
** failmsg
)
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
;
110 #define CHECK_NOT(var, value) \
111 if ((var)==(value)) { \
112 *failmsg = "Tool error: '" #var "' not initialised\n"; \
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
);
123 /* Check that new_mem_stack is defined if 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
;
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";
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
;
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";
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
);
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";
184 /* Check that die_mem_stack is defined if 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
;
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";
209 /* Use macro because they're so repetitive */
210 #define NEEDS(need) \
211 extern void VG_(needs_##need)(void) \
213 VG_(needs).need = True; \
216 // These ones don't require any tool-supplied functions
221 void VG_(needs_superblock_discards
)(
222 void (*discard
)(Addr64
, VexGuestExtents
)
225 VG_(needs
).superblock_discards
= True
;
226 VG_(tdict
).tool_discard_superblock_info
= discard
;
229 void VG_(needs_tool_errors
)(
230 Bool (*eq
) (VgRes
, const Error
*, const Error
*),
231 void (*before_pp
) (const Error
*),
232 void (*pp
) (const Error
*),
234 UInt (*update
) (const Error
*),
235 Bool (*recog
) (const HChar
*, Supp
*),
236 Bool (*read_extra
) (Int
, HChar
**, SizeT
*, Int
*, Supp
*),
237 Bool (*matches
) (const Error
*, const Supp
*),
238 const HChar
* (*name
) (const Error
*),
239 SizeT (*get_xtra_si
)(const Error
*,/*OUT*/HChar
*,Int
),
240 SizeT (*print_xtra_su
)(const Supp
*,/*OUT*/HChar
*,Int
),
241 void (*update_xtra_su
)(const Error
*, const Supp
*)
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
;
259 void VG_(needs_command_line_options
)(
260 Bool (*process
)(const HChar
*),
262 void (*debug_usage
)(void)
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
;
271 void VG_(needs_client_requests
)(
272 Bool (*handle
)(ThreadId
, UWord
*, UWord
*)
275 VG_(needs
).client_requests
= True
;
276 VG_(tdict
).tool_handle_client_request
= handle
;
279 void VG_(needs_syscall_wrapper
)(
280 void(*pre
) (ThreadId
, UInt
, UWord
*, UInt
),
281 void(*post
)(ThreadId
, UInt
, UWord
*, UInt
, SysRes res
)
284 VG_(needs
).syscall_wrapper
= True
;
285 VG_(tdict
).tool_pre_syscall
= pre
;
286 VG_(tdict
).tool_post_syscall
= post
;
289 void VG_(needs_sanity_checks
)(
294 VG_(needs
).sanity_checks
= True
;
295 VG_(tdict
).tool_cheap_sanity_check
= cheap
;
296 VG_(tdict
).tool_expensive_sanity_check
= expen
;
299 void VG_(needs_print_stats
) (
300 void (*print_stats
)(void)
303 VG_(needs
).print_stats
= True
;
304 VG_(tdict
).tool_print_stats
= print_stats
;
307 void VG_(needs_info_location
) (
308 void (*info_location
)(Addr
)
311 VG_(needs
).info_location
= True
;
312 VG_(tdict
).tool_info_location
= info_location
;
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
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
;
343 void VG_(needs_xml_output
)( void )
345 VG_(needs
).xml_output
= True
;
348 void VG_(needs_final_IR_tidy_pass
)(
349 IRSB
*(*final_tidy
)(IRSB
*)
352 VG_(needs
).final_IR_tidy_pass
= True
;
353 VG_(tdict
).tool_final_IR_tidy_pass
= final_tidy
;
356 /*--------------------------------------------------------------------*/
357 /* Tracked events. Digit 'n' on DEFn is the REGPARMness. */
359 #define DEF0(fn, args...) \
360 void VG_(fn)(void(*f)(args)) { \
364 #define DEF1(fn, args...) \
365 void VG_(fn)(VG_REGPARM(1) void(*f)(args)) { \
369 #define DEF2(fn, args...) \
370 void VG_(fn)(VG_REGPARM(2) void(*f)(args)) { \
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
)
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
)
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
)
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
)
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
)
418 DEF0(track_ban_mem_stack
, Addr
, SizeT
)
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
)
425 DEF0(track_pre_reg_read
, CorePart
, ThreadId
, const HChar
*, PtrdiffT
, SizeT
)
426 DEF0(track_post_reg_write
, CorePart
, ThreadId
, PtrdiffT
, SizeT
)
428 DEF0(track_post_reg_write_clientcall_return
, ThreadId
, PtrdiffT
, SizeT
, Addr
)
430 DEF0(track_start_client_code
, ThreadId
, ULong
)
431 DEF0(track_stop_client_code
, ThreadId
, ULong
)
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
)
437 DEF0(track_pre_deliver_signal
, ThreadId
, Int sigNo
, Bool
)
438 DEF0(track_post_deliver_signal
, ThreadId
, Int sigNo
)
440 /*--------------------------------------------------------------------*/
442 /*--------------------------------------------------------------------*/