Files updated, added and removed in order to turn the ERASER branch into HEAD
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@1086 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/vg_include.h b/coregrind/vg_include.h
index 74e1016..edf7aef 100644
--- a/coregrind/vg_include.h
+++ b/coregrind/vg_include.h
@@ -1,6 +1,6 @@
/*--------------------------------------------------------------------*/
-/*--- A header file for all parts of Valgrind. ---*/
+/*--- A header file for all private parts of Valgrind's core. ---*/
/*--- Include no other! ---*/
/*--- vg_include.h ---*/
/*--------------------------------------------------------------------*/
@@ -27,17 +27,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA.
- The GNU General Public License is contained in the file LICENSE.
+ The GNU General Public License is contained in the file COPYING.
*/
#ifndef __VG_INCLUDE_H
#define __VG_INCLUDE_H
-
-#include <stdarg.h> /* ANSI varargs stuff */
-#include <setjmp.h> /* for jmp_buf */
-
-
/* ---------------------------------------------------------------------
Where to send bug reports to.
------------------------------------------------------------------ */
@@ -52,21 +47,9 @@
#include "vg_constants.h"
-
-/* Set to 1 to enable time profiling. Since this uses SIGPROF, we
- don't want this permanently enabled -- only for profiling
- builds. */
-#if 0
-# define VG_PROFILE
-#endif
-
-
-/* Total number of integer registers available for allocation. That's
- all of them except %esp, %edi and %ebp. %edi is a general spare
- temporary. %ebp permanently points at VG_(baseBlock). Note that
- it's important that this tie in with what rankToRealRegNo() says.
- DO NOT CHANGE THIS VALUE FROM 5. ! */
-#define VG_MAX_REALREGS 5
+/* All stuff visible to core and skins goes in vg_skin.h. Things visible
+ * to core but private to skins go here. */
+#include "vg_skin.h"
/* Total number of spill slots available for allocation, if a TempReg
doesn't make it into a RealReg. Just bomb the entire system if
@@ -111,10 +94,6 @@
errors at all. Counterpart to M_VG_COLLECT_NO_ERRORS_AFTER_SHOWN. */
#define M_VG_COLLECT_NO_ERRORS_AFTER_FOUND 30000
-/* These many bytes below %ESP are considered addressible if we're
- doing the --workaround-gcc296-bugs hack. */
-#define VG_GCC296_BUG_STACK_SLOP 1024
-
/* The maximum number of calls we're prepared to save in a
backtrace. */
#define VG_DEEPEST_BACKTRACE 50
@@ -132,17 +111,6 @@
give finer interleaving but much increased scheduling overheads. */
#define VG_SCHEDULING_QUANTUM 50000
-/* The maximum number of pthreads that we support. This is
- deliberately not very high since our implementation of some of the
- scheduler algorithms is surely O(N) in the number of threads, since
- that's simple, at least. And (in practice) we hope that most
- programs do not need many threads. */
-#define VG_N_THREADS 50
-
-/* Maximum number of pthread keys available. Again, we start low until
- the need for a higher number presents itself. */
-#define VG_N_THREAD_KEYS 50
-
/* Number of file descriptors that can simultaneously be waited on for
I/O to complete. Perhaps this should be the same as VG_N_THREADS
(surely a thread can't wait on more than one fd at once?. Who
@@ -165,97 +133,43 @@
/* Number of entries in each thread's fork-handler stack. */
#define VG_N_FORKHANDLERSTACK 2
+/* Max number of callers for context in a suppression. */
+#define VG_N_SUPP_CALLERS 4
+
/* ---------------------------------------------------------------------
Basic types
------------------------------------------------------------------ */
-typedef unsigned char UChar;
-typedef unsigned short UShort;
-typedef unsigned int UInt;
-typedef unsigned long long int ULong;
-
-typedef signed char Char;
-typedef signed short Short;
-typedef signed int Int;
-typedef signed long long int Long;
-
-typedef unsigned int Addr;
-
-typedef unsigned char Bool;
-#define False ((Bool)0)
-#define True ((Bool)1)
-
-#define mycat_wrk(aaa,bbb) aaa##bbb
-#define mycat(aaa,bbb) mycat_wrk(aaa,bbb)
-
/* Just pray that gcc's constant folding works properly ... */
#define BITS(bit7,bit6,bit5,bit4,bit3,bit2,bit1,bit0) \
( ((bit7) << 7) | ((bit6) << 6) | ((bit5) << 5) | ((bit4) << 4) \
| ((bit3) << 3) | ((bit2) << 2) | ((bit1) << 1) | (bit0))
-/* For cache simulation */
-typedef struct {
- int size; /* bytes */
- int assoc;
- int line_size; /* bytes */
-} cache_t;
-
-#define UNDEFINED_CACHE ((cache_t) { -1, -1, -1 })
-
-/* ---------------------------------------------------------------------
- Now the basic types are set up, we can haul in the kernel-interface
- definitions.
- ------------------------------------------------------------------ */
-
-#include "./vg_kerneliface.h"
-
-
/* ---------------------------------------------------------------------
Command-line-settable options
------------------------------------------------------------------ */
-#define VG_CLO_SMC_NONE 0
-#define VG_CLO_SMC_SOME 1
-#define VG_CLO_SMC_ALL 2
-
#define VG_CLO_MAX_SFILES 10
/* Should we stop collecting errors if too many appear? default: YES */
extern Bool VG_(clo_error_limit);
-/* Shall we V-check addrs (they are always A checked too): default: YES */
-extern Bool VG_(clo_check_addrVs);
/* Enquire about whether to attach to GDB at errors? default: NO */
extern Bool VG_(clo_GDB_attach);
/* Sanity-check level: 0 = none, 1 (default), > 1 = expensive. */
extern Int VG_(sanity_level);
-/* Verbosity level: 0 = silent, 1 (default), > 1 = more verbose. */
-extern Int VG_(clo_verbosity);
/* Automatically attempt to demangle C++ names? default: YES */
extern Bool VG_(clo_demangle);
-/* Do leak check at exit? default: NO */
-extern Bool VG_(clo_leak_check);
-/* In leak check, show reachable-but-not-freed blocks? default: NO */
-extern Bool VG_(clo_show_reachable);
-/* How closely should we compare ExeContexts in leak records? default: 2 */
-extern Int VG_(clo_leak_resolution);
/* Round malloc sizes upwards to integral number of words? default:
NO */
extern Bool VG_(clo_sloppy_malloc);
/* Minimum alignment in functions that don't specify alignment explicitly.
default: 0, i.e. use default of the machine (== 4) */
extern Int VG_(clo_alignment);
-/* Allow loads from partially-valid addresses? default: YES */
-extern Bool VG_(clo_partial_loads_ok);
/* Simulate child processes? default: NO */
extern Bool VG_(clo_trace_children);
/* The file id on which we send all messages. default: 2 (stderr). */
extern Int VG_(clo_logfile_fd);
-/* Max volume of the freed blocks queue. */
-extern Int VG_(clo_freelist_vol);
-/* Assume accesses immediately below %esp are due to gcc-2.96 bugs.
- default: NO */
-extern Bool VG_(clo_workaround_gcc296_bugs);
/* The number of suppression files specified. */
extern Int VG_(clo_n_suppressions);
@@ -266,20 +180,8 @@
extern Bool VG_(clo_single_step);
/* Code improvement? default: YES */
extern Bool VG_(clo_optimise);
-/* Memory-check instrumentation? default: YES */
-extern Bool VG_(clo_instrument);
-/* DEBUG: clean up instrumented code? default: YES */
-extern Bool VG_(clo_cleanup);
-/* Cache simulation instrumentation? default: NO */
-extern Bool VG_(clo_cachesim);
-/* I1 cache configuration. default: undefined */
-extern cache_t VG_(clo_I1_cache);
-/* D1 cache configuration. default: undefined */
-extern cache_t VG_(clo_D1_cache);
-/* L2 cache configuration. default: undefined */
-extern cache_t VG_(clo_L2_cache);
-/* SMC write checks? default: SOME (1,2,4 byte movs to mem) */
-extern Int VG_(clo_smc_check);
+/* DEBUG: print generated code? default: 00000 ( == NO ) */
+extern Bool VG_(clo_trace_codegen);
/* DEBUG: print system calls? default: NO */
extern Bool VG_(clo_trace_syscalls);
/* DEBUG: print signal details? default: NO */
@@ -308,78 +210,35 @@
Debugging and profiling stuff
------------------------------------------------------------------ */
+/* Change to 1 to get more accurate but more expensive core profiling. */
+#if 0
+# define VGP_ACCURATE_PROFILING
+#endif
+
/* No, really. I _am_ that strange. */
#define OINK(nnn) VG_(message)(Vg_DebugMsg, "OINK %d",nnn)
-/* Tools for building messages from multiple parts. */
-typedef
- enum { Vg_UserMsg, Vg_DebugMsg, Vg_DebugExtraMsg }
- VgMsgKind;
-
-extern void VG_(start_msg) ( VgMsgKind kind );
-extern void VG_(add_to_msg) ( Char* format, ... );
-extern void VG_(end_msg) ( void );
-
-/* Send a simple, single-part message. */
-extern void VG_(message) ( VgMsgKind kind, Char* format, ... );
-
/* Create a logfile into which messages can be dumped. */
extern void VG_(startup_logging) ( void );
-extern void VG_(shutdown_logging) ( void );
-
-
-/* Profiling stuff */
-#ifdef VG_PROFILE
-
-#define VGP_M_STACK 10
-
-#define VGP_M_CCS 26 /* == the # of elems in VGP_LIST */
-#define VGP_LIST \
- VGP_PAIR(VgpUnc=0, "unclassified"), \
- VGP_PAIR(VgpRun, "running"), \
- VGP_PAIR(VgpSched, "scheduler"), \
- VGP_PAIR(VgpMalloc, "low-lev malloc/free"), \
- VGP_PAIR(VgpCliMalloc, "client malloc/free"), \
- VGP_PAIR(VgpTranslate, "translate-main"), \
- VGP_PAIR(VgpToUCode, "to-ucode"), \
- VGP_PAIR(VgpFromUcode, "from-ucode"), \
- VGP_PAIR(VgpImprove, "improve"), \
- VGP_PAIR(VgpInstrument, "instrument"), \
- VGP_PAIR(VgpCleanup, "cleanup"), \
- VGP_PAIR(VgpRegAlloc, "reg-alloc"), \
- VGP_PAIR(VgpDoLRU, "do-lru"), \
- VGP_PAIR(VgpSlowFindT, "slow-search-transtab"), \
- VGP_PAIR(VgpInitAudit, "init-mem-audit"), \
- VGP_PAIR(VgpExeContext, "exe-context"), \
- VGP_PAIR(VgpReadSyms, "read-syms"), \
- VGP_PAIR(VgpAddToT, "add-to-transtab"), \
- VGP_PAIR(VgpSARP, "set-addr-range-perms"), \
- VGP_PAIR(VgpSyscall, "syscall wrapper"), \
- VGP_PAIR(VgpCacheInstrument, "cache instrument"), \
- VGP_PAIR(VgpCacheGetBBCC,"cache get BBCC"), \
- VGP_PAIR(VgpCacheSimulate, "cache simulate"), \
- VGP_PAIR(VgpCacheDump, "cache stats dump"), \
- VGP_PAIR(VgpSpare1, "spare 1"), \
- VGP_PAIR(VgpSpare2, "spare 2")
-
-#define VGP_PAIR(enumname,str) enumname
-typedef enum { VGP_LIST } VgpCC;
-#undef VGP_PAIR
+extern void VG_(shutdown_logging)( void );
extern void VGP_(init_profiling) ( void );
extern void VGP_(done_profiling) ( void );
-extern void VGP_(pushcc) ( VgpCC );
-extern void VGP_(popcc) ( void );
-#define VGP_PUSHCC(cc) VGP_(pushcc)(cc)
-#define VGP_POPCC VGP_(popcc)()
+#undef VGP_PUSHCC
+#undef VGP_POPCC
+#define VGP_PUSHCC(x) if (VG_(clo_profile)) VGP_(pushcc)(x)
+#define VGP_POPCC(x) if (VG_(clo_profile)) VGP_(popcc)(x)
+/* Use this for ones that happen a lot and thus we don't want to put in
+ all the time, eg. for %esp assignment. */
+#ifdef VGP_ACCURATE_PROFILING
+# define VGP_MAYBE_PUSHCC(x) if (VG_(clo_profile)) VGP_(pushcc)(x)
+# define VGP_MAYBE_POPCC(x) if (VG_(clo_profile)) VGP_(popcc)(x)
#else
-
-#define VGP_PUSHCC(cc) /* */
-#define VGP_POPCC /* */
-
-#endif /* VG_PROFILE */
+# define VGP_MAYBE_PUSHCC(x)
+# define VGP_MAYBE_POPCC(x)
+#endif
/* ---------------------------------------------------------------------
@@ -387,37 +246,40 @@
------------------------------------------------------------------ */
/* Allocation arenas.
+ CORE is for the core's general use.
+ SKIN is for the skin to use (and the only one it uses).
SYMTAB is for Valgrind's symbol table storage.
+ JITTER is for small storage during translation.
CLIENT is for the client's mallocs/frees.
DEMANGLE is for the C++ demangler.
EXECTXT is for storing ExeContexts.
- ERRCTXT is for storing ErrContexts.
- PRIVATE is for Valgrind general stuff.
+ ERRORS is for storing CoreErrors.
TRANSIENT is for very short-term use. It should be empty
in between uses.
- When adding a new arena, remember also to add it
- to ensure_mm_init().
+ When adding a new arena, remember also to add it to ensure_mm_init().
*/
typedef Int ArenaId;
-#define VG_N_ARENAS 7
+#define VG_N_ARENAS 9
-#define VG_AR_PRIVATE 0 /* :: ArenaId */
-#define VG_AR_SYMTAB 1 /* :: ArenaId */
-#define VG_AR_CLIENT 2 /* :: ArenaId */
-#define VG_AR_DEMANGLE 3 /* :: ArenaId */
-#define VG_AR_EXECTXT 4 /* :: ArenaId */
-#define VG_AR_ERRCTXT 5 /* :: ArenaId */
-#define VG_AR_TRANSIENT 6 /* :: ArenaId */
+#define VG_AR_CORE 0 /* :: ArenaId */
+#define VG_AR_SKIN 1 /* :: ArenaId */
+#define VG_AR_SYMTAB 2 /* :: ArenaId */
+#define VG_AR_JITTER 3 /* :: ArenaId */
+#define VG_AR_CLIENT 4 /* :: ArenaId */
+#define VG_AR_DEMANGLE 5 /* :: ArenaId */
+#define VG_AR_EXECTXT 6 /* :: ArenaId */
+#define VG_AR_ERRORS 7 /* :: ArenaId */
+#define VG_AR_TRANSIENT 8 /* :: ArenaId */
-extern void* VG_(malloc) ( ArenaId arena, Int nbytes );
-extern void VG_(free) ( ArenaId arena, void* ptr );
-extern void* VG_(calloc) ( ArenaId arena, Int nmemb, Int nbytes );
-extern void* VG_(realloc) ( ArenaId arena, void* ptr, Int size );
-extern void* VG_(malloc_aligned) ( ArenaId aid, Int req_alignB,
+extern void* VG_(arena_malloc) ( ArenaId arena, Int nbytes );
+extern void VG_(arena_free) ( ArenaId arena, void* ptr );
+extern void* VG_(arena_calloc) ( ArenaId arena, Int nmemb, Int nbytes );
+extern void* VG_(arena_realloc) ( ArenaId arena, void* ptr, Int alignment,
+ Int size );
+extern void* VG_(arena_malloc_aligned) ( ArenaId aid, Int req_alignB,
Int req_pszB );
-extern void VG_(mallocSanityCheckArena) ( ArenaId arena );
extern void VG_(mallocSanityCheckAll) ( void );
extern void VG_(show_all_arena_stats) ( void );
@@ -433,13 +295,13 @@
/* ---------------------------------------------------------------------
- Exports of vg_clientfuns.c
+ Exports of vg_clientfuncs.c
------------------------------------------------------------------ */
/* This doesn't export code or data that valgrind.so needs to link
against. However, the scheduler does need to know the following
request codes. A few, publically-visible, request codes are also
- defined in valgrind.h. */
+ defined in valgrind.h, and similar headers for some skins. */
#define VG_USERREQ__MALLOC 0x2001
#define VG_USERREQ__BUILTIN_NEW 0x2002
@@ -552,16 +414,6 @@
Exports of vg_scheduler.c
------------------------------------------------------------------ */
-/* ThreadIds are simply indices into the vg_threads[] array. */
-typedef
- UInt
- ThreadId;
-
-/* Special magic value for an invalid ThreadId. It corresponds to
- LinuxThreads using zero as the initial value for
- pthread_mutex_t.__m_owner and pthread_cond_t.__c_waiting. */
-#define VG_INVALID_THREADID ((ThreadId)(0))
-
typedef
enum {
VgTs_Empty, /* this slot is not in use */
@@ -594,140 +446,138 @@
ForkHandlerEntry;
-typedef
- struct {
- /* ThreadId == 0 (and hence vg_threads[0]) is NEVER USED.
- The thread identity is simply the index in vg_threads[].
- ThreadId == 1 is the root thread and has the special property
- that we don't try and allocate or deallocate its stack. For
- convenience of generating error message, we also put the
- ThreadId in this tid field, but be aware that it should
- ALWAYS == the index in vg_threads[]. */
- ThreadId tid;
+struct _ThreadState {
+ /* ThreadId == 0 (and hence vg_threads[0]) is NEVER USED.
+ The thread identity is simply the index in vg_threads[].
+ ThreadId == 1 is the root thread and has the special property
+ that we don't try and allocate or deallocate its stack. For
+ convenience of generating error message, we also put the
+ ThreadId in this tid field, but be aware that it should
+ ALWAYS == the index in vg_threads[]. */
+ ThreadId tid;
- /* Current scheduling status.
+ /* Current scheduling status.
- Complications: whenever this is set to VgTs_WaitMX, you
- should also set .m_edx to whatever the required return value
- is for pthread_mutex_lock / pthread_cond_timedwait for when
- the mutex finally gets unblocked. */
- ThreadStatus status;
+ Complications: whenever this is set to VgTs_WaitMX, you
+ should also set .m_edx to whatever the required return value
+ is for pthread_mutex_lock / pthread_cond_timedwait for when
+ the mutex finally gets unblocked. */
+ ThreadStatus status;
- /* When .status == WaitMX, points to the mutex I am waiting for.
- When .status == WaitCV, points to the mutex associated with
- the condition variable indicated by the .associated_cv field.
- In all other cases, should be NULL. */
- void* /* pthread_mutex_t* */ associated_mx;
+ /* When .status == WaitMX, points to the mutex I am waiting for.
+ When .status == WaitCV, points to the mutex associated with
+ the condition variable indicated by the .associated_cv field.
+ In all other cases, should be NULL. */
+ void* /*pthread_mutex_t* */ associated_mx;
- /* When .status == WaitCV, points to the condition variable I am
- waiting for. In all other cases, should be NULL. */
- void* /* pthread_cond_t* */ associated_cv;
+ /* When .status == WaitCV, points to the condition variable I am
+ waiting for. In all other cases, should be NULL. */
+ void* /*pthread_cond_t* */ associated_cv;
- /* If VgTs_Sleeping, this is when we should wake up, measured in
- milliseconds as supplied by VG_(read_millisecond_counter).
-
- If VgTs_WaitCV, this indicates the time at which
- pthread_cond_timedwait should wake up. If == 0xFFFFFFFF,
- this means infinitely far in the future, viz,
- pthread_cond_wait. */
- UInt awaken_at;
+ /* If VgTs_Sleeping, this is when we should wake up, measured in
+ milliseconds as supplied by VG_(read_millisecond_counter).
- /* If VgTs_WaitJoiner, return value, as generated by joinees. */
- void* joinee_retval;
+ If VgTs_WaitCV, this indicates the time at which
+ pthread_cond_timedwait should wake up. If == 0xFFFFFFFF,
+ this means infinitely far in the future, viz,
+ pthread_cond_wait. */
+ UInt awaken_at;
- /* If VgTs_WaitJoinee, place to copy the return value to, and
- the identity of the thread we're waiting for. */
- void** joiner_thread_return;
- ThreadId joiner_jee_tid;
+ /* If VgTs_WaitJoiner, return value, as generated by joinees. */
+ void* joinee_retval;
- /* Whether or not detached. */
- Bool detached;
+ /* If VgTs_WaitJoinee, place to copy the return value to, and
+ the identity of the thread we're waiting for. */
+ void** joiner_thread_return;
+ ThreadId joiner_jee_tid;
- /* Cancelability state and type. */
- Bool cancel_st; /* False==PTH_CANCEL_DISABLE; True==.._ENABLE */
- Bool cancel_ty; /* False==PTH_CANC_ASYNCH; True==..._DEFERRED */
-
- /* Pointer to fn to call to do cancellation. Indicates whether
- or not cancellation is pending. If NULL, not pending. Else
- should be &thread_exit_wrapper(), indicating that
- cancallation is pending. */
- void (*cancel_pend)(void*);
+ /* Whether or not detached. */
+ Bool detached;
- /* The cleanup stack. */
- Int custack_used;
- CleanupEntry custack[VG_N_CLEANUPSTACK];
+ /* Cancelability state and type. */
+ Bool cancel_st; /* False==PTH_CANCEL_DISABLE; True==.._ENABLE */
+ Bool cancel_ty; /* False==PTH_CANC_ASYNCH; True==..._DEFERRED */
+
+ /* Pointer to fn to call to do cancellation. Indicates whether
+ or not cancellation is pending. If NULL, not pending. Else
+ should be &thread_exit_wrapper(), indicating that
+ cancallation is pending. */
+ void (*cancel_pend)(void*);
- /* thread-specific data */
- void* specifics[VG_N_THREAD_KEYS];
+ /* The cleanup stack. */
+ Int custack_used;
+ CleanupEntry custack[VG_N_CLEANUPSTACK];
- /* This thread's blocked-signals mask. Semantics is that for a
- signal to be delivered to this thread, the signal must not be
- blocked by either the process-wide signal mask nor by this
- one. So, if this thread is prepared to handle any signal that
- the process as a whole is prepared to handle, this mask should
- be made empty -- and that it is its default, starting
- state. */
- vki_ksigset_t sig_mask;
+ /* thread-specific data */
+ void* specifics[VG_N_THREAD_KEYS];
- /* When not VgTs_WaitSIG, has no meaning. When VgTs_WaitSIG,
- is the set of signals for which we are sigwait()ing. */
- vki_ksigset_t sigs_waited_for;
+ /* This thread's blocked-signals mask. Semantics is that for a
+ signal to be delivered to this thread, the signal must not be
+ blocked by either the process-wide signal mask nor by this
+ one. So, if this thread is prepared to handle any signal that
+ the process as a whole is prepared to handle, this mask should
+ be made empty -- and that it is its default, starting
+ state. */
+ vki_ksigset_t sig_mask;
- /* Counts the number of times a signal handler for this thread
- has returned. This makes it easy to implement pause(), by
- polling this value, of course interspersed with nanosleeps,
- and waiting till it changes. */
- UInt n_signals_returned;
+ /* When not VgTs_WaitSIG, has no meaning. When VgTs_WaitSIG,
+ is the set of signals for which we are sigwait()ing. */
+ vki_ksigset_t sigs_waited_for;
- /* Stacks. When a thread slot is freed, we don't deallocate its
- stack; we just leave it lying around for the next use of the
- slot. If the next use of the slot requires a larger stack,
- only then is the old one deallocated and a new one
- allocated.
-
- For the main thread (threadid == 0), this mechanism doesn't
- apply. We don't know the size of the stack since we didn't
- allocate it, and furthermore we never reallocate it. */
+ /* Counts the number of times a signal handler for this thread
+ has returned. This makes it easy to implement pause(), by
+ polling this value, of course interspersed with nanosleeps,
+ and waiting till it changes. */
+ UInt n_signals_returned;
- /* The allocated size of this thread's stack (permanently zero
- if this is ThreadId == 0, since we didn't allocate its stack) */
- UInt stack_size;
+ /* Stacks. When a thread slot is freed, we don't deallocate its
+ stack; we just leave it lying around for the next use of the
+ slot. If the next use of the slot requires a larger stack,
+ only then is the old one deallocated and a new one
+ allocated.
- /* Address of the lowest word in this thread's stack. NULL means
- not allocated yet.
- */
- Addr stack_base;
+ For the main thread (threadid == 0), this mechanism doesn't
+ apply. We don't know the size of the stack since we didn't
+ allocate it, and furthermore we never reallocate it. */
- /* Address of the highest legitimate word in this stack. This is
- used for error messages only -- not critical for execution
- correctness. Is is set for all stacks, specifically including
- ThreadId == 0 (the main thread). */
- Addr stack_highest_word;
+ /* The allocated size of this thread's stack (permanently zero
+ if this is ThreadId == 0, since we didn't allocate its stack) */
+ UInt stack_size;
- /* Saved machine context. */
- UInt m_eax;
- UInt m_ebx;
- UInt m_ecx;
- UInt m_edx;
- UInt m_esi;
- UInt m_edi;
- UInt m_ebp;
- UInt m_esp;
- UInt m_eflags;
- UInt m_eip;
- UInt m_fpu[VG_SIZE_OF_FPUSTATE_W];
+ /* Address of the lowest word in this thread's stack. NULL means
+ not allocated yet.
+ */
+ Addr stack_base;
- UInt sh_eax;
- UInt sh_ebx;
- UInt sh_ecx;
- UInt sh_edx;
- UInt sh_esi;
- UInt sh_edi;
- UInt sh_ebp;
- UInt sh_esp;
- UInt sh_eflags;
- }
- ThreadState;
+ /* Address of the highest legitimate word in this stack. This is
+ used for error messages only -- not critical for execution
+ correctness. Is is set for all stacks, specifically including
+ ThreadId == 0 (the main thread). */
+ Addr stack_highest_word;
+
+ /* Saved machine context. */
+ UInt m_eax;
+ UInt m_ebx;
+ UInt m_ecx;
+ UInt m_edx;
+ UInt m_esi;
+ UInt m_edi;
+ UInt m_ebp;
+ UInt m_esp;
+ UInt m_eflags;
+ UInt m_eip;
+ UInt m_fpu[VG_SIZE_OF_FPUSTATE_W];
+
+ UInt sh_eax;
+ UInt sh_ebx;
+ UInt sh_ecx;
+ UInt sh_edx;
+ UInt sh_esi;
+ UInt sh_edi;
+ UInt sh_ebp;
+ UInt sh_esp;
+ UInt sh_eflags;
+};
/* The thread table. */
@@ -753,10 +603,6 @@
/* Similarly ... */
extern ThreadId VG_(get_current_tid) ( void );
-/* Which thread is this address in the stack of, if any? Used for
- error message generation. */
-extern ThreadId VG_(identify_stack_addr)( Addr a );
-
/* Nuke all threads except tid. */
extern void VG_(nuke_all_threads_except) ( ThreadId me );
@@ -795,12 +641,14 @@
the initial stack, which we can't move, is allocated here.
VG_(scheduler_init) checks this. Andrea Archelangi's 2.4 kernels
have been rumoured to start stacks at 0x80000000, so that too is
- considered. It seems systems with longer uptimes tend to to use
- stacks which start at 0x40000000 sometimes.
-*/
+ considered. It seems systems with longer uptimes tend to to use
+ stacks which start at 0x40000000 sometimes. JRS 2002-Aug-21: I
+ also have reports of stacks starting at 0xE0000000.*/
+
#define VG_STARTUP_STACK_BASE_1 (Addr)0xC0000000
#define VG_STARTUP_STACK_BASE_2 (Addr)0x80000000
#define VG_STARTUP_STACK_BASE_3 (Addr)0x40000000
+#define VG_STARTUP_STACK_BASE_4 (Addr)0xE0000000
#define VG_STARTUP_STACK_SMALLERTHAN 0x100000 /* 1024k */
#define VG_STACK_MATCHES_BASE(zzstack, zzbase) \
@@ -819,17 +667,24 @@
#define VG_AR_CLIENT_STACKBASE_REDZONE_SZB \
(VG_AR_CLIENT_STACKBASE_REDZONE_SZW * VKI_BYTES_PER_WORD)
+/* Junk to fill up a thread's shadow regs with when shadow regs aren't
+ * being used. */
+#define VG_UNUSED_SHADOW_REG_VALUE 0x27182818
+
+/* What we set a shadow register to when written by SET_EAX and similar
+ * things. */
+extern UInt VG_(written_shadow_reg);
/* Write a value to the client's %EDX (request return value register)
and set the shadow to indicate it is defined. */
-#define SET_EDX(zztid, zzval) \
- do { VG_(threads)[zztid].m_edx = (zzval); \
- VG_(threads)[zztid].sh_edx = VGM_WORD_VALID; \
+#define SET_EDX(zztid, zzval) \
+ do { VG_(threads)[zztid].m_edx = (zzval); \
+ VG_(threads)[zztid].sh_edx = VG_(written_shadow_reg); \
} while (0)
-#define SET_EAX(zztid, zzval) \
- do { VG_(threads)[zztid].m_eax = (zzval); \
- VG_(threads)[zztid].sh_eax = VGM_WORD_VALID; \
+#define SET_EAX(zztid, zzval) \
+ do { VG_(threads)[zztid].m_eax = (zzval); \
+ VG_(threads)[zztid].sh_eax = VG_(written_shadow_reg); \
} while (0)
@@ -875,87 +730,21 @@
Exports of vg_mylibc.c
------------------------------------------------------------------ */
+__attribute__((noreturn))
+extern void VG_(skin_error) ( Char* s );
-#if !defined(NULL)
-# define NULL ((void*)0)
-#endif
+/* VG_(brk) not public so skins cannot screw with curr_dataseg_end */
+extern void* VG_(brk) ( void* end_data_segment );
-extern void VG_(exit)( Int status )
- __attribute__ ((__noreturn__));
+/* Skins use VG_(strdup)() which doesn't expose ArenaId */
+extern Char* VG_(arena_strdup) ( ArenaId aid, const Char* s);
-extern void VG_(printf) ( const char *format, ... );
-/* too noisy ... __attribute__ ((format (printf, 1, 2))) ; */
-
-extern void VG_(sprintf) ( Char* buf, Char *format, ... );
-
-extern void VG_(vprintf) ( void(*send)(Char),
- const Char *format, va_list vargs );
-
-extern Bool VG_(isspace) ( Char c );
-extern Bool VG_(isdigit) ( Char c );
-
-extern Int VG_(strlen) ( const Char* str );
-
-extern Long VG_(atoll) ( Char* str );
-extern Long VG_(atoll36) ( Char* str );
-
-extern Char* VG_(strcat) ( Char* dest, const Char* src );
-extern Char* VG_(strncat) ( Char* dest, const Char* src, Int n );
-extern Char* VG_(strpbrk) ( const Char* s, const Char* accept );
-
-extern Char* VG_(strcpy) ( Char* dest, const Char* src );
-
-extern Int VG_(strcmp) ( const Char* s1, const Char* s2 );
-extern Int VG_(strcmp_ws) ( const Char* s1, const Char* s2 );
-
-extern Int VG_(strncmp) ( const Char* s1, const Char* s2, Int nmax );
-extern Int VG_(strncmp_ws) ( const Char* s1, const Char* s2, Int nmax );
-
-extern Char* VG_(strstr) ( const Char* haystack, Char* needle );
-extern Char* VG_(strchr) ( const Char* s, Char c );
-extern Char* VG_(strdup) ( ArenaId aid, const Char* s);
-
-extern Char* VG_(getenv) ( Char* name );
-extern Int VG_(getpid) ( void );
-
+/* Skins shouldn't need these...(?) */
extern void VG_(start_rdtsc_calibration) ( void );
extern void VG_(end_rdtsc_calibration) ( void );
extern UInt VG_(read_millisecond_timer) ( void );
-
-extern Char VG_(toupper) ( Char c );
-
-extern void VG_(strncpy_safely) ( Char* dest, const Char* src, Int ndest );
-
-extern void VG_(strncpy) ( Char* dest, const Char* src, Int ndest );
-
-extern Bool VG_(stringMatch) ( Char* pat, Char* str );
-
-
-#define VG__STRING(__str) #__str
-
-/* Asserts are permanently enabled. Hurrah! */
-#define vg_assert(expr) \
- ((void) ((expr) ? 0 : \
- (VG_(assert_fail) (VG__STRING(expr), \
- __FILE__, __LINE__, \
- __PRETTY_FUNCTION__), 0)))
-
-extern void VG_(assert_fail) ( Char* expr, Char* file,
- Int line, Char* fn )
- __attribute__ ((__noreturn__));
-
-/* Reading and writing files. */
-extern Int VG_(open_read) ( Char* pathname );
-extern Int VG_(open_write) ( Char* pathname );
-extern Int VG_(create_and_write) ( Char* pathname );
-extern void VG_(close) ( Int fd );
-extern Int VG_(read) ( Int fd, void* buf, Int count);
-extern Int VG_(write) ( Int fd, void* buf, Int count);
-extern Int VG_(stat) ( Char* file_name, struct vki_stat* buf );
-
-extern Int VG_(fcntl) ( Int fd, Int cmd, Int arg );
-
+extern Int VG_(fcntl) ( Int fd, Int cmd, Int arg );
extern Int VG_(select)( Int n,
vki_fd_set* readfds,
vki_fd_set* writefds,
@@ -964,306 +753,37 @@
extern Int VG_(nanosleep)( const struct vki_timespec *req,
struct vki_timespec *rem );
-
-/* mmap-ery ... */
-extern void* VG_(mmap)( void* start, UInt length,
- UInt prot, UInt flags, UInt fd, UInt offset );
-
-extern Int VG_(munmap)( void* start, Int length );
-
-extern void* VG_(brk) ( void* end_data_segment );
-
-
-/* Print a (panic) message, and abort. */
-extern void VG_(panic) ( Char* str )
- __attribute__ ((__noreturn__));
-
-/* Get memory by anonymous mmap. */
-extern void* VG_(get_memory_from_mmap) ( Int nBytes, Char* who );
-
-/* Crude stand-in for the glibc system() call. */
-extern Int VG_(system) ( Char* cmd );
-
-
-/* Signal stuff. Note that these use the vk_ (kernel) structure
- definitions, which are different in places from those that glibc
- defines. Since we're operating right at the kernel interface,
- glibc's view of the world is entirely irrelevant. */
-
-/* --- Signal set ops --- */
-extern Int VG_(ksigfillset)( vki_ksigset_t* set );
-extern Int VG_(ksigemptyset)( vki_ksigset_t* set );
-
-extern Bool VG_(kisfullsigset)( vki_ksigset_t* set );
-extern Bool VG_(kisemptysigset)( vki_ksigset_t* set );
-
-extern Int VG_(ksigaddset)( vki_ksigset_t* set, Int signum );
-extern Int VG_(ksigdelset)( vki_ksigset_t* set, Int signum );
-extern Int VG_(ksigismember) ( vki_ksigset_t* set, Int signum );
-
-extern void VG_(ksigaddset_from_set)( vki_ksigset_t* dst,
- vki_ksigset_t* src );
-extern void VG_(ksigdelset_from_set)( vki_ksigset_t* dst,
- vki_ksigset_t* src );
-
-/* --- Mess with the kernel's sig state --- */
-extern Int VG_(ksigprocmask)( Int how, const vki_ksigset_t* set,
- vki_ksigset_t* oldset );
-extern Int VG_(ksigaction) ( Int signum,
- const vki_ksigaction* act,
- vki_ksigaction* oldact );
-
-extern Int VG_(ksignal)(Int signum, void (*sighandler)(Int));
-
-extern Int VG_(ksigaltstack)( const vki_kstack_t* ss, vki_kstack_t* oss );
-
-extern Int VG_(kill)( Int pid, Int signo );
-extern Int VG_(sigpending) ( vki_ksigset_t* set );
-
-
/* ---------------------------------------------------------------------
Definitions for the JITter (vg_translate.c, vg_to_ucode.c,
vg_from_ucode.c).
------------------------------------------------------------------ */
-/* Tags which describe what operands are. */
-typedef
- enum { TempReg=0, ArchReg=1, RealReg=2,
- SpillNo=3, Literal=4, Lit16=5,
- NoValue=6 }
- Tag;
-
-
-/* Microinstruction opcodes. */
-typedef
- enum {
- NOP,
- GET,
- PUT,
- LOAD,
- STORE,
- MOV,
- CMOV, /* Used for cmpxchg and cmov */
- WIDEN,
- JMP,
-
- /* Read/write the %EFLAGS register into a TempReg. */
- GETF, PUTF,
-
- ADD, ADC, AND, OR, XOR, SUB, SBB,
- SHL, SHR, SAR, ROL, ROR, RCL, RCR,
- NOT, NEG, INC, DEC, BSWAP,
- CC2VAL,
-
- /* Not strictly needed, but useful for making better
- translations of address calculations. */
- LEA1, /* reg2 := const + reg1 */
- LEA2, /* reg3 := const + reg1 + reg2 * 1,2,4 or 8 */
-
- /* not for translating x86 calls -- only to call helpers */
- CALLM_S, CALLM_E, /* Mark start and end of push/pop sequences
- for CALLM. */
- PUSH, POP, CLEAR, /* Add/remove/zap args for helpers. */
- CALLM, /* call to a machine-code helper */
-
- /* for calling C functions -- CCALL_M_N passes M arguments and returns N
- * (0 or 1) return values */
- CCALL_1_0, CCALL_2_0,
-
- /* Hack for translating string (REP-) insns. Jump to literal if
- TempReg/RealReg is zero. */
- JIFZ,
-
- /* FPU ops which read/write mem or don't touch mem at all. */
- FPU_R,
- FPU_W,
- FPU,
-
- /* Advance the simulated %eip by some small (< 128) number. */
- INCEIP,
-
- /* uinstrs which are not needed for mere translation of x86 code,
- only for instrumentation of it. */
- LOADV,
- STOREV,
- GETV,
- PUTV,
- TESTV,
- SETV,
- /* Get/set the v-bit (and it is only one bit) for the simulated
- %eflags register. */
- GETVF,
- PUTVF,
-
- /* Do a unary or binary tag op. Only for post-instrumented
- code. For TAG1, first and only arg is a TempReg, and is both
- arg and result reg. For TAG2, first arg is src, second is
- dst, in the normal way; both are TempRegs. In both cases,
- 3rd arg is a RiCHelper with a Lit16 tag. This indicates
- which tag op to do. */
- TAG1,
- TAG2
- }
- Opcode;
-
-
-/* Condition codes, observing the Intel encoding. CondAlways is an
- extra. */
-typedef
- enum {
- CondO = 0, /* overflow */
- CondNO = 1, /* no overflow */
- CondB = 2, /* below */
- CondNB = 3, /* not below */
- CondZ = 4, /* zero */
- CondNZ = 5, /* not zero */
- CondBE = 6, /* below or equal */
- CondNBE = 7, /* not below or equal */
- CondS = 8, /* negative */
- ConsNS = 9, /* not negative */
- CondP = 10, /* parity even */
- CondNP = 11, /* not parity even */
- CondL = 12, /* jump less */
- CondNL = 13, /* not less */
- CondLE = 14, /* less or equal */
- CondNLE = 15, /* not less or equal */
- CondAlways = 16 /* Jump always */
- }
- Condcode;
-
-
-/* Descriptions of additional properties of *unconditional* jumps. */
-typedef
- enum {
- JmpBoring=0, /* boring unconditional jump */
- JmpCall=1, /* jump due to an x86 call insn */
- JmpRet=2, /* jump due to an x86 ret insn */
- JmpSyscall=3, /* do a system call, then jump */
- JmpClientReq=4 /* do a client request, then jump */
- }
- JmpKind;
-
-
-/* Flags. User-level code can only read/write O(verflow), S(ign),
- Z(ero), A(ux-carry), C(arry), P(arity), and may also write
- D(irection). That's a total of 7 flags. A FlagSet is a bitset,
- thusly:
- 76543210
- DOSZACP
- and bit 7 must always be zero since it is unused.
-*/
-typedef UChar FlagSet;
-
-#define FlagD (1<<6)
-#define FlagO (1<<5)
-#define FlagS (1<<4)
-#define FlagZ (1<<3)
-#define FlagA (1<<2)
-#define FlagC (1<<1)
-#define FlagP (1<<0)
-
-#define FlagsOSZACP (FlagO | FlagS | FlagZ | FlagA | FlagC | FlagP)
-#define FlagsOSZAP (FlagO | FlagS | FlagZ | FlagA | FlagP)
-#define FlagsOSZCP (FlagO | FlagS | FlagZ | FlagC | FlagP)
-#define FlagsOSACP (FlagO | FlagS | FlagA | FlagC | FlagP)
-#define FlagsSZACP ( FlagS | FlagZ | FlagA | FlagC | FlagP)
-#define FlagsSZAP ( FlagS | FlagZ | FlagA | FlagP)
-#define FlagsZCP ( FlagZ | FlagC | FlagP)
-#define FlagsOC (FlagO | FlagC )
-#define FlagsAC ( FlagA | FlagC )
-
-#define FlagsALL (FlagsOSZACP | FlagD)
-#define FlagsEmpty (FlagSet)0
-
#define VG_IS_FLAG_SUBSET(set1,set2) \
(( ((FlagSet)set1) & ((FlagSet)set2) ) == ((FlagSet)set1) )
#define VG_UNION_FLAG_SETS(set1,set2) \
( ((FlagSet)set1) | ((FlagSet)set2) )
-
-
-/* A Micro (u)-instruction. */
-typedef
- struct {
- /* word 1 */
- UInt lit32; /* 32-bit literal */
-
- /* word 2 */
- UShort val1; /* first operand */
- UShort val2; /* second operand */
-
- /* word 3 */
- UShort val3; /* third operand */
- UChar opcode; /* opcode */
- UChar size; /* data transfer size */
-
- /* word 4 */
- FlagSet flags_r; /* :: FlagSet */
- FlagSet flags_w; /* :: FlagSet */
- UChar tag1:4; /* first operand tag */
- UChar tag2:4; /* second operand tag */
- UChar tag3:4; /* third operand tag */
- UChar extra4b:4; /* Spare field, used by WIDEN for src
- -size, and by LEA2 for scale
- (1,2,4 or 8), and by unconditional JMPs for
- orig x86 instr size if --cachesim=yes */
-
-
- /* word 5 */
- UChar cond; /* condition, for jumps */
- Bool smc_check:1; /* do a smc test, if writes memory. */
- Bool signed_widen:1; /* signed or unsigned WIDEN ? */
- JmpKind jmpkind:3; /* additional properties of unconditional JMP */
- }
- UInstr;
-
-
-/* Expandable arrays of uinstrs. */
-typedef
- struct {
- Int used;
- Int size;
- UInstr* instrs;
- Int nextTemp;
- }
- UCodeBlock;
-
-/* Refer to `the last instruction stuffed in', including as an
- lvalue. */
-#define LAST_UINSTR(cb) (cb)->instrs[(cb)->used-1]
-
-/* An invalid temporary number :-) */
-#define INVALID_TEMPREG 999999999
-
-
/* ---------------------------------------------------------------------
Exports of vg_demangle.c
------------------------------------------------------------------ */
extern void VG_(demangle) ( Char* orig, Char* result, Int result_size );
-
/* ---------------------------------------------------------------------
Exports of vg_from_ucode.c
------------------------------------------------------------------ */
extern UChar* VG_(emit_code) ( UCodeBlock* cb, Int* nbytes );
+extern void VG_(print_ccall_stats) ( void );
+extern void VG_(print_UInstr_histogram) ( void );
/* ---------------------------------------------------------------------
Exports of vg_to_ucode.c
------------------------------------------------------------------ */
extern Int VG_(disBB) ( UCodeBlock* cb, Addr eip0 );
-extern Char* VG_(nameOfIntReg) ( Int size, Int reg );
-extern Char VG_(nameOfIntSize) ( Int size );
-extern UInt VG_(extend_s_8to32) ( UInt x );
-extern Int VG_(getNewTemp) ( UCodeBlock* cb );
-extern Int VG_(getNewShadow) ( UCodeBlock* cb );
-
-#define SHADOW(tempreg) ((tempreg)+1)
-
/* ---------------------------------------------------------------------
Exports of vg_translate.c
@@ -1275,41 +795,11 @@
Addr* trans_addr,
UInt* trans_size );
-extern void VG_(emptyUInstr) ( UInstr* u );
-extern void VG_(newUInstr0) ( UCodeBlock* cb, Opcode opcode, Int sz );
-extern void VG_(newUInstr1) ( UCodeBlock* cb, Opcode opcode, Int sz,
- Tag tag1, UInt val1 );
-extern void VG_(newUInstr2) ( UCodeBlock* cb, Opcode opcode, Int sz,
- Tag tag1, UInt val1,
- Tag tag2, UInt val2 );
-extern void VG_(newUInstr3) ( UCodeBlock* cb, Opcode opcode, Int sz,
- Tag tag1, UInt val1,
- Tag tag2, UInt val2,
- Tag tag3, UInt val3 );
-extern void VG_(setFlagRW) ( UInstr* u,
- FlagSet fr, FlagSet fw );
-
-extern void VG_(setLiteralField) ( UCodeBlock* cb, UInt lit32 );
-extern Bool VG_(anyFlagUse) ( UInstr* u );
-
-
-
-extern void VG_(ppUInstr) ( Int instrNo, UInstr* u );
-extern void VG_(ppUCodeBlock) ( UCodeBlock* cb, Char* title );
-
-extern UCodeBlock* VG_(allocCodeBlock) ( void );
-extern void VG_(freeCodeBlock) ( UCodeBlock* cb );
-extern void VG_(copyUInstr) ( UCodeBlock* cb, UInstr* instr );
-
-extern Char* VG_(nameCondcode) ( Condcode cond );
-extern Bool VG_(saneUInstr) ( Bool beforeRA, UInstr* u );
-extern Bool VG_(saneUCodeBlock) ( UCodeBlock* cb );
-extern Char* VG_(nameUOpcode) ( Bool upper, Opcode opc );
-extern Int VG_(rankToRealRegNo) ( Int rank );
-
-extern void* VG_(jitmalloc) ( Int nbytes );
-extern void VG_(jitfree) ( void* ptr );
-
+extern Char* VG_(nameCondcode) ( Condcode cond );
+extern Bool VG_(saneUInstr) ( Bool beforeRA, Bool beforeLiveness,
+ UInstr* u );
+extern void VG_(saneUCodeBlock) ( UCodeBlock* cb );
+extern Bool VG_(saneUCodeBlockCalls) ( UCodeBlock* cb );
/* ---------------------------------------------------------------------
Exports of vg_execontext.c.
@@ -1320,15 +810,13 @@
comparing against suppression specifications. The rest are purely
informational (but often important). */
-typedef
- struct _ExeContextRec {
- struct _ExeContextRec * next;
- /* The size of this array is VG_(clo_backtrace_size); at least
- 2, at most VG_DEEPEST_BACKTRACE. [0] is the current %eip,
- [1] is its caller, [2] is the caller of [1], etc. */
- Addr eips[0];
- }
- ExeContext;
+struct _ExeContext {
+ struct _ExeContext * next;
+ /* Variable-length array. The size is VG_(clo_backtrace_size); at
+ least 2, at most VG_DEEPEST_BACKTRACE. [0] is the current %eip,
+ [1] is its caller, [2] is the caller of [1], etc. */
+ Addr eips[0];
+};
/* Initialise the ExeContext storage mechanism. */
@@ -1337,91 +825,86 @@
/* Print stats (informational only). */
extern void VG_(show_ExeContext_stats) ( void );
-
-/* Take a snapshot of the client's stack. Search our collection of
- ExeContexts to see if we already have it, and if not, allocate a
- new one. Either way, return a pointer to the context. */
-extern ExeContext* VG_(get_ExeContext) ( Bool skip_top_frame,
- Addr eip, Addr ebp );
-
-/* Print an ExeContext. */
-extern void VG_(pp_ExeContext) ( ExeContext* );
-
-/* Compare two ExeContexts, just comparing the top two callers. */
-extern Bool VG_(eq_ExeContext_top2) ( ExeContext* e1, ExeContext* e2 );
-
-/* Compare two ExeContexts, just comparing the top four callers. */
-extern Bool VG_(eq_ExeContext_top4) ( ExeContext* e1, ExeContext* e2 );
-
-/* Compare two ExeContexts, comparing all callers. */
-extern Bool VG_(eq_ExeContext_all) ( ExeContext* e1, ExeContext* e2 );
-
+/* Like VG_(get_ExeContext), but with a slightly different type */
+extern ExeContext* VG_(get_ExeContext2) ( Addr eip, Addr ebp,
+ Addr ebp_min, Addr ebp_max );
/* ---------------------------------------------------------------------
Exports of vg_errcontext.c.
------------------------------------------------------------------ */
-extern void VG_(load_suppressions) ( void );
-extern void VG_(show_all_errors) ( void );
-extern void VG_(record_value_error) ( Int size );
-extern void VG_(record_free_error) ( ThreadState* tst, Addr a );
-extern void VG_(record_freemismatch_error) ( ThreadState* tst, Addr a );
-extern void VG_(record_address_error) ( Addr a, Int size,
- Bool isWrite );
-
-extern void VG_(record_jump_error) ( ThreadState* tst, Addr a );
-
-extern void VG_(record_param_err) ( ThreadState* tst,
- Addr a,
- Bool isWriteLack,
- Char* msg );
-extern void VG_(record_user_err) ( ThreadState* tst,
- Addr a, Bool isWriteLack );
-extern void VG_(record_pthread_err) ( ThreadId tid, Char* msg );
-
-
-
-/* The classification of a faulting address. */
-typedef
- enum { Undescribed, /* as-yet unclassified */
- Stack,
- Unknown, /* classification yielded nothing useful */
- Freed, Mallocd,
- UserG, UserS }
- AddrKind;
-
-/* Records info about a faulting address. */
+/* Note: it is imperative this doesn't overlap with (0..) at all, as skins
+ * effectively extend it by defining their own enums in the (0..) range. */
typedef
- struct {
- /* ALL */
- AddrKind akind;
- /* Freed, Mallocd */
- Int blksize;
- /* Freed, Mallocd */
- Int rwoffset;
- /* Freed, Mallocd */
- ExeContext* lastchange;
- /* Stack */
- ThreadId stack_tid;
- /* True if is just-below %esp -- could be a gcc bug. */
- Bool maybe_gcc;
+ enum {
+ PThreadSupp = -1, /* Matches PThreadErr */
}
- AddrInfo;
+ CoreSuppKind;
+
+/* For each caller specified for a suppression, record the nature of
+ the caller name. Not of interest to skins. */
+typedef
+ enum {
+ ObjName, /* Name is of an shared object file. */
+ FunName /* Name is of a function. */
+ }
+ SuppLocTy;
+
+/* Suppressions. Skin part `SkinSupp' (which is all skins have to deal
+ with) is in vg_skin.h */
+typedef
+ struct _CoreSupp {
+ struct _CoreSupp* next;
+ /* The number of times this error has been suppressed. */
+ Int count;
+ /* The name by which the suppression is referred to. */
+ Char* sname;
+ /* First two (name of fn where err occurs, and immediate caller)
+ * are mandatory; extra two are optional. */
+ SuppLocTy caller_ty[VG_N_SUPP_CALLERS];
+ Char* caller [VG_N_SUPP_CALLERS];
+ /* The skin-specific part */
+ SkinSupp skin_supp;
+ }
+ CoreSupp;
+
+/* Note: it is imperative this doesn't overlap with (0..) at all, as skins
+ * effectively extend it by defining their own enums in the (0..) range. */
+typedef
+ enum {
+ PThreadErr = -1, /* Pthreading error */
+ }
+ CoreErrorKind;
+
+/* Errors. Skin part `SkinError' (which is all skins have to deal
+ with) is in vg_skin.h */
+typedef
+ struct _CoreErrContext {
+ struct _CoreErrContext* next;
+ /* NULL if unsuppressed; or ptr to suppression record. */
+ CoreSupp* supp;
+ Int count;
+ ExeContext* where;
+ ThreadId tid;
+ /* These record %EIP, %ESP and %EBP at the error point. They
+ are only used to make GDB-attaching convenient; there is no
+ other purpose; specifically they are not used to do
+ comparisons between errors. */
+ UInt m_eip;
+ UInt m_esp;
+ UInt m_ebp;
+ /* The skin-specific part */
+ SkinError skin_err;
+ }
+ CoreError;
-/* ---------------------------------------------------------------------
- Exports of vg_clientperms.c
- ------------------------------------------------------------------ */
+extern void VG_(load_suppressions) ( void );
-extern Bool VG_(client_perm_maybe_describe)( Addr a, AddrInfo* ai );
+extern void VG_(record_pthread_error) ( ThreadId tid, Char* msg );
-extern UInt VG_(handle_client_request) ( ThreadState* tst, UInt* arg_block );
-
-extern void VG_(delete_client_stack_blocks_following_ESP_change) ( void );
-
-extern void VG_(show_client_block_stats) ( void );
-
+extern void VG_(show_all_errors) ( void );
/* ---------------------------------------------------------------------
Exports of vg_procselfmaps.c
@@ -1438,52 +921,26 @@
------------------------------------------------------------------ */
/* We assume the executable is loaded here ... can't really find
- out. There is a hacky sanity check in vg_init_memory_audit()
+ out. There is a hacky sanity check in VG_(init_memory)()
which should trip up most stupidities.
*/
#define VG_ASSUMED_EXE_BASE (Addr)0x8048000
-extern void VG_(read_symbols) ( void );
-extern void VG_(mini_stack_dump) ( ExeContext* ec );
-extern void VG_(what_obj_and_fun_is_this)
- ( Addr a,
- Char* obj_buf, Int n_obj_buf,
- Char* fun_buf, Int n_fun_buf );
-extern Bool VG_(what_line_is_this) ( Addr a,
- UChar* filename, Int n_filename,
- UInt* lineno );
-extern Bool VG_(what_fn_is_this) ( Bool no_demangle, Addr a,
- Char* fn_name, Int n_fn_name);
+extern void VG_(maybe_read_symbols) ( void );
+extern void VG_(read_symtab_callback) ( Addr start, UInt size,
+ Char rr, Char ww, Char xx,
+ UInt foffset, UChar* filename );
+extern void VG_(maybe_unload_symbols) ( Addr start, UInt length );
-extern Bool VG_(symtab_notify_munmap) ( Addr start, UInt length );
+extern Bool VG_(get_fnname_nodemangle)( Addr a, Char* fnname, Int n_fnname );
+extern void VG_(mini_stack_dump) ( ExeContext* ec );
/* ---------------------------------------------------------------------
Exports of vg_clientmalloc.c
------------------------------------------------------------------ */
-typedef
- enum {
- Vg_AllocMalloc = 0,
- Vg_AllocNew = 1,
- Vg_AllocNewVec = 2
- }
- VgAllocKind;
-
-/* Description of a malloc'd chunk. */
-typedef
- struct _ShadowChunk {
- struct _ShadowChunk* next;
- ExeContext* where; /* where malloc'd/free'd */
- UInt size : 30; /* size requested. */
- VgAllocKind allockind : 2; /* which wrapper did the allocation */
- Addr data; /* ptr to actual block. */
- }
- ShadowChunk;
-
-extern void VG_(clientmalloc_done) ( void );
-extern void VG_(describe_addr) ( Addr a, AddrInfo* ai );
-extern ShadowChunk** VG_(get_malloc_shadows) ( /*OUT*/ UInt* n_shadows );
+extern void VG_(client_malloc_init)();
/* These are called from the scheduler, when it intercepts a user
request. */
@@ -1503,11 +960,14 @@
Exports of vg_main.c
------------------------------------------------------------------ */
+/* Sanity checks which may be done at any time. The scheduler decides when. */
+extern void VG_(do_sanity_checks) ( Bool force_expensive );
+
/* A structure used as an intermediary when passing the simulated
CPU's state to some assembly fragments, particularly system calls.
Stuff is copied from baseBlock to here, the assembly magic runs,
- and then the inverse copy is done. */
-
+ and then the inverse copy is done.
+ */
extern UInt VG_(m_state_static) [8 /* int regs, in Intel order */
+ 1 /* %eflags */
+ 1 /* %eip */
@@ -1520,30 +980,27 @@
/* Called when some unhandleable client behaviour is detected.
Prints a msg and aborts. */
-extern void VG_(unimplemented) ( Char* msg );
+extern void VG_(unimplemented) ( Char* msg )
+ __attribute__((__noreturn__));
extern void VG_(nvidia_moan) ( void );
/* The stack on which Valgrind runs. We can't use the same stack as the
simulatee -- that's an important design decision. */
extern UInt VG_(stack)[10000];
-/* Similarly, we have to ask for signals to be delivered on an
- alternative stack, since it is possible, although unlikely, that
- we'll have to run client code from inside the Valgrind-installed
- signal handler. If this happens it will be done by
- vg_deliver_signal_immediately(). */
+/* Similarly, we have to ask for signals to be delivered on an alternative
+ stack, since it is possible, although unlikely, that we'll have to run
+ client code from inside the Valgrind-installed signal handler. If this
+ happens it will be done by vg_deliver_signal_immediately(). */
extern UInt VG_(sigstack)[10000];
/* Holds client's %esp at the point we gained control. From this the
client's argc, argv and envp are deduced. */
extern Addr VG_(esp_at_startup);
-extern Int VG_(client_argc);
-extern Char** VG_(client_argv);
-extern Char** VG_(client_envp);
-/* Remove valgrind.so from a LD_PRELOAD=... string so child processes
- don't get traced into. Also mess up $libdir/valgrind so that our
- libpthread.so disappears from view. */
+/* Remove valgrind.so and skin's .so from a LD_PRELOAD=... string so child
+ processes don't get traced into. Also mess up $libdir/valgrind so that
+ our libpthread.so disappears from view. */
void VG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH) ( Char* ld_preload_str,
Char* ld_library_path_str );
@@ -1553,9 +1010,6 @@
the client program really was running on the real cpu. */
extern void VG_(start_GDB_whilst_on_client_stack) ( void );
-/* Spew out vast amounts of junk during JITting? */
-extern Bool VG_(disassemble);
-
/* 64-bit counter for the number of basic blocks done. */
extern ULong VG_(bbs_done);
/* 64-bit counter for the number of bbs to go before a debug exit. */
@@ -1573,6 +1027,11 @@
/* This is the ThreadId of the last thread the scheduler ran. */
extern ThreadId VG_(last_run_tid);
+/* This is the argument to __NR_exit() supplied by the first thread to
+ call that syscall. We eventually pass that to __NR_exit() for
+ real. */
+extern UInt VG_(exitcode);
+
/* --- Counters, for informational purposes only. --- */
@@ -1628,83 +1087,38 @@
Exports of vg_memory.c
------------------------------------------------------------------ */
-extern void VGM_(init_memory_audit) ( void );
-extern Addr VGM_(curr_dataseg_end);
-extern void VG_(show_reg_tags) ( void );
-extern void VG_(detect_memory_leaks) ( void );
-extern void VG_(done_prof_mem) ( void );
+extern void VG_(init_memory) ( void );
+extern void VG_(new_exe_segment) ( Addr a, UInt len );
+extern void VG_(remove_if_exe_segment) ( Addr a, UInt len );
-/* Set permissions for an address range. Not speed-critical. */
-extern void VGM_(make_noaccess) ( Addr a, UInt len );
-extern void VGM_(make_writable) ( Addr a, UInt len );
-extern void VGM_(make_readable) ( Addr a, UInt len );
-/* Use with care! (read: use for shmat only) */
-extern void VGM_(make_readwritable) ( Addr a, UInt len );
-extern void VGM_(copy_address_range_perms) ( Addr src, Addr dst,
- UInt len );
-
-/* Check permissions for an address range. Not speed-critical. */
-extern Bool VGM_(check_writable) ( Addr a, UInt len, Addr* bad_addr );
-extern Bool VGM_(check_readable) ( Addr a, UInt len, Addr* bad_addr );
-extern Bool VGM_(check_readable_asciiz) ( Addr a, Addr* bad_addr );
-
-/* Sanity checks which may be done at any time. The scheduler decides
- when. */
-extern void VG_(do_sanity_checks) ( Bool force_expensive );
-/* Very cheap ... */
-extern Bool VG_(first_and_last_secondaries_look_plausible) ( void );
-
-/* These functions are called from generated code. */
-extern void VG_(helperc_STOREV4) ( UInt, Addr );
-extern void VG_(helperc_STOREV2) ( UInt, Addr );
-extern void VG_(helperc_STOREV1) ( UInt, Addr );
-
-extern UInt VG_(helperc_LOADV1) ( Addr );
-extern UInt VG_(helperc_LOADV2) ( Addr );
-extern UInt VG_(helperc_LOADV4) ( Addr );
-
-extern void VGM_(handle_esp_assignment) ( Addr new_espA );
-extern void VGM_(fpu_write_check) ( Addr addr, Int size );
-extern void VGM_(fpu_read_check) ( Addr addr, Int size );
-
-/* Safely (avoiding SIGSEGV / SIGBUS) scan the entire valid address
- space and pass the addresses and values of all addressible,
- defined, aligned words to notify_word. This is the basis for the
- leak detector. Returns the number of calls made to notify_word. */
-UInt VG_(scan_all_valid_memory) ( void (*notify_word)( Addr, UInt ) );
-
-/* Is this address within some small distance below %ESP? Used only
- for the --workaround-gcc296-bugs kludge. */
-extern Bool VG_(is_just_below_ESP)( Addr esp, Addr aa );
+/* Called from generated code. */
+extern void VG_(handle_esp_assignment) ( Addr new_espA );
/* Nasty kludgery to deal with applications which switch stacks,
like netscape. */
#define VG_PLAUSIBLE_STACK_SIZE 8000000
-/* Needed by the pthreads implementation. */
-#define VGM_WORD_VALID 0
-#define VGM_WORD_INVALID 0xFFFFFFFF
-
-
/* ---------------------------------------------------------------------
- Exports of vg_syscall_mem.c
+ Exports of vg_syscalls.c
------------------------------------------------------------------ */
+extern void VG_(init_dataseg_end_for_brk) ( void );
+
extern void VG_(perform_assumed_nonblocking_syscall) ( ThreadId tid );
-extern void VG_(check_known_blocking_syscall) ( ThreadId tid,
- Int syscallno,
- Int* /*IN*/ res );
+extern void* VG_(pre_known_blocking_syscall) ( ThreadId tid, Int syscallno );
+extern void VG_(post_known_blocking_syscall)( ThreadId tid, Int syscallno,
+ void* pre_res, Int res );
extern Bool VG_(is_kerror) ( Int res );
-#define KERNEL_DO_SYSCALL(thread_id, result_lvalue) \
- VG_(load_thread_state)(thread_id); \
- VG_(copy_baseBlock_to_m_state_static)(); \
- VG_(do_syscall)(); \
- VG_(copy_m_state_static_to_baseBlock)(); \
- VG_(save_thread_state)(thread_id); \
- VG_(threads)[thread_id].sh_eax = VGM_WORD_VALID; \
+#define KERNEL_DO_SYSCALL(thread_id, result_lvalue) \
+ VG_(load_thread_state)(thread_id); \
+ VG_(copy_baseBlock_to_m_state_static)(); \
+ VG_(do_syscall)(); \
+ VG_(copy_m_state_static_to_baseBlock)(); \
+ VG_(save_thread_state)(thread_id); \
+ VG_(threads)[thread_id].sh_eax = VG_(written_shadow_reg);\
result_lvalue = VG_(threads)[thread_id].m_eax;
@@ -1726,6 +1140,9 @@
/* The number of basic blocks in an epoch (one age-step). */
#define VG_BBS_PER_EPOCH 20000
+/* The fast-cache for tt-lookup. */
+extern Addr VG_(tt_fast)[VG_TT_FAST_SIZE];
+
extern void VG_(get_tt_tc_used) ( UInt* tt_used, UInt* tc_used );
extern void VG_(maybe_do_lru_pass) ( void );
extern void VG_(flush_transtab) ( void );
@@ -1742,40 +1159,6 @@
/* ---------------------------------------------------------------------
- Exports of vg_vtagops.c
- ------------------------------------------------------------------ */
-
-/* Lists the names of value-tag operations used in instrumented
- code. These are the third argument to TAG1 and TAG2 uinsns. */
-
-typedef
- enum {
- /* Unary. */
- VgT_PCast40, VgT_PCast20, VgT_PCast10,
- VgT_PCast01, VgT_PCast02, VgT_PCast04,
-
- VgT_PCast14, VgT_PCast12, VgT_PCast11,
-
- VgT_Left4, VgT_Left2, VgT_Left1,
-
- VgT_SWiden14, VgT_SWiden24, VgT_SWiden12,
- VgT_ZWiden14, VgT_ZWiden24, VgT_ZWiden12,
-
- /* Binary; 1st is rd; 2nd is rd+wr */
- VgT_UifU4, VgT_UifU2, VgT_UifU1, VgT_UifU0,
- VgT_DifD4, VgT_DifD2, VgT_DifD1,
-
- VgT_ImproveAND4_TQ, VgT_ImproveAND2_TQ, VgT_ImproveAND1_TQ,
- VgT_ImproveOR4_TQ, VgT_ImproveOR2_TQ, VgT_ImproveOR1_TQ,
- VgT_DebugFn
- }
- VgTagOp;
-
-extern Char* VG_(nameOfTagOp) ( VgTagOp );
-extern UInt VG_(DebugFn) ( UInt a1, UInt a2 );
-
-
-/* ---------------------------------------------------------------------
Exports of vg_syscall.S
------------------------------------------------------------------ */
@@ -1844,60 +1227,24 @@
extern void VG_(helper_DAS);
extern void VG_(helper_DAA);
-extern void VG_(helper_value_check4_fail);
-extern void VG_(helper_value_check2_fail);
-extern void VG_(helper_value_check1_fail);
-extern void VG_(helper_value_check0_fail);
-
/* NOT A FUNCTION; this is a bogus RETURN ADDRESS. */
extern void VG_(signalreturn_bogusRA)( void );
-
/* ---------------------------------------------------------------------
- Exports of vg_cachesim.c
+ Things relating to the used skin
------------------------------------------------------------------ */
-extern Int VG_(log2) ( Int x );
-
-extern UCodeBlock* VG_(cachesim_instrument) ( UCodeBlock* cb_in,
- Addr orig_addr );
-
-typedef struct _iCC iCC;
-typedef struct _idCC idCC;
-
-extern void VG_(init_cachesim) ( void );
-extern void VG_(do_cachesim_results)( Int client_argc, Char** client_argv );
-
-extern void VG_(cachesim_log_non_mem_instr)( iCC* cc );
-extern void VG_(cachesim_log_mem_instr) ( idCC* cc, Addr data_addr );
-
-extern void VG_(cachesim_notify_discard) ( TTEntry* tte );
+#define VG_TRACK(fn, args...) \
+ do { \
+ if (VG_(track_events).fn) \
+ VG_(track_events).fn(args); \
+ } while (0)
/* ---------------------------------------------------------------------
The state of the simulated CPU.
------------------------------------------------------------------ */
-/* This is the Intel register encoding. */
-#define R_EAX 0
-#define R_ECX 1
-#define R_EDX 2
-#define R_EBX 3
-#define R_ESP 4
-#define R_EBP 5
-#define R_ESI 6
-#define R_EDI 7
-
-#define R_AL (0+R_EAX)
-#define R_CL (0+R_ECX)
-#define R_DL (0+R_EDX)
-#define R_BL (0+R_EBX)
-#define R_AH (4+R_EAX)
-#define R_CH (4+R_ECX)
-#define R_DH (4+R_EDX)
-#define R_BH (4+R_EBX)
-
-
/* ---------------------------------------------------------------------
Offsets into baseBlock for everything which needs to referred to
from generated code. The order of these decls does not imply
@@ -1948,7 +1295,6 @@
extern Int VGOFF_(sh_edi);
extern Int VGOFF_(sh_eflags);
-
/* -----------------------------------------------------
Read-only parts of baseBlock.
-------------------------------------------------- */
@@ -1993,25 +1339,22 @@
extern Int VGOFF_(helper_DAS);
extern Int VGOFF_(helper_DAA);
-extern Int VGOFF_(helper_value_check4_fail);
-extern Int VGOFF_(helper_value_check2_fail);
-extern Int VGOFF_(helper_value_check1_fail);
-extern Int VGOFF_(helper_value_check0_fail);
-
-extern Int VGOFF_(helperc_STOREV4); /* :: UInt -> Addr -> void */
-extern Int VGOFF_(helperc_STOREV2); /* :: UInt -> Addr -> void */
-extern Int VGOFF_(helperc_STOREV1); /* :: UInt -> Addr -> void */
-
-extern Int VGOFF_(helperc_LOADV4); /* :: Addr -> UInt -> void */
-extern Int VGOFF_(helperc_LOADV2); /* :: Addr -> UInt -> void */
-extern Int VGOFF_(helperc_LOADV1); /* :: Addr -> UInt -> void */
-
extern Int VGOFF_(handle_esp_assignment); /* :: Addr -> void */
-extern Int VGOFF_(fpu_write_check); /* :: Addr -> Int -> void */
-extern Int VGOFF_(fpu_read_check); /* :: Addr -> Int -> void */
-extern Int VGOFF_(cachesim_log_non_mem_instr);
-extern Int VGOFF_(cachesim_log_mem_instr);
+/* For storing extension-specific helpers, determined at runtime. The addr
+ * and offset arrays together form a (addr, offset) map that allows a
+ * helper's baseBlock offset to be computed from its address. It's done
+ * like this so CCALL_M_Ns and other helper calls can use the function
+ * address rather than having to much around with offsets. */
+extern UInt VG_(n_compact_helpers);
+extern UInt VG_(n_noncompact_helpers);
+
+extern Addr VG_(compact_helper_addrs) [];
+extern Int VG_(compact_helper_offsets)[];
+
+extern Addr VG_(noncompact_helper_addrs) [];
+extern Int VG_(noncompact_helper_offsets)[];
+
#endif /* ndef __VG_INCLUDE_H */