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