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 */