mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-06 03:23:58 +00:00
274 lines
11 KiB
Modula-2
274 lines
11 KiB
Modula-2
# 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. Some/all default
|
|
## definitions are overridden by the 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 be done before command line processing.
|
|
void, pre_clo_init
|
|
|
|
## 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...
|
|
IRBB*, instrument, IRBB* bb, VexGuestLayout* layout, IRType hWordTy
|
|
|
|
## Finish up, print out any results, etc. `exitcode' is program's exit
|
|
## code. The shadow can be found with VG_(get_exit_status_shadow)().
|
|
void, fini, Int exitcode
|
|
|
|
|
|
## ------------------------------------------------------------------
|
|
## VG_(needs).core_errors
|
|
|
|
## (none needed)
|
|
|
|
## ------------------------------------------------------------------
|
|
## VG_(needs).tool_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_Error, VgRes res, Error* e1, Error* e2
|
|
|
|
## Print error context.
|
|
void, pp_Error, 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 TL_(eq_Error)()). 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
|
|
## TL_(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
|
|
## TL_(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, SizeT size
|
|
|
|
|
|
## ------------------------------------------------------------------
|
|
## 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_TOOL_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_TOOL_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, UWord* arg_block, UWord* ret
|
|
|
|
|
|
## ------------------------------------------------------------------
|
|
## 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
|
|
void, post_syscall, ThreadId tid, UInt syscallno, Int res
|
|
|
|
|
|
## ---------------------------------------------------------------------
|
|
## VG_(needs).sanity_checks
|
|
|
|
## Can be useful for ensuring a tool's correctness. TL_(cheap_sanity_check)
|
|
## is called very frequently; TL_(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 (the default is for events to be ignored).
|
|
|
|
## Note that most events aren't passed a ThreadId. If the event is one called
|
|
## from generated code (eg. new_mem_stack_*), you can use
|
|
## VG_(get_current_tid)() to find it. Otherwise, it has to be passed in,
|
|
## as in pre_mem_read, and so the event signature will require changing.
|
|
|
|
## 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, SizeT len, Bool rr, Bool ww, Bool xx
|
|
void, new_mem_stack_signal, Addr a, SizeT len
|
|
void, new_mem_brk, Addr a, SizeT len
|
|
void, new_mem_mmap, Addr a, SizeT len, Bool rr, Bool ww, Bool xx
|
|
|
|
void, copy_mem_remap, Addr from, Addr to, SizeT len
|
|
void, change_mem_mprotect, Addr a, SizeT len, Bool rr, Bool ww, Bool xx
|
|
void, die_mem_stack_signal, Addr a, SizeT len
|
|
void, die_mem_brk, Addr a, SizeT len
|
|
void, die_mem_munmap, Addr a, SizeT 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, SizeT 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, SizeT len
|
|
|
|
## Used for redzone at end of thread stacks
|
|
void, ban_mem_stack, Addr a, SizeT len
|
|
|
|
## These ones occur around syscalls, signal handling, etc
|
|
void, pre_mem_read, CorePart part, ThreadId tid, Char* s, Addr a, SizeT 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, SizeT size
|
|
void, post_mem_write, CorePart part, ThreadId tid, Addr a, SizeT size
|
|
|
|
|
|
## Register events. Use VG_(set_shadow_state_area)() to set the shadow regs
|
|
## for these events.
|
|
|
|
void, pre_reg_read, CorePart part, ThreadId tid, Char* s, OffT guest_state_offset, SizeT size
|
|
void, post_reg_write, CorePart part, ThreadId tid, OffT guest_state_offset, SizeT size
|
|
|
|
## This one is called for malloc() et al if they are replaced by a tool.
|
|
void, post_reg_write_clientcall_return, ThreadId tid, OffT guest_state_offset, SizeT size, 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, ThreadId tid, SizeT n
|
|
void*, __builtin_new, ThreadId tid, SizeT n
|
|
void*, __builtin_vec_new, ThreadId tid, SizeT n
|
|
void*, memalign, ThreadId tid, SizeT align, SizeT n
|
|
void*, calloc, ThreadId tid, SizeT nmemb, SizeT n
|
|
void, free, ThreadId tid, void* p
|
|
void, __builtin_delete, ThreadId tid, void* p
|
|
void, __builtin_vec_delete, ThreadId tid, void* p
|
|
void*, realloc, ThreadId tid, void* p, SizeT size
|