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) 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*, 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. */ 59VgDetails 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 75DETAILS(const HChar*, name) 76DETAILS(const HChar*, version) 77DETAILS(const HChar*, description) 78DETAILS(const HChar*, copyright_author) 79DETAILS(const HChar*, bug_reports_to) 80DETAILS(UInt, avg_translation_sizeB) 81 82 83/*--------------------------------------------------------------------*/ 84/* Setting needs */ 85 86VgNeeds 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 */ 104Bool 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 217NEEDS(libc_freeres) 218NEEDS(core_errors) 219NEEDS(var_info) 220 221void 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 229void 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 259void 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 271void 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 279void 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 289void 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 299void 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 307void 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 315void 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 343void VG_(needs_xml_output)( void ) 344{ 345 VG_(needs).xml_output = True; 346} 347 348void 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...) \ 360void VG_(fn)(void(*f)(args)) { \ 361 VG_(tdict).fn = f; \ 362} 363 364#define DEF1(fn, args...) \ 365void VG_(fn)(VG_REGPARM(1) void(*f)(args)) { \ 366 VG_(tdict).fn = f; \ 367} 368 369#define DEF2(fn, args...) \ 370void VG_(fn)(VG_REGPARM(2) void(*f)(args)) { \ 371 VG_(tdict).fn = f; \ 372} 373 374DEF0(track_new_mem_startup, Addr, SizeT, Bool, Bool, Bool, ULong) 375DEF0(track_new_mem_stack_signal, Addr, SizeT, UInt) 376DEF0(track_new_mem_brk, Addr, SizeT, UInt) 377DEF0(track_new_mem_mmap, Addr, SizeT, Bool, Bool, Bool, ULong) 378 379DEF0(track_copy_mem_remap, Addr, Addr, SizeT) 380DEF0(track_change_mem_mprotect, Addr, SizeT, Bool, Bool, Bool) 381DEF0(track_die_mem_stack_signal, Addr, SizeT) 382DEF0(track_die_mem_brk, Addr, SizeT) 383DEF0(track_die_mem_munmap, Addr, SizeT) 384 385DEF2(track_new_mem_stack_4_w_ECU, Addr, UInt) 386DEF2(track_new_mem_stack_8_w_ECU, Addr, UInt) 387DEF2(track_new_mem_stack_12_w_ECU, Addr, UInt) 388DEF2(track_new_mem_stack_16_w_ECU, Addr, UInt) 389DEF2(track_new_mem_stack_32_w_ECU, Addr, UInt) 390DEF2(track_new_mem_stack_112_w_ECU, Addr, UInt) 391DEF2(track_new_mem_stack_128_w_ECU, Addr, UInt) 392DEF2(track_new_mem_stack_144_w_ECU, Addr, UInt) 393DEF2(track_new_mem_stack_160_w_ECU, Addr, UInt) 394DEF0(track_new_mem_stack_w_ECU, Addr, SizeT, UInt) 395 396DEF1(track_new_mem_stack_4, Addr) 397DEF1(track_new_mem_stack_8, Addr) 398DEF1(track_new_mem_stack_12, Addr) 399DEF1(track_new_mem_stack_16, Addr) 400DEF1(track_new_mem_stack_32, Addr) 401DEF1(track_new_mem_stack_112, Addr) 402DEF1(track_new_mem_stack_128, Addr) 403DEF1(track_new_mem_stack_144, Addr) 404DEF1(track_new_mem_stack_160, Addr) 405DEF0(track_new_mem_stack, Addr, SizeT) 406 407DEF1(track_die_mem_stack_4, Addr) 408DEF1(track_die_mem_stack_8, Addr) 409DEF1(track_die_mem_stack_12, Addr) 410DEF1(track_die_mem_stack_16, Addr) 411DEF1(track_die_mem_stack_32, Addr) 412DEF1(track_die_mem_stack_112, Addr) 413DEF1(track_die_mem_stack_128, Addr) 414DEF1(track_die_mem_stack_144, Addr) 415DEF1(track_die_mem_stack_160, Addr) 416DEF0(track_die_mem_stack, Addr, SizeT) 417 418DEF0(track_ban_mem_stack, Addr, SizeT) 419 420DEF0(track_pre_mem_read, CorePart, ThreadId, const HChar*, Addr, SizeT) 421DEF0(track_pre_mem_read_asciiz, CorePart, ThreadId, const HChar*, Addr) 422DEF0(track_pre_mem_write, CorePart, ThreadId, const HChar*, Addr, SizeT) 423DEF0(track_post_mem_write, CorePart, ThreadId, Addr, SizeT) 424 425DEF0(track_pre_reg_read, CorePart, ThreadId, const HChar*, PtrdiffT, SizeT) 426DEF0(track_post_reg_write, CorePart, ThreadId, PtrdiffT, SizeT) 427 428DEF0(track_post_reg_write_clientcall_return, ThreadId, PtrdiffT, SizeT, Addr) 429 430DEF0(track_start_client_code, ThreadId, ULong) 431DEF0(track_stop_client_code, ThreadId, ULong) 432 433DEF0(track_pre_thread_ll_create, ThreadId, ThreadId) 434DEF0(track_pre_thread_first_insn, ThreadId) 435DEF0(track_pre_thread_ll_exit, ThreadId) 436 437DEF0(track_pre_deliver_signal, ThreadId, Int sigNo, Bool) 438DEF0(track_post_deliver_signal, ThreadId, Int sigNo) 439 440/*--------------------------------------------------------------------*/ 441/*--- end ---*/ 442/*--------------------------------------------------------------------*/ 443