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 (at) 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 41 void 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. */ 58 VgDetails 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 74 DETAILS(Char*, name) 75 DETAILS(Char*, version) 76 DETAILS(Char*, description) 77 DETAILS(Char*, copyright_author) 78 DETAILS(Char*, bug_reports_to) 79 DETAILS(UInt, avg_translation_sizeB) 80 81 82 /*--------------------------------------------------------------------*/ 83 /* Setting needs */ 84 85 VgNeeds 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 */ 101 Bool 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 214 NEEDS(libc_freeres) 215 NEEDS(core_errors) 216 NEEDS(var_info) 217 218 void 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 226 void 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 252 void 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 264 void 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 272 void 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 282 void 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 292 void 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 320 void VG_(needs_xml_output)( void ) 321 { 322 VG_(needs).xml_output = True; 323 } 324 325 void 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...) \ 337 void VG_(fn)(void(*f)(args)) { \ 338 VG_(tdict).fn = f; \ 339 } 340 341 #define DEF1(fn, args...) \ 342 void VG_(fn)(VG_REGPARM(1) void(*f)(args)) { \ 343 VG_(tdict).fn = f; \ 344 } 345 346 #define DEF2(fn, args...) \ 347 void VG_(fn)(VG_REGPARM(2) void(*f)(args)) { \ 348 VG_(tdict).fn = f; \ 349 } 350 351 DEF0(track_new_mem_startup, Addr, SizeT, Bool, Bool, Bool, ULong) 352 DEF0(track_new_mem_stack_signal, Addr, SizeT, UInt) 353 DEF0(track_new_mem_brk, Addr, SizeT, UInt) 354 DEF0(track_new_mem_mmap, Addr, SizeT, Bool, Bool, Bool, ULong) 355 356 DEF0(track_copy_mem_remap, Addr, Addr, SizeT) 357 DEF0(track_change_mem_mprotect, Addr, SizeT, Bool, Bool, Bool) 358 DEF0(track_die_mem_stack_signal, Addr, SizeT) 359 DEF0(track_die_mem_brk, Addr, SizeT) 360 DEF0(track_die_mem_munmap, Addr, SizeT) 361 362 DEF2(track_new_mem_stack_4_w_ECU, Addr, UInt) 363 DEF2(track_new_mem_stack_8_w_ECU, Addr, UInt) 364 DEF2(track_new_mem_stack_12_w_ECU, Addr, UInt) 365 DEF2(track_new_mem_stack_16_w_ECU, Addr, UInt) 366 DEF2(track_new_mem_stack_32_w_ECU, Addr, UInt) 367 DEF2(track_new_mem_stack_112_w_ECU, Addr, UInt) 368 DEF2(track_new_mem_stack_128_w_ECU, Addr, UInt) 369 DEF2(track_new_mem_stack_144_w_ECU, Addr, UInt) 370 DEF2(track_new_mem_stack_160_w_ECU, Addr, UInt) 371 DEF0(track_new_mem_stack_w_ECU, Addr, SizeT, UInt) 372 373 DEF1(track_new_mem_stack_4, Addr) 374 DEF1(track_new_mem_stack_8, Addr) 375 DEF1(track_new_mem_stack_12, Addr) 376 DEF1(track_new_mem_stack_16, Addr) 377 DEF1(track_new_mem_stack_32, Addr) 378 DEF1(track_new_mem_stack_112, Addr) 379 DEF1(track_new_mem_stack_128, Addr) 380 DEF1(track_new_mem_stack_144, Addr) 381 DEF1(track_new_mem_stack_160, Addr) 382 DEF0(track_new_mem_stack, Addr, SizeT) 383 384 DEF1(track_die_mem_stack_4, Addr) 385 DEF1(track_die_mem_stack_8, Addr) 386 DEF1(track_die_mem_stack_12, Addr) 387 DEF1(track_die_mem_stack_16, Addr) 388 DEF1(track_die_mem_stack_32, Addr) 389 DEF1(track_die_mem_stack_112, Addr) 390 DEF1(track_die_mem_stack_128, Addr) 391 DEF1(track_die_mem_stack_144, Addr) 392 DEF1(track_die_mem_stack_160, Addr) 393 DEF0(track_die_mem_stack, Addr, SizeT) 394 395 DEF0(track_ban_mem_stack, Addr, SizeT) 396 397 DEF0(track_pre_mem_read, CorePart, ThreadId, Char*, Addr, SizeT) 398 DEF0(track_pre_mem_read_asciiz, CorePart, ThreadId, Char*, Addr) 399 DEF0(track_pre_mem_write, CorePart, ThreadId, Char*, Addr, SizeT) 400 DEF0(track_post_mem_write, CorePart, ThreadId, Addr, SizeT) 401 402 DEF0(track_pre_reg_read, CorePart, ThreadId, Char*, PtrdiffT, SizeT) 403 DEF0(track_post_reg_write, CorePart, ThreadId, PtrdiffT, SizeT) 404 405 DEF0(track_post_reg_write_clientcall_return, ThreadId, PtrdiffT, SizeT, Addr) 406 407 DEF0(track_start_client_code, ThreadId, ULong) 408 DEF0(track_stop_client_code, ThreadId, ULong) 409 410 DEF0(track_pre_thread_ll_create, ThreadId, ThreadId) 411 DEF0(track_workq_task_start, ThreadId, Addr) 412 DEF0(track_pre_thread_first_insn, ThreadId) 413 DEF0(track_pre_thread_ll_exit, ThreadId) 414 415 DEF0(track_pre_deliver_signal, ThreadId, Int sigNo, Bool) 416 DEF0(track_post_deliver_signal, ThreadId, Int sigNo) 417 418 /*--------------------------------------------------------------------*/ 419 /*--- end ---*/ 420 /*--------------------------------------------------------------------*/ 421