| # Tool interface functions |
| # The format for an interface function definition is: |
| # return_type, func_name, type arg, type arg |
| # If the function has no arguments, specify no arguments (rather than void) |
| # |
| # Comments starting with "##" are turned into C comments in the output |
| # |
| # Lines starting with : set the prefix |
| |
| ## These are the parameterised functions in the core. The default definitions |
| ## are overridden by LD_PRELOADed tool version. At the very least, a tool |
| ## must define the fundamental template functions. Depending on what needs |
| ## are set, extra template functions will be used too. Functions are |
| ## grouped under the needs that govern their use. |
| |
| :tool |
| ## ------------------------------------------------------------------ |
| ## Fundamental template functions |
| |
| ## Do initialisation that can only be done after command line processing. |
| void, post_clo_init |
| |
| ## Instrument a basic block. Must be a true function, ie. the same input |
| ## always results in the same output, because basic blocks can be |
| ## retranslated. Unless you're doing something really strange... |
| ## 'orig_addr' is the address of the first instruction in the block. |
| UCodeBlock*, instrument, UCodeBlock* cb, Addr orig_addr |
| |
| ## Finish up, print out any results, etc. `exitcode' is program's exit |
| ## code. The shadow (if the `shadow_regs' need is set) can be found with |
| ## VG_(get_shadow_archreg)(R_EBX), since %ebx holds the argument to the |
| ## exit() syscall. |
| void, fini, Int exitcode |
| |
| |
| ## ------------------------------------------------------------------ |
| ## VG_(needs).core_errors |
| |
| ## (none needed) |
| |
| ## ------------------------------------------------------------------ |
| ## VG_(needs).skin_errors |
| |
| ## Identify if two errors are equal, or equal enough. `res' indicates how |
| ## close is "close enough". `res' should be passed on as necessary, eg. if |
| ## the Error's `extra' part contains an ExeContext, `res' should be |
| ## passed to VG_(eq_ExeContext)() if the ExeContexts are considered. Other |
| ## than that, probably don't worry about it unless you have lots of very |
| ## similar errors occurring. |
| Bool, eq_SkinError, VgRes res, Error* e1, Error* e2 |
| |
| ## Print error context. |
| void, pp_SkinError, Error* err |
| |
| ## Should fill in any details that could be postponed until after the |
| ## decision whether to ignore the error (ie. details not affecting the |
| ## result of SK_(eq_SkinError)()). This saves time when errors are ignored. |
| ## Yuk. |
| |
| ## Return value: must be the size of the `extra' part in bytes -- used by |
| ## the core to make a copy. |
| UInt, update_extra, Error* err |
| |
| ## Return value indicates recognition. If recognised, must set skind using |
| ## VG_(set_supp_kind)(). |
| Bool, recognised_suppression, Char* name, Supp* su |
| |
| ## Read any extra info for this suppression kind. Most likely for filling |
| ## in the `extra' and `string' parts (with VG_(set_supp_{extra, string})()) |
| ## of a suppression if necessary. Should return False if a syntax error |
| ## occurred, True otherwise. |
| Bool, read_extra_suppression_info, Int fd, Char* buf, Int nBuf, Supp* su |
| |
| ## This should just check the kinds match and maybe some stuff in the |
| ## `string' and `extra' field if appropriate (using VG_(get_supp_*)() to |
| ## get the relevant suppression parts). |
| Bool, error_matches_suppression, Error* err, Supp* su |
| |
| ## This should return the suppression name, for --gen-suppressions, or NULL |
| ## if that error type cannot be suppressed. This is the inverse of |
| ## SK_(recognised_suppression)(). |
| Char*, get_error_name, Error* err |
| |
| ## This should print any extra info for the error, for --gen-suppressions, |
| ## including the newline. This is the inverse of |
| ## SK_(read_extra_suppression_info)(). |
| void, print_extra_suppression_info, Error* err |
| |
| |
| ## ------------------------------------------------------------------ |
| ## VG_(needs).basic_block_discards |
| |
| ## Should discard any information that pertains to specific basic blocks |
| ## or instructions within the address range given. |
| void, discard_basic_block_info, Addr a, UInt size |
| |
| |
| ## ------------------------------------------------------------------ |
| ## VG_(needs).shadow_regs |
| |
| ## No functions must be defined, but the post_reg[s]_write_* events should |
| ## be tracked. |
| |
| ## ------------------------------------------------------------------ |
| ## VG_(needs).command_line_options |
| |
| ## Return True if option was recognised. Presumably sets some state to |
| ## record the option as well. |
| Bool, process_cmd_line_option, Char* argv |
| |
| ## Print out command line usage for options for normal tool operation. |
| void, print_usage |
| |
| ## Print out command line usage for options for debugging the tool. |
| void, print_debug_usage |
| |
| ## ------------------------------------------------------------------ |
| ## VG_(needs).client_requests |
| |
| ## If using client requests, the number of the first request should be equal |
| ## to VG_USERREQ_SKIN_BASE('X', 'Y'), where 'X' and 'Y' form a suitable two |
| ## character identification for the string. The second and subsequent |
| ## requests should follow. |
| |
| ## This function should use the VG_IS_SKIN_USERREQ macro (in |
| ## include/valgrind.h) to first check if it's a request for this tool. Then |
| ## should handle it if it's recognised (and return True), or return False if |
| ## not recognised. arg_block[0] holds the request number, any further args |
| ## from the request are in arg_block[1..]. 'ret' is for the return value... |
| ## it should probably be filled, if only with 0. |
| Bool, handle_client_request, ThreadId tid, UInt* arg_block, UInt* ret |
| |
| |
| ## ------------------------------------------------------------------ |
| ## VG_(needs).extends_UCode |
| |
| ## 'X' prefix indicates eXtended UCode. |
| Int, get_Xreg_usage, UInstr* u, Tag tag, Int* regs, Bool* isWrites |
| void, emit_XUInstr, UInstr* u, RRegSet regs_live_before |
| Bool, sane_XUInstr, Bool beforeRA, Bool beforeLiveness, UInstr* u |
| Char *, name_XUOpcode, Opcode opc |
| void, pp_XUInstr, UInstr* u |
| |
| |
| ## ------------------------------------------------------------------ |
| ## VG_(needs).syscall_wrapper |
| |
| ## If either of the pre_ functions malloc() something to return, the |
| ## corresponding post_ function had better free() it! |
| |
| void *, pre_syscall, ThreadId tid, UInt syscallno, Bool is_blocking |
| void, post_syscall, ThreadId tid, UInt syscallno, void* pre_result, Int res, Bool is_blocking |
| |
| |
| ## --------------------------------------------------------------------- |
| ## VG_(needs).sanity_checks |
| |
| ## Can be useful for ensuring a tool's correctness. SK_(cheap_sanity_check) |
| ## is called very frequently; SK_(expensive_sanity_check) is called less |
| ## frequently and can be more involved. |
| Bool, cheap_sanity_check |
| Bool, expensive_sanity_check |
| |
| |
| ## ================================================================================ |
| ## Event tracking functions |
| :track |
| |
| ## Events happening in core to track. To be notified, pass a callback |
| ## function to the appropriate function. To ignore an event, don't do |
| ## anything (default is for events to be ignored). |
| |
| ## Note that most events aren't passed a ThreadId. To find out the ThreadId |
| ## of the affected thread, use VG_(get_current_or_recent_tid)(). For the |
| ## ones passed a ThreadId, use that instead, since |
| ## VG_(get_current_or_recent_tid)() might not give the right ThreadId in |
| ## that case. |
| |
| ## Memory events (Nb: to track heap allocation/freeing, a tool must replace |
| ## malloc() et al. See above how to do this.) |
| |
| ## These ones occur at startup, upon some signals, and upon some syscalls |
| void, new_mem_startup, Addr a, UInt len, Bool rr, Bool ww, Bool xx |
| void, new_mem_stack_signal, Addr a, UInt len |
| void, new_mem_brk, Addr a, UInt len |
| void, new_mem_mmap, Addr a, UInt len, Bool rr, Bool ww, Bool xx |
| |
| void, copy_mem_remap, Addr from, Addr to, UInt len |
| void, change_mem_mprotect, Addr a, UInt len, Bool rr, Bool ww, Bool xx |
| void, die_mem_stack_signal, Addr a, UInt len |
| void, die_mem_brk, Addr a, UInt len |
| void, die_mem_munmap, Addr a, UInt len |
| |
| ## These ones are called when %esp changes. A tool could track these itself |
| ## (except for ban_mem_stack) but it's much easier to use the core's help. |
| |
| ## The specialised ones are called in preference to the general one, if they |
| ## are defined. These functions are called a lot if they are used, so |
| ## specialising can optimise things significantly. If any of the |
| ## specialised cases are defined, the general case must be defined too. |
| |
| ## Nb: they must all use the REGPARM(n) attribute. |
| void, new_mem_stack_4, Addr new_ESP |
| void, new_mem_stack_8, Addr new_ESP |
| void, new_mem_stack_12, Addr new_ESP |
| void, new_mem_stack_16, Addr new_ESP |
| void, new_mem_stack_32, Addr new_ESP |
| void, new_mem_stack, Addr a, UInt len |
| |
| void, die_mem_stack_4, Addr die_ESP |
| void, die_mem_stack_8, Addr die_ESP |
| void, die_mem_stack_12, Addr die_ESP |
| void, die_mem_stack_16, Addr die_ESP |
| void, die_mem_stack_32, Addr die_ESP |
| void, die_mem_stack, Addr a, UInt len |
| |
| ## Used for redzone at end of thread stacks |
| void, ban_mem_stack, Addr a, UInt len |
| |
| ## These ones occur around syscalls, signal handling, etc |
| void, pre_mem_read, CorePart part, ThreadId tid, Char* s, Addr a, UInt size |
| void, pre_mem_read_asciiz, CorePart part, ThreadId tid, Char* s, Addr a |
| void, pre_mem_write, CorePart part, ThreadId tid, Char* s, Addr a, UInt size |
| ## Not implemented yet -- have to add in lots of places, which is a |
| ## pain. Won't bother unless/until there's a need. |
| ## void (*post_mem_read) ( ThreadState* tst, Char* s, Addr a, UInt size ); |
| void, post_mem_write, Addr a, UInt size |
| |
| |
| ## Register events -- if `shadow_regs' need is set, all should probably be |
| ## used. Use VG_(set_thread_shadow_archreg)() to set the shadow of the |
| ## changed register. |
| |
| ## Use VG_(set_shadow_archreg)() to set the eight general purpose regs, |
| ## and use VG_(set_shadow_eflags)() to set eflags. |
| void, post_regs_write_init, void |
| |
| ## Use VG_(set_thread_shadow_archreg)() to set the shadow regs for these |
| ## events. |
| void, post_reg_write_syscall_return, ThreadId tid, UInt reg |
| void, post_reg_write_deliver_signal, ThreadId tid, UInt reg |
| void, post_reg_write_pthread_return, ThreadId tid, UInt reg |
| void, post_reg_write_clientreq_return, ThreadId tid, UInt reg |
| ## This one is called for malloc() et al if they are replaced by a tool. |
| void, post_reg_write_clientcall_return, ThreadId tid, UInt reg, Addr f |
| |
| |
| ## Scheduler events (not exhaustive) |
| void, thread_run, ThreadId tid |
| |
| |
| ## Thread events (not exhaustive) |
| |
| ## Called during thread create, before the new thread has run any |
| ## instructions (or touched any memory). |
| void, post_thread_create, ThreadId tid, ThreadId child |
| void, post_thread_join, ThreadId joiner, ThreadId joinee |
| |
| |
| ## Mutex events (not exhaustive) |
| ## "void *mutex" is really a pthread_mutex * |
| |
| ## Called before a thread can block while waiting for a mutex (called |
| ## regardless of whether the thread will block or not). |
| void, pre_mutex_lock, ThreadId tid, void* mutex |
| ## Called once the thread actually holds the mutex (always paired with |
| ## pre_mutex_lock). |
| void, post_mutex_lock, ThreadId tid, void* mutex |
| ## Called after a thread has released a mutex (no need for a corresponding |
| ## pre_mutex_unlock, because unlocking can't block). |
| void, post_mutex_unlock, ThreadId tid, void* mutex |
| |
| ## Signal events (not exhaustive) |
| |
| ## ... pre_send_signal, post_send_signal ... |
| |
| ## Called before a signal is delivered; `alt_stack' indicates if it is |
| ## delivered on an alternative stack. |
| void, pre_deliver_signal, ThreadId tid, Int sigNo, Bool alt_stack |
| ## Called after a signal is delivered. Nb: unfortunately, if the signal |
| ## handler longjmps, this won't be called. |
| void, post_deliver_signal, ThreadId tid, Int sigNo |
| |
| |
| ## Others... condition variable... |
| ## ... |
| |
| ## Shadow memory management |
| void, init_shadow_page, Addr p |
| |
| ## ================================================================================ |
| ## malloc and friends |
| :malloc |
| void*, malloc, Int n |
| void*, __builtin_new, Int n |
| void*, __builtin_vec_new, Int n |
| void*, memalign, Int align, Int n |
| void*, calloc, Int nmemb, Int n |
| void, free, void* p |
| void, __builtin_delete, void* p |
| void, __builtin_vec_delete, void* p |
| void*, realloc, void* p, Int size |