blob: d7fc9f627955941df2054c600c3512f7fbeef174 [file] [log] [blame]
njn810086f2002-11-14 12:42:47 +00001
2/*--------------------------------------------------------------------*/
nethercote7cc9c232004-01-21 15:08:04 +00003/*--- Stuff relating to tool data structures. ---*/
sewardja7658342005-05-17 13:43:54 +00004/*--- m_tooliface.c ---*/
njn810086f2002-11-14 12:42:47 +00005/*--------------------------------------------------------------------*/
6
7/*
njnb9c427c2004-12-01 14:14:42 +00008 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
njn810086f2002-11-14 12:42:47 +000010
njn53612422005-03-12 16:22:54 +000011 Copyright (C) 2000-2005 Nicholas Nethercote
njn2bc10122005-05-08 02:10:27 +000012 njn@valgrind.org
njn810086f2002-11-14 12:42:47 +000013
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
njnc7561b92005-06-19 01:24:32 +000032#include "pub_core_basics.h"
njn4802b382005-06-11 04:58:29 +000033#include "pub_core_tooliface.h"
njn810086f2002-11-14 12:42:47 +000034
njn51d827b2005-05-09 01:02:08 +000035// The core/tool dictionary of functions (initially zeroed, as we want it)
36VgToolInterface VG_(tdict);
njn810086f2002-11-14 12:42:47 +000037
njn8a97c6d2005-03-31 04:37:24 +000038/*--------------------------------------------------------------------*/
39/* Setting basic functions */
40
41void VG_(basic_tool_funcs)(
42 void(*post_clo_init)(void),
sewardj4ba057c2005-10-18 12:04:18 +000043 IRBB*(*instrument)(IRBB*, VexGuestLayout*,
44 Addr64, VexGuestExtents*, IRType, IRType ),
njn8a97c6d2005-03-31 04:37:24 +000045 void(*fini)(Int)
46)
47{
njncf81d552005-03-31 04:52:26 +000048 VG_(tdict).tool_post_clo_init = post_clo_init;
49 VG_(tdict).tool_instrument = instrument;
50 VG_(tdict).tool_fini = fini;
njn8a97c6d2005-03-31 04:37:24 +000051}
52
njn51d827b2005-05-09 01:02:08 +000053
njn8a97c6d2005-03-31 04:37:24 +000054/*--------------------------------------------------------------------*/
55/* Setting details */
56
njn810086f2002-11-14 12:42:47 +000057/* Init with default values. */
58VgDetails VG_(details) = {
sewardjc0d8f682002-11-30 00:49:43 +000059 .name = NULL,
60 .version = NULL,
61 .description = NULL,
62 .copyright_author = NULL,
63 .bug_reports_to = NULL,
njn120281f2003-02-03 12:20:07 +000064 .avg_translation_sizeB = VG_DEFAULT_TRANS_SIZEB,
njn810086f2002-11-14 12:42:47 +000065};
66
njn8a97c6d2005-03-31 04:37:24 +000067/* Use macro because they're so repetitive */
68#define DETAILS(type, detail) \
69 extern void VG_(details_##detail)(type detail) \
70 { \
71 VG_(details).detail = detail; \
72 }
73
74DETAILS(Char*, name)
75DETAILS(Char*, version)
76DETAILS(Char*, description)
77DETAILS(Char*, copyright_author)
78DETAILS(Char*, bug_reports_to)
79DETAILS(UInt, avg_translation_sizeB)
80
njn51d827b2005-05-09 01:02:08 +000081
njn8a97c6d2005-03-31 04:37:24 +000082/*--------------------------------------------------------------------*/
83/* Setting needs */
84
njn810086f2002-11-14 12:42:47 +000085VgNeeds VG_(needs) = {
86 .core_errors = False,
njn95ec8702004-11-22 16:46:13 +000087 .tool_errors = False,
njn810086f2002-11-14 12:42:47 +000088 .libc_freeres = False,
njn810086f2002-11-14 12:42:47 +000089 .basic_block_discards = False,
njn810086f2002-11-14 12:42:47 +000090 .command_line_options = False,
91 .client_requests = False,
njn810086f2002-11-14 12:42:47 +000092 .syscall_wrapper = False,
njn810086f2002-11-14 12:42:47 +000093 .sanity_checks = False,
94 .data_syms = False,
njnfc51f8d2005-06-21 03:20:17 +000095 .malloc_replacement = False,
njn810086f2002-11-14 12:42:47 +000096};
97
98/* static */
sewardj45f4e7c2005-09-27 19:20:21 +000099Bool VG_(sanity_check_needs)(Char** failmsg)
njn810086f2002-11-14 12:42:47 +0000100{
njn64c83242005-06-21 01:54:38 +0000101#define CHECK_NOT(var, value) \
102 if ((var)==(value)) { \
103 *failmsg = "Tool error: '" #var "' not initialised\n"; \
104 return False; \
njn810086f2002-11-14 12:42:47 +0000105 }
106
njn120281f2003-02-03 12:20:07 +0000107 /* Ones that must be set */
njn810086f2002-11-14 12:42:47 +0000108 CHECK_NOT(VG_(details).name, NULL);
109 /* Nb: .version can be NULL */
110 CHECK_NOT(VG_(details).description, NULL);
111 CHECK_NOT(VG_(details).copyright_author, NULL);
112 CHECK_NOT(VG_(details).bug_reports_to, NULL);
113
njn51d827b2005-05-09 01:02:08 +0000114 if ( (VG_(tdict).track_new_mem_stack_4 ||
115 VG_(tdict).track_new_mem_stack_8 ||
116 VG_(tdict).track_new_mem_stack_12 ||
117 VG_(tdict).track_new_mem_stack_16 ||
118 VG_(tdict).track_new_mem_stack_32 ) &&
119 ! VG_(tdict).track_new_mem_stack)
njnd3040452003-05-19 15:04:06 +0000120 {
njn64c83242005-06-21 01:54:38 +0000121 *failmsg = "Tool error: one of the specialised 'new_mem_stack_n'\n"
122 " events tracked, but not the generic 'new_mem_stack' one.\n"
123 " 'new_mem_stack' should be defined\n";
124 return False;
njn9b007f62003-04-07 14:40:25 +0000125 }
126
njn51d827b2005-05-09 01:02:08 +0000127 if ( (VG_(tdict).track_die_mem_stack_4 ||
128 VG_(tdict).track_die_mem_stack_8 ||
129 VG_(tdict).track_die_mem_stack_12 ||
130 VG_(tdict).track_die_mem_stack_16 ||
131 VG_(tdict).track_die_mem_stack_32 ) &&
132 ! VG_(tdict).track_die_mem_stack)
njnd3040452003-05-19 15:04:06 +0000133 {
njn64c83242005-06-21 01:54:38 +0000134 *failmsg = "Tool error: one of the specialised 'die_mem_stack_n'\n"
135 " events tracked, but not the generic 'die_mem_stack' one.\n"
136 " 'die_mem_stack' should be defined\n";
137 return False;
njn9b007f62003-04-07 14:40:25 +0000138 }
139
njn64c83242005-06-21 01:54:38 +0000140 return True;
141
njn810086f2002-11-14 12:42:47 +0000142#undef CHECK_NOT
njn810086f2002-11-14 12:42:47 +0000143}
144
njn810086f2002-11-14 12:42:47 +0000145/* Use macro because they're so repetitive */
146#define NEEDS(need) \
147 extern void VG_(needs_##need)(void) \
148 { \
149 VG_(needs).need = True; \
150 }
151
njn8a97c6d2005-03-31 04:37:24 +0000152// These ones don't require any tool-supplied functions
njn810086f2002-11-14 12:42:47 +0000153NEEDS(libc_freeres)
154NEEDS(core_errors)
njn810086f2002-11-14 12:42:47 +0000155NEEDS(data_syms)
njnfdc28af2003-02-24 10:36:48 +0000156
njn8a97c6d2005-03-31 04:37:24 +0000157void VG_(needs_basic_block_discards)(
sewardj4ba057c2005-10-18 12:04:18 +0000158 void (*discard)(Addr64, VexGuestExtents)
njn8a97c6d2005-03-31 04:37:24 +0000159)
160{
161 VG_(needs).basic_block_discards = True;
njncf81d552005-03-31 04:52:26 +0000162 VG_(tdict).tool_discard_basic_block_info = discard;
njn8a97c6d2005-03-31 04:37:24 +0000163}
164
165void VG_(needs_tool_errors)(
166 Bool (*eq) (VgRes, Error*, Error*),
167 void (*pp) (Error*),
168 UInt (*update) (Error*),
169 Bool (*recog) (Char*, Supp*),
170 Bool (*read_extra) (Int, Char*, Int, Supp*),
171 Bool (*matches) (Error*, Supp*),
172 Char* (*name) (Error*),
173 void (*print_extra)(Error*)
174)
175{
176 VG_(needs).tool_errors = True;
njncf81d552005-03-31 04:52:26 +0000177 VG_(tdict).tool_eq_Error = eq;
178 VG_(tdict).tool_pp_Error = pp;
179 VG_(tdict).tool_update_extra = update;
180 VG_(tdict).tool_recognised_suppression = recog;
181 VG_(tdict).tool_read_extra_suppression_info = read_extra;
182 VG_(tdict).tool_error_matches_suppression = matches;
183 VG_(tdict).tool_get_error_name = name;
184 VG_(tdict).tool_print_extra_suppression_info = print_extra;
njn8a97c6d2005-03-31 04:37:24 +0000185}
186
187void VG_(needs_command_line_options)(
188 Bool (*process)(Char*),
189 void (*usage)(void),
190 void (*debug_usage)(void)
191)
192{
193 VG_(needs).command_line_options = True;
njncf81d552005-03-31 04:52:26 +0000194 VG_(tdict).tool_process_cmd_line_option = process;
195 VG_(tdict).tool_print_usage = usage;
196 VG_(tdict).tool_print_debug_usage = debug_usage;
njn8a97c6d2005-03-31 04:37:24 +0000197}
198
199void VG_(needs_client_requests)(
200 Bool (*handle)(ThreadId, UWord*, UWord*)
201)
202{
203 VG_(needs).client_requests = True;
njncf81d552005-03-31 04:52:26 +0000204 VG_(tdict).tool_handle_client_request = handle;
njn8a97c6d2005-03-31 04:37:24 +0000205}
206
207void VG_(needs_syscall_wrapper)(
208 void(*pre) (ThreadId, UInt),
sewardja8d8e232005-06-07 20:04:56 +0000209 void(*post)(ThreadId, UInt, SysRes res)
njn8a97c6d2005-03-31 04:37:24 +0000210)
211{
212 VG_(needs).syscall_wrapper = True;
njncf81d552005-03-31 04:52:26 +0000213 VG_(tdict).tool_pre_syscall = pre;
214 VG_(tdict).tool_post_syscall = post;
njn8a97c6d2005-03-31 04:37:24 +0000215}
216
217void VG_(needs_sanity_checks)(
218 Bool(*cheap)(void),
219 Bool(*expen)(void)
220)
221{
222 VG_(needs).sanity_checks = True;
njncf81d552005-03-31 04:52:26 +0000223 VG_(tdict).tool_cheap_sanity_check = cheap;
224 VG_(tdict).tool_expensive_sanity_check = expen;
njn8a97c6d2005-03-31 04:37:24 +0000225}
226
njnfc51f8d2005-06-21 03:20:17 +0000227void VG_(needs_malloc_replacement)(
njn8a97c6d2005-03-31 04:37:24 +0000228 void* (*malloc) ( ThreadId, SizeT ),
229 void* (*__builtin_new) ( ThreadId, SizeT ),
230 void* (*__builtin_vec_new) ( ThreadId, SizeT ),
231 void* (*memalign) ( ThreadId, SizeT, SizeT ),
232 void* (*calloc) ( ThreadId, SizeT, SizeT ),
233 void (*free) ( ThreadId, void* ),
234 void (*__builtin_delete) ( ThreadId, void* ),
235 void (*__builtin_vec_delete) ( ThreadId, void* ),
236 void* (*realloc) ( ThreadId, void*, SizeT ),
237 SizeT client_malloc_redzone_szB
238)
239{
njnfc51f8d2005-06-21 03:20:17 +0000240 VG_(needs).malloc_replacement = True;
241 VG_(tdict).tool_malloc = malloc;
242 VG_(tdict).tool___builtin_new = __builtin_new;
243 VG_(tdict).tool___builtin_vec_new = __builtin_vec_new;
244 VG_(tdict).tool_memalign = memalign;
245 VG_(tdict).tool_calloc = calloc;
246 VG_(tdict).tool_free = free;
247 VG_(tdict).tool___builtin_delete = __builtin_delete;
248 VG_(tdict).tool___builtin_vec_delete = __builtin_vec_delete;
249 VG_(tdict).tool_realloc = realloc;
250 VG_(tdict).tool_client_redzone_szB = client_malloc_redzone_szB;
njn8a97c6d2005-03-31 04:37:24 +0000251}
252
njn51d827b2005-05-09 01:02:08 +0000253
njn810086f2002-11-14 12:42:47 +0000254/*--------------------------------------------------------------------*/
njn51d827b2005-05-09 01:02:08 +0000255/* Tracked events */
256
257#define DEF(fn, args...) \
258void VG_(fn)(void(*f)(args)) \
259{ \
260 VG_(tdict).fn = f; \
261}
262
263#define DEF2(fn, args...) \
njnaf839f52005-06-23 03:27:57 +0000264void VG_(fn)(VG_REGPARM(1) void(*f)(args)) \
njn51d827b2005-05-09 01:02:08 +0000265{ \
266 VG_(tdict).fn = f; \
267}
268
269DEF(track_new_mem_startup, Addr, SizeT, Bool, Bool, Bool)
270DEF(track_new_mem_stack_signal, Addr, SizeT)
271DEF(track_new_mem_brk, Addr, SizeT)
272DEF(track_new_mem_mmap, Addr, SizeT, Bool, Bool, Bool)
273
274DEF(track_copy_mem_remap, Addr, Addr, SizeT)
275DEF(track_change_mem_mprotect, Addr, SizeT, Bool, Bool, Bool)
276DEF(track_die_mem_stack_signal, Addr, SizeT)
277DEF(track_die_mem_brk, Addr, SizeT)
278DEF(track_die_mem_munmap, Addr, SizeT)
279
280DEF2(track_new_mem_stack_4, Addr)
281DEF2(track_new_mem_stack_8, Addr)
282DEF2(track_new_mem_stack_12, Addr)
283DEF2(track_new_mem_stack_16, Addr)
284DEF2(track_new_mem_stack_32, Addr)
285DEF (track_new_mem_stack, Addr, SizeT)
286
287DEF2(track_die_mem_stack_4, Addr)
288DEF2(track_die_mem_stack_8, Addr)
289DEF2(track_die_mem_stack_12, Addr)
290DEF2(track_die_mem_stack_16, Addr)
291DEF2(track_die_mem_stack_32, Addr)
292DEF (track_die_mem_stack, Addr, SizeT)
293
294DEF(track_ban_mem_stack, Addr, SizeT)
295
296DEF(track_pre_mem_read, CorePart, ThreadId, Char*, Addr, SizeT)
297DEF(track_pre_mem_read_asciiz, CorePart, ThreadId, Char*, Addr)
298DEF(track_pre_mem_write, CorePart, ThreadId, Char*, Addr, SizeT)
299DEF(track_post_mem_write, CorePart, ThreadId, Addr, SizeT)
300
301DEF(track_pre_reg_read, CorePart, ThreadId, Char*, OffT, SizeT)
302DEF(track_post_reg_write, CorePart, ThreadId, OffT, SizeT)
303
304DEF(track_post_reg_write_clientcall_return, ThreadId, OffT, SizeT, Addr)
305
306DEF(track_thread_run, ThreadId)
307
308DEF(track_post_thread_create, ThreadId, ThreadId)
309DEF(track_post_thread_join, ThreadId, ThreadId)
310
311DEF(track_pre_mutex_lock, ThreadId, void*)
312DEF(track_post_mutex_lock, ThreadId, void*)
313DEF(track_post_mutex_unlock, ThreadId, void*)
314
315DEF(track_pre_deliver_signal, ThreadId, Int sigNo, Bool)
316DEF(track_post_deliver_signal, ThreadId, Int sigNo)
317
njn51d827b2005-05-09 01:02:08 +0000318/*--------------------------------------------------------------------*/
319/*--- end ---*/
njn810086f2002-11-14 12:42:47 +0000320/*--------------------------------------------------------------------*/