Removed all uses of register numbers (eg. arch-specific ones like R_EAX, and
arch-neutral ones like R_STACK_PTR).  Where they were used, we now always talk
about an offset into the Vex guest state, and an offset.  As a result,
the shadow register get/set functions had to change.  They now also use
an offset and size, and in an arch-neutral way.

Also, I combined the five the post_reg_write* functions into a single one that
takes a 'CorePart' parameter (plus also a ThreadId).  Also, I added more
arguments (the CorePart, and the ThreadId) to the post_mem_write event, for
consistency with the pre_mem_* events.

Also, I reduced the number of register names that must be specified by each
arch, by factoring out duplication; and shortened their names for the core (eg.
ARCH_STACK_PTR is now STACK_PTR).

Plus some related minor cleanups in syscall wrappers.



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3094 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/addrcheck/ac_main.c b/addrcheck/ac_main.c
index 12ae62a..22d8169 100644
--- a/addrcheck/ac_main.c
+++ b/addrcheck/ac_main.c
@@ -630,6 +630,12 @@
    }
 }
 
+static
+void ac_post_mem_write(CorePart part, ThreadId tid, Addr a, SizeT len)
+{
+   ac_make_accessible(a, len);
+}
+
 
 /*------------------------------------------------------------*/
 /*--- Functions called directly from generated code.       ---*/
diff --git a/coregrind/core.h b/coregrind/core.h
index 8fac3b1..9d7302d 100644
--- a/coregrind/core.h
+++ b/coregrind/core.h
@@ -913,26 +913,26 @@
 // Write a value to a client's thread register, and shadow (if necessary).
 // Note that there are some further similar macros in the arch- and
 // platform-specific parts;  these ones are the totally generic ones.
-#define SET_THREAD_REG( zztid, zzval, zzGETREG, zzREG, zzevent, zzargs... ) \
-   do { zzGETREG(VG_(threads)[zztid].arch) = (zzval);         \
-        VG_TRACK( zzevent, zztid, zzREG, ##zzargs );          \
+#define SET_THREAD_REG( zztid, zzval, zzGETREG, zzevent, zzargs... ) \
+   do { zzGETREG(VG_(threads)[zztid].arch) = (zzval); \
+        VG_TRACK( zzevent, ##zzargs ); \
    } while (0)
 
 #define SET_CLREQ_RETVAL(zztid, zzval) \
-   SET_THREAD_REG(zztid, zzval, ARCH_CLREQ_RET, R_CLREQ_RET, \
-                  post_reg_write_clientreq_return)
+   SET_THREAD_REG(zztid, zzval, CLREQ_RET, post_reg_write, \
+                  Vg_CoreClientReq, zztid, O_CLREQ_RET, sizeof(UWord))
 
 #define SET_CLCALL_RETVAL(zztid, zzval, f) \
-   SET_THREAD_REG(zztid, zzval, ARCH_CLREQ_RET, R_CLREQ_RET, \
-                  post_reg_write_clientcall_return, f)
+   SET_THREAD_REG(zztid, zzval, CLREQ_RET, post_reg_write_clientcall_return, \
+                  zztid, O_CLREQ_RET, sizeof(UWord), f)
 
 #define SET_PTHREQ_ESP(zztid, zzval) \
-   SET_THREAD_REG(zztid, zzval, ARCH_STACK_PTR, R_STACK_PTR, \
-                  post_reg_write_pthread_return)
+   SET_THREAD_REG(zztid, zzval, STACK_PTR, post_reg_write, \
+                  Vg_CorePThread, zztid, O_STACK_PTR, sizeof(Addr))
 
 #define SET_PTHREQ_RETVAL(zztid, zzval) \
-   SET_THREAD_REG(zztid, zzval, ARCH_PTHREQ_RET, R_PTHREQ_RET, \
-                  post_reg_write_pthread_return)
+   SET_THREAD_REG(zztid, zzval, PTHREQ_RET, post_reg_write, \
+                  Vg_CorePThread, zztid, O_PTHREQ_RET, sizeof(UWord))
 
 
 /* ---------------------------------------------------------------------
@@ -1630,10 +1630,10 @@
 
 #define PRRSN \
       TL_(pre_reg_read)(Vg_CoreSysCall, tid, "(syscallno)", \
-                        R_SYSCALL_NUM, sizeof(UWord));
+                        O_SYSCALL_NUM, sizeof(UWord));
 #define PRRAn(n,s,t,a) \
       TL_(pre_reg_read)(Vg_CoreSysCall, tid, s"("#a")", \
-                        R_SYSCALL_ARG##n, sizeof(t));
+                        O_SYSCALL_ARG##n, sizeof(t));
 #define PRE_REG_READ0(tr, s) \
    if (VG_(defined_pre_reg_read)()) { \
       PRRSN; \
@@ -1682,7 +1682,7 @@
    VG_TRACK( pre_mem_write, Vg_CoreSysCall, tid, zzname, zzaddr, zzlen)
 
 #define POST_MEM_WRITE(zzaddr, zzlen) \
-   VG_TRACK( post_mem_write, zzaddr, zzlen)
+   VG_TRACK( post_mem_write, Vg_CoreSysCall, tid, zzaddr, zzlen)
 
 /* ---------------------------------------------------------------------
    Exports of vg_transtab.c
@@ -1754,6 +1754,23 @@
 // Architecture-specific things defined in eg. x86/*.c
 // ---------------------------------------------------------------------
 
+// Accessors for the ThreadArchState
+#define INSTR_PTR(regs)    ((regs).vex.ARCH_INSTR_PTR)
+#define STACK_PTR(regs)    ((regs).vex.ARCH_STACK_PTR)
+#define FRAME_PTR(regs)    ((regs).vex.ARCH_FRAME_PTR)
+
+#define CLREQ_ARGS(regs)   ((regs).vex.ARCH_CLREQ_ARGS)
+#define PTHREQ_RET(regs)   ((regs).vex.ARCH_PTHREQ_RET)
+#define CLREQ_RET(regs)    ((regs).vex.ARCH_CLREQ_RET)
+
+// Offsets for the shadow state
+#define O_STACK_PTR        (offsetof(VexGuestArchState, ARCH_STACK_PTR))
+#define O_FRAME_PTR        (offsetof(VexGuestArchState, ARCH_FRAME_PTR))
+
+#define O_CLREQ_RET        (offsetof(VexGuestArchState, ARCH_CLREQ_RET))
+#define O_PTHREQ_RET       (offsetof(VexGuestArchState, ARCH_PTHREQ_RET))
+
+
 // Setting up the initial thread (1) state
 extern void 
        VGA_(init_thread1state) ( Addr client_eip, 
@@ -1769,7 +1786,7 @@
 extern void VGA_(thread_initial_stack)  ( ThreadId tid, UWord arg, Addr ret );
 
 // Symtab stuff
-extern UInt* VGA_(reg_addr_from_tst) ( Int reg, ThreadArchState* );
+extern UInt* VGA_(reg_addr_from_tst) ( Int regno, ThreadArchState* );
 
 // Pointercheck
 extern Bool VGA_(setup_pointercheck) ( void );
@@ -1818,6 +1835,26 @@
 // Platform-specific things defined in eg. x86/*.c
 // ---------------------------------------------------------------------
 
+// Accessors for the ThreadArchState
+#define SYSCALL_NUM(regs)  ((regs).vex.PLATFORM_SYSCALL_NUM)
+#define SYSCALL_ARG1(regs) ((regs).vex.PLATFORM_SYSCALL_ARG1)
+#define SYSCALL_ARG2(regs) ((regs).vex.PLATFORM_SYSCALL_ARG2)
+#define SYSCALL_ARG3(regs) ((regs).vex.PLATFORM_SYSCALL_ARG3)
+#define SYSCALL_ARG4(regs) ((regs).vex.PLATFORM_SYSCALL_ARG4)
+#define SYSCALL_ARG5(regs) ((regs).vex.PLATFORM_SYSCALL_ARG5)
+#define SYSCALL_ARG6(regs) ((regs).vex.PLATFORM_SYSCALL_ARG6)
+#define SYSCALL_RET(regs)  ((regs).vex.PLATFORM_SYSCALL_RET)
+
+// Offsets for the shadow state
+#define O_SYSCALL_NUM   (offsetof(VexGuestArchState, PLATFORM_SYSCALL_ARG6))
+#define O_SYSCALL_ARG1  (offsetof(VexGuestArchState, PLATFORM_SYSCALL_ARG1))
+#define O_SYSCALL_ARG2  (offsetof(VexGuestArchState, PLATFORM_SYSCALL_ARG2))
+#define O_SYSCALL_ARG3  (offsetof(VexGuestArchState, PLATFORM_SYSCALL_ARG3))
+#define O_SYSCALL_ARG4  (offsetof(VexGuestArchState, PLATFORM_SYSCALL_ARG4))
+#define O_SYSCALL_ARG5  (offsetof(VexGuestArchState, PLATFORM_SYSCALL_ARG5))
+#define O_SYSCALL_ARG6  (offsetof(VexGuestArchState, PLATFORM_SYSCALL_ARG6))
+#define O_SYSCALL_RET   (offsetof(VexGuestArchState, PLATFORM_SYSCALL_RET))
+
 struct SyscallTableEntry {
    UInt  *flags_ptr;
    void        (*before)(ThreadId tid, ThreadState *tst);
diff --git a/coregrind/linux/syscalls.c b/coregrind/linux/syscalls.c
index 2832e4f..e731c82 100644
--- a/coregrind/linux/syscalls.c
+++ b/coregrind/linux/syscalls.c
@@ -43,14 +43,14 @@
 #define POST(x) \
    void VGA_(linux_##x##_after) (ThreadId tid, ThreadState *tst)
 
-#define SYSNO	PLATFORM_SYSCALL_NUM(tst->arch)    // in PRE(x)
-#define res	PLATFORM_SYSCALL_RET(tst->arch)	   // in POST(x)
-#define arg1	PLATFORM_SYSCALL_ARG1(tst->arch)
-#define arg2	PLATFORM_SYSCALL_ARG2(tst->arch)
-#define arg3	PLATFORM_SYSCALL_ARG3(tst->arch)
-#define arg4	PLATFORM_SYSCALL_ARG4(tst->arch)
-#define arg5	PLATFORM_SYSCALL_ARG5(tst->arch)
-#define arg6	PLATFORM_SYSCALL_ARG6(tst->arch)
+#define SYSNO   SYSCALL_NUM(tst->arch)    // in PRE(x)
+#define res     SYSCALL_RET(tst->arch)    // in POST(x)
+#define arg1    SYSCALL_ARG1(tst->arch)
+#define arg2    SYSCALL_ARG2(tst->arch)
+#define arg3    SYSCALL_ARG3(tst->arch)
+#define arg4    SYSCALL_ARG4(tst->arch)
+#define arg5    SYSCALL_ARG5(tst->arch)
+#define arg6    SYSCALL_ARG6(tst->arch)
 
 #define set_result(val) PLATFORM_SET_SYSCALL_RESULT(tst->arch, (val))
 
@@ -127,7 +127,7 @@
 
 POST(sys_adjtimex)
 {
-   VG_TRACK(post_mem_write, arg1, sizeof(struct vki_timex));
+   POST_MEM_WRITE( arg1, sizeof(struct vki_timex) );
 }
 
 PRE(sys_setfsuid16, 0)
diff --git a/coregrind/toolfuncs.def b/coregrind/toolfuncs.def
index 1fa39ef..cf60f1c 100644
--- a/coregrind/toolfuncs.def
+++ b/coregrind/toolfuncs.def
@@ -204,33 +204,21 @@
 void,	ban_mem_stack,	Addr a, SizeT len
 
 ## These ones occur around syscalls, signal handling, etc
-void,	pre_mem_read,	CorePart part, ThreadId tid, Char* s, Addr a, SizeT size
-void,	pre_mem_read_asciiz,	CorePart part, ThreadId tid, Char* s, Addr a
-void,	pre_mem_write,	CorePart part, ThreadId tid, Char* s, Addr a, SizeT size
-## Not implemented yet -- have to add in lots of places, which is a
-## pain.  Won't bother unless/until there's a need.
-## void (*post_mem_read)  ( ThreadState* tst, Char* s, Addr a, SizeT size );
-void,	post_mem_write,	Addr a, SizeT size
+void,	pre_mem_read,	    CorePart part, ThreadId tid, Char* s, Addr a, SizeT size
+void,	pre_mem_read_asciiz,CorePart part, ThreadId tid, Char* s, Addr a
+void,	pre_mem_write,	    CorePart part, ThreadId tid, Char* s, Addr a, SizeT size
+void,	post_mem_write,	    CorePart part, ThreadId tid, Addr a, SizeT size
 
 
-## Register events -- if `shadow_regs' need is set, all should probably be
-## used.  Use VG_(set_thread_shadow_archreg)() to set the shadow of the
-## changed register.
-
-void,	pre_reg_read,	CorePart part, ThreadId tid, Char* s, UInt reg, SizeT size
-
-## Use VG_(set_shadow_archreg)() to set the eight general purpose regs,
-## and use VG_(set_shadow_eflags)() to set eflags.
-void,	post_regs_write_init,	void
-
-## Use VG_(set_thread_shadow_archreg)() to set the shadow regs for these
+## Register events -- if `shadow_regs' need is set, these should probably be
+## used.  Use VG_(set_shadow_state_area)() to set the shadow regs for these
 ## events.
-void,	post_reg_write_syscall_return,	ThreadId tid, UInt reg
-void,	post_reg_write_deliver_signal,	ThreadId tid, UInt reg
-void,	post_reg_write_pthread_return,	ThreadId tid, UInt reg
-void,	post_reg_write_clientreq_return,	ThreadId tid, UInt reg
+
+void,	pre_reg_read,	CorePart part, ThreadId tid, Char* s, OffT guest_state_offset, SizeT size
+void,	post_reg_write,	CorePart part, ThreadId tid, OffT guest_state_offset, SizeT size
+
 ## This one is called for malloc() et al if they are replaced by a tool.
-void,	post_reg_write_clientcall_return,	ThreadId tid, UInt reg, Addr f
+void,	post_reg_write_clientcall_return,	ThreadId tid, OffT guest_state_offset, SizeT size, Addr f
 
 
 ## Scheduler events (not exhaustive)
diff --git a/coregrind/vg_execontext.c b/coregrind/vg_execontext.c
index 371d26e..8f53fc4 100644
--- a/coregrind/vg_execontext.c
+++ b/coregrind/vg_execontext.c
@@ -306,9 +306,9 @@
                      Addr* stack_highest_word)
 {
    ThreadState* tst = & VG_(threads)[ tid ];
-   *ip                 = ARCH_INSTR_PTR(tst->arch);
-   *fp                 = ARCH_FRAME_PTR(tst->arch);
-   *sp                 = ARCH_STACK_PTR(tst->arch);
+   *ip                 = INSTR_PTR(tst->arch);
+   *fp                 = FRAME_PTR(tst->arch);
+   *sp                 = STACK_PTR(tst->arch);
    *stack_highest_word = tst->stack_highest_word;
 
    /* Nasty little hack to deal with sysinfo syscalls - if libc is
@@ -355,7 +355,7 @@
 
 Addr VG_(get_EIP) ( ThreadId tid )
 {
-   return ARCH_INSTR_PTR(VG_(threads)[ tid ].arch);
+   return INSTR_PTR(VG_(threads)[ tid ].arch);
 }
 
 /*--------------------------------------------------------------------*/
diff --git a/coregrind/vg_main.c b/coregrind/vg_main.c
index 091391b..114ad1e 100644
--- a/coregrind/vg_main.c
+++ b/coregrind/vg_main.c
@@ -326,7 +326,7 @@
 /* Get the simulated stack pointer */
 Addr VG_(get_stack_pointer) ( ThreadId tid )
 {
-   return ARCH_STACK_PTR( VG_(threads)[tid].arch );
+   return STACK_PTR( VG_(threads)[tid].arch );
 }
 
 /* Initialize the PID and PGRP of scheduler LWP; this is also called
diff --git a/coregrind/vg_needs.c b/coregrind/vg_needs.c
index 4ac6354..c62c5b5 100644
--- a/coregrind/vg_needs.c
+++ b/coregrind/vg_needs.c
@@ -102,10 +102,7 @@
       VG_(tool_panic)("`die_mem_stack' should be defined\n");
    }
 
-   if ( (VG_(defined_post_reg_write_syscall_return)()    ||
-         VG_(defined_post_reg_write_deliver_signal)()    ||
-         VG_(defined_post_reg_write_pthread_return)()    ||
-         VG_(defined_post_reg_write_clientreq_return)()  ||
+   if ( (VG_(defined_post_reg_write)()    ||
          VG_(defined_post_reg_write_clientcall_return)()) &&
        ! VG_(needs).shadow_regs) 
    {
diff --git a/coregrind/vg_proxylwp.c b/coregrind/vg_proxylwp.c
index dde25f7..ae3d1f3 100644
--- a/coregrind/vg_proxylwp.c
+++ b/coregrind/vg_proxylwp.c
@@ -307,7 +307,7 @@
 	 anywhere else, except that we can make some assertions about
 	 the proxy and machine state here. */
       vg_assert(px->state == PXS_RunSyscall);
-      vg_assert(PLATFORM_SYSCALL_RET(px->tst->arch) == -VKI_ERESTARTSYS);
+      vg_assert(SYSCALL_RET(px->tst->arch) == -VKI_ERESTARTSYS);
    } else if (vga_sys_after <= ip && ip <= vga_sys_done) {
       /* We're after the syscall.  Either it was interrupted by the
 	 signal, or the syscall completed normally.  In either case
@@ -316,7 +316,7 @@
       vg_assert(px->state == PXS_RunSyscall ||
 		px->state == PXS_SysDone);
       px->state = PXS_SysDone;
-      PLATFORM_SYSCALL_RET(px->tst->arch) = sysnum;
+      SYSCALL_RET(px->tst->arch) = sysnum;
    }
    px_printf("  signalled in state %s\n", pxs_name(px->state));
 
@@ -433,7 +433,7 @@
 	       */
 	       reply.u.syscallno = tst->syscallno;
 
-	       PLATFORM_SYSCALL_RET(tst->arch) = -VKI_ERESTARTSYS;
+	       SYSCALL_RET(tst->arch) = -VKI_ERESTARTSYS;
 	       px->state = PXS_IntReply;
 	       break;
 
@@ -603,14 +603,14 @@
 	       */
 	       px_printf("RunSyscall in SigACK: rejecting syscall %d with ERESTARTSYS\n",
 			 reply.u.syscallno);
-	       PLATFORM_SYSCALL_RET(tst->arch) = -VKI_ERESTARTSYS;
+	       SYSCALL_RET(tst->arch) = -VKI_ERESTARTSYS;
 	    } else {
 	       Int syscallno = tst->syscallno;
 	       
 	       px->state = PXS_RunSyscall;
 	       /* If we're interrupted before we get to the syscall
 		  itself, we want the syscall restarted. */
-	       PLATFORM_SYSCALL_RET(tst->arch) = -VKI_ERESTARTSYS;
+	       SYSCALL_RET(tst->arch) = -VKI_ERESTARTSYS;
 
 	       /* set our process group ID to match parent */
 	       if (VG_(getpgrp)() != VG_(main_pgrp))
@@ -1022,8 +1022,8 @@
 	    if (VG_(clo_trace_syscalls))
 	       VG_(printf)("sys_wait_results: got PX_RunSyscall for SYSCALL[%d,%d](%3d) --> %lld (%llx)\n",
 			   VG_(getpid)(), res.tid, tst->syscallno,
-                            (Long)(Word)PLATFORM_SYSCALL_RET(tst->arch),
-                           (ULong)PLATFORM_SYSCALL_RET(tst->arch));
+                            (Long)(Word)SYSCALL_RET(tst->arch),
+                           (ULong)SYSCALL_RET(tst->arch));
 
 	    if (tst->status != VgTs_WaitSys)
 	       VG_(printf)("tid %d in status %d\n",
@@ -1201,8 +1201,8 @@
 
    req.request = PX_RunSyscall;
 
-   tst->syscallno = PLATFORM_SYSCALL_NUM(tst->arch);
-   PLATFORM_SYSCALL_RET(tst->arch) = -VKI_ERESTARTSYS;
+   tst->syscallno = SYSCALL_NUM(tst->arch);
+   SYSCALL_RET(tst->arch) = -VKI_ERESTARTSYS;
 
    res = VG_(write)(proxy->topx, &req, sizeof(req));
 
diff --git a/coregrind/vg_scheduler.c b/coregrind/vg_scheduler.c
index 4179360..ffb09d7 100644
--- a/coregrind/vg_scheduler.c
+++ b/coregrind/vg_scheduler.c
@@ -148,7 +148,7 @@
    for (tid = 1; tid < VG_N_THREADS; tid++) {
       if (VG_(threads)[tid].status == VgTs_Empty) continue;
       if (tid == tid_to_skip) continue;
-      if ( p ( ARCH_STACK_PTR(VG_(threads)[tid].arch),
+      if ( p ( STACK_PTR(VG_(threads)[tid].arch),
                VG_(threads)[tid].stack_highest_word, d ) )
          return tid;
    }
@@ -180,9 +180,9 @@
                   VG_(threads)[i].associated_mx,
                   VG_(threads)[i].associated_cv );
       VG_(pp_ExeContext)( 
-         VG_(get_ExeContext2)( ARCH_INSTR_PTR(VG_(threads)[i].arch),
-                               ARCH_FRAME_PTR(VG_(threads)[i].arch),
-                               ARCH_STACK_PTR(VG_(threads)[i].arch),
+         VG_(get_ExeContext2)( INSTR_PTR(VG_(threads)[i].arch),
+                               FRAME_PTR(VG_(threads)[i].arch),
+                               STACK_PTR(VG_(threads)[i].arch),
                                VG_(threads)[i].stack_highest_word)
       );
    }
@@ -443,12 +443,12 @@
       return;
 
    if (VG_(threads)[tid].status == VgTs_Sleeping
-       && PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_nanosleep) {
+       && SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_nanosleep) {
       /* We interrupted a nanosleep().  The right thing to do is to
          write the unused time to nanosleep's second param, but that's
          too much effort ... we just say that 1 nanosecond was not
          used, and return EINTR. */
-      rem = (struct vki_timespec*)PLATFORM_SYSCALL_ARG2(VG_(threads)[tid].arch);
+      rem = (struct vki_timespec*)SYSCALL_ARG2(VG_(threads)[tid].arch);
       if (rem != NULL) {
          rem->tv_sec = 0;
          rem->tv_nsec = 1;
@@ -502,7 +502,7 @@
    vg_assert(VG_(is_valid_tid)(tid));
    vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
 
-   syscall_no = PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch);
+   syscall_no = SYSCALL_NUM(VG_(threads)[tid].arch);
 
    /* Special-case nanosleep because we can.  But should we?
 
@@ -512,7 +512,7 @@
    if (0 && syscall_no == __NR_nanosleep) {
       UInt t_now, t_awaken;
       struct vki_timespec* req;
-      req = (struct vki_timespec*)PLATFORM_SYSCALL_ARG1(VG_(threads)[tid].arch);
+      req = (struct vki_timespec*)SYSCALL_ARG1(VG_(threads)[tid].arch);
 
       if (req->tv_sec < 0 || req->tv_nsec < 0 || req->tv_nsec >= 1000000000) {
 	 SET_SYSCALL_RETVAL(tid, -VKI_EINVAL);
@@ -821,18 +821,18 @@
          if (VG_(bbs_done) > 31700000 + 0) {
             dispatch_ctr_SAVED = VG_(dispatch_ctr) = 2;
             VG_(translate)(&VG_(threads)[tid], 
-                           ARCH_INSTR_PTR(VG_(threads)[tid].arch),
+                           INSTR_PTR(VG_(threads)[tid].arch),
                            /*debugging*/True);
          }
-         vg_assert(ARCH_INSTR_PTR(VG_(threads)[tid].arch) != 0);
+         vg_assert(INSTR_PTR(VG_(threads)[tid].arch) != 0);
 #        endif
 
          trc = run_thread_for_a_while ( tid );
 
 #        if 0
-         if (0 == ARCH_INSTR_PTR(VG_(threads)[tid].arch)) {
+         if (0 == INSTR_PTR(VG_(threads)[tid].arch)) {
             VG_(printf)("tid = %d,  dc = %llu\n", tid, VG_(bbs_done));
-            vg_assert(0 != ARCH_INSTR_PTR(VG_(threads)[tid].arch));
+            vg_assert(0 != INSTR_PTR(VG_(threads)[tid].arch));
          }
 #        endif
 
@@ -840,7 +840,7 @@
             thread. */
 
          if (trc == VG_TRC_INNER_FASTMISS) {
-            Addr ip = ARCH_INSTR_PTR(VG_(threads)[tid].arch);
+            Addr ip = INSTR_PTR(VG_(threads)[tid].arch);
 
             vg_assert(VG_(dispatch_ctr) > 1);
 
@@ -868,7 +868,7 @@
          }
 
          if (trc == VG_TRC_EBP_JMP_CLIENTREQ) {
-            UWord* args = (UWord*)(ARCH_CLREQ_ARGS(VG_(threads)[tid].arch));
+            UWord* args = (UWord*)(CLREQ_ARGS(VG_(threads)[tid].arch));
             UWord reqno = args[0];
             /* VG_(printf)("request 0x%x\n", reqno); */
 
@@ -899,7 +899,7 @@
                to exit. */
 #           if 0
             { UInt* esp; Int i;
-              esp=(UInt*)ARCH_STACK_PTR(VG_(threads)[tid].arch);
+              esp=(UInt*)STACK_PTR(VG_(threads)[tid].arch);
               VG_(printf)("\nBEFORE\n");
               for (i = 10; i >= -10; i--)
                  VG_(printf)("%2d  %p  =  0x%x\n", i, &esp[i], esp[i]);
@@ -917,24 +917,24 @@
                __libc_freeres does some invalid frees which crash
                the unprotected malloc/free system. */
 
-            if (PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_exit
-                || PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_exit_group
+            if (SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_exit
+                || SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_exit_group
                ) {
 
                /* Remember the supplied argument. */
-               *exitcode = PLATFORM_SYSCALL_ARG1(VG_(threads)[tid].arch);
+               *exitcode = SYSCALL_ARG1(VG_(threads)[tid].arch);
 
                // Inform tool about regs read by syscall
                VG_TRACK( pre_reg_read, Vg_CoreSysCall, tid, "(syscallno)",
-                         R_SYSCALL_NUM, sizeof(UWord) );
+                         O_SYSCALL_NUM, sizeof(UWord) );
 
-               if (PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_exit)
+               if (SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_exit)
                   VG_TRACK( pre_reg_read, Vg_CoreSysCall, tid,
-                            "exit(error_code)", R_SYSCALL_ARG1, sizeof(int) );
+                            "exit(error_code)", O_SYSCALL_ARG1, sizeof(int) );
 
-               if (PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_exit_group)
+               if (SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_exit_group)
                   VG_TRACK( pre_reg_read, Vg_CoreSysCall, tid,
-                            "exit_group(error_code)", R_SYSCALL_ARG1,
+                            "exit_group(error_code)", O_SYSCALL_ARG1,
                             sizeof(int) );
 
                /* Only run __libc_freeres if the tool says it's ok and
@@ -950,7 +950,7 @@
                         "Caught __NR_exit; running __libc_freeres()");
                   }
                   VG_(nuke_all_threads_except) ( tid );
-                  ARCH_INSTR_PTR(VG_(threads)[tid].arch) = 
+                  INSTR_PTR(VG_(threads)[tid].arch) = 
                      __libc_freeres_wrapper;
                   vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
                   goto stage1; /* party on, dudes (but not for much longer :) */
@@ -968,13 +968,13 @@
             }
 
             /* We've dealt with __NR_exit at this point. */
-            vg_assert(PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) != __NR_exit && 
-                      PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) != __NR_exit_group);
+            vg_assert(SYSCALL_NUM(VG_(threads)[tid].arch) != __NR_exit && 
+                      SYSCALL_NUM(VG_(threads)[tid].arch) != __NR_exit_group);
 
             /* Trap syscalls to __NR_sched_yield and just have this
                thread yield instead.  Not essential, just an
                optimisation. */
-	    if (PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_sched_yield) {
+	    if (SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_sched_yield) {
                SET_SYSCALL_RETVAL(tid, 0); /* syscall returns with success */
                goto stage1; /* find a new thread to run */
 	    }
@@ -983,7 +983,7 @@
 
 #           if 0
             { UInt* esp; Int i;
-              esp=(UInt*)ARCH_STACK_PTR(VG_(threads)[tid].arch);
+              esp=(UInt*)STACK_PTR(VG_(threads)[tid].arch);
               VG_(printf)("AFTER\n");
               for (i = 10; i >= -10; i--)
                  VG_(printf)("%2d  %p  =  0x%x\n", i, &esp[i], esp[i]);
@@ -1166,7 +1166,7 @@
    VGA_(set_arg_and_bogus_ret)(tid, (UWord)PTHREAD_CANCELED, 0xBEADDEEF);
 
    /* .cancel_pend will hold &thread_exit_wrapper */
-   ARCH_INSTR_PTR(VG_(threads)[tid].arch) = (UWord)VG_(threads)[tid].cancel_pend;
+   INSTR_PTR(VG_(threads)[tid].arch) = (UWord)VG_(threads)[tid].cancel_pend;
 
    VG_(proxy_abort_syscall)(tid);
 
@@ -1304,7 +1304,8 @@
          *thread_return = VG_(threads)[jee].joinee_retval;
          /* Not really right, since it makes the thread's return value
             appear to be defined even if it isn't. */
-         VG_TRACK( post_mem_write, (Addr)thread_return, sizeof(void*) );
+         VG_TRACK( post_mem_write, Vg_CorePThread, jnr,
+                   (Addr)thread_return, sizeof(void*) );
       }
 
       /* Joinee is discarded */
@@ -1413,7 +1414,8 @@
    VG_TRACK( pre_mem_write, Vg_CorePThread, tid,
                             "cleanup pop", (Addr)cu, sizeof(CleanupEntry) );
    *cu = VG_(threads)[tid].custack[sp];
-   VG_TRACK( post_mem_write, (Addr)cu, sizeof(CleanupEntry) );
+   VG_TRACK( post_mem_write, Vg_CorePThread, tid,
+                                           (Addr)cu, sizeof(CleanupEntry) );
    VG_(threads)[tid].custack_used = sp;
    SET_PTHREQ_RETVAL(tid, 0);
 }
@@ -1802,14 +1804,14 @@
    VG_TRACK ( die_mem_stack, VG_(threads)[tid].stack_base, 
                              VG_(threads)[tid].stack_size
                              - VG_AR_CLIENT_STACKBASE_REDZONE_SZB);
-   VG_TRACK ( ban_mem_stack, ARCH_STACK_PTR(VG_(threads)[tid].arch), 
+   VG_TRACK ( ban_mem_stack, STACK_PTR(VG_(threads)[tid].arch), 
                              VG_AR_CLIENT_STACKBASE_REDZONE_SZB );
    
    VGA_(thread_initial_stack)(tid, (UWord)arg,
                               (Addr)&do__apply_in_new_thread_bogusRA);
 
    /* this is where we start */
-   ARCH_INSTR_PTR(VG_(threads)[tid].arch) = (UWord)fn;
+   INSTR_PTR(VG_(threads)[tid].arch) = (UWord)fn;
 
    if (VG_(clo_trace_sched)) {
       VG_(sprintf)(msg_buf, "new thread, created by %d", parent_tid );
@@ -2482,7 +2484,8 @@
    VG_TRACK( pre_mem_write, Vg_CorePThread, tid, "pthread_key_create: key",
                             (Addr)key, sizeof(pthread_key_t));
    *key = i;
-   VG_TRACK( post_mem_write, (Addr)key, sizeof(pthread_key_t) );
+   VG_TRACK( post_mem_write, Vg_CorePThread, tid,
+                            (Addr)key, sizeof(pthread_key_t) );
 
    SET_PTHREQ_RETVAL(tid, 0);
 }
@@ -2598,7 +2601,8 @@
       cu->data.function.arg = VG_(threads)[tid].specifics_ptr[key];
    }
 
-   VG_TRACK( post_mem_write, (Addr)cu, sizeof(CleanupEntry) );
+   VG_TRACK( post_mem_write, Vg_CorePThread, tid, 
+                             (Addr)cu, sizeof(CleanupEntry) );
    SET_PTHREQ_RETVAL(tid, 0);
 }
 
@@ -2639,7 +2643,8 @@
    VG_(do_pthread_sigmask_SCSS_upd) ( tid, vki_how, newmask, oldmask );
 
    if (oldmask)
-      VG_TRACK( post_mem_write, (Addr)oldmask, sizeof(vki_sigset_t) );
+      VG_TRACK( post_mem_write, Vg_CorePThread, tid,
+                                (Addr)oldmask, sizeof(vki_sigset_t) );
 
    /* Success. */
    SET_PTHREQ_RETVAL(tid, 0);
@@ -2780,7 +2785,8 @@
    *fh = vg_fhstack[n];
    SET_PTHREQ_RETVAL(tid, 0);
 
-   VG_TRACK( post_mem_write, (Addr)fh, sizeof(ForkHandlerEntry) );
+   VG_TRACK( post_mem_write, Vg_CorePThread, tid,
+                             (Addr)fh, sizeof(ForkHandlerEntry) );
 }
 
 
@@ -2812,17 +2818,52 @@
 }
 
 /* ---------------------------------------------------------------------
-   Specifying shadow register values
+   Shadow register manipulations
    ------------------------------------------------------------------ */
 
-void VG_(set_return_from_syscall_shadow) ( ThreadId tid, UInt ret_shadow )
+void VG_(set_shadow_regs_area) ( ThreadId tid, OffT offset, SizeT size, 
+                                 const UChar* area )
 {
-   VGA_(set_thread_shadow_archreg)(tid, R_SYSCALL_RET, ret_shadow);
+   ThreadState* tst;
+
+   vg_assert(VG_(is_valid_tid)(tid));
+   tst = & VG_(threads)[tid];
+
+   // Bounds check
+   vg_assert(0 <= offset && offset < sizeof(VexGuestArchState));
+   vg_assert(offset + size <= sizeof(VexGuestArchState));
+
+   VG_(memcpy)( (void*)(((Addr)(&tst->arch.vex_shadow)) + offset), area, size);
+}
+
+void VG_(get_shadow_regs_area) ( ThreadId tid, OffT offset, SizeT size, 
+                                 UChar* area )
+{
+   ThreadState* tst;
+
+   vg_assert(VG_(is_valid_tid)(tid));
+   tst = & VG_(threads)[tid];
+
+   // Bounds check
+   vg_assert(0 <= offset && offset < sizeof(VexGuestArchState));
+   vg_assert(offset + size <= sizeof(VexGuestArchState));
+
+   VG_(memcpy)( area, (void*)(((Addr)&(tst->arch.vex_shadow)) + offset), size);
+}
+
+
+void VG_(set_return_from_syscall_shadow) ( ThreadId tid, UWord ret_shadow )
+{
+   VG_(set_shadow_regs_area)(tid, O_SYSCALL_RET, sizeof(UWord),
+                             (UChar*)&ret_shadow);
 }
 
 UInt VG_(get_exit_status_shadow) ( ThreadId tid )
 {
-   return VGA_(get_thread_shadow_archreg)(tid, R_SYSCALL_ARG1);
+   UInt ret;
+   VG_(get_shadow_regs_area)(tid, O_SYSCALL_ARG1, sizeof(UInt),
+                             (UChar*)&ret);
+   return ret;
 }
 
 void VG_(intercept_libc_freeres_wrapper)(Addr addr)
@@ -3273,7 +3314,7 @@
       if (VG_(threads)[i].status != VgTs_Empty) {
          Int
          stack_used = (Addr)VG_(threads)[i].stack_highest_word 
-                      - (Addr)ARCH_STACK_PTR(VG_(threads)[i].arch);
+                      - (Addr)STACK_PTR(VG_(threads)[i].arch);
          Int
          stack_avail = VG_(threads)[i].stack_size
                        - VG_AR_CLIENT_STACKBASE_REDZONE_SZB
diff --git a/coregrind/vg_signals.c b/coregrind/vg_signals.c
index 046ce2d..044e3b0 100644
--- a/coregrind/vg_signals.c
+++ b/coregrind/vg_signals.c
@@ -481,9 +481,9 @@
    Addr         m_SP;
 
    vg_assert(VG_(is_valid_tid)(tid));
-   ss    = (vki_stack_t*)PLATFORM_SYSCALL_ARG1(VG_(threads)[tid].arch);
-   oss   = (vki_stack_t*)PLATFORM_SYSCALL_ARG2(VG_(threads)[tid].arch);
-   m_SP  = ARCH_STACK_PTR(VG_(threads)[tid].arch);
+   ss    = (vki_stack_t*)SYSCALL_ARG1(VG_(threads)[tid].arch);
+   oss   = (vki_stack_t*)SYSCALL_ARG2(VG_(threads)[tid].arch);
+   m_SP  = STACK_PTR(VG_(threads)[tid].arch);
 
    if (VG_(clo_trace_signals))
       VG_(message)(Vg_DebugExtraMsg, 
@@ -498,7 +498,7 @@
    }
 
    if (ss != NULL) {
-      if (on_sig_stack(tid, ARCH_STACK_PTR(VG_(threads)[tid].arch))) {
+      if (on_sig_stack(tid, STACK_PTR(VG_(threads)[tid].arch))) {
          SET_SYSCALL_RETVAL(tid, -VKI_EPERM);
          return;
       }
@@ -534,9 +534,9 @@
    vg_assert(is_correct_sigmask());
 
    vg_assert(VG_(is_valid_tid)(tid));
-   signo   =                        PLATFORM_SYSCALL_ARG1(VG_(threads)[tid].arch);
-   new_act = (struct vki_sigaction*)PLATFORM_SYSCALL_ARG2(VG_(threads)[tid].arch);
-   old_act = (struct vki_sigaction*)PLATFORM_SYSCALL_ARG3(VG_(threads)[tid].arch);
+   signo   =                        SYSCALL_ARG1(VG_(threads)[tid].arch);
+   new_act = (struct vki_sigaction*)SYSCALL_ARG2(VG_(threads)[tid].arch);
+   old_act = (struct vki_sigaction*)SYSCALL_ARG3(VG_(threads)[tid].arch);
 
    if (VG_(clo_trace_signals))
       VG_(message)(Vg_DebugExtraMsg, 
@@ -839,7 +839,7 @@
        && /* there is a defined and enabled alt stack, which we're not
              already using.  Logic from get_sigframe in
              arch/i386/kernel/signal.c. */
-          sas_ss_flags(tid, ARCH_STACK_PTR(tst->arch)) == 0
+          sas_ss_flags(tid, STACK_PTR(tst->arch)) == 0
       ) {
       esp_top_of_frame 
          = (Addr)(tst->altstack.ss_sp) + tst->altstack.ss_size;
@@ -852,7 +852,7 @@
       VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/True );
       
    } else {
-      esp_top_of_frame = ARCH_STACK_PTR(tst->arch);
+      esp_top_of_frame = STACK_PTR(tst->arch);
 
       /* Signal delivery to tools */
       VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/False );
@@ -1503,8 +1503,8 @@
 
       if (tst->status == VgTs_WaitSys) {
 	 /* blocked in a syscall; we assume it should be interrupted */
-	 if (PLATFORM_SYSCALL_RET(tst->arch) == -VKI_ERESTARTSYS)
-	    PLATFORM_SYSCALL_RET(tst->arch) = -VKI_EINTR;
+	 if (SYSCALL_RET(tst->arch) == -VKI_ERESTARTSYS)
+	    SYSCALL_RET(tst->arch) = -VKI_EINTR;
       }
 
       VG_(proxy_sigack)(tid, &tst->sig_mask);
@@ -1729,7 +1729,7 @@
    if (info->si_signo == VKI_SIGSEGV) {
       ThreadId tid = VG_(get_current_tid)();
       Addr fault = (Addr)info->_sifields._sigfault._addr;
-      Addr esp   =  ARCH_STACK_PTR(VG_(threads)[tid].arch);
+      Addr esp   =  STACK_PTR(VG_(threads)[tid].arch);
       Segment *seg;
 
       seg = VG_(find_segment)(fault);
diff --git a/coregrind/vg_syscalls.c b/coregrind/vg_syscalls.c
index 9d02ccc..88cdd13 100644
--- a/coregrind/vg_syscalls.c
+++ b/coregrind/vg_syscalls.c
@@ -858,8 +858,7 @@
    if (VG_(defined_pre_mem_write)()) {
       UInt buflen_in = deref_UInt( tid, buflen_p, buflen_s);
       if (buflen_in > 0) {
-         TL_(pre_mem_write) ( Vg_CoreSysCall,
-			      tid, buf_s, buf_p, buflen_in );
+         TL_(pre_mem_write) ( Vg_CoreSysCall, tid, buf_s, buf_p, buflen_in );
       }
    }
 }
@@ -871,7 +870,7 @@
    if (!VG_(is_kerror)(res) && VG_(defined_post_mem_write)()) {
       UInt buflen_out = deref_UInt( tid, buflen_p, s);
       if (buflen_out > 0 && buf_p != (Addr)NULL) {
-         TL_(post_mem_write) ( buf_p, buflen_out );
+         TL_(post_mem_write) ( Vg_CoreSysCall, tid, buf_p, buflen_out );
       }
    }
 }
@@ -1023,14 +1022,14 @@
 #define POST(x) \
    void VGA_(gen_##x##_after) (ThreadId tid, ThreadState *tst)
 
-#define SYSNO	PLATFORM_SYSCALL_NUM(tst->arch)    // in PRE(x)
-#define res	PLATFORM_SYSCALL_RET(tst->arch)	   // in POST(x)
-#define arg1	PLATFORM_SYSCALL_ARG1(tst->arch)
-#define arg2	PLATFORM_SYSCALL_ARG2(tst->arch)
-#define arg3	PLATFORM_SYSCALL_ARG3(tst->arch)
-#define arg4	PLATFORM_SYSCALL_ARG4(tst->arch)
-#define arg5	PLATFORM_SYSCALL_ARG5(tst->arch)
-#define arg6	PLATFORM_SYSCALL_ARG6(tst->arch)
+#define SYSNO   SYSCALL_NUM(tst->arch)    // in PRE(x)
+#define res     SYSCALL_RET(tst->arch)    // in POST(x)
+#define arg1    SYSCALL_ARG1(tst->arch)
+#define arg2    SYSCALL_ARG2(tst->arch)
+#define arg3    SYSCALL_ARG3(tst->arch)
+#define arg4    SYSCALL_ARG4(tst->arch)
+#define arg5    SYSCALL_ARG5(tst->arch)
+#define arg6    SYSCALL_ARG6(tst->arch)
 
 #define set_result(val) PLATFORM_SET_SYSCALL_RESULT(tst->arch, (val))
 
@@ -1415,7 +1414,7 @@
 POST(sys_getitimer)
 {
    if (arg2 != (Addr)NULL) {
-      VG_TRACK( post_mem_write,arg2, sizeof(struct vki_itimerval));
+      POST_MEM_WRITE(arg2, sizeof(struct vki_itimerval));
    }
 }
 
@@ -1434,7 +1433,7 @@
 POST(sys_setitimer)
 {
    if (arg3 != (Addr)NULL) {
-      VG_TRACK( post_mem_write,arg3, sizeof(struct vki_itimerval));
+      POST_MEM_WRITE(arg3, sizeof(struct vki_itimerval));
    }
 }
 
@@ -2275,7 +2274,7 @@
    PRE_REG_READ0(long, "getppid");
 }
 
-static void common_post_getrlimit(UWord a1, UWord a2)
+static void common_post_getrlimit(ThreadId tid, UWord a1, UWord a2)
 {
    POST_MEM_WRITE( a2, sizeof(struct vki_rlimit) );
 
@@ -2305,7 +2304,7 @@
 
 POST(sys_old_getrlimit)
 {
-   common_post_getrlimit(arg1, arg2);
+   common_post_getrlimit(tid, arg1, arg2);
 }
 
 PRE(sys_getrlimit, 0)
@@ -2318,7 +2317,7 @@
 
 POST(sys_getrlimit)
 {
-   common_post_getrlimit(arg1, arg2);
+   common_post_getrlimit(tid, arg1, arg2);
 }
 
 PRE(sys_getrusage, 0)
@@ -2332,7 +2331,7 @@
 POST(sys_getrusage)
 {
    if (res == 0)
-      VG_TRACK( post_mem_write, arg2, sizeof(struct vki_rusage) );
+      POST_MEM_WRITE( arg2, sizeof(struct vki_rusage) );
 }
 
 PRE(sys_gettimeofday, 0)
@@ -3027,7 +3026,7 @@
 	 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", arg3, sizeof(struct ifconf));
 	 KERNEL_DO_SYSCALL(tid,res);
 	 if (!VG_(is_kerror)(res) && res == 0)
-	 VG_TRACK( post_mem_write,arg3, sizeof(struct ifconf));
+	 POST_MEM_WRITE(arg3, sizeof(struct ifconf));
       */
       PRE_MEM_READ( "ioctl(SIOCGIFCONF)", arg3, sizeof(struct vki_ifconf));
       if ( arg3 ) {
@@ -3645,28 +3644,28 @@
    case VKI_SG_SET_COMMAND_Q:
       break;
    case VKI_SG_IO:
-      VG_TRACK( post_mem_write,arg3, sizeof(vki_sg_io_hdr_t));
+      POST_MEM_WRITE(arg3, sizeof(vki_sg_io_hdr_t));
       break;
    case VKI_SG_GET_SCSI_ID:
-      VG_TRACK( post_mem_write,arg3, sizeof(vki_sg_scsi_id_t));
+      POST_MEM_WRITE(arg3, sizeof(vki_sg_scsi_id_t));
       break;
    case VKI_SG_SET_RESERVED_SIZE:
       break;
    case VKI_SG_SET_TIMEOUT:
       break;
    case VKI_SG_GET_RESERVED_SIZE:
-      VG_TRACK( post_mem_write,arg3, sizeof(int));
+      POST_MEM_WRITE(arg3, sizeof(int));
       break;
    case VKI_SG_GET_TIMEOUT:
-      VG_TRACK( post_mem_write,arg3, sizeof(int));
+      POST_MEM_WRITE(arg3, sizeof(int));
       break;
    case VKI_SG_GET_VERSION_NUM:
       break;
    case VKI_SG_EMULATED_HOST:
-      VG_TRACK( post_mem_write,arg3, sizeof(int));
+      POST_MEM_WRITE(arg3, sizeof(int));
       break;
    case VKI_SG_GET_SG_TABLESIZE:
-      VG_TRACK( post_mem_write,arg3, sizeof(int));
+      POST_MEM_WRITE(arg3, sizeof(int));
       break;      
 
    case VKI_IIOCGETCPS:
@@ -3678,61 +3677,57 @@
 
       /* These all use struct ifreq AFAIK */
    case VKI_SIOCGIFINDEX:        /* get iface index              */
-      VG_TRACK( post_mem_write,
-                (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_ifindex,
-                sizeof(((struct vki_ifreq *)arg3)->vki_ifr_ifindex) );
+      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_ifindex,
+                      sizeof(((struct vki_ifreq *)arg3)->vki_ifr_ifindex) );
       break;
    case VKI_SIOCGIFFLAGS:        /* get flags                    */
-      VG_TRACK( post_mem_write,
-                (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_flags,
-                sizeof(((struct vki_ifreq *)arg3)->vki_ifr_flags) );
+      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_flags,
+                      sizeof(((struct vki_ifreq *)arg3)->vki_ifr_flags) );
       break;
    case VKI_SIOCGIFHWADDR:       /* Get hardware address         */
-      VG_TRACK( post_mem_write,
-                (Addr)&((struct vki_ifreq *)arg3)->ifr_hwaddr,
-                sizeof(((struct vki_ifreq *)arg3)->ifr_hwaddr) );
+      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)arg3)->ifr_hwaddr,
+                      sizeof(((struct vki_ifreq *)arg3)->ifr_hwaddr) );
       break;
    case VKI_SIOCGIFMTU:          /* get MTU size                 */
-      VG_TRACK( post_mem_write,
-                (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_mtu,
-                sizeof(((struct vki_ifreq *)arg3)->vki_ifr_mtu) );
+      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_mtu,
+                      sizeof(((struct vki_ifreq *)arg3)->vki_ifr_mtu) );
       break;
    case VKI_SIOCGIFADDR:         /* get PA address               */
    case VKI_SIOCGIFDSTADDR:      /* get remote PA address        */
    case VKI_SIOCGIFBRDADDR:      /* get broadcast PA address     */
    case VKI_SIOCGIFNETMASK:      /* get network PA mask          */
-      VG_TRACK( post_mem_write,
+      POST_MEM_WRITE(
                 (Addr)&((struct vki_ifreq *)arg3)->ifr_addr,
                 sizeof(((struct vki_ifreq *)arg3)->ifr_addr) );
       break;
    case VKI_SIOCGIFMETRIC:       /* get metric                   */
-      VG_TRACK( post_mem_write,
+      POST_MEM_WRITE(
                 (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_metric,
                 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_metric) );
       break;
    case VKI_SIOCGIFMAP:          /* Get device parameters        */
-      VG_TRACK( post_mem_write,
+      POST_MEM_WRITE(
                 (Addr)&((struct vki_ifreq *)arg3)->ifr_map,
                 sizeof(((struct vki_ifreq *)arg3)->ifr_map) );
       break;
      break;
    case VKI_SIOCGIFTXQLEN:       /* Get the tx queue length      */
-      VG_TRACK( post_mem_write,
+      POST_MEM_WRITE(
                 (Addr)&((struct vki_ifreq *)arg3)->ifr_qlen,
                 sizeof(((struct vki_ifreq *)arg3)->ifr_qlen) );
       break;
    case VKI_SIOCGIFNAME:         /* get iface name               */
-      VG_TRACK( post_mem_write,
+      POST_MEM_WRITE(
                 (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_name,
                 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_name) );
       break;
    case VKI_SIOCGMIIPHY:         /* get hardware entry           */
-      VG_TRACK( post_mem_write,
+      POST_MEM_WRITE(
                 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->phy_id,
                 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->phy_id) );
       break;
    case VKI_SIOCGMIIREG:         /* get hardware entry registers */
-      VG_TRACK( post_mem_write,
+      POST_MEM_WRITE(
                 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->val_out,
                 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->val_out) );
       break;
@@ -3741,7 +3736,7 @@
 	 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", arg3, sizeof(struct ifconf));
 	 KERNEL_DO_SYSCALL(tid,res);
 	 if (!VG_(is_kerror)(res) && res == 0)
-	 VG_TRACK( post_mem_write,arg3, sizeof(struct ifconf));
+	 POST_MEM_WRITE(arg3, sizeof(struct ifconf));
       */
       if (res == 0 && arg3 ) {
 	 struct vki_ifconf *ifc = (struct vki_ifconf *) arg3;
@@ -3750,18 +3745,18 @@
       }
       break;
    case VKI_SIOCGSTAMP:
-      VG_TRACK( post_mem_write,arg3, sizeof(struct vki_timeval));
+      POST_MEM_WRITE( arg3, sizeof(struct vki_timeval) );
       break;
       /* SIOCOUTQ is an ioctl that, when called on a socket, returns
 	 the number of bytes currently in that socket's send buffer.
 	 It writes this value as an int to the memory location
 	 indicated by the third argument of ioctl(2). */
    case VKI_SIOCOUTQ:
-      VG_TRACK( post_mem_write,arg3, sizeof(int));
+      POST_MEM_WRITE(arg3, sizeof(int));
       break;
    case VKI_SIOCGRARP:           /* get RARP table entry         */
    case VKI_SIOCGARP:            /* get ARP table entry          */
-      VG_TRACK( post_mem_write,arg3, sizeof(struct vki_arpreq));
+      POST_MEM_WRITE(arg3, sizeof(struct vki_arpreq));
       break;
                     
    case VKI_SIOCSIFFLAGS:        /* set flags                    */
@@ -3790,7 +3785,7 @@
       break;
 
    case VKI_SIOCGPGRP:
-      VG_TRACK( post_mem_write,arg3, sizeof(int));
+      POST_MEM_WRITE(arg3, sizeof(int));
       break;
    case VKI_SIOCSPGRP:
       break;
@@ -3814,7 +3809,7 @@
    case VKI_SOUND_PCM_READ_BITS:
    case (VKI_SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */
    case VKI_SOUND_PCM_READ_FILTER:
-      VG_TRACK( post_mem_write,arg3, sizeof(int));
+      POST_MEM_WRITE(arg3, sizeof(int));
       break;
    case VKI_SNDCTL_SEQ_CTRLRATE:
    case VKI_SNDCTL_DSP_SPEED:
@@ -3834,7 +3829,7 @@
       break;
    case VKI_SNDCTL_DSP_GETOSPACE:
    case VKI_SNDCTL_DSP_GETISPACE:
-      VG_TRACK( post_mem_write,arg3, sizeof(vki_audio_buf_info));
+      POST_MEM_WRITE(arg3, sizeof(vki_audio_buf_info));
       break;
    case VKI_SNDCTL_DSP_SETTRIGGER:
       break;
@@ -3857,38 +3852,38 @@
       break;
    case VKI_RTC_RD_TIME:
    case VKI_RTC_ALM_READ:
-      VG_TRACK( post_mem_write,arg3, sizeof(struct vki_rtc_time));
+      POST_MEM_WRITE(arg3, sizeof(struct vki_rtc_time));
       break;
    case VKI_RTC_ALM_SET:
       break;
    case VKI_RTC_IRQP_READ:
-      VG_TRACK( post_mem_write,arg3, sizeof(unsigned long));
+      POST_MEM_WRITE(arg3, sizeof(unsigned long));
       break;
 
    case VKI_BLKGETSIZE:
-      VG_TRACK( post_mem_write,arg3, sizeof(unsigned long));
+      POST_MEM_WRITE(arg3, sizeof(unsigned long));
       break;
 
       /* Hard disks */
    case VKI_HDIO_GET_IDENTITY: /* 0x030d */
-      VG_TRACK( post_mem_write,arg3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
+      POST_MEM_WRITE(arg3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
       break;
 
       /* CD ROM stuff (??)  */
    case VKI_CDROMSUBCHNL:
-      VG_TRACK( post_mem_write,arg3, sizeof(struct vki_cdrom_subchnl));
+      POST_MEM_WRITE(arg3, sizeof(struct vki_cdrom_subchnl));
       break;
    case VKI_CDROMREADTOCHDR:
-      VG_TRACK( post_mem_write,arg3, sizeof(struct vki_cdrom_tochdr));
+      POST_MEM_WRITE(arg3, sizeof(struct vki_cdrom_tochdr));
       break;
    case VKI_CDROMREADTOCENTRY:
-      VG_TRACK( post_mem_write,arg3, sizeof(struct vki_cdrom_tochdr));
+      POST_MEM_WRITE(arg3, sizeof(struct vki_cdrom_tochdr));
       break;
    case VKI_CDROMMULTISESSION:
-      VG_TRACK( post_mem_write,arg3, sizeof(struct vki_cdrom_multisession));
+      POST_MEM_WRITE(arg3, sizeof(struct vki_cdrom_multisession));
       break;
    case VKI_CDROMVOLREAD:
-      VG_TRACK( post_mem_write,arg3, sizeof(struct vki_cdrom_volctrl));
+      POST_MEM_WRITE(arg3, sizeof(struct vki_cdrom_volctrl));
       break;
    case VKI_CDROMREADAUDIO:
    {
@@ -3906,17 +3901,17 @@
       break;
 
    case VKI_FIGETBSZ:
-      VG_TRACK( post_mem_write,arg3, sizeof(unsigned long));
+      POST_MEM_WRITE(arg3, sizeof(unsigned long));
       break;
    case VKI_FIBMAP:
-      VG_TRACK( post_mem_write,arg3, sizeof(unsigned long));
+      POST_MEM_WRITE(arg3, sizeof(unsigned long));
       break;
 
    case VKI_FBIOGET_VSCREENINFO: //0x4600
-      VG_TRACK( post_mem_write,arg3, sizeof(struct vki_fb_var_screeninfo));
+      POST_MEM_WRITE(arg3, sizeof(struct vki_fb_var_screeninfo));
       break;
    case VKI_FBIOGET_FSCREENINFO: //0x4602
-      VG_TRACK( post_mem_write,arg3, sizeof(struct vki_fb_fix_screeninfo));
+      POST_MEM_WRITE(arg3, sizeof(struct vki_fb_fix_screeninfo));
       break;
 
    case VKI_PPCLAIM:
@@ -4090,7 +4085,7 @@
       if (size > 0 && (dir & _VKI_IOC_READ)
 	  && res == 0
 	  && arg3 != (Addr)NULL)
-	 VG_TRACK( post_mem_write,arg3, size);
+	 POST_MEM_WRITE(arg3, size);
       break;
    }
    }
@@ -5282,7 +5277,7 @@
 
 POST(sys_sched_getaffinity)
 {
-   VG_TRACK(post_mem_write, arg3, arg2);
+   POST_MEM_WRITE(arg3, arg2);
 }
 
 PRE(sys_acct, 0)
diff --git a/coregrind/x86-linux/core_platform.h b/coregrind/x86-linux/core_platform.h
index 7810905..01ac0cd 100644
--- a/coregrind/x86-linux/core_platform.h
+++ b/coregrind/x86-linux/core_platform.h
@@ -36,36 +36,27 @@
 //#include "platform_arch.h"        // platform-specific tool stuff
 
 /* ---------------------------------------------------------------------
-   Interesting registers
+   Dealing with registers
    ------------------------------------------------------------------ */
 
 // Accessors for the ThreadArchState
-#define PLATFORM_SYSCALL_NUM(regs)     ((regs).vex.guest_EAX)
-#define PLATFORM_SYSCALL_RET(regs)     ((regs).vex.guest_EAX)
-#define PLATFORM_SYSCALL_ARG1(regs)    ((regs).vex.guest_EBX)
-#define PLATFORM_SYSCALL_ARG2(regs)    ((regs).vex.guest_ECX)
-#define PLATFORM_SYSCALL_ARG3(regs)    ((regs).vex.guest_EDX)
-#define PLATFORM_SYSCALL_ARG4(regs)    ((regs).vex.guest_ESI)
-#define PLATFORM_SYSCALL_ARG5(regs)    ((regs).vex.guest_EDI)
-#define PLATFORM_SYSCALL_ARG6(regs)    ((regs).vex.guest_EBP)
+#define PLATFORM_SYSCALL_NUM     guest_EAX
+#define PLATFORM_SYSCALL_ARG1    guest_EBX
+#define PLATFORM_SYSCALL_ARG2    guest_ECX
+#define PLATFORM_SYSCALL_ARG3    guest_EDX
+#define PLATFORM_SYSCALL_ARG4    guest_ESI
+#define PLATFORM_SYSCALL_ARG5    guest_EDI
+#define PLATFORM_SYSCALL_ARG6    guest_EBP
+#define PLATFORM_SYSCALL_RET     guest_EAX
 
+// Setting a syscall result
 #define PLATFORM_SET_SYSCALL_RESULT(regs, val)     \
    ((regs).vex.guest_EAX = (val))
 
-// Interesting register numbers
-#define R_SYSCALL_NUM                  R_EAX
-#define R_SYSCALL_ARG1                 R_EBX
-#define R_SYSCALL_ARG2                 R_ECX
-#define R_SYSCALL_ARG3                 R_EDX
-#define R_SYSCALL_ARG4                 R_ESI
-#define R_SYSCALL_ARG5                 R_EDI
-#define R_SYSCALL_ARG6                 R_EBP
-#define R_SYSCALL_RET                  R_EAX
-
 // Setting thread regs and shadow regs from within the core
 #define SET_SYSCALL_RETVAL(zztid, zzval) \
-   SET_THREAD_REG(zztid, zzval, PLATFORM_SYSCALL_RET, R_SYSCALL_RET, \
-                  post_reg_write_syscall_return)
+   SET_THREAD_REG(zztid, zzval, SYSCALL_RET, post_reg_write, \
+                  Vg_CoreSysCall, zztid, O_SYSCALL_RET, sizeof(UWord))
 
 /* ---------------------------------------------------------------------
    Exports of vg_ldt.c
@@ -115,7 +106,7 @@
 }
 
 #define PLATFORM_GET_MMAP_ARGS(tst, a1, a2, a3, a4, a5, a6) do {\
-   UInt *arg_block = (UInt*)PLATFORM_SYSCALL_ARG1(tst->arch);   \
+   UInt *arg_block = (UInt*)SYSCALL_ARG1(tst->arch);            \
    PRE_MEM_READ( "old_mmap(args)", arg1, 6*sizeof(UWord) );     \
    a1 = arg_block[0];                                           \
    a2 = arg_block[1];                                           \
diff --git a/coregrind/x86-linux/ldt.c b/coregrind/x86-linux/ldt.c
index 86173d1..a85b480 100644
--- a/coregrind/x86-linux/ldt.c
+++ b/coregrind/x86-linux/ldt.c
@@ -450,7 +450,7 @@
              "set_thread_area(info->entry)",
              (Addr) & info->entry_number, sizeof(unsigned int) );
    info->entry_number = idx + VKI_GDT_ENTRY_TLS_MIN;
-   VG_TRACK( post_mem_write,
+   VG_TRACK( post_mem_write, Vg_CoreSysCall, tid,
              (Addr) & info->entry_number, sizeof(unsigned int) );
 
    return 0;
diff --git a/coregrind/x86-linux/syscalls.c b/coregrind/x86-linux/syscalls.c
index 70d5758..97aede5 100644
--- a/coregrind/x86-linux/syscalls.c
+++ b/coregrind/x86-linux/syscalls.c
@@ -181,14 +181,14 @@
 #define POST(x) \
    static void x86_linux_##x##_after (ThreadId tid, ThreadState *tst)
 
-#define SYSNO	PLATFORM_SYSCALL_NUM(tst->arch)    // in PRE(x)
-#define res	PLATFORM_SYSCALL_RET(tst->arch)	   // in POST(x)
-#define arg1	PLATFORM_SYSCALL_ARG1(tst->arch)
-#define arg2	PLATFORM_SYSCALL_ARG2(tst->arch)
-#define arg3	PLATFORM_SYSCALL_ARG3(tst->arch)
-#define arg4	PLATFORM_SYSCALL_ARG4(tst->arch)
-#define arg5	PLATFORM_SYSCALL_ARG5(tst->arch)
-#define arg6	PLATFORM_SYSCALL_ARG6(tst->arch)
+#define SYSNO   SYSCALL_NUM(tst->arch)    // in PRE(x)
+#define res     SYSCALL_RET(tst->arch)    // in POST(x)
+#define arg1    SYSCALL_ARG1(tst->arch)
+#define arg2    SYSCALL_ARG2(tst->arch)
+#define arg3    SYSCALL_ARG3(tst->arch)
+#define arg4    SYSCALL_ARG4(tst->arch)
+#define arg5    SYSCALL_ARG5(tst->arch)
+#define arg6    SYSCALL_ARG6(tst->arch)
 
 #define set_result(val) PLATFORM_SET_SYSCALL_RESULT(tst->arch, (val))
 
diff --git a/coregrind/x86/core_arch.h b/coregrind/x86/core_arch.h
index 0d8747a..1b8f702 100644
--- a/coregrind/x86/core_arch.h
+++ b/coregrind/x86/core_arch.h
@@ -41,21 +41,18 @@
    Interesting registers
    ------------------------------------------------------------------ */
 
-// Accessors for the ThreadArchState
-#define ARCH_INSTR_PTR(regs)           ((regs).vex.guest_EIP)
-#define ARCH_STACK_PTR(regs)           ((regs).vex.guest_ESP)
-#define ARCH_FRAME_PTR(regs)           ((regs).vex.guest_EBP)
+// Vex field names
+#define ARCH_INSTR_PTR        guest_EIP
+#define ARCH_STACK_PTR        guest_ESP
+#define ARCH_FRAME_PTR        guest_EBP
 
-#define ARCH_CLREQ_ARGS(regs)          ((regs).vex.guest_EAX)
-#define ARCH_PTHREQ_RET(regs)          ((regs).vex.guest_EDX)
-#define ARCH_CLREQ_RET(regs)           ((regs).vex.guest_EDX)
+#define ARCH_CLREQ_ARGS       guest_EAX
+#define ARCH_CLREQ_RET        guest_EDX
+#define ARCH_PTHREQ_RET       guest_EDX
 
-// Accessors for the baseBlock
-#define R_STACK_PTR                    R_ESP
-#define R_FRAME_PTR                    R_EBP
-
-#define R_CLREQ_RET                    R_EDX
-#define R_PTHREQ_RET                   R_EDX
+// Register numbers, for vg_symtab2.c
+#define R_STACK_PTR           4
+#define R_FRAME_PTR           5
 
 // Stack frame layout and linkage
 #define FIRST_STACK_FRAME(ebp)         (ebp)
@@ -155,6 +152,7 @@
    } 
    ThreadArchState;
 
+typedef VexGuestX86State VexGuestArchState;
 
 /* ---------------------------------------------------------------------
    libpthread stuff
diff --git a/coregrind/x86/signal.c b/coregrind/x86/signal.c
index 59cf02b..3eed1c1 100644
--- a/coregrind/x86/signal.c
+++ b/coregrind/x86/signal.c
@@ -147,8 +147,8 @@
 }
 
 #define SET_SIGNAL_ESP(zztid, zzval) \
-   SET_THREAD_REG(zztid, zzval, ARCH_STACK_PTR, R_STACK_PTR, \
-                  post_reg_write_deliver_signal)
+   SET_THREAD_REG(zztid, zzval, STACK_PTR, post_reg_write, \
+                  Vg_CoreSignal, zztid, O_STACK_PTR, sizeof(Addr))
 
 void VGA_(push_signal_frame)(ThreadId tid, Addr esp_top_of_frame,
                              const vki_siginfo_t *siginfo,
@@ -181,7 +181,8 @@
    frame->retaddr    = (UInt)VG_(client_trampoline_code)+VG_(tramp_sigreturn_offset);
    frame->sigNo      = sigNo;
    frame->sigNo_private = sigNo;
-   VG_TRACK( post_mem_write, (Addr)frame, offsetof(VgSigFrame, handlerArgs) );
+   VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
+             (Addr)frame, offsetof(VgSigFrame, handlerArgs) );
 
    if (flags & VKI_SA_SIGINFO) {
       /* if the client asked for a siginfo delivery, then build the stack that way */
@@ -189,17 +190,20 @@
 		(Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigInfo) );
       frame->handlerArgs.sigInfo.psigInfo   = (Addr)&frame->sigInfo;
       frame->handlerArgs.sigInfo.puContext = (Addr)&frame->uContext;
-      VG_TRACK( post_mem_write, (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigInfo) );
+      VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
+                (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigInfo) );
 
       VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (siginfo)", 
 		(Addr)&frame->sigInfo, sizeof(frame->sigInfo) );
       VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t));
-      VG_TRACK( post_mem_write, (Addr)&frame->sigInfo, sizeof(frame->sigInfo) );
+      VG_TRACK( post_mem_write, Vg_CoreSignal, tid, 
+                (Addr)&frame->sigInfo, sizeof(frame->sigInfo) );
 
       VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (siginfo)", 
 		(Addr)&frame->uContext, sizeof(frame->uContext) );
       synth_ucontext(tid, siginfo, mask, &frame->uContext);
-      VG_TRACK( post_mem_write, (Addr)&frame->uContext, sizeof(frame->uContext) );
+      VG_TRACK( post_mem_write, Vg_CoreSignal, tid, 
+                (Addr)&frame->uContext, sizeof(frame->uContext) );
    } else {
       struct vki_ucontext uc;
 
@@ -211,8 +215,8 @@
 		(Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigContext) );
       VG_(memcpy)(&frame->handlerArgs.sigContext, &uc.uc_mcontext, 
 		  sizeof(struct vki_sigcontext));
-      VG_TRACK( post_mem_write, (Addr)&frame->handlerArgs, 
-		sizeof(frame->handlerArgs.sigContext) );
+      VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
+                (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigContext) );
       
       frame->handlerArgs.sigContext.oldmask = tst->sig_mask.sig[0];
    }
diff --git a/coregrind/x86/state.c b/coregrind/x86/state.c
index 3f710a9..5e97522 100644
--- a/coregrind/x86/state.c
+++ b/coregrind/x86/state.c
@@ -79,7 +79,8 @@
    VGOFF_(m_eip) = offsetof(VexGuestX86State,guest_EIP)/4;
 
    if (VG_(needs).shadow_regs) {
-      VG_TRACK( post_regs_write_init );
+      VG_TRACK( post_reg_write, Vg_CoreStartup, /*tid*/1, /*offset*/0,
+                sizeof(VexGuestArchState));
    }
 
    /* I assume that if we have SSE2 we also have SSE */
@@ -97,57 +98,6 @@
 
 
 /*------------------------------------------------------------*/
-/*--- Register access stuff                                ---*/
-/*------------------------------------------------------------*/
-
-void VGA_(set_thread_shadow_archreg) ( ThreadId tid, UInt archreg, UInt val )
-{
-   ThreadState* tst;
-
-   vg_assert(VG_(is_valid_tid)(tid));
-   tst = & VG_(threads)[tid];
-   if (0)
-   VG_(printf)("set_thread_shadow_archreg(%d, %d, 0x%x)\n",
-               tid, archreg, val);
-   switch (archreg) {
-      case R_EAX: tst->arch.vex_shadow.guest_EAX = val; break;
-      case R_ECX: tst->arch.vex_shadow.guest_ECX = val; break;
-      case R_EDX: tst->arch.vex_shadow.guest_EDX = val; break;
-      case R_EBX: tst->arch.vex_shadow.guest_EBX = val; break;
-      case R_ESP: tst->arch.vex_shadow.guest_ESP = val; break;
-      case R_EBP: tst->arch.vex_shadow.guest_EBP = val; break;
-      case R_ESI: tst->arch.vex_shadow.guest_ESI = val; break;
-      case R_EDI: tst->arch.vex_shadow.guest_EDI = val; break;
-      default:    VG_(core_panic)( "set_thread_shadow_archreg");
-   }
-}
-
-UInt VGA_(get_thread_shadow_archreg) ( ThreadId tid, UInt archreg )
-{
-   ThreadState* tst;
-
-   vg_assert(VG_(is_valid_tid)(tid));
-   tst = & VG_(threads)[tid];
-
-   if (0)
-   VG_(printf)("get_thread_shadow_archreg(%d, %d)\n",
-               tid, archreg);
-
-   switch (archreg) {
-      case R_EAX: return tst->arch.vex_shadow.guest_EAX;
-      case R_ECX: return tst->arch.vex_shadow.guest_ECX;
-      case R_EDX: return tst->arch.vex_shadow.guest_EDX;
-      case R_EBX: return tst->arch.vex_shadow.guest_EBX;
-      case R_ESP: return tst->arch.vex_shadow.guest_ESP;
-      case R_EBP: return tst->arch.vex_shadow.guest_EBP;
-      case R_ESI: return tst->arch.vex_shadow.guest_ESI;
-      case R_EDI: return tst->arch.vex_shadow.guest_EDI;
-      default:    VG_(core_panic)( "get_thread_shadow_archreg");
-   }
-}
-
-
-/*------------------------------------------------------------*/
 /*--- Thread stuff                                         ---*/
 /*------------------------------------------------------------*/
 
@@ -187,8 +137,8 @@
    /* Push the arg, and mark it as readable. */
    SET_PTHREQ_ESP(tid, VG_(threads)[tid].arch.vex.guest_ESP - sizeof(UWord));
    * (UInt*)(VG_(threads)[tid].arch.vex.guest_ESP) = arg;
-   VG_TRACK( post_mem_write, VG_(threads)[tid].arch.vex.guest_ESP, 
-                             sizeof(void*) );
+   VG_TRACK( post_mem_write, Vg_CoreSignal, tid, 
+             VG_(threads)[tid].arch.vex.guest_ESP, sizeof(void*) );
 
    /* Don't mark the pushed return address as readable; any attempt to read
       this is an internal valgrind bug since thread_exit_wrapper() should not
@@ -199,7 +149,7 @@
 
 void VGA_(thread_initial_stack)(ThreadId tid, UWord arg, Addr ret)
 {
-   Addr esp = (Addr)ARCH_STACK_PTR(VG_(threads)[tid].arch);
+   Addr esp = (Addr)STACK_PTR(VG_(threads)[tid].arch);
 
    /* push two args */
    esp -= 2 * sizeof(UWord);
@@ -213,7 +163,7 @@
    *(UWord*)(esp+sizeof(UWord)) = arg;
    *(UWord*)(esp)               = ret;
 
-   VG_TRACK ( post_mem_write, esp, 2 * sizeof(UWord) );
+   VG_TRACK ( post_mem_write, Vg_CoreSignal, tid, esp, 2 * sizeof(UWord) );
 }
 
 
@@ -221,6 +171,16 @@
 /*--- Symtab stuff                                         ---*/
 /*------------------------------------------------------------*/
 
+/* This is the Intel register encoding -- integer regs. */
+#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
+
 UInt *VGA_(reg_addr_from_tst)(Int regno, ThreadArchState *arch)
 {
    switch (regno) {
diff --git a/include/tool.h.base b/include/tool.h.base
index 31b278e..b59eb7e 100644
--- a/include/tool.h.base
+++ b/include/tool.h.base
@@ -566,28 +566,13 @@
 /* ------------------------------------------------------------------ */
 /* Accessing archregs and their shadows */
 
-extern UInt VGA_(get_archreg)            ( UInt archreg );
-extern UInt VGA_(get_thread_archreg)     ( ThreadId tid, UInt archreg );
+// For get/set, 'area' is where the asked-for shadow state will be copied
+// into/from.
 
-extern UInt VGA_(get_shadow_archreg)     ( UInt archreg );
-extern void VGA_(set_shadow_archreg)     ( UInt archreg, UInt val );
-
-extern UInt VGA_(get_thread_shadow_archreg) ( ThreadId tid, UInt archreg );
-extern void VGA_(set_thread_shadow_archreg) ( ThreadId tid, UInt archreg,
-                                              UInt val );
-
-/* ToDo: FIX */
-/* This is the Intel register encoding -- integer regs. */
-#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
-
-
+extern void VG_(get_shadow_regs_area) ( ThreadId tid, OffT guest_state_offset,
+                                        SizeT size, UChar* area );
+extern void VG_(set_shadow_regs_area) ( ThreadId tid, OffT guest_state_offset,
+                                        SizeT size, const UChar* area );
 
 /*====================================================================*/
 /*=== Execution contexts                                           ===*/
@@ -957,7 +942,7 @@
    syscall.  Call it from TL_(post_syscall)() (not TL_(pre_syscall)()!) to
    override the default shadow register value. */
 extern void VG_(set_return_from_syscall_shadow) ( ThreadId tid,
-                                                  UInt ret_shadow );
+                                                  UWord ret_shadow );
 
 /* This can be called from TL_(fini)() to find the shadow of the argument
    to exit(), ie. the shadow of the program's return value. */
@@ -1101,7 +1086,8 @@
 /* Part of the core from which this call was made.  Useful for determining
    what kind of error message should be emitted. */
 typedef
-   enum { Vg_CorePThread, Vg_CoreSignal, Vg_CoreSysCall, Vg_CoreTranslate }
+   enum { Vg_CoreStartup, Vg_CorePThread, Vg_CoreSignal, Vg_CoreSysCall,
+          Vg_CoreTranslate, Vg_CoreClientReq }
    CorePart;
 
 /* Useful to use in VG_(get_Xreg_usage)() */
diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c
index 94667c8..776814a 100644
--- a/memcheck/mc_main.c
+++ b/memcheck/mc_main.c
@@ -740,35 +740,36 @@
    else         mc_make_noaccess(a, len);
 }
 
+static
+void mc_post_mem_write(CorePart part, ThreadId tid, Addr a, SizeT len)
+{
+   mc_make_readable(a, len);
+}
 
 /*------------------------------------------------------------*/
 /*--- Register event handlers                              ---*/
 /*------------------------------------------------------------*/
 
-static void mc_post_regs_write_init ( void )
+// When a reg is written, mark the corresponding shadow reg bytes as valid.
+static void mc_post_reg_write(CorePart part, ThreadId tid, OffT offset,
+                              SizeT size)
 {
-#if 0
-   UInt i;
-   for (i = FIRST_ARCH_REG; i <= LAST_ARCH_REG; i++)
-      VG_(set_shadow_archreg)( i, VGM_WORD_VALID );
-   VG_(set_shadow_eflags)( VGM_EFLAGS_VALID );
-#endif
+   UChar area[size];
+   VG_(memset)(area, VGM_BYTE_VALID, size);
+   VG_(set_shadow_regs_area)( tid, offset, size, area );
 }
 
-static void mc_post_reg_write(ThreadId tid, UInt reg)
+static void mc_post_reg_write_clientcall(ThreadId tid, OffT offset, SizeT size,
+                                         Addr f)
 {
-   VGA_(set_thread_shadow_archreg)( tid, reg, VGM_WORD_VALID );
+   mc_post_reg_write(/*dummy*/0, tid, offset, size);
 }
 
-static void mc_post_reg_write_clientcall(ThreadId tid, UInt reg, Addr f )
-{
-   VGA_(set_thread_shadow_archreg)( tid, reg, VGM_WORD_VALID );
-}
-
-static void mc_pre_reg_read(CorePart part, ThreadId tid, Char* s, UInt reg,
+static void mc_pre_reg_read(CorePart part, ThreadId tid, Char* s, OffT offset,
                             SizeT size)
 {
    UWord mask;
+   UWord sh_reg_contents;
    
    // XXX: the only one at the moment
    tl_assert(Vg_CoreSysCall == part);
@@ -780,7 +781,8 @@
    default: VG_(tool_panic)("Unhandled size in mc_pre_reg_read");
    }
 
-   if (VGM_WORD_VALID != (mask & VGA_(get_thread_shadow_archreg)( tid, reg )) )
+   VG_(get_shadow_regs_area)( tid, offset, size, (UChar*)&sh_reg_contents );
+   if ( VGM_WORD_VALID != (mask & sh_reg_contents) )
       MAC_(record_param_error) ( tid, 0, /*isReg*/True, /*isUnaddr*/False, s );
 }
 
@@ -1950,15 +1952,11 @@
    VG_(init_pre_mem_read)         ( & mc_check_is_readable );
    VG_(init_pre_mem_read_asciiz)  ( & mc_check_is_readable_asciiz );
    VG_(init_pre_mem_write)        ( & mc_check_is_writable );
-   VG_(init_post_mem_write)       ( & mc_make_readable );
+   VG_(init_post_mem_write)       ( & mc_post_mem_write );
 
    VG_(init_pre_reg_read)         ( & mc_pre_reg_read );
 
-   VG_(init_post_regs_write_init)             ( & mc_post_regs_write_init );
-   VG_(init_post_reg_write_syscall_return)    ( & mc_post_reg_write );
-   VG_(init_post_reg_write_deliver_signal)    ( & mc_post_reg_write );
-   VG_(init_post_reg_write_pthread_return)    ( & mc_post_reg_write );
-   VG_(init_post_reg_write_clientreq_return)  ( & mc_post_reg_write );
+   VG_(init_post_reg_write)                   ( & mc_post_reg_write );
    VG_(init_post_reg_write_clientcall_return) ( & mc_post_reg_write_clientcall );
 
    VGP_(register_profile_event) ( VgpSetMem,   "set-mem-perms" );