]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Arch-abstraction:
authorNicholas Nethercote <n.nethercote@gmail.com>
Fri, 3 Sep 2004 13:45:29 +0000 (13:45 +0000)
committerNicholas Nethercote <n.nethercote@gmail.com>
Fri, 3 Sep 2004 13:45:29 +0000 (13:45 +0000)
- Added include/x86/:  contains tool_arch.h, Makefile.am, .cvsignore.

- Added coregrind/x86/state.c.  Contains some arch-specific code for dealing
  with x86 registers -- eg. setting up the baseBlock, loading/saving the whole
  register state.  It is compiled into coregrind/x86/libarch.a and linked via
  ${VG_ARCH} with the core.

  Relatedly, also added coregrind/x86/{core_arch.h,core_arch_asm.h}.

- Correspondingly abstracted the register state out of ThreadState.  This
  affected every place that touches registers, and there are a lot of them.
  (Eventually all the register touching should be abstracted out in an
  arch-neutral way, but not yet;  one step at a time.)

- Added some declarations about register loading/saving functions to core.h;
  all architectures will have to provide these functions.

- Rejigged the build system so that the arch-specific stuff is all done via
  ${VG_ARCH}, rather than naming e.g. x86/ directly.  Appropriate -I arguments
  are used so that all the headers are found, etc.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2656

29 files changed:
Makefile.core-AM_CPPFLAGS.am
Makefile.tool.am
configure.in
coregrind/Makefile.am
coregrind/core.h
coregrind/core_asm.h
coregrind/valgrind.vs
coregrind/vg_execontext.c
coregrind/vg_from_ucode.c
coregrind/vg_ldt.c
coregrind/vg_main.c
coregrind/vg_proxylwp.c
coregrind/vg_scheduler.c
coregrind/vg_signals.c
coregrind/vg_symtab2.c
coregrind/vg_syscalls.c
coregrind/vg_translate.c
coregrind/x86/Makefile.am
coregrind/x86/core_arch.h [new file with mode: 0644]
coregrind/x86/core_arch_asm.h [new file with mode: 0644]
coregrind/x86/state.c [new file with mode: 0644]
include/Makefile.am
include/tool.h.base
include/tool_asm.h
include/x86/.cvsignore [new file with mode: 0644]
include/x86/Makefile.am [new file with mode: 0644]
include/x86/tool_arch.h [new file with mode: 0644]
memcheck/mc_main.c
valgrind.spec.in

index 4a68b1ad099c2b24c3c7504da475a3b1b7a378af..ff660077e6281aa4db2c5702722c9600292bfcda 100644 (file)
@@ -1,5 +1,7 @@
 add_includes = -I$(top_builddir)/coregrind -I$(top_srcdir)/coregrind \
-               -I$(top_builddir)/include -I$(top_srcdir)/include
+               -I$(top_srcdir)/coregrind/$(VG_ARCH) \
+               -I$(top_builddir)/include -I$(top_srcdir)/include \
+               -I$(top_srcdir)/include/$(VG_ARCH)
 
 AM_CPPFLAGS = $(add_includes)
 
index cdde4b8d3b070000985bbcf3f18009b7253123d4..321f53a5515e84f74bb6920c0592827fba63de82 100644 (file)
@@ -5,7 +5,8 @@ SUBDIRS = . tests docs
 
 ## Need $(top_builddir)/include because tool.h is built from tool.h.base;
 ## otherwise it will not work if builddir != srcdir.
-add_includes = -I$(top_builddir)/include -I$(top_srcdir)/include
+add_includes = -I$(top_builddir)/include -I$(top_srcdir)/include \
+               -I$(top_srcdir)/include/$(VG_ARCH)
 
 AM_CPPFLAGS = $(add_includes)
 AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -O -fomit-frame-pointer \
index 50af03769e3bc8b3effc5dee2d44bb6d7cf6d437..8867f0749d0cb4b08fd575e97f59b492a33680eb 100644 (file)
@@ -391,6 +391,7 @@ AC_OUTPUT(
    tests/vg_regtest 
    tests/unused/Makefile 
    include/Makefile 
+   include/x86/Makefile 
    auxprogs/Makefile
    coregrind/Makefile 
    coregrind/demangle/Makefile 
index 1ef20f25293e63fa616f44edea88879c125a6c7f..cd9705481fb604cd02cb3c4c979bb82992a0fd12 100644 (file)
@@ -1,10 +1,9 @@
 include $(top_srcdir)/Makefile.all.am
 include $(top_srcdir)/Makefile.core-AM_CPPFLAGS.am
 
-SUBDIRS = x86 demangle . docs
+SUBDIRS = $(VG_ARCH) demangle . docs
 
 AM_CPPFLAGS += -DVG_LIBDIR="\"$(valdir)"\" -I$(srcdir)/demangle \
-               -I$(srcdir)/x86 \
                -DKICKSTART_BASE=$(KICKSTART_BASE)
 AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -O -fno-omit-frame-pointer \
                @PREFERRED_STACK_BOUNDARY@ -g -DELFSZ=32
@@ -92,6 +91,7 @@ stage2_LDADD= \
        demangle/cplus-dem.o \
        demangle/dyn-string.o \
        demangle/safe-ctype.o \
+       ${VG_ARCH}/libarch.a \
        -ldl
 
 vg_intercept.c: $(srcdir)/gen_intercepts.pl $(srcdir)/vg_intercept.c.base
index 2811a55218db77c969bd8a830cc31a94a43b0dc7..0eaabf4e0404e01fadf2577e287fa9acf20aa0f4 100644 (file)
@@ -85,6 +85,7 @@
 
 #include "core_asm.h"      // asm stuff
 #include "tool.h"          // tool stuff
+#include "core_arch.h"     // arch-specific stuff;  eg. x86/arch.h
 
 #include "valgrind.h"
 
@@ -573,26 +574,6 @@ struct vg_mallocfunc_info {
    Bool        clo_trace_malloc;
 };
 
-/* ---------------------------------------------------------------------
-   Constants pertaining to the simulated CPU state, VG_(baseBlock),
-   which need to go here to avoid ugly circularities.
-   ------------------------------------------------------------------ */
-
-/* How big is the saved SSE/SSE2 state?  Note that this subsumes the
-   FPU state.  On machines without SSE, we just save/restore the FPU
-   state into the first part of this area. */
-/* A general comment about SSE save/restore: It appears that the 7th
-   word (which is the MXCSR) has to be &ed with 0x0000FFBF in order
-   that restoring from it later does not cause a GP fault (which is
-   delivered as a segfault).  I guess this will have to be done
-   any time we do fxsave :-(  7th word means word offset 6 or byte
-   offset 24 from the start address of the save area.
- */
-#define VG_SIZE_OF_SSESTATE 512
-/* ... and in words ... */
-#define VG_SIZE_OF_SSESTATE_W ((VG_SIZE_OF_SSESTATE+3)/4)
-
-
 /* ---------------------------------------------------------------------
    Exports of vg_defaults.c
    ------------------------------------------------------------------ */
@@ -600,37 +581,6 @@ struct vg_mallocfunc_info {
 extern Bool VG_(sk_malloc_called_by_scheduler);
 
 
-/* ---------------------------------------------------------------------
-   Exports of vg_ldt.c
-   ------------------------------------------------------------------ */
-
-/* This is the hardware-format for a segment descriptor, ie what the
-   x86 actually deals with.  It is 8 bytes long.  It's ugly.  */
-
-typedef struct _LDT_ENTRY {
-    union {
-       struct {
-          UShort      LimitLow;
-          UShort      BaseLow;
-          unsigned    BaseMid         : 8;
-          unsigned    Type            : 5;
-          unsigned    Dpl             : 2;
-          unsigned    Pres            : 1;
-          unsigned    LimitHi         : 4;
-          unsigned    Sys             : 1;
-          unsigned    Reserved_0      : 1;
-          unsigned    Default_Big     : 1;
-          unsigned    Granularity     : 1;
-          unsigned    BaseHi          : 8;
-       } Bits;
-       struct {
-          UInt word1;
-          UInt word2;
-       } Words;
-    } 
-    LdtEnt;
-} VgLdtEntry;
-
 /* Maximum number of LDT entries supported (by the x86). */
 #define VG_M_LDT_ENTRIES     8192
 /* The size of each LDT entry == sizeof(VgLdtEntry) */
@@ -893,57 +843,8 @@ typedef
    /* Alternate signal stack */
    vki_kstack_t altstack;
 
-   /* Pointer to this thread's Local (Segment) Descriptor Table.
-      Starts out as NULL, indicating there is no table, and we hope to
-      keep it that way.  If the thread does __NR_modify_ldt to create
-      entries, we allocate a 8192-entry table at that point.  This is
-      a straight copy of the Linux kernel's scheme.  Don't forget to
-      deallocate this at thread exit. */
-   VgLdtEntry* ldt;
-
-   /* TLS table. This consists of a small number (currently 3) of
-      entries from the Global Descriptor Table. */
-   VgLdtEntry tls[VKI_GDT_TLS_ENTRIES];
-
-   /* Saved machine context.  Note the FPU state, %EIP and segment
-      registers are not shadowed.
-
-      Although the segment registers are 16 bits long, storage
-      management here and in VG_(baseBlock) is
-      simplified if we pretend they are 32 bits. */
-   UInt m_cs;
-   UInt m_ss;
-   UInt m_ds;
-   UInt m_es;
-   UInt m_fs;
-   UInt m_gs;
-
-   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;
-
-   /* The SSE/FPU state.  This array does not (necessarily) have the
-      required 16-byte alignment required to get stuff in/out by
-      fxsave/fxrestore.  So we have to do it "by hand".
-   */
-   UInt m_sse[VG_SIZE_OF_SSESTATE_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;
+   /* Architecture-specific thread state */
+   arch_thread_t arch;
 } 
 ThreadState;
 
@@ -1007,7 +908,7 @@ extern void VG_(scheduler_handle_fatal_signal)( Int sigNo );
 
 /* Write a value to a client's thread register, and shadow (if necessary) */
 #define SET_THREAD_REG( zztid, zzval, zzreg, zzREG, zzevent, zzargs... ) \
-   do { VG_(threads)[zztid].m_##zzreg = (zzval);                  \
+   do { VG_(threads)[zztid].arch.m_##zzreg = (zzval);             \
         VG_TRACK( zzevent, zztid, R_##zzREG, ##zzargs );          \
    } while (0)
 
@@ -1668,7 +1569,12 @@ extern Int VGOFF_(tls_ptr);
 
 extern Int VGOFF_(helper_undefined_instruction);
 
-#endif /* ndef __CORE_H */
+// ---------------------------------------------------------------------
+// Architecture-specific things defined in eg. x86/*.c
+// ---------------------------------------------------------------------
+
+extern void VGA_(load_state) ( arch_thread_t*, ThreadId tid );
+extern void VGA_(save_state) ( arch_thread_t*, ThreadId tid );
 
 
 /* ---------------------------------------------------------------------
@@ -1677,6 +1583,8 @@ extern Int VGOFF_(helper_undefined_instruction);
 
 #include "config.h"
 
+#endif /* ndef __CORE_H */
+
 /*--------------------------------------------------------------------*/
 /*--- end                                                          ---*/
 /*--------------------------------------------------------------------*/
index 9d470d4636dc7affee46d355d7b7161f92a96dc8..25b62418eb9fa79d1e7e1a4b183503026c8a6e51 100644 (file)
@@ -31,7 +31,8 @@
 #ifndef __CORE_ASM_H
 #define __CORE_ASM_H
 
-#include "tool_asm.h"
+#include "tool_asm.h"            // tool asm stuff
+#include "core_arch_asm.h"       // arch-specific asm stuff
 
 /* This file is included in all Valgrind source files, including
    assembly ones. */
 #define VG_TRC_INNER_COUNTERZERO  29 /* TRC only; means bb ctr == 0 */
 #define VG_TRC_UNRESUMABLE_SIGNAL 37 /* TRC only; got sigsegv/sigbus */
 
-/* size of call instruction put into generated code at jump sites */
-#define VG_PATCHME_CALLSZ      5
-
-/* size of jmp instruction which overwrites the call */
-#define VG_PATCHME_JMPSZ       5
-
 /* maximum number of normal jumps which can appear in a basic block */
 #define VG_MAX_JUMPS           2
 
index 0d4652f21d302e6ce5e13c215b5eca5decc5cd0e..a246684b1256a36ca5dc8356407edcd20d2a7d20 100644 (file)
@@ -4,6 +4,7 @@ VALGRIND_2.1 {
                vgSkin_*;
                vgProf_*;
                 vgOff_*;
+                vgArch_*;
 
        local:
                *;              # default to hidden
index d4e87a82eb830078fa107e5c8cb6058b02ddbf4f..4e077c4d1fbdc8346e927b1e5a1b52f3d3cb3259 100644 (file)
@@ -314,9 +314,9 @@ void get_needed_regs(ThreadId tid, Addr* eip, Addr* ebp, Addr* esp,
    } else {
       /* thread in thread table */
       ThreadState* tst = & VG_(threads)[ tid ];
-      *eip                = tst->m_eip;
-      *ebp                = tst->m_ebp;
-      *esp                = tst->m_esp; 
+      *eip                = tst->arch.m_eip;
+      *ebp                = tst->arch.m_ebp;
+      *esp                = tst->arch.m_esp; 
       *stack_highest_word = tst->stack_highest_word;
    }
 
@@ -370,7 +370,7 @@ Addr VG_(get_EIP) ( ThreadId tid )
    if (VG_(is_running_thread)(tid))
       ret = VG_(baseBlock)[VGOFF_(m_eip)];
    else
-      ret = VG_(threads)[ tid ].m_eip;
+      ret = VG_(threads)[ tid ].arch.m_eip;
 
    return ret;
 }
index 1391423da0dcd66e8d3aabd48b7c2d8f1799457d..5f1fcc7601ccebc56ab154caa66ec272bd7f5e20 100644 (file)
@@ -3427,14 +3427,14 @@ UInt VG_(get_thread_archreg) ( ThreadId tid, UInt arch )
    tst = & VG_(threads)[tid];
 
    switch (arch) {
-      case R_EAX: return tst->m_eax;
-      case R_ECX: return tst->m_ecx;
-      case R_EDX: return tst->m_edx;
-      case R_EBX: return tst->m_ebx;
-      case R_ESP: return tst->m_esp;
-      case R_EBP: return tst->m_ebp;
-      case R_ESI: return tst->m_esi;
-      case R_EDI: return tst->m_edi;
+      case R_EAX: return tst->arch.m_eax;
+      case R_ECX: return tst->arch.m_ecx;
+      case R_EDX: return tst->arch.m_edx;
+      case R_EBX: return tst->arch.m_ebx;
+      case R_ESP: return tst->arch.m_esp;
+      case R_EBP: return tst->arch.m_ebp;
+      case R_ESI: return tst->arch.m_esi;
+      case R_EDI: return tst->arch.m_edi;
       default:    VG_(core_panic)( "get_thread_archreg");
    }
 }
@@ -3491,14 +3491,14 @@ UInt VG_(get_thread_shadow_archreg) ( ThreadId tid, UInt archreg )
    tst = & VG_(threads)[tid];
 
    switch (archreg) {
-      case R_EAX: return tst->sh_eax;
-      case R_ECX: return tst->sh_ecx;
-      case R_EDX: return tst->sh_edx; 
-      case R_EBX: return tst->sh_ebx; 
-      case R_ESP: return tst->sh_esp; 
-      case R_EBP: return tst->sh_ebp; 
-      case R_ESI: return tst->sh_esi; 
-      case R_EDI: return tst->sh_edi; 
+      case R_EAX: return tst->arch.sh_eax;
+      case R_ECX: return tst->arch.sh_ecx;
+      case R_EDX: return tst->arch.sh_edx; 
+      case R_EBX: return tst->arch.sh_ebx; 
+      case R_ESP: return tst->arch.sh_esp; 
+      case R_EBP: return tst->arch.sh_ebp; 
+      case R_ESI: return tst->arch.sh_esi; 
+      case R_EDI: return tst->arch.sh_edi; 
       default:    VG_(core_panic)( "get_thread_shadow_archreg");
    }
 }
@@ -3511,14 +3511,14 @@ void VG_(set_thread_shadow_archreg) ( ThreadId tid, UInt archreg, UInt val )
    tst = & VG_(threads)[tid];
 
    switch (archreg) {
-      case R_EAX: tst->sh_eax = val; break;
-      case R_ECX: tst->sh_ecx = val; break;
-      case R_EDX: tst->sh_edx = val; break;
-      case R_EBX: tst->sh_ebx = val; break;
-      case R_ESP: tst->sh_esp = val; break;
-      case R_EBP: tst->sh_ebp = val; break;
-      case R_ESI: tst->sh_esi = val; break;
-      case R_EDI: tst->sh_edi = val; break;
+      case R_EAX: tst->arch.sh_eax = val; break;
+      case R_ECX: tst->arch.sh_ecx = val; break;
+      case R_EDX: tst->arch.sh_edx = val; break;
+      case R_EBX: tst->arch.sh_ebx = val; break;
+      case R_ESP: tst->arch.sh_esp = val; break;
+      case R_EBP: tst->arch.sh_ebp = val; break;
+      case R_ESI: tst->arch.sh_esi = val; break;
+      case R_EDI: tst->arch.sh_edi = val; break;
       default:    VG_(core_panic)( "set_thread_shadow_archreg");
    }
 }
index 45b4c4c388bf4a42ace50a6ed1516bf776563aae..cce9fefcb5c8b9bcfb0a4b8192f576ecaa4d24c9 100644 (file)
@@ -320,7 +320,7 @@ Int read_ldt ( ThreadId tid, UChar* ptr, UInt bytecount )
       VG_(printf)("read_ldt: tid = %d, ptr = %p, bytecount = %d\n",
                   tid, ptr, bytecount );
 
-   ldt = (Char*)(VG_(threads)[tid].ldt);
+   ldt = (Char*)(VG_(threads)[tid].arch.ldt);
    err = 0;
    if (ldt == NULL)
       /* LDT not allocated, meaning all entries are null */
@@ -351,7 +351,7 @@ Int write_ldt ( ThreadId tid, void* ptr, UInt bytecount, Int oldmode )
                   "bytecount = %d, oldmode = %d\n",
                   tid, ptr, bytecount, oldmode );
 
-   ldt      = VG_(threads)[tid].ldt;
+   ldt      = VG_(threads)[tid].arch.ldt;
    ldt_info = (struct vki_modify_ldt_ldt_s*)ptr;
 
    error = -VKI_EINVAL;
@@ -372,7 +372,7 @@ Int write_ldt ( ThreadId tid, void* ptr, UInt bytecount, Int oldmode )
       now. */
    if (ldt == NULL) {
       ldt = VG_(allocate_LDT_for_thread)( NULL );
-      VG_(threads)[tid].ldt = ldt;
+      VG_(threads)[tid].arch.ldt = ldt;
    }
 
    /* Install the new entry ...  */
@@ -417,7 +417,7 @@ Int VG_(sys_set_thread_area) ( ThreadId tid,
 
    if (idx == -1) {
       for (idx = 0; idx < VKI_GDT_TLS_ENTRIES; idx++) {
-         VgLdtEntry* tls = VG_(threads)[tid].tls + idx;
+         VgLdtEntry* tls = VG_(threads)[tid].arch.tls + idx;
 
          if (tls->LdtEnt.Words.word1 == 0 && tls->LdtEnt.Words.word2 == 0)
             break;
@@ -431,7 +431,7 @@ Int VG_(sys_set_thread_area) ( ThreadId tid,
       idx = info->entry_number - VKI_GDT_TLS_MIN;
    }
 
-   translate_to_hw_format(info, VG_(threads)[tid].tls + idx, 0);
+   translate_to_hw_format(info, VG_(threads)[tid].arch.tls + idx, 0);
 
    VG_TRACK( pre_mem_write, Vg_CoreSysCall, tid,
              "set_thread_area(info->entry)",
@@ -453,7 +453,7 @@ Int VG_(sys_get_thread_area) ( ThreadId tid,
    if (idx < VKI_GDT_TLS_MIN || idx > VKI_GDT_TLS_MAX)
       return -VKI_EINVAL;
 
-   tls = VG_(threads)[tid].tls + idx - VKI_GDT_TLS_MIN;
+   tls = VG_(threads)[tid].arch.tls + idx - VKI_GDT_TLS_MIN;
 
    info->base_addr = ( tls->LdtEnt.Bits.BaseHi << 24 ) |
                      ( tls->LdtEnt.Bits.BaseMid << 16 ) |
index c7b81549bf1e44869898b072e96c428fc015a3d0..3dc0de3e8077023606ec46996b8dbd187d1599a0 100644 (file)
@@ -266,22 +266,22 @@ void VG_(start_debugger) ( Int tid )
       } else {
          ThreadState* tst = & VG_(threads)[ tid ];
          
-         regs.cs  = tst->m_cs;
-         regs.ss  = tst->m_ss;
-         regs.ds  = tst->m_ds;
-         regs.es  = tst->m_es;
-         regs.fs  = tst->m_fs;
-         regs.gs  = tst->m_gs;
-         regs.eax = tst->m_eax;
-         regs.ebx = tst->m_ebx;
-         regs.ecx = tst->m_ecx;
-         regs.edx = tst->m_edx;
-         regs.esi = tst->m_esi;
-         regs.edi = tst->m_edi;
-         regs.ebp = tst->m_ebp;
-         regs.esp = tst->m_esp;
-         regs.eflags = tst->m_eflags;
-         regs.eip = tst->m_eip;
+         regs.cs  = tst->arch.m_cs;
+         regs.ss  = tst->arch.m_ss;
+         regs.ds  = tst->arch.m_ds;
+         regs.es  = tst->arch.m_es;
+         regs.fs  = tst->arch.m_fs;
+         regs.gs  = tst->arch.m_gs;
+         regs.eax = tst->arch.m_eax;
+         regs.ebx = tst->arch.m_ebx;
+         regs.ecx = tst->arch.m_ecx;
+         regs.edx = tst->arch.m_edx;
+         regs.esi = tst->arch.m_esi;
+         regs.edi = tst->arch.m_edi;
+         regs.ebp = tst->arch.m_ebp;
+         regs.esp = tst->arch.m_esp;
+         regs.eflags = tst->arch.m_eflags;
+         regs.eip = tst->arch.m_eip;
       }
 
       if ((res = VG_(waitpid)(pid, &status, 0)) == pid &&
index 57625e94edf2a88aa4bd2c9dcc15851df6e7fb29..90fe9e73d569f8c2f5b3566a814139e6dc3c8ead 100644 (file)
@@ -151,13 +151,13 @@ static void thread_syscall(Int syscallno, ThreadState *tst,
                           enum PXState *state , enum PXState poststate)
 {
    do_thread_syscall(syscallno,   /* syscall no. */
-                    tst->m_ebx,  /* arg 1 */
-                    tst->m_ecx,  /* arg 2 */
-                    tst->m_edx,  /* arg 3 */
-                    tst->m_esi,  /* arg 4 */
-                    tst->m_edi,  /* arg 5 */
-                    tst->m_ebp,  /* arg 6 */
-                    &tst->m_eax, /* result */
+                    tst->arch.m_ebx,  /* arg 1 */
+                    tst->arch.m_ecx,  /* arg 2 */
+                    tst->arch.m_edx,  /* arg 3 */
+                    tst->arch.m_esi,  /* arg 4 */
+                    tst->arch.m_edi,  /* arg 5 */
+                    tst->arch.m_ebp,  /* arg 6 */
+                    &tst->arch.m_eax, /* result */
                     state,       /* state to update */
                     poststate);  /* state when syscall has finished */
 }
@@ -430,7 +430,7 @@ void VG_(proxy_handlesig)(const vki_ksiginfo_t *siginfo,
         anywhere else, except that we can make some assertions about
         the proxy and machine state here. */
       vg_assert(px->state == PXS_RunSyscall);
-      vg_assert(px->tst->m_eax == -VKI_ERESTARTSYS);
+      vg_assert(px->tst->arch.m_eax == -VKI_ERESTARTSYS);
    } else if (sys_after <= eip && eip <= sys_done) {
       /* We're after the syscall.  Either it was interrupted by the
         signal, or the syscall completed normally.  In either case
@@ -439,7 +439,7 @@ void VG_(proxy_handlesig)(const vki_ksiginfo_t *siginfo,
       vg_assert(px->state == PXS_RunSyscall ||
                px->state == PXS_SysDone);
       px->state = PXS_SysDone;
-      px->tst->m_eax = eax;
+      px->tst->arch.m_eax = eax;
    }
    px_printf("  signalled in state %s\n", pxs_name(px->state));
 
@@ -556,7 +556,7 @@ static Int proxylwp(void *v)
               */
               reply.u.syscallno = tst->syscallno;
 
-              tst->m_eax = -VKI_ERESTARTSYS;
+              tst->arch.m_eax = -VKI_ERESTARTSYS;
               px->state = PXS_IntReply;
               break;
 
@@ -726,14 +726,14 @@ static Int proxylwp(void *v)
               */
               px_printf("RunSyscall in SigACK: rejecting syscall %d with ERESTARTSYS\n",
                         reply.u.syscallno);
-              tst->m_eax = -VKI_ERESTARTSYS;
+              tst->arch.m_eax = -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. */
-              tst->m_eax = -VKI_ERESTARTSYS;
+              tst->arch.m_eax = -VKI_ERESTARTSYS;
 
               /* set our process group ID to match parent */
               if (VG_(getpgrp)() != VG_(main_pgrp))
@@ -1142,7 +1142,7 @@ static void sys_wait_results(Bool block, ThreadId tid, enum RequestType reqtype,
         case PX_RunSyscall:
            if (VG_(clo_trace_syscalls))
               VG_(message)(Vg_DebugMsg, "sys_wait_results: got PX_RunSyscall for TID %d: syscall %d result %d",
-                           res.tid, tst->syscallno, tst->m_eax);
+                           res.tid, tst->syscallno, tst->arch.m_eax);
 
            if (tst->status != VgTs_WaitSys)
               VG_(printf)("tid %d in status %d\n",
@@ -1301,8 +1301,8 @@ Int VG_(sys_issue)(int tid)
 
    req.request = PX_RunSyscall;
 
-   tst->syscallno = tst->m_eax;
-   tst->m_eax = -VKI_ERESTARTSYS;
+   tst->syscallno = tst->arch.m_eax;
+   tst->arch.m_eax = -VKI_ERESTARTSYS;
 
    res = VG_(write)(proxy->topx, &req, sizeof(req));
 
index c27ce364737aaccaef639d60891233e20622d3b0..65c7bf55b894835cbfd9cac613a73f6f5a941ea8 100644 (file)
@@ -162,7 +162,7 @@ ThreadId VG_(first_matching_thread_stack)
    for (tid = 1; tid < VG_N_THREADS; tid++) {
       if (VG_(threads)[tid].status == VgTs_Empty) continue;
       if (tid == tid_to_skip) continue;
-      if ( p ( VG_(threads)[tid].m_esp,
+      if ( p ( VG_(threads)[tid].arch.m_esp,
                VG_(threads)[tid].stack_highest_word, d ) )
          return tid;
    }
@@ -194,8 +194,8 @@ void VG_(pp_sched_status) ( void )
                   VG_(threads)[i].associated_mx,
                   VG_(threads)[i].associated_cv );
       VG_(pp_ExeContext)( 
-         VG_(get_ExeContext2)( VG_(threads)[i].m_eip, VG_(threads)[i].m_ebp,
-                               VG_(threads)[i].m_esp, 
+         VG_(get_ExeContext2)( VG_(threads)[i].arch.m_eip, VG_(threads)[i].arch.m_ebp,
+                               VG_(threads)[i].arch.m_esp, 
                                VG_(threads)[i].stack_highest_word)
       );
    }
@@ -272,80 +272,13 @@ ThreadId VG_(get_current_or_recent_tid) ( void )
    return vg_tid_last_in_baseBlock;
 }
 
-static UInt insertDflag(UInt eflags, Int d)
-{
-   vg_assert(d == 1 || d == -1);
-   eflags &= ~EFlagD;
-   if (d < 0) eflags |= EFlagD;
-   return eflags;
-}
-
-static Int extractDflag(UInt eflags)
-{
-   return ( eflags & EFlagD ? -1 : 1 );
-}
-
-/* Junk to fill up a thread's shadow regs with when shadow regs aren't
-   being used. */
-#define VG_UNUSED_SHADOW_REG_VALUE  0x27182818
-
 /* Copy the saved state of a thread into VG_(baseBlock), ready for it
    to be run. */
 static void load_thread_state ( ThreadId tid )
 {
-   Int i;
    vg_assert(vg_tid_currently_in_baseBlock == VG_INVALID_THREADID);
 
-   VG_(baseBlock)[VGOFF_(ldt)]  = (UInt)VG_(threads)[tid].ldt;
-   VG_(baseBlock)[VGOFF_(tls_ptr)]  = (UInt)VG_(threads)[tid].tls;
-   VG_(baseBlock)[VGOFF_(m_cs)] = VG_(threads)[tid].m_cs;
-   VG_(baseBlock)[VGOFF_(m_ss)] = VG_(threads)[tid].m_ss;
-   VG_(baseBlock)[VGOFF_(m_ds)] = VG_(threads)[tid].m_ds;
-   VG_(baseBlock)[VGOFF_(m_es)] = VG_(threads)[tid].m_es;
-   VG_(baseBlock)[VGOFF_(m_fs)] = VG_(threads)[tid].m_fs;
-   VG_(baseBlock)[VGOFF_(m_gs)] = VG_(threads)[tid].m_gs;
-
-   VG_(baseBlock)[VGOFF_(m_eax)] = VG_(threads)[tid].m_eax;
-   VG_(baseBlock)[VGOFF_(m_ebx)] = VG_(threads)[tid].m_ebx;
-   VG_(baseBlock)[VGOFF_(m_ecx)] = VG_(threads)[tid].m_ecx;
-   VG_(baseBlock)[VGOFF_(m_edx)] = VG_(threads)[tid].m_edx;
-   VG_(baseBlock)[VGOFF_(m_esi)] = VG_(threads)[tid].m_esi;
-   VG_(baseBlock)[VGOFF_(m_edi)] = VG_(threads)[tid].m_edi;
-   VG_(baseBlock)[VGOFF_(m_ebp)] = VG_(threads)[tid].m_ebp;
-   VG_(baseBlock)[VGOFF_(m_esp)] = VG_(threads)[tid].m_esp;
-   VG_(baseBlock)[VGOFF_(m_eflags)] 
-      = VG_(threads)[tid].m_eflags & ~EFlagD;
-   VG_(baseBlock)[VGOFF_(m_dflag)] 
-      = extractDflag(VG_(threads)[tid].m_eflags);
-   VG_(baseBlock)[VGOFF_(m_eip)] = VG_(threads)[tid].m_eip;
-
-   for (i = 0; i < VG_SIZE_OF_SSESTATE_W; i++)
-      VG_(baseBlock)[VGOFF_(m_ssestate) + i] 
-         = VG_(threads)[tid].m_sse[i];
-
-   if (VG_(needs).shadow_regs) {
-      VG_(baseBlock)[VGOFF_(sh_eax)] = VG_(threads)[tid].sh_eax;
-      VG_(baseBlock)[VGOFF_(sh_ebx)] = VG_(threads)[tid].sh_ebx;
-      VG_(baseBlock)[VGOFF_(sh_ecx)] = VG_(threads)[tid].sh_ecx;
-      VG_(baseBlock)[VGOFF_(sh_edx)] = VG_(threads)[tid].sh_edx;
-      VG_(baseBlock)[VGOFF_(sh_esi)] = VG_(threads)[tid].sh_esi;
-      VG_(baseBlock)[VGOFF_(sh_edi)] = VG_(threads)[tid].sh_edi;
-      VG_(baseBlock)[VGOFF_(sh_ebp)] = VG_(threads)[tid].sh_ebp;
-      VG_(baseBlock)[VGOFF_(sh_esp)] = VG_(threads)[tid].sh_esp;
-      VG_(baseBlock)[VGOFF_(sh_eflags)] = VG_(threads)[tid].sh_eflags;
-   } else {
-      /* Fields shouldn't be used -- check their values haven't changed. */
-      vg_assert(
-         VG_UNUSED_SHADOW_REG_VALUE == VG_(threads)[tid].sh_eax &&
-         VG_UNUSED_SHADOW_REG_VALUE == VG_(threads)[tid].sh_ebx &&
-         VG_UNUSED_SHADOW_REG_VALUE == VG_(threads)[tid].sh_ecx &&
-         VG_UNUSED_SHADOW_REG_VALUE == VG_(threads)[tid].sh_edx &&
-         VG_UNUSED_SHADOW_REG_VALUE == VG_(threads)[tid].sh_esi &&
-         VG_UNUSED_SHADOW_REG_VALUE == VG_(threads)[tid].sh_edi &&
-         VG_UNUSED_SHADOW_REG_VALUE == VG_(threads)[tid].sh_ebp &&
-         VG_UNUSED_SHADOW_REG_VALUE == VG_(threads)[tid].sh_esp &&
-         VG_UNUSED_SHADOW_REG_VALUE == VG_(threads)[tid].sh_eflags);
-   }
+   VGA_(load_state)(&VG_(threads)[tid].arch, tid);
 
    vg_tid_currently_in_baseBlock = tid;
    vg_tid_last_in_baseBlock = tid;
@@ -360,108 +293,9 @@ static void load_thread_state ( ThreadId tid )
 */
 static void save_thread_state ( ThreadId tid )
 {
-   Int i;
-   const UInt junk = 0xDEADBEEF;
-
    vg_assert(vg_tid_currently_in_baseBlock != VG_INVALID_THREADID);
 
-
-   /* We don't copy out the LDT entry, because it can never be changed
-      by the normal actions of the thread, only by the modify_ldt
-      syscall, in which case we will correctly be updating
-      VG_(threads)[tid].ldt.  This printf happens iff the following
-      assertion fails. */
-   if ((void*)VG_(threads)[tid].ldt != (void*)VG_(baseBlock)[VGOFF_(ldt)])
-      VG_(printf)("VG_(threads)[%d].ldt=%p  VG_(baseBlock)[VGOFF_(ldt)]=%p\n",
-                 tid, (void*)VG_(threads)[tid].ldt, 
-                       (void*)VG_(baseBlock)[VGOFF_(ldt)]);
-
-   vg_assert((void*)VG_(threads)[tid].ldt 
-             == (void*)VG_(baseBlock)[VGOFF_(ldt)]);
-
-   /* We don't copy out the TLS entry, because it can never be changed
-      by the normal actions of the thread, only by the set_thread_area
-      syscall, in which case we will correctly be updating
-      VG_(threads)[tid].tls.  This printf happens iff the following
-      assertion fails. */
-   if ((void*)VG_(threads)[tid].tls != (void*)VG_(baseBlock)[VGOFF_(tls_ptr)])
-      VG_(printf)("VG_(threads)[%d].tls=%p  VG_(baseBlock)[VGOFF_(tls_ptr)]=%p\n",
-                 tid, (void*)VG_(threads)[tid].tls, 
-                       (void*)VG_(baseBlock)[VGOFF_(tls_ptr)]);
-
-   vg_assert((void*)VG_(threads)[tid].tls 
-             == (void*)VG_(baseBlock)[VGOFF_(tls_ptr)]);
-
-   VG_(threads)[tid].m_cs = VG_(baseBlock)[VGOFF_(m_cs)];
-   VG_(threads)[tid].m_ss = VG_(baseBlock)[VGOFF_(m_ss)];
-   VG_(threads)[tid].m_ds = VG_(baseBlock)[VGOFF_(m_ds)];
-   VG_(threads)[tid].m_es = VG_(baseBlock)[VGOFF_(m_es)];
-   VG_(threads)[tid].m_fs = VG_(baseBlock)[VGOFF_(m_fs)];
-   VG_(threads)[tid].m_gs = VG_(baseBlock)[VGOFF_(m_gs)];
-
-   VG_(threads)[tid].m_eax = VG_(baseBlock)[VGOFF_(m_eax)];
-   VG_(threads)[tid].m_ebx = VG_(baseBlock)[VGOFF_(m_ebx)];
-   VG_(threads)[tid].m_ecx = VG_(baseBlock)[VGOFF_(m_ecx)];
-   VG_(threads)[tid].m_edx = VG_(baseBlock)[VGOFF_(m_edx)];
-   VG_(threads)[tid].m_esi = VG_(baseBlock)[VGOFF_(m_esi)];
-   VG_(threads)[tid].m_edi = VG_(baseBlock)[VGOFF_(m_edi)];
-   VG_(threads)[tid].m_ebp = VG_(baseBlock)[VGOFF_(m_ebp)];
-   VG_(threads)[tid].m_esp = VG_(baseBlock)[VGOFF_(m_esp)];
-   VG_(threads)[tid].m_eflags 
-      = insertDflag(VG_(baseBlock)[VGOFF_(m_eflags)],
-                    VG_(baseBlock)[VGOFF_(m_dflag)]);
-   VG_(threads)[tid].m_eip = VG_(baseBlock)[VGOFF_(m_eip)];
-
-   for (i = 0; i < VG_SIZE_OF_SSESTATE_W; i++)
-      VG_(threads)[tid].m_sse[i] 
-         = VG_(baseBlock)[VGOFF_(m_ssestate) + i];
-
-   if (VG_(needs).shadow_regs) {
-      VG_(threads)[tid].sh_eax = VG_(baseBlock)[VGOFF_(sh_eax)];
-      VG_(threads)[tid].sh_ebx = VG_(baseBlock)[VGOFF_(sh_ebx)];
-      VG_(threads)[tid].sh_ecx = VG_(baseBlock)[VGOFF_(sh_ecx)];
-      VG_(threads)[tid].sh_edx = VG_(baseBlock)[VGOFF_(sh_edx)];
-      VG_(threads)[tid].sh_esi = VG_(baseBlock)[VGOFF_(sh_esi)];
-      VG_(threads)[tid].sh_edi = VG_(baseBlock)[VGOFF_(sh_edi)];
-      VG_(threads)[tid].sh_ebp = VG_(baseBlock)[VGOFF_(sh_ebp)];
-      VG_(threads)[tid].sh_esp = VG_(baseBlock)[VGOFF_(sh_esp)];
-      VG_(threads)[tid].sh_eflags = VG_(baseBlock)[VGOFF_(sh_eflags)];
-   } else {
-      /* Fill with recognisable junk */
-      VG_(threads)[tid].sh_eax =
-      VG_(threads)[tid].sh_ebx =
-      VG_(threads)[tid].sh_ecx =
-      VG_(threads)[tid].sh_edx =
-      VG_(threads)[tid].sh_esi =
-      VG_(threads)[tid].sh_edi =
-      VG_(threads)[tid].sh_ebp =
-      VG_(threads)[tid].sh_esp = 
-      VG_(threads)[tid].sh_eflags = VG_UNUSED_SHADOW_REG_VALUE;
-   }
-
-   /* Fill it up with junk. */
-   VG_(baseBlock)[VGOFF_(ldt)] = junk;
-   VG_(baseBlock)[VGOFF_(tls_ptr)] = junk;
-   VG_(baseBlock)[VGOFF_(m_cs)] = junk;
-   VG_(baseBlock)[VGOFF_(m_ss)] = junk;
-   VG_(baseBlock)[VGOFF_(m_ds)] = junk;
-   VG_(baseBlock)[VGOFF_(m_es)] = junk;
-   VG_(baseBlock)[VGOFF_(m_fs)] = junk;
-   VG_(baseBlock)[VGOFF_(m_gs)] = junk;
-
-   VG_(baseBlock)[VGOFF_(m_eax)] = junk;
-   VG_(baseBlock)[VGOFF_(m_ebx)] = junk;
-   VG_(baseBlock)[VGOFF_(m_ecx)] = junk;
-   VG_(baseBlock)[VGOFF_(m_edx)] = junk;
-   VG_(baseBlock)[VGOFF_(m_esi)] = junk;
-   VG_(baseBlock)[VGOFF_(m_edi)] = junk;
-   VG_(baseBlock)[VGOFF_(m_ebp)] = junk;
-   VG_(baseBlock)[VGOFF_(m_esp)] = junk;
-   VG_(baseBlock)[VGOFF_(m_eflags)] = junk;
-   VG_(baseBlock)[VGOFF_(m_eip)] = junk;
-
-   for (i = 0; i < VG_SIZE_OF_SSESTATE_W; i++)
-      VG_(baseBlock)[VGOFF_(m_ssestate) + i] = junk;
+   VGA_(save_state)(&VG_(threads)[tid].arch, tid);
 
    vg_tid_currently_in_baseBlock = VG_INVALID_THREADID;
 }
@@ -521,8 +355,8 @@ static
 void mostly_clear_thread_record ( ThreadId tid )
 {
    vg_assert(tid >= 0 && tid < VG_N_THREADS);
-   VG_(threads)[tid].ldt                  = NULL;
-   VG_(clear_TLS_for_thread)(VG_(threads)[tid].tls);
+   VG_(threads)[tid].arch.ldt                  = NULL;
+   VG_(clear_TLS_for_thread)(VG_(threads)[tid].arch.tls);
    VG_(threads)[tid].tid                  = tid;
    VG_(threads)[tid].status               = VgTs_Empty;
    VG_(threads)[tid].associated_mx        = NULL;
@@ -587,7 +421,7 @@ void VG_(scheduler_init) ( void )
    /* Copy VG_(baseBlock) state to tid_main's slot. */
    vg_tid_currently_in_baseBlock = tid_main;
    vg_tid_last_in_baseBlock = tid_main;
-   VG_(baseBlock)[VGOFF_(tls_ptr)] = (UInt)VG_(threads)[tid_main].tls;
+   VG_(baseBlock)[VGOFF_(tls_ptr)] = (UInt)VG_(threads)[tid_main].arch.tls;
    save_thread_state ( tid_main );
 
    VG_(threads)[tid_main].stack_highest_word 
@@ -632,12 +466,12 @@ void handle_signal_return ( ThreadId tid )
       return;
 
    if (VG_(threads)[tid].status == VgTs_Sleeping
-       && VG_(threads)[tid].m_eax == __NR_nanosleep) {
+       && VG_(threads)[tid].arch.m_eax == __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 *)VG_(threads)[tid].m_ecx; /* arg2 */
+      rem = (struct vki_timespec *)VG_(threads)[tid].arch.m_ecx; /* arg2 */
       if (rem != NULL) {
          rem->tv_sec = 0;
          rem->tv_nsec = 1;
@@ -691,7 +525,7 @@ void sched_do_syscall ( ThreadId tid )
    vg_assert(VG_(is_valid_tid)(tid));
    vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
 
-   syscall_no = VG_(threads)[tid].m_eax; /* syscall number */
+   syscall_no = VG_(threads)[tid].arch.m_eax; /* syscall number */
 
    /* Special-case nanosleep because we can.  But should we?
 
@@ -701,7 +535,7 @@ void sched_do_syscall ( ThreadId tid )
    if (0 && syscall_no == __NR_nanosleep) {
       UInt t_now, t_awaken;
       struct vki_timespec* req;
-      req = (struct vki_timespec*)VG_(threads)[tid].m_ebx; /* arg1 */
+      req = (struct vki_timespec*)VG_(threads)[tid].arch.m_ebx; /* arg1 */
 
       if (req->tv_sec < 0 || req->tv_nsec < 0 || req->tv_nsec >= 1000000000) {
         SET_SYSCALL_RETVAL(tid, -VKI_EINVAL);
@@ -1002,18 +836,18 @@ VgSchedReturnCode do_scheduler ( Int* exitcode, ThreadId* last_run_tid )
 #        if 0
          if (VG_(bbs_done) > 31700000 + 0) {
             dispatch_ctr_SAVED = VG_(dispatch_ctr) = 2;
-            VG_(translate)(&VG_(threads)[tid], VG_(threads)[tid].m_eip,
+            VG_(translate)(&VG_(threads)[tid], VG_(threads)[tid].arch.m_eip,
                            /*debugging*/True);
          }
-         vg_assert(VG_(threads)[tid].m_eip != 0);
+         vg_assert(VG_(threads)[tid].arch.m_eip != 0);
 #        endif
 
          trc = run_thread_for_a_while ( tid );
 
 #        if 0
-         if (0 == VG_(threads)[tid].m_eip) {
+         if (0 == VG_(threads)[tid].arch.m_eip) {
             VG_(printf)("tid = %d,  dc = %llu\n", tid, VG_(bbs_done));
-            vg_assert(0 != VG_(threads)[tid].m_eip);
+            vg_assert(0 != VG_(threads)[tid].arch.m_eip);
          }
 #        endif
 
@@ -1025,11 +859,11 @@ VgSchedReturnCode do_scheduler ( Int* exitcode, ThreadId* last_run_tid )
 
             /* Trivial event.  Miss in the fast-cache.  Do a full
                lookup for it. */
-            trans_addr = VG_(search_transtab) ( VG_(threads)[tid].m_eip );
+            trans_addr = VG_(search_transtab) ( VG_(threads)[tid].arch.m_eip );
             if (trans_addr == (Addr)0) {
                /* Not found; we need to request a translation. */
-               VG_(translate)( tid, VG_(threads)[tid].m_eip, /*debug*/False ); 
-               trans_addr = VG_(search_transtab) ( VG_(threads)[tid].m_eip ); 
+               VG_(translate)( tid, VG_(threads)[tid].arch.m_eip, /*debug*/False ); 
+               trans_addr = VG_(search_transtab) ( VG_(threads)[tid].arch.m_eip ); 
                if (trans_addr == (Addr)0)
                   VG_(core_panic)("VG_TRC_INNER_FASTMISS: missing tt_fast entry");
             }
@@ -1037,7 +871,7 @@ VgSchedReturnCode do_scheduler ( Int* exitcode, ThreadId* last_run_tid )
          }
 
          if (trc == VG_TRC_EBP_JMP_CLIENTREQ) {
-            UInt reqno = *(UInt*)(VG_(threads)[tid].m_eax);
+            UInt reqno = *(UInt*)(VG_(threads)[tid].arch.m_eax);
             /* VG_(printf)("request 0x%x\n", reqno); */
 
             /* Are we really absolutely totally quitting? */
@@ -1067,7 +901,7 @@ VgSchedReturnCode do_scheduler ( Int* exitcode, ThreadId* last_run_tid )
                to exit. */
 #           if 0
             { UInt* esp; Int i;
-              esp=(UInt*)VG_(threads)[tid].m_esp;
+              esp=(UInt*)VG_(threads)[tid].arch.m_esp;
               VG_(printf)("\nBEFORE\n");
               for (i = 10; i >= -10; i--)
                  VG_(printf)("%2d  %p  =  0x%x\n", i, &esp[i], esp[i]);
@@ -1085,12 +919,12 @@ VgSchedReturnCode do_scheduler ( Int* exitcode, ThreadId* last_run_tid )
                __libc_freeres does some invalid frees which crash
                the unprotected malloc/free system. */
 
-            if (VG_(threads)[tid].m_eax == __NR_exit
-                || VG_(threads)[tid].m_eax == __NR_exit_group
+            if (VG_(threads)[tid].arch.m_eax == __NR_exit
+                || VG_(threads)[tid].arch.m_eax == __NR_exit_group
                ) {
 
                /* If __NR_exit, remember the supplied argument. */
-               *exitcode = VG_(threads)[tid].m_ebx; /* syscall arg1 */
+               *exitcode = VG_(threads)[tid].arch.m_ebx; /* syscall arg1 */
 
                /* Only run __libc_freeres if the tool says it's ok and
                   it hasn't been overridden with --run-libc-freeres=no
@@ -1105,7 +939,7 @@ VgSchedReturnCode do_scheduler ( Int* exitcode, ThreadId* last_run_tid )
                         "Caught __NR_exit; running __libc_freeres()");
                   }
                   VG_(nuke_all_threads_except) ( tid );
-                  VG_(threads)[tid].m_eip = (UInt)__libc_freeres_wrapper;
+                  VG_(threads)[tid].arch.m_eip = (UInt)__libc_freeres_wrapper;
                   vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
                   goto stage1; /* party on, dudes (but not for much longer :) */
 
@@ -1122,13 +956,13 @@ VgSchedReturnCode do_scheduler ( Int* exitcode, ThreadId* last_run_tid )
             }
 
             /* We've dealt with __NR_exit at this point. */
-           vg_assert(VG_(threads)[tid].m_eax != __NR_exit && 
-                     VG_(threads)[tid].m_eax != __NR_exit_group);
+           vg_assert(VG_(threads)[tid].arch.m_eax != __NR_exit && 
+                     VG_(threads)[tid].arch.m_eax != __NR_exit_group);
 
             /* Trap syscalls to __NR_sched_yield and just have this
                thread yield instead.  Not essential, just an
                optimisation. */
-           if (VG_(threads)[tid].m_eax == __NR_sched_yield) {
+           if (VG_(threads)[tid].arch.m_eax == __NR_sched_yield) {
                SET_SYSCALL_RETVAL(tid, 0); /* syscall returns with success */
                goto stage1; /* find a new thread to run */
            }
@@ -1137,7 +971,7 @@ VgSchedReturnCode do_scheduler ( Int* exitcode, ThreadId* last_run_tid )
 
 #           if 0
             { UInt* esp; Int i;
-              esp=(UInt*)VG_(threads)[tid].m_esp;
+              esp=(UInt*)VG_(threads)[tid].arch.m_esp;
               VG_(printf)("AFTER\n");
               for (i = 10; i >= -10; i--)
                  VG_(printf)("%2d  %p  =  0x%x\n", i, &esp[i], esp[i]);
@@ -1319,19 +1153,19 @@ void make_thread_jump_to_cancelhdlr ( ThreadId tid )
    vg_assert(VG_(threads)[tid].cancel_pend != NULL);
 
    /* Push a suitable arg, and mark it as readable. */
-   SET_PTHREQ_ESP(tid, VG_(threads)[tid].m_esp - 4);
-   * (UInt*)(VG_(threads)[tid].m_esp) = (UInt)PTHREAD_CANCELED;
-   VG_TRACK( post_mem_write, VG_(threads)[tid].m_esp, sizeof(void*) );
+   SET_PTHREQ_ESP(tid, VG_(threads)[tid].arch.m_esp - 4);
+   * (UInt*)(VG_(threads)[tid].arch.m_esp) = (UInt)PTHREAD_CANCELED;
+   VG_TRACK( post_mem_write, VG_(threads)[tid].arch.m_esp, sizeof(void*) );
 
    /* Push a bogus return address.  It will not return, but we still
       need to have it so that the arg is at the correct stack offset.
       Don't mark as readable; any attempt to read this is and internal
       valgrind bug since thread_exit_wrapper should not return. */
-   SET_PTHREQ_ESP(tid, VG_(threads)[tid].m_esp - 4);
-   * (UInt*)(VG_(threads)[tid].m_esp) = 0xBEADDEEF;
+   SET_PTHREQ_ESP(tid, VG_(threads)[tid].arch.m_esp - 4);
+   * (UInt*)(VG_(threads)[tid].arch.m_esp) = 0xBEADDEEF;
 
    /* .cancel_pend will hold &thread_exit_wrapper */
-   VG_(threads)[tid].m_eip = (UInt)VG_(threads)[tid].cancel_pend;
+   VG_(threads)[tid].arch.m_eip = (UInt)VG_(threads)[tid].cancel_pend;
 
    VG_(proxy_abort_syscall)(tid);
 
@@ -1413,11 +1247,11 @@ void cleanup_after_thread_exited ( ThreadId tid, Bool forcekill )
                             VG_(threads)[tid].stack_size );
 
    /* Deallocate its LDT, if it ever had one. */
-   VG_(deallocate_LDT_for_thread)( VG_(threads)[tid].ldt );
-   VG_(threads)[tid].ldt = NULL;
+   VG_(deallocate_LDT_for_thread)( VG_(threads)[tid].arch.ldt );
+   VG_(threads)[tid].arch.ldt = NULL;
 
    /* Clear its TLS array. */
-   VG_(clear_TLS_for_thread)( VG_(threads)[tid].tls );
+   VG_(clear_TLS_for_thread)( VG_(threads)[tid].arch.tls );
 
    /* Not interested in the timeout anymore */
    VG_(threads)[tid].awaken_at = 0xFFFFFFFF;
@@ -1919,19 +1753,19 @@ void do__apply_in_new_thread ( ThreadId parent_tid,
    load_thread_state(parent_tid);
 
    /* We inherit our parent's LDT. */
-   if (VG_(threads)[parent_tid].ldt == NULL) {
+   if (VG_(threads)[parent_tid].arch.ldt == NULL) {
       /* We hope this is the common case. */
       VG_(baseBlock)[VGOFF_(ldt)] = 0;
    } else {
       /* No luck .. we have to take a copy of the parent's. */
-      VG_(threads)[tid].ldt
-        = VG_(allocate_LDT_for_thread)( VG_(threads)[parent_tid].ldt );
-      VG_(baseBlock)[VGOFF_(ldt)] = (UInt)VG_(threads)[tid].ldt;
+      VG_(threads)[tid].arch.ldt
+        = VG_(allocate_LDT_for_thread)( VG_(threads)[parent_tid].arch.ldt );
+      VG_(baseBlock)[VGOFF_(ldt)] = (UInt)VG_(threads)[tid].arch.ldt;
    }
 
    /* Initialise the thread's TLS array */
-   VG_(clear_TLS_for_thread)( VG_(threads)[tid].tls );
-   VG_(baseBlock)[VGOFF_(tls_ptr)] = (UInt)VG_(threads)[tid].tls;
+   VG_(clear_TLS_for_thread)( VG_(threads)[tid].arch.tls );
+   VG_(baseBlock)[VGOFF_(tls_ptr)] = (UInt)VG_(threads)[tid].arch.tls;
 
    save_thread_state(tid);
    vg_tid_last_in_baseBlock = tid;
@@ -1980,25 +1814,25 @@ void do__apply_in_new_thread ( ThreadId parent_tid,
    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, VG_(threads)[tid].m_esp, 
+   VG_TRACK ( ban_mem_stack, VG_(threads)[tid].arch.m_esp, 
                              VG_AR_CLIENT_STACKBASE_REDZONE_SZB );
    
    /* push two args */
-   SET_PTHREQ_ESP(tid, VG_(threads)[tid].m_esp - 8);
+   SET_PTHREQ_ESP(tid, VG_(threads)[tid].arch.m_esp - 8);
 
-   VG_TRACK ( new_mem_stack, (Addr)VG_(threads)[tid].m_esp, 2 * 4 );
+   VG_TRACK ( new_mem_stack, (Addr)VG_(threads)[tid].arch.m_esp, 2 * 4 );
    VG_TRACK ( pre_mem_write, Vg_CorePThread, tid, "new thread: stack",
-                             (Addr)VG_(threads)[tid].m_esp, 2 * 4 );
+                             (Addr)VG_(threads)[tid].arch.m_esp, 2 * 4 );
  
    /* push arg and (bogus) return address */
-   * (UInt*)(VG_(threads)[tid].m_esp+4) = (UInt)arg;
-   * (UInt*)(VG_(threads)[tid].m_esp) 
+   * (UInt*)(VG_(threads)[tid].arch.m_esp+4) = (UInt)arg;
+   * (UInt*)(VG_(threads)[tid].arch.m_esp) 
       = (UInt)&do__apply_in_new_thread_bogusRA;
 
-   VG_TRACK ( post_mem_write, VG_(threads)[tid].m_esp, 2 * 4 );
+   VG_TRACK ( post_mem_write, VG_(threads)[tid].arch.m_esp, 2 * 4 );
 
    /* this is where we start */
-   VG_(threads)[tid].m_eip = (UInt)fn;
+   VG_(threads)[tid].arch.m_eip = (UInt)fn;
 
    if (VG_(clo_trace_sched)) {
       VG_(sprintf)(msg_buf, "new thread, created by %d", parent_tid );
@@ -3001,7 +2835,7 @@ void VG_(intercept_libc_freeres_wrapper)(Addr addr)
 static
 void do_client_request ( ThreadId tid )
 {
-   UInt* arg    = (UInt*)(VG_(threads)[tid].m_eax);
+   UInt* arg    = (UInt*)(VG_(threads)[tid].arch.m_eax);
    UInt  req_no = arg[0];
 
    if (0)
@@ -3430,7 +3264,7 @@ void scheduler_sanity ( void )
       if (VG_(threads)[i].status != VgTs_Empty) {
          Int
          stack_used = (Addr)VG_(threads)[i].stack_highest_word 
-                      - (Addr)VG_(threads)[i].m_esp;
+                      - (Addr)VG_(threads)[i].arch.m_esp;
          Int
          stack_avail = VG_(threads)[i].stack_size
                        - VG_AR_CLIENT_STACKBASE_REDZONE_SZB
index 1fb60eaf737a49b00ccc0b950103721b31aa0760..d47cfdd76b458a0042a405f8cd709eb743d5053d 100644 (file)
@@ -489,9 +489,9 @@ void VG_(do__NR_sigaltstack) ( ThreadId tid )
    Addr          m_esp;
 
    vg_assert(VG_(is_valid_tid)(tid));
-   ss    = (vki_kstack_t*)(VG_(threads)[tid].m_ebx);
-   oss   = (vki_kstack_t*)(VG_(threads)[tid].m_ecx);
-   m_esp = VG_(threads)[tid].m_esp;
+   ss    = (vki_kstack_t*)(VG_(threads)[tid].arch.m_ebx);
+   oss   = (vki_kstack_t*)(VG_(threads)[tid].arch.m_ecx);
+   m_esp = VG_(threads)[tid].arch.m_esp;
 
    if (VG_(clo_trace_signals))
       VG_(message)(Vg_DebugExtraMsg, 
@@ -506,7 +506,7 @@ void VG_(do__NR_sigaltstack) ( ThreadId tid )
    }
 
    if (ss != NULL) {
-      if (on_sig_stack(tid, VG_(threads)[tid].m_esp)) {
+      if (on_sig_stack(tid, VG_(threads)[tid].arch.m_esp)) {
          SET_SYSCALL_RETVAL(tid, -VKI_EPERM);
          return;
       }
@@ -542,9 +542,9 @@ void VG_(do__NR_sigaction) ( ThreadId tid )
    vg_assert(is_correct_sigmask());
 
    vg_assert(VG_(is_valid_tid)(tid));
-   signo     = VG_(threads)[tid].m_ebx; /* int sigNo */
-   new_act   = (vki_ksigaction*)(VG_(threads)[tid].m_ecx);
-   old_act   = (vki_ksigaction*)(VG_(threads)[tid].m_edx);
+   signo     = VG_(threads)[tid].arch.m_ebx; /* int sigNo */
+   new_act   = (vki_ksigaction*)(VG_(threads)[tid].arch.m_ecx);
+   old_act   = (vki_ksigaction*)(VG_(threads)[tid].arch.m_edx);
 
    if (VG_(clo_trace_signals))
       VG_(message)(Vg_DebugExtraMsg, 
@@ -921,7 +921,7 @@ static void synth_ucontext(ThreadId tid, const vki_ksiginfo_t *si,
    uc->uc_sigmask = *set;
    uc->uc_stack = tst->altstack;
 
-#define SC(reg)        sc->reg = tst->m_##reg
+#define SC(reg)        sc->reg = tst->arch.m_##reg
    SC(gs);
    SC(fs);
    SC(es);
@@ -973,7 +973,7 @@ void vg_push_signal_frame ( ThreadId tid, const vki_ksiginfo_t *siginfo )
        && /* 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, tst->m_esp) == 0
+          sas_ss_flags(tid, tst->arch.m_esp) == 0
       ) {
       esp_top_of_frame 
          = (Addr)(tst->altstack.ss_sp) + tst->altstack.ss_size;
@@ -986,7 +986,7 @@ void vg_push_signal_frame ( ThreadId tid, const vki_ksiginfo_t *siginfo )
       VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/True );
       
    } else {
-      esp_top_of_frame = tst->m_esp;
+      esp_top_of_frame = tst->arch.m_esp;
 
       /* Signal delivery to tools */
       VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/False );
@@ -1025,7 +1025,7 @@ void vg_push_signal_frame ( ThreadId tid, const vki_ksiginfo_t *siginfo )
                (Addr)&frame->sigInfo, sizeof(frame->sigInfo) );
       VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_ksiginfo_t));
       if (sigNo == VKI_SIGFPE) {
-         frame->sigInfo._sifields._sigfault._addr = (void *)tst->m_eip;
+         frame->sigInfo._sifields._sigfault._addr = (void *)tst->arch.m_eip;
       }
       VG_TRACK( post_mem_write, (Addr)&frame->sigInfo, sizeof(frame->sigInfo) );
 
@@ -1053,29 +1053,29 @@ void vg_push_signal_frame ( ThreadId tid, const vki_ksiginfo_t *siginfo )
    frame->magicPI    = 0x31415927;
 
    for (i = 0; i < VG_SIZE_OF_SSESTATE_W; i++)
-      frame->m_sse[i] = tst->m_sse[i];
-
-   frame->m_eax      = tst->m_eax;
-   frame->m_ecx      = tst->m_ecx;
-   frame->m_edx      = tst->m_edx;
-   frame->m_ebx      = tst->m_ebx;
-   frame->m_ebp      = tst->m_ebp;
-   frame->m_esp      = tst->m_esp;
-   frame->m_esi      = tst->m_esi;
-   frame->m_edi      = tst->m_edi;
-   frame->m_eflags   = tst->m_eflags;
-   frame->m_eip      = tst->m_eip;
+      frame->m_sse[i] = tst->arch.m_sse[i];
+
+   frame->m_eax      = tst->arch.m_eax;
+   frame->m_ecx      = tst->arch.m_ecx;
+   frame->m_edx      = tst->arch.m_edx;
+   frame->m_ebx      = tst->arch.m_ebx;
+   frame->m_ebp      = tst->arch.m_ebp;
+   frame->m_esp      = tst->arch.m_esp;
+   frame->m_esi      = tst->arch.m_esi;
+   frame->m_edi      = tst->arch.m_edi;
+   frame->m_eflags   = tst->arch.m_eflags;
+   frame->m_eip      = tst->arch.m_eip;
 
    if (VG_(needs).shadow_regs) {
-      frame->sh_eax     = tst->sh_eax;
-      frame->sh_ecx     = tst->sh_ecx;
-      frame->sh_edx     = tst->sh_edx;
-      frame->sh_ebx     = tst->sh_ebx;
-      frame->sh_ebp     = tst->sh_ebp;
-      frame->sh_esp     = tst->sh_esp;
-      frame->sh_esi     = tst->sh_esi;
-      frame->sh_edi     = tst->sh_edi;
-      frame->sh_eflags  = tst->sh_eflags;
+      frame->sh_eax     = tst->arch.sh_eax;
+      frame->sh_ecx     = tst->arch.sh_ecx;
+      frame->sh_edx     = tst->arch.sh_edx;
+      frame->sh_ebx     = tst->arch.sh_ebx;
+      frame->sh_ebp     = tst->arch.sh_ebp;
+      frame->sh_esp     = tst->arch.sh_esp;
+      frame->sh_esi     = tst->arch.sh_esi;
+      frame->sh_edi     = tst->arch.sh_edi;
+      frame->sh_eflags  = tst->arch.sh_eflags;
    }
 
    frame->mask = tst->sig_mask;
@@ -1092,16 +1092,16 @@ void vg_push_signal_frame ( ThreadId tid, const vki_ksiginfo_t *siginfo )
    /* Ensure 'tid' and 'tst' correspond */
    vg_assert(& VG_(threads)[tid] == tst);
    /* Set the thread so it will next run the handler. */
-   /* tst->m_esp  = esp; */
+   /* tst->arch.m_esp  = esp; */
    SET_SIGNAL_ESP(tid, esp);
 
-   tst->m_eip  = (Addr)vg_scss.scss_per_sig[sigNo].scss_handler;
+   tst->arch.m_eip  = (Addr)vg_scss.scss_per_sig[sigNo].scss_handler;
    /* This thread needs to be marked runnable, but we leave that the
       caller to do. */
 
    if (0)
       VG_(printf)("pushed signal frame; %%ESP now = %p, next %%EBP = %p, status=%d\n", 
-                 esp, tst->m_eip, tst->status);
+                 esp, tst->arch.m_eip, tst->status);
 }
 
 /* Clear the signal frame created by vg_push_signal_frame, restore the
@@ -1119,7 +1119,7 @@ Int vg_pop_signal_frame ( ThreadId tid )
    tst = & VG_(threads)[tid];
 
    /* Correctly reestablish the frame base address. */
-   esp   = tst->m_esp;
+   esp   = tst->arch.m_esp;
    frame = (VgSigFrame*)
               (esp -4 /* because the handler's RET pops the RA */
                   +20 /* because signalreturn_bogusRA pushes 5 words */);
@@ -1135,29 +1135,29 @@ Int vg_pop_signal_frame ( ThreadId tid )
 
    /* restore machine state */
    for (i = 0; i < VG_SIZE_OF_SSESTATE_W; i++)
-      tst->m_sse[i] = frame->m_sse[i];
-
-   tst->m_eax     = frame->m_eax;
-   tst->m_ecx     = frame->m_ecx;
-   tst->m_edx     = frame->m_edx;
-   tst->m_ebx     = frame->m_ebx;
-   tst->m_ebp     = frame->m_ebp; 
-   tst->m_esp     = frame->m_esp;
-   tst->m_esi     = frame->m_esi;
-   tst->m_edi     = frame->m_edi;
-   tst->m_eflags  = frame->m_eflags;
-   tst->m_eip     = frame->m_eip;
+      tst->arch.m_sse[i] = frame->m_sse[i];
+
+   tst->arch.m_eax     = frame->m_eax;
+   tst->arch.m_ecx     = frame->m_ecx;
+   tst->arch.m_edx     = frame->m_edx;
+   tst->arch.m_ebx     = frame->m_ebx;
+   tst->arch.m_ebp     = frame->m_ebp; 
+   tst->arch.m_esp     = frame->m_esp;
+   tst->arch.m_esi     = frame->m_esi;
+   tst->arch.m_edi     = frame->m_edi;
+   tst->arch.m_eflags  = frame->m_eflags;
+   tst->arch.m_eip     = frame->m_eip;
 
    if (VG_(needs).shadow_regs) {
-      tst->sh_eax     = frame->sh_eax;
-      tst->sh_ecx     = frame->sh_ecx;
-      tst->sh_edx     = frame->sh_edx;
-      tst->sh_ebx     = frame->sh_ebx;
-      tst->sh_ebp     = frame->sh_ebp; 
-      tst->sh_esp     = frame->sh_esp;
-      tst->sh_esi     = frame->sh_esi;
-      tst->sh_edi     = frame->sh_edi;
-      tst->sh_eflags  = frame->sh_eflags;
+      tst->arch.sh_eax     = frame->sh_eax;
+      tst->arch.sh_ecx     = frame->sh_ecx;
+      tst->arch.sh_edx     = frame->sh_edx;
+      tst->arch.sh_ebx     = frame->sh_ebx;
+      tst->arch.sh_ebp     = frame->sh_ebp; 
+      tst->arch.sh_esp     = frame->sh_esp;
+      tst->arch.sh_esi     = frame->sh_esi;
+      tst->arch.sh_edi     = frame->sh_edi;
+      tst->arch.sh_eflags  = frame->sh_eflags;
    }
    
    /* don't use the copy exposed to the handler; it might have changed
@@ -1473,24 +1473,24 @@ static void fill_prstatus(const ThreadState *tst, struct elf_prstatus *prs, cons
       regs->fs = VG_(baseBlock)[VGOFF_(m_fs)];
       regs->gs = VG_(baseBlock)[VGOFF_(m_gs)];
    } else {
-      regs->eflags = tst->m_eflags;
-      regs->esp = tst->m_esp;
-      regs->eip = tst->m_eip;
-
-      regs->ebx = tst->m_ebx;
-      regs->ecx = tst->m_ecx;
-      regs->edx = tst->m_edx;
-      regs->esi = tst->m_esi;
-      regs->edi = tst->m_edi;
-      regs->ebp = tst->m_ebp;
-      regs->eax = tst->m_eax;
-
-      regs->cs = tst->m_cs;
-      regs->ds = tst->m_ds;
-      regs->ss = tst->m_ss;
-      regs->es = tst->m_es;
-      regs->fs = tst->m_fs;
-      regs->gs = tst->m_gs;
+      regs->eflags = tst->arch.m_eflags;
+      regs->esp = tst->arch.m_esp;
+      regs->eip = tst->arch.m_eip;
+
+      regs->ebx = tst->arch.m_ebx;
+      regs->ecx = tst->arch.m_ecx;
+      regs->edx = tst->arch.m_edx;
+      regs->esi = tst->arch.m_esi;
+      regs->edi = tst->arch.m_edi;
+      regs->ebp = tst->arch.m_ebp;
+      regs->eax = tst->arch.m_eax;
+
+      regs->cs = tst->arch.m_cs;
+      regs->ds = tst->arch.m_ds;
+      regs->ss = tst->arch.m_ss;
+      regs->es = tst->arch.m_es;
+      regs->fs = tst->arch.m_fs;
+      regs->gs = tst->arch.m_gs;
    }
 }
 
@@ -1501,7 +1501,7 @@ static void fill_fpu(const ThreadState *tst, elf_fpregset_t *fpu)
    if (VG_(is_running_thread)(tst->tid)) {
       from = (const Char *)&VG_(baseBlock)[VGOFF_(m_ssestate)];
    } else {
-      from = (const Char *)&tst->m_sse;
+      from = (const Char *)&tst->arch.m_sse;
    }
 
    if (VG_(have_ssestate)) {
@@ -1527,7 +1527,7 @@ static void fill_xfpu(const ThreadState *tst, elf_fpxregset_t *xfpu)
    if (VG_(is_running_thread)(tst->tid)) 
       from = (UShort *)&VG_(baseBlock)[VGOFF_(m_ssestate)];
    else 
-      from = (UShort *)tst->m_sse;
+      from = (UShort *)tst->arch.m_sse;
 
    VG_(memcpy)(xfpu, from, sizeof(*xfpu));
 }
@@ -1867,8 +1867,8 @@ void VG_(deliver_signal) ( ThreadId tid, const vki_ksiginfo_t *info, Bool async
 
       if (tst->status == VgTs_WaitSys) {
         /* blocked in a syscall; we assume it should be interrupted */
-        if (tst->m_eax == -VKI_ERESTARTSYS)
-           tst->m_eax = -VKI_EINTR;
+        if (tst->arch.m_eax == -VKI_ERESTARTSYS)
+           tst->arch.m_eax = -VKI_EINTR;
       }
 
       VG_(proxy_sigack)(tid, &tst->sig_mask);
@@ -2076,7 +2076,7 @@ void vg_sync_signalhandler ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontex
       ThreadId tid = VG_(get_current_or_recent_tid)();
       Addr fault = (Addr)info->_sifields._sigfault._addr;
       Addr esp = VG_(is_running_thread)(tid) ?
-        VG_(baseBlock)[VGOFF_(m_esp)] : VG_(threads)[tid].m_esp;
+        VG_(baseBlock)[VGOFF_(m_esp)] : VG_(threads)[tid].arch.m_esp;
       Segment *seg;
 
       seg = VG_(find_segment)(fault);
index 2759f991a28dbd00ca87ca1d44852e3682c71986..a250d4abba4ed2713be60b0205b478bb8179cfc3 100644 (file)
@@ -2024,14 +2024,14 @@ static UInt *regaddr(ThreadId tid, Int regno)
       ThreadState *tst = &VG_(threads)[tid];
 
       switch(regno) {
-      case R_EAX:      ret = &tst->m_eax; break;
-      case R_ECX:      ret = &tst->m_ecx; break;
-      case R_EDX:      ret = &tst->m_edx; break;
-      case R_EBX:      ret = &tst->m_ebx; break;
-      case R_ESP:      ret = &tst->m_esp; break;
-      case R_EBP:      ret = &tst->m_ebp; break;
-      case R_ESI:      ret = &tst->m_esi; break;
-      case R_EDI:      ret = &tst->m_edi; break;
+      case R_EAX:      ret = &tst->arch.m_eax; break;
+      case R_ECX:      ret = &tst->arch.m_ecx; break;
+      case R_EDX:      ret = &tst->arch.m_edx; break;
+      case R_EBX:      ret = &tst->arch.m_ebx; break;
+      case R_ESP:      ret = &tst->arch.m_esp; break;
+      case R_EBP:      ret = &tst->arch.m_ebp; break;
+      case R_ESI:      ret = &tst->arch.m_esi; break;
+      case R_EDI:      ret = &tst->arch.m_edi; break;
       default: 
         break;
       }
index 9c836bb66751e1e21b8c1a1b9146464e44caf3e1..39591cebae6e00dd6baf2c1f80365a5e6633273f 100644 (file)
@@ -1010,14 +1010,14 @@ static Bool fd_allowed(Int fd, const Char *syscall, ThreadId tid, Bool soft)
 #define POSTALIAS(new, old)    \
        POST(new) __attribute__((alias(STR(after_##old))))
 
-#define SYSNO  (tst->m_eax)            /* in PRE(x)  */
-#define res    (tst->m_eax)    /* in POST(x) */
-#define arg1   (tst->m_ebx)
-#define arg2   (tst->m_ecx)
-#define arg3   (tst->m_edx)
-#define arg4   (tst->m_esi)
-#define arg5   (tst->m_edi)
-#define arg6   (tst->m_ebp)
+#define SYSNO  (tst->arch.m_eax)       /* in PRE(x)  */
+#define res    (tst->arch.m_eax)       /* in POST(x) */
+#define arg1   (tst->arch.m_ebx)
+#define arg2   (tst->arch.m_ecx)
+#define arg3   (tst->arch.m_edx)
+#define arg4   (tst->arch.m_esi)
+#define arg5   (tst->arch.m_edi)
+#define arg6   (tst->arch.m_ebp)
 
 PRE(exit_group)
 {
@@ -6284,7 +6284,7 @@ static void restart_syscall(ThreadId tid)
    vg_assert(tst->syscallno != -1);
 
    SYSNO = tst->syscallno;
-   tst->m_eip -= 2;            /* sizeof(int $0x80) */
+   tst->arch.m_eip -= 2;               /* sizeof(int $0x80) */
 
    /* Make sure our caller is actually sane, and we're really backing
       back over a syscall.
@@ -6292,12 +6292,12 @@ static void restart_syscall(ThreadId tid)
       int $0x80 == CD 80 
    */
    {
-      UChar *p = (UChar *)tst->m_eip;
+      UChar *p = (UChar *)tst->arch.m_eip;
       
       if (p[0] != 0xcd || p[1] != 0x80)
         VG_(message)(Vg_DebugMsg, 
                      "?! restarting over syscall at %p %02x %02x\n",
-                     tst->m_eip, p[0], p[1]);
+                     tst->arch.m_eip, p[0], p[1]);
 
       vg_assert(p[0] == 0xcd && p[1] == 0x80);
    }
index 688db25c833712ec0fe5d928edc474cc983ac1e4..b88c1f8a27b40c5d48034bebc026b60c58aa0bca 100644 (file)
@@ -1589,8 +1589,8 @@ Bool uInstrMentionsTempReg ( UInstr* u, Int tempreg )
 static void vg_improve ( UCodeBlock* cb )
 {
    Int     i, j, k, m, n, ar, tr, told, actual_areg;
-   Int     areg_map[8];
-   Bool    annul_put[8];
+   Int     areg_map[N_ARCH_REGS];
+   Bool    annul_put[N_ARCH_REGS];
    Int     tempUse[VG_MAX_REGS_USED];
    Bool    isWrites[VG_MAX_REGS_USED];
    UInstr* u;
@@ -1636,14 +1636,14 @@ static void vg_improve ( UCodeBlock* cb )
 #  define BIND_ARCH_TO_TEMP(archreg,tempreg)\
    { Int q;                                           \
      /* Invalidate any old binding(s) to tempreg. */  \
-     for (q = 0; q < 8; q++)                          \
+     for (q = 0; q < N_ARCH_REGS; q++)                \
         if (areg_map[q] == tempreg) areg_map[q] = -1; \
      /* Add the new binding. */                       \
      areg_map[archreg] = (tempreg);                   \
    }
 
    /* Set up the A-reg map. */
-   for (i = 0; i < 8; i++) areg_map[i] = -1;
+   for (i = 0; i < N_ARCH_REGS; i++) areg_map[i] = -1;
 
    /* Scan insns. */
    for (i = 0; i < cb->used; i++) {
@@ -1735,7 +1735,7 @@ static void vg_improve ( UCodeBlock* cb )
             wr  = isWrites[j];
             if (!wr) continue;
             tr = tempUse[j];
-            for (m = 0; m < 8; m++)
+            for (m = 0; m < N_ARCH_REGS; m++)
                if (areg_map[m] == tr) areg_map[m] = -1;
          }
       }
@@ -1749,7 +1749,7 @@ static void vg_improve ( UCodeBlock* cb )
       in-memory value of %ESP to be up to date.  Although this isn't
       actually required by other analyses (cache simulation), it's
       simplest to be consistent for all end-uses. */
-   for (j = 0; j < 8; j++)
+   for (j = 0; j < N_ARCH_REGS; j++)
       annul_put[j] = False;
 
    for (i = cb->used-1; i >= 0; i--) {
@@ -1775,7 +1775,7 @@ static void vg_improve ( UCodeBlock* cb )
       } 
       else if (u->opcode == JMP || u->opcode == JIFZ
                || u->opcode == CALLM) {
-         for (j = 0; j < 8; j++)
+         for (j = 0; j < N_ARCH_REGS; j++)
             annul_put[j] = False;
       }
       else {
index 5e84ea7ae2f7ee2723938e0be38eb9f704196bb8..e6995219b6de1baad76c90a54d95ec4f7e302dde 100644 (file)
@@ -1,6 +1,15 @@
+include $(top_srcdir)/Makefile.all.am
+include $(top_srcdir)/Makefile.core-AM_CPPFLAGS.am
+
+AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -O -fomit-frame-pointer -g
+
 noinst_HEADERS = \
+       core_arch.h \
+       core_arch_asm.h \
        ume_archdefs.h
 
+noinst_LIBRARIES = libarch.a
+
 EXTRA_DIST =           \
        ume_archdefs.c  \
        ume_entry.S     \
@@ -9,6 +18,9 @@ EXTRA_DIST =           \
 BUILT_SOURCES = stage2.lds
 CLEANFILES = stage2.lds
 
+libarch_a_SOURCES = \
+       state.c
+
 # Extract ld's default linker script and hack it to our needs
 stage2.lds: Makefile
        $(CC) -Wl,--verbose -nostdlib 2>&1 | sed \
diff --git a/coregrind/x86/core_arch.h b/coregrind/x86/core_arch.h
new file mode 100644 (file)
index 0000000..a73717b
--- /dev/null
@@ -0,0 +1,149 @@
+
+/*--------------------------------------------------------------------*/
+/*---                                              x86/core_arch.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, an extensible x86 protected-mode
+   emulator for monitoring program execution on x86-Unixes.
+
+   Copyright (C) 2000-2004 Nicholas Nethercote
+      njn25@cam.ac.uk
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307, USA.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __X86_CORE_ARCH_H
+#define __X86_CORE_ARCH_H
+
+#include "core_arch_asm.h"    // arch-specific asm  stuff
+#include "tool_arch.h"        // arch-specific tool stuff
+
+/* ---------------------------------------------------------------------
+   Exports of vg_ldt.c
+   ------------------------------------------------------------------ */
+
+/* This is the hardware-format for a segment descriptor, ie what the
+   x86 actually deals with.  It is 8 bytes long.  It's ugly.  */
+
+typedef struct _LDT_ENTRY {
+    union {
+       struct {
+          UShort      LimitLow;
+          UShort      BaseLow;
+          unsigned    BaseMid         : 8;
+          unsigned    Type            : 5;
+          unsigned    Dpl             : 2;
+          unsigned    Pres            : 1;
+          unsigned    LimitHi         : 4;
+          unsigned    Sys             : 1;
+          unsigned    Reserved_0      : 1;
+          unsigned    Default_Big     : 1;
+          unsigned    Granularity     : 1;
+          unsigned    BaseHi          : 8;
+       } Bits;
+       struct {
+          UInt word1;
+          UInt word2;
+       } Words;
+    } 
+    LdtEnt;
+} VgLdtEntry;
+
+/* ---------------------------------------------------------------------
+   Constants pertaining to the simulated CPU state, VG_(baseBlock),
+   which need to go here to avoid ugly circularities.
+   ------------------------------------------------------------------ */
+
+/* How big is the saved SSE/SSE2 state?  Note that this subsumes the
+   FPU state.  On machines without SSE, we just save/restore the FPU
+   state into the first part of this area. */
+/* A general comment about SSE save/restore: It appears that the 7th
+   word (which is the MXCSR) has to be &ed with 0x0000FFBF in order
+   that restoring from it later does not cause a GP fault (which is
+   delivered as a segfault).  I guess this will have to be done
+   any time we do fxsave :-(  7th word means word offset 6 or byte
+   offset 24 from the start address of the save area.
+ */
+#define VG_SIZE_OF_SSESTATE 512
+/* ... and in words ... */
+#define VG_SIZE_OF_SSESTATE_W ((VG_SIZE_OF_SSESTATE+3)/4)
+
+
+// Architecture-specific part of a ThreadState
+typedef struct {
+   /* Pointer to this thread's Local (Segment) Descriptor Table.
+      Starts out as NULL, indicating there is no table, and we hope to
+      keep it that way.  If the thread does __NR_modify_ldt to create
+      entries, we allocate a 8192-entry table at that point.  This is
+      a straight copy of the Linux kernel's scheme.  Don't forget to
+      deallocate this at thread exit. */
+   VgLdtEntry* ldt;
+
+
+   /* TLS table. This consists of a small number (currently 3) of
+      entries from the Global Descriptor Table. */
+   VgLdtEntry tls[VKI_GDT_TLS_ENTRIES];
+
+   /* Saved machine context.  Note the FPU state, %EIP and segment
+      registers are not shadowed.
+
+      Although the segment registers are 16 bits long, storage
+      management here and in VG_(baseBlock) is
+      simplified if we pretend they are 32 bits. */
+   UInt m_cs;
+   UInt m_ss;
+   UInt m_ds;
+   UInt m_es;
+   UInt m_fs;
+   UInt m_gs;
+
+   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;
+
+   /* The SSE/FPU state.  This array does not (necessarily) have the
+      required 16-byte alignment required to get stuff in/out by
+      fxsave/fxrestore.  So we have to do it "by hand".
+   */
+   UInt m_sse[VG_SIZE_OF_SSESTATE_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;
+} 
+arch_thread_t;
+
+#endif   // __X86_CORE_ARCH_H
+
+/*--------------------------------------------------------------------*/
+/*--- end                                                          ---*/
+/*--------------------------------------------------------------------*/
diff --git a/coregrind/x86/core_arch_asm.h b/coregrind/x86/core_arch_asm.h
new file mode 100644 (file)
index 0000000..dfb16ac
--- /dev/null
@@ -0,0 +1,43 @@
+/*--------------------------------------------------------------------*/
+/*---                                          x86/core_arch_asm.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, an extensible x86 protected-mode
+   emulator for monitoring program execution on x86-Unixes.
+
+   Copyright (C) 2000-2004 Nicholas Nethercote
+      njn25@cam.ac.uk
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307, USA.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __X86_CORE_ARCH_ASM_H
+#define __X86_CORE_ARCH_ASM_H
+
+/* size of call instruction put into generated code at jump sites */
+#define VG_PATCHME_CALLSZ      5
+
+/* size of jmp instruction which overwrites the call */
+#define VG_PATCHME_JMPSZ       5
+
+#endif   // __X86_CORE_ARCH_ASM_H
+
+/*--------------------------------------------------------------------*/
+/*--- end                                                          ---*/
+/*--------------------------------------------------------------------*/
diff --git a/coregrind/x86/state.c b/coregrind/x86/state.c
new file mode 100644 (file)
index 0000000..a27e9bc
--- /dev/null
@@ -0,0 +1,209 @@
+
+/*--------------------------------------------------------------------*/
+/*--- x86 registers, etc.                                  state.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, an extensible x86 protected-mode
+   emulator for monitoring program execution on x86-Unixes.
+
+   Copyright (C) 2000-2004 Nicholas Nethercote
+      njn25@cam.ac.uk
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307, USA.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "core.h"
+
+static Int extractDflag(UInt eflags)
+{
+   return ( eflags & EFlagD ? -1 : 1 );
+}
+
+static UInt insertDflag(UInt eflags, Int d)
+{
+   vg_assert(d == 1 || d == -1);
+   eflags &= ~EFlagD;
+   if (d < 0) eflags |= EFlagD;
+   return eflags;
+}
+
+
+/* Junk to fill up a thread's shadow regs with when shadow regs aren't
+   being used. */
+#define VG_UNUSED_SHADOW_REG_VALUE  0x27182818
+
+void VGA_(load_state) ( arch_thread_t* arch, ThreadId tid )
+{
+   Int i;
+
+   VG_(baseBlock)[VGOFF_(ldt)]  = (UInt)arch->ldt;
+   VG_(baseBlock)[VGOFF_(tls_ptr)]  = (UInt)arch->tls;
+   VG_(baseBlock)[VGOFF_(m_cs)] = arch->m_cs;
+   VG_(baseBlock)[VGOFF_(m_ss)] = arch->m_ss;
+   VG_(baseBlock)[VGOFF_(m_ds)] = arch->m_ds;
+   VG_(baseBlock)[VGOFF_(m_es)] = arch->m_es;
+   VG_(baseBlock)[VGOFF_(m_fs)] = arch->m_fs;
+   VG_(baseBlock)[VGOFF_(m_gs)] = arch->m_gs;
+
+   VG_(baseBlock)[VGOFF_(m_eax)] = arch->m_eax;
+   VG_(baseBlock)[VGOFF_(m_ebx)] = arch->m_ebx;
+   VG_(baseBlock)[VGOFF_(m_ecx)] = arch->m_ecx;
+   VG_(baseBlock)[VGOFF_(m_edx)] = arch->m_edx;
+   VG_(baseBlock)[VGOFF_(m_esi)] = arch->m_esi;
+   VG_(baseBlock)[VGOFF_(m_edi)] = arch->m_edi;
+   VG_(baseBlock)[VGOFF_(m_ebp)] = arch->m_ebp;
+   VG_(baseBlock)[VGOFF_(m_esp)] = arch->m_esp;
+   VG_(baseBlock)[VGOFF_(m_eflags)] = arch->m_eflags & ~EFlagD;
+   VG_(baseBlock)[VGOFF_(m_dflag)] = extractDflag(arch->m_eflags);
+   VG_(baseBlock)[VGOFF_(m_eip)] = arch->m_eip;
+
+   for (i = 0; i < VG_SIZE_OF_SSESTATE_W; i++)
+      VG_(baseBlock)[VGOFF_(m_ssestate) + i] = arch->m_sse[i];
+
+   if (VG_(needs).shadow_regs) {
+      VG_(baseBlock)[VGOFF_(sh_eax)] = arch->sh_eax;
+      VG_(baseBlock)[VGOFF_(sh_ebx)] = arch->sh_ebx;
+      VG_(baseBlock)[VGOFF_(sh_ecx)] = arch->sh_ecx;
+      VG_(baseBlock)[VGOFF_(sh_edx)] = arch->sh_edx;
+      VG_(baseBlock)[VGOFF_(sh_esi)] = arch->sh_esi;
+      VG_(baseBlock)[VGOFF_(sh_edi)] = arch->sh_edi;
+      VG_(baseBlock)[VGOFF_(sh_ebp)] = arch->sh_ebp;
+      VG_(baseBlock)[VGOFF_(sh_esp)] = arch->sh_esp;
+      VG_(baseBlock)[VGOFF_(sh_eflags)] = arch->sh_eflags;
+   } else {
+      /* Fields shouldn't be used -- check their values haven't changed. */
+      vg_assert(
+         VG_UNUSED_SHADOW_REG_VALUE == arch->sh_eax &&
+         VG_UNUSED_SHADOW_REG_VALUE == arch->sh_ebx &&
+         VG_UNUSED_SHADOW_REG_VALUE == arch->sh_ecx &&
+         VG_UNUSED_SHADOW_REG_VALUE == arch->sh_edx &&
+         VG_UNUSED_SHADOW_REG_VALUE == arch->sh_esi &&
+         VG_UNUSED_SHADOW_REG_VALUE == arch->sh_edi &&
+         VG_UNUSED_SHADOW_REG_VALUE == arch->sh_ebp &&
+         VG_UNUSED_SHADOW_REG_VALUE == arch->sh_esp &&
+         VG_UNUSED_SHADOW_REG_VALUE == arch->sh_eflags);
+   }
+
+}
+
+void VGA_(save_state)( arch_thread_t *arch, ThreadId tid )
+{
+   Int i;
+   const UInt junk = 0xDEADBEEF;
+
+   /* We don't copy out the LDT entry, because it can never be changed
+      by the normal actions of the thread, only by the modify_ldt
+      syscall, in which case we will correctly be updating
+      VG_(threads)[tid].ldt.  This printf happens iff the following
+      assertion fails. */
+   if ((void*)arch->ldt != (void*)VG_(baseBlock)[VGOFF_(ldt)])
+      VG_(printf)("VG_(threads)[%d].ldt=%p  VG_(baseBlock)[VGOFF_(ldt)]=%p\n",
+                 tid, (void*)arch->ldt, 
+                       (void*)VG_(baseBlock)[VGOFF_(ldt)]);
+
+   vg_assert((void*)arch->ldt == (void*)VG_(baseBlock)[VGOFF_(ldt)]);
+
+   /* We don't copy out the TLS entry, because it can never be changed
+      by the normal actions of the thread, only by the set_thread_area
+      syscall, in which case we will correctly be updating
+      arch->tls.  This printf happens iff the following
+      assertion fails. */
+   if ((void*)arch->tls != (void*)VG_(baseBlock)[VGOFF_(tls_ptr)])
+      VG_(printf)("VG_(threads)[%d].tls=%p  VG_(baseBlock)[VGOFF_(tls_ptr)]=%p\
+n",
+                 tid, (void*)arch->tls, 
+                       (void*)VG_(baseBlock)[VGOFF_(tls_ptr)]);
+
+   vg_assert((void*)arch->tls 
+             == (void*)VG_(baseBlock)[VGOFF_(tls_ptr)]);
+
+   arch->m_cs = VG_(baseBlock)[VGOFF_(m_cs)];
+   arch->m_ss = VG_(baseBlock)[VGOFF_(m_ss)];
+   arch->m_ds = VG_(baseBlock)[VGOFF_(m_ds)];
+   arch->m_es = VG_(baseBlock)[VGOFF_(m_es)];
+   arch->m_fs = VG_(baseBlock)[VGOFF_(m_fs)];
+   arch->m_gs = VG_(baseBlock)[VGOFF_(m_gs)];
+
+   arch->m_eax = VG_(baseBlock)[VGOFF_(m_eax)];
+   arch->m_ebx = VG_(baseBlock)[VGOFF_(m_ebx)];
+   arch->m_ecx = VG_(baseBlock)[VGOFF_(m_ecx)];
+   arch->m_edx = VG_(baseBlock)[VGOFF_(m_edx)];
+   arch->m_esi = VG_(baseBlock)[VGOFF_(m_esi)];
+   arch->m_edi = VG_(baseBlock)[VGOFF_(m_edi)];
+   arch->m_ebp = VG_(baseBlock)[VGOFF_(m_ebp)];
+   arch->m_esp = VG_(baseBlock)[VGOFF_(m_esp)];
+   arch->m_eflags 
+      = insertDflag(VG_(baseBlock)[VGOFF_(m_eflags)],
+                    VG_(baseBlock)[VGOFF_(m_dflag)]);
+   arch->m_eip = VG_(baseBlock)[VGOFF_(m_eip)];
+
+   for (i = 0; i < VG_SIZE_OF_SSESTATE_W; i++)
+      arch->m_sse[i] 
+         = VG_(baseBlock)[VGOFF_(m_ssestate) + i];
+
+   if (VG_(needs).shadow_regs) {
+      arch->sh_eax = VG_(baseBlock)[VGOFF_(sh_eax)];
+      arch->sh_ebx = VG_(baseBlock)[VGOFF_(sh_ebx)];
+      arch->sh_ecx = VG_(baseBlock)[VGOFF_(sh_ecx)];
+      arch->sh_edx = VG_(baseBlock)[VGOFF_(sh_edx)];
+      arch->sh_esi = VG_(baseBlock)[VGOFF_(sh_esi)];
+      arch->sh_edi = VG_(baseBlock)[VGOFF_(sh_edi)];
+      arch->sh_ebp = VG_(baseBlock)[VGOFF_(sh_ebp)];
+      arch->sh_esp = VG_(baseBlock)[VGOFF_(sh_esp)];
+      arch->sh_eflags = VG_(baseBlock)[VGOFF_(sh_eflags)];
+   } else {
+      /* Fill with recognisable junk */
+      arch->sh_eax =
+      arch->sh_ebx =
+      arch->sh_ecx =
+      arch->sh_edx =
+      arch->sh_esi =
+      arch->sh_edi =
+      arch->sh_ebp =
+      arch->sh_esp = 
+      arch->sh_eflags = VG_UNUSED_SHADOW_REG_VALUE;
+   }
+   /* Fill it up with junk. */
+   VG_(baseBlock)[VGOFF_(ldt)] = junk;
+   VG_(baseBlock)[VGOFF_(tls_ptr)] = junk;
+   VG_(baseBlock)[VGOFF_(m_cs)] = junk;
+   VG_(baseBlock)[VGOFF_(m_ss)] = junk;
+   VG_(baseBlock)[VGOFF_(m_ds)] = junk;
+   VG_(baseBlock)[VGOFF_(m_es)] = junk;
+   VG_(baseBlock)[VGOFF_(m_fs)] = junk;
+   VG_(baseBlock)[VGOFF_(m_gs)] = junk;
+
+   VG_(baseBlock)[VGOFF_(m_eax)] = junk;
+   VG_(baseBlock)[VGOFF_(m_ebx)] = junk;
+   VG_(baseBlock)[VGOFF_(m_ecx)] = junk;
+   VG_(baseBlock)[VGOFF_(m_edx)] = junk;
+   VG_(baseBlock)[VGOFF_(m_esi)] = junk;
+   VG_(baseBlock)[VGOFF_(m_edi)] = junk;
+   VG_(baseBlock)[VGOFF_(m_ebp)] = junk;
+   VG_(baseBlock)[VGOFF_(m_esp)] = junk;
+   VG_(baseBlock)[VGOFF_(m_eflags)] = junk;
+   VG_(baseBlock)[VGOFF_(m_eip)] = junk;
+
+   for (i = 0; i < VG_SIZE_OF_SSESTATE_W; i++)
+      VG_(baseBlock)[VGOFF_(m_ssestate) + i] = junk;
+}
+
+/*--------------------------------------------------------------------*/
+/*--- end                                                          ---*/
+/*--------------------------------------------------------------------*/
index 3861cf5e345e2401dc54719bb212942960637a86..6680b586a28f0ed7ba5db299ec4bfa086b27e42a 100644 (file)
@@ -1,3 +1,6 @@
+
+SUBDIRS = $(VG_ARCH) .
+
 EXTRA_DIST = \
        vg_profile.c \
        tool.h.base
index 5b69c7a052c2fd0e9b4b0977c85d90afea70944d..36f86b0d060378ea64637d698e3dd1b89ea91ca4 100644 (file)
@@ -35,9 +35,7 @@
 #include <setjmp.h>       /* for jmp_buf         */
 
 #include "tool_asm.h"           // asm stuff
-
-// XXX: here temporarily, will eventually go in arch-specific headers...
-#define REGPARM(x)     __attribute__((regparm (x)))
+#include "tool_arch.h"          // arch-specific tool stuff
 
 /* ---------------------------------------------------------------------
    Where to send bug reports to.
index 9480ff579f4ceb8fe37d555c9517b57bf1e8b2e8..9e0ea2acb996b3fe33e33e8aaf45449e1de6fdcf 100644 (file)
@@ -43,6 +43,7 @@
 #define VG_(str)    VGAPPEND(vgPlain_,str)
 #define VGP_(str)   VGAPPEND(vgProf_,str)
 #define VGOFF_(str) VGAPPEND(vgOff_,str)
+#define VGA_(str)   VGAPPEND(vgArch_,str)
 
 /* Tool-specific ones.  Note that final name still starts with "vg". */
 #define SK_(str)    VGAPPEND(vgSkin_,str)
diff --git a/include/x86/.cvsignore b/include/x86/.cvsignore
new file mode 100644 (file)
index 0000000..282522d
--- /dev/null
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/include/x86/Makefile.am b/include/x86/Makefile.am
new file mode 100644 (file)
index 0000000..7d61728
--- /dev/null
@@ -0,0 +1,4 @@
+incincdir = $(includedir)/valgrind/x86
+
+incinc_HEADERS = tool_arch.h
+
diff --git a/include/x86/tool_arch.h b/include/x86/tool_arch.h
new file mode 100644 (file)
index 0000000..2e10c75
--- /dev/null
@@ -0,0 +1,44 @@
+/*--------------------------------------------------------------------*/
+/*---                                              x86/tool_arch.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, an extensible x86 protected-mode
+   emulator for monitoring program execution on x86-Unixes.
+
+   Copyright (C) 2000-2004 Nicholas Nethercote
+      njn25@cam.ac.uk
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307, USA.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __X86_TOOL_ARCH_H
+#define __X86_TOOL_ARCH_H
+
+#define REGPARM(n)      __attribute__((regparm(n)))
+
+#define FIRST_ARCH_REG  R_EAX
+#define LAST_ARCH_REG   R_EDI
+
+#define N_ARCH_REGS     8
+
+#endif   // __X86_TOOL_ARCH_H
+
+/*--------------------------------------------------------------------*/
+/*--- end                                                          ---*/
+/*--------------------------------------------------------------------*/
index bfad60b8ad01cb3b9d9241f9e404e9d00705d10c..a8369cfadf8a9d56804c1ee47699e3c30527b399 100644 (file)
@@ -722,7 +722,7 @@ void mc_set_perms (Addr a, UInt len, Bool rr, Bool ww, Bool xx)
 static void mc_post_regs_write_init ( void )
 {
    UInt i;
-   for (i = R_EAX; i <= R_EDI; 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 );
 }
index c16a2db13b1709e4451e7d392c6b93f7c6d461bb..92f9c841d29edd2384037fd0ca214fed0cbd5ecd 100644 (file)
@@ -40,6 +40,7 @@ make install DESTDIR=$RPM_BUILD_ROOT
 /usr/include/valgrind/tool_asm.h
 /usr/include/valgrind/vg_kerneliface.h
 /usr/include/valgrind/vg_skin.h
+/usr/include/valgrind/x86/tool_arch.h
 /usr/bin/valgrind
 /usr/bin/cg_annotate
 /usr/lib/valgrind