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