]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Arch-abstraction:
authorNicholas Nethercote <n.nethercote@gmail.com>
Fri, 10 Sep 2004 17:42:11 +0000 (17:42 +0000)
committerNicholas Nethercote <n.nethercote@gmail.com>
Fri, 10 Sep 2004 17:42:11 +0000 (17:42 +0000)
- added x86-linux/core_platform.h
- factored out getting/setting of system call arguments, put it in
  platform-specific part.

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

coregrind/core.h
coregrind/vg_proxylwp.c
coregrind/vg_scheduler.c
coregrind/vg_signals.c
coregrind/vg_syscalls.c
coregrind/x86-linux/Makefile.am
coregrind/x86-linux/core_platform.h [new file with mode: 0644]
coregrind/x86/core_arch.h

index 018da8b7d50666074d17de397f500a32b070c8d8..deff8721f5e250d35c9b146d6ff00541d3a2d454 100644 (file)
@@ -85,7 +85,9 @@
 
 #include "core_asm.h"      // asm stuff
 #include "tool.h"          // tool stuff
-#include "core_arch.h"     // arch-specific stuff;  eg. x86/arch.h
+#include "core_arch.h"     // arch-specific stuff,  eg. x86/core_arch.h
+#include "core_platform.h" // platform-specific stuff,
+                           //   eg. x86-linux/core_platform.h
 
 #include "valgrind.h"
 
index 90fe9e73d569f8c2f5b3566a814139e6dc3c8ead..8c57639c552ab828b8b66d4ea312e7b1cd328637 100644 (file)
@@ -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->arch.m_eax == -VKI_ERESTARTSYS);
+      vg_assert(PLATFORM_SYSCALL_RET(px->tst->arch) == -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->arch.m_eax = eax;
+      PLATFORM_SYSCALL_RET(px->tst->arch) = 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->arch.m_eax = -VKI_ERESTARTSYS;
+              PLATFORM_SYSCALL_RET(tst->arch) = -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->arch.m_eax = -VKI_ERESTARTSYS;
+              PLATFORM_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. */
-              tst->arch.m_eax = -VKI_ERESTARTSYS;
+              PLATFORM_SYSCALL_RET(tst->arch) = -VKI_ERESTARTSYS;
 
               /* set our process group ID to match parent */
               if (VG_(getpgrp)() != VG_(main_pgrp))
@@ -1142,7 +1142,8 @@ 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->arch.m_eax);
+                           res.tid, tst->syscallno,
+                            PLATFORM_SYSCALL_RET(tst->arch));
 
            if (tst->status != VgTs_WaitSys)
               VG_(printf)("tid %d in status %d\n",
@@ -1301,8 +1302,8 @@ Int VG_(sys_issue)(int tid)
 
    req.request = PX_RunSyscall;
 
-   tst->syscallno = tst->arch.m_eax;
-   tst->arch.m_eax = -VKI_ERESTARTSYS;
+   tst->syscallno = PLATFORM_SYSCALL_NUM(tst->arch);
+   PLATFORM_SYSCALL_RET(tst->arch) = -VKI_ERESTARTSYS;
 
    res = VG_(write)(proxy->topx, &req, sizeof(req));
 
index 71a979638deb8c01332ab9e22ea429d9933648ca..021fe6075b8fccb93663dc6114a0e01c684be717 100644 (file)
@@ -467,12 +467,12 @@ void handle_signal_return ( ThreadId tid )
       return;
 
    if (VG_(threads)[tid].status == VgTs_Sleeping
-       && VG_(threads)[tid].arch.m_eax == __NR_nanosleep) {
+       && PLATFORM_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 *)VG_(threads)[tid].arch.m_ecx; /* arg2 */
+      rem = (struct vki_timespec*)PLATFORM_SYSCALL_ARG2(VG_(threads)[tid].arch);
       if (rem != NULL) {
          rem->tv_sec = 0;
          rem->tv_nsec = 1;
@@ -526,7 +526,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].arch.m_eax; /* syscall number */
+   syscall_no = PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch);
 
    /* Special-case nanosleep because we can.  But should we?
 
@@ -536,7 +536,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].arch.m_ebx; /* arg1 */
+      req = (struct vki_timespec*)PLATFORM_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);
@@ -924,12 +924,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].arch.m_eax == __NR_exit
-                || VG_(threads)[tid].arch.m_eax == __NR_exit_group
+            if (PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_exit
+                || PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_exit_group
                ) {
 
                /* If __NR_exit, remember the supplied argument. */
-               *exitcode = VG_(threads)[tid].arch.m_ebx; /* syscall arg1 */
+               *exitcode = PLATFORM_SYSCALL_ARG1(VG_(threads)[tid].arch);
 
                /* Only run __libc_freeres if the tool says it's ok and
                   it hasn't been overridden with --run-libc-freeres=no
@@ -962,13 +962,13 @@ VgSchedReturnCode do_scheduler ( Int* exitcode, ThreadId* last_run_tid )
             }
 
             /* We've dealt with __NR_exit at this point. */
-           vg_assert(VG_(threads)[tid].arch.m_eax != __NR_exit && 
-                     VG_(threads)[tid].arch.m_eax != __NR_exit_group);
+            vg_assert(PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) != __NR_exit && 
+                      PLATFORM_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 (VG_(threads)[tid].arch.m_eax == __NR_sched_yield) {
+           if (PLATFORM_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 */
            }
index d47cfdd76b458a0042a405f8cd709eb743d5053d..e0df4ac7157b999a29bec9a5043ffb005b992284 100644 (file)
@@ -489,8 +489,8 @@ void VG_(do__NR_sigaltstack) ( ThreadId tid )
    Addr          m_esp;
 
    vg_assert(VG_(is_valid_tid)(tid));
-   ss    = (vki_kstack_t*)(VG_(threads)[tid].arch.m_ebx);
-   oss   = (vki_kstack_t*)(VG_(threads)[tid].arch.m_ecx);
+   ss    = (vki_kstack_t*)(PLATFORM_SYSCALL_ARG1(VG_(threads)[tid].arch));
+   oss   = (vki_kstack_t*)(PLATFORM_SYSCALL_ARG2(VG_(threads)[tid].arch));
    m_esp = VG_(threads)[tid].arch.m_esp;
 
    if (VG_(clo_trace_signals))
@@ -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].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);
+   signo     =                  PLATFORM_SYSCALL_ARG1(VG_(threads)[tid].arch);
+   new_act   = (vki_ksigaction*)PLATFORM_SYSCALL_ARG2(VG_(threads)[tid].arch);
+   old_act   = (vki_ksigaction*)PLATFORM_SYSCALL_ARG3(VG_(threads)[tid].arch);
 
    if (VG_(clo_trace_signals))
       VG_(message)(Vg_DebugExtraMsg, 
@@ -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->arch.m_eax == -VKI_ERESTARTSYS)
-           tst->arch.m_eax = -VKI_EINTR;
+        if (PLATFORM_SYSCALL_RET(tst->arch) == -VKI_ERESTARTSYS)
+           PLATFORM_SYSCALL_RET(tst->arch) = -VKI_EINTR;
       }
 
       VG_(proxy_sigack)(tid, &tst->sig_mask);
index 39591cebae6e00dd6baf2c1f80365a5e6633273f..2934f40e453aa27af916d38732f7673f86a9501e 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->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)
+#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)
 
 PRE(exit_group)
 {
index 15936733cca13fe1cc2096977ecfd8c9d4e23ac1..31e8cc5a01a6db562f6174d5a84642df76bbc60c 100644 (file)
@@ -4,4 +4,5 @@ include $(top_srcdir)/Makefile.core-AM_CPPFLAGS.am
 AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -O -fomit-frame-pointer -g
 
 noinst_HEADERS = \
+       core_platform.h \
        vki_unistd.h
diff --git a/coregrind/x86-linux/core_platform.h b/coregrind/x86-linux/core_platform.h
new file mode 100644 (file)
index 0000000..3dafc78
--- /dev/null
@@ -0,0 +1,63 @@
+
+/*--------------------------------------------------------------------*/
+/*--- x86-Linux-specific stuff for the core.                       ---*/
+/*---                                    x86-linux/core_platform.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_LINUX_CORE_PLATFORM_H
+#define __X86_LINUX_CORE_PLATFORM_H
+
+//#include "core_platform_asm.h"    // platform-specific asm  stuff
+//#include "platform_arch.h"        // platform-specific tool stuff
+
+/* ---------------------------------------------------------------------
+   Interesting registers
+   ------------------------------------------------------------------ */
+
+// Accessors for the arch_thread_t
+#define PLATFORM_SYSCALL_NUM(regs)     ((regs).m_eax)
+#define PLATFORM_SYSCALL_RET(regs)     ((regs).m_eax)
+#define PLATFORM_SYSCALL_ARG1(regs)    ((regs).m_ebx)
+#define PLATFORM_SYSCALL_ARG2(regs)    ((regs).m_ecx)
+#define PLATFORM_SYSCALL_ARG3(regs)    ((regs).m_edx)
+#define PLATFORM_SYSCALL_ARG4(regs)    ((regs).m_esi)
+#define PLATFORM_SYSCALL_ARG5(regs)    ((regs).m_edi)
+#define PLATFORM_SYSCALL_ARG6(regs)    ((regs).m_ebp)
+
+#define PLATFORM_PRE_SYSCALL_RESULT(regs, val)     ((regs).m_eax = (val))
+
+// Interesting register numbers
+#define R_SYSCALL_NUM                  R_EAX
+#define R_SYSCALL_ARG1                 R_EBX
+#define R_SYSCALL_RET                  R_EAX
+
+#endif   // __X86_LINUX_CORE_PLATFORM_H
+
+/*--------------------------------------------------------------------*/
+/*--- end                                                          ---*/
+/*--------------------------------------------------------------------*/
index 55fae1945b67ddf9b7fb78d6c050ca2a9d5e2e44..425ff5b5b46379c1c9c5fa51c9057a57795d7f4a 100644 (file)
@@ -1,6 +1,6 @@
 
 /*--------------------------------------------------------------------*/
-/*--- Arch-specific stuff for the core.            x86/core_arch.h ---*/
+/*--- x86-specific stuff for the core.             x86/core_arch.h ---*/
 /*--------------------------------------------------------------------*/
 
 /*