• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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