mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-04 02:18:37 +00:00
- All memory-related errors are now clear whether they are caused by
unaddressable or uninitialised memory. (Previously, writes were
clearly addressability errors, but reads could be either.) Mostly
done by replacing the 'isWrite' field in MAC_Error with 'isUnaddr'.
Also, mc_check_readable() now indicates not just if an error occurred,
but what kind of error (ie. addressability or definedness).
- Put machinery into place in the core to inform tools when registers
are being read by the core -- ie. a 'pre_reg_read' event. Most
notably, this facilitates syscall scalar arg definedness checking for
Memcheck. Currently this is only working for read(), write(), exit()
and exit_group(), but it will be extended as the syscalls are
overhauled as part of the arch-abstraction work.
A consequence of this is that the ParamErr messages have changed. This:
Syscall param write(buf) contains uninitialised byte(s)
now means that the pointer 'buf' is partially undefined. If the memory
pointed to by 'buf' is partially undefined or unaddressable, it says one of:
Syscall param write(buf) points to uninitialised byte(s)
Syscall param write(buf) points to unaddressable byte(s)
The docs have been updated accordingly.
I also added a couple of regression tests.
These two change sare notable for being the first improvements to
Memcheck's checking/errors in a long time.
I also folded mc_clientreqs.c into mc_main.c, which saves exporting a
whole bunch of things that are not used anywhere else.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2949
304 lines
12 KiB
Modula-2
304 lines
12 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. 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, SizeT 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, UWord* arg_block, UWord* 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, 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
|
|
## 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, SizeT size );
|
|
void, post_mem_write, Addr a, SizeT 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.
|
|
|
|
void, pre_reg_read, CorePart part, ThreadId tid, Char* s, UInt reg, SizeT size
|
|
|
|
## 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, SizeT n
|
|
void*, __builtin_new, SizeT n
|
|
void*, __builtin_vec_new, SizeT n
|
|
void*, memalign, SizeT align, SizeT n
|
|
void*, calloc, SizeT nmemb, SizeT n
|
|
void, free, void* p
|
|
void, __builtin_delete, void* p
|
|
void, __builtin_vec_delete, void* p
|
|
void*, realloc, void* p, SizeT size
|