# 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_exit_status_shadow)().
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
