X86: Reorganize the native tracing code.
authorGabe Black <gblack@eecs.umich.edu>
Wed, 1 Aug 2007 19:01:51 +0000 (12:01 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 1 Aug 2007 19:01:51 +0000 (12:01 -0700)
Ignore different values or rcx and r11 after a syscall until either the local or remote value changes. Also change the codes organization somewhat.

--HG--
extra : convert_revision : 2c1f69d4e55b443e68bfc7b43e8387b02cf0b6b5

src/cpu/nativetrace.cc
src/cpu/nativetrace.hh

index 90a0e1a62f145db0b6b61d622c78a483cbab7285..fe524e2456d39764fb06625c0a149ea1d4c618f4 100644 (file)
@@ -60,119 +60,122 @@ NativeTrace::NativeTrace(const std::string & _name) : InstTracer(_name)
     }
     ccprintf(cerr, "Listening for native process on port %d\n", port);
     fd = native_listener.accept();
+    checkRcx = true;
+    checkR11 = true;
 }
 
 bool
-NativeTraceRecord::checkIntReg(const char * regName, int index, int size)
+NativeTrace::checkRcxReg(const char * name, uint64_t &mVal, uint64_t &nVal)
 {
-    uint64_t regVal;
-    int res = read(parent->fd, &regVal, size);
-    if(res < 0)
-        panic("Read call failed! %s\n", strerror(errno));
-    regVal = TheISA::gtoh(regVal);
-    uint64_t realRegVal = thread->readIntReg(index);
-    if(regVal != realRegVal)
-    {
-        DPRINTFN("Register %s should be %#x but is %#x.\n",
-                regName, regVal, realRegVal);
-        return false;
-    }
+    if(!checkRcx)
+        checkRcx = (mVal != oldRcxVal || nVal != oldRealRcxVal);
+    if(checkRcx)
+        return checkReg(name, mVal, nVal);
     return true;
 }
 
-bool NativeTraceRecord::checkPC(const char * regName, int size)
+bool
+NativeTrace::checkR11Reg(const char * name, uint64_t &mVal, uint64_t &nVal)
 {
-    uint64_t regVal;
-    int res = read(parent->fd, &regVal, size);
-    if(res < 0)
-        panic("Read call failed! %s\n", strerror(errno));
-    regVal = TheISA::gtoh(regVal);
-    uint64_t realRegVal = thread->readNextPC();
-    if(regVal != realRegVal)
-    {
-        DPRINTFN("%s should be %#x but is %#x.\n",
-                regName, regVal, realRegVal);
-        return false;
-    }
+    if(!checkR11)
+        checkR11 = (mVal != oldR11Val || nVal != oldRealR11Val);
+    if(checkR11)
+        return checkReg(name, mVal, nVal);
     return true;
 }
 
 void
 Trace::NativeTraceRecord::dump()
 {
-//    ostream &outs = Trace::output();
-
     //Don't print what happens for each micro-op, just print out
     //once at the last op, and for regular instructions.
     if(!staticInst->isMicroop() || staticInst->isLastMicroop())
+    parent->check(thread, staticInst->isSyscall());
+}
+
+void
+Trace::NativeTrace::check(ThreadContext * tc, bool isSyscall)
+{
+//    ostream &outs = Trace::output();
+    nState.update(fd);
+    mState.update(tc);
+
+    if(isSyscall)
     {
-        checkIntReg("rax", INTREG_RAX, sizeof(uint64_t));
-        checkIntReg("rcx", INTREG_RCX, sizeof(uint64_t));
-        checkIntReg("rdx", INTREG_RDX, sizeof(uint64_t));
-        checkIntReg("rbx", INTREG_RBX, sizeof(uint64_t));
-        checkIntReg("rsp", INTREG_RSP, sizeof(uint64_t));
-        checkIntReg("rbp", INTREG_RBP, sizeof(uint64_t));
-        checkIntReg("rsi", INTREG_RSI, sizeof(uint64_t));
-        checkIntReg("rdi", INTREG_RDI, sizeof(uint64_t));
-        checkIntReg("r8", INTREG_R8, sizeof(uint64_t));
-        checkIntReg("r9", INTREG_R9, sizeof(uint64_t));
-        checkIntReg("r10", INTREG_R10, sizeof(uint64_t));
-        checkIntReg("r11", INTREG_R11, sizeof(uint64_t));
-        checkIntReg("r12", INTREG_R12, sizeof(uint64_t));
-        checkIntReg("r13", INTREG_R13, sizeof(uint64_t));
-        checkIntReg("r14", INTREG_R14, sizeof(uint64_t));
-        checkIntReg("r15", INTREG_R15, sizeof(uint64_t));
-        checkPC("rip", sizeof(uint64_t));
+        checkRcx = false;
+        checkR11 = false;
+        oldRcxVal = mState.rcx;
+        oldRealRcxVal = nState.rcx;
+        oldR11Val = mState.r11;
+        oldRealR11Val = nState.r11;
+    }
+
+    checkReg("rax", mState.rax, nState.rax);
+    checkRcxReg("rcx", mState.rcx, nState.rcx);
+    checkReg("rdx", mState.rdx, nState.rdx);
+    checkReg("rbx", mState.rbx, nState.rbx);
+    checkReg("rsp", mState.rsp, nState.rsp);
+    checkReg("rbp", mState.rbp, nState.rbp);
+    checkReg("rsi", mState.rsi, nState.rsi);
+    checkReg("rdi", mState.rdi, nState.rdi);
+    checkReg("r8",  mState.r8,  nState.r8);
+    checkReg("r9",  mState.r9,  nState.r9);
+    checkReg("r10", mState.r10, nState.r10);
+    checkR11Reg("r11", mState.r11, nState.r11);
+    checkReg("r12", mState.r12, nState.r12);
+    checkReg("r13", mState.r13, nState.r13);
+    checkReg("r14", mState.r14, nState.r14);
+    checkReg("r15", mState.r15, nState.r15);
+    checkReg("rip", mState.rip, nState.rip);
 #if THE_ISA == SPARC_ISA
-        /*for(int f = 0; f <= 62; f+=2)
-        {
-            uint64_t regVal;
-            int res = read(fd, &regVal, sizeof(regVal));
-            if(res < 0)
-                panic("First read call failed! %s\n", strerror(errno));
-            regVal = TheISA::gtoh(regVal);
-            uint64_t realRegVal = thread->readFloatRegBits(f, 64);
-            if(regVal != realRegVal)
-            {
-                DPRINTF(ExecRegDelta, "Register f%d should be %#x but is %#x.\n", f, regVal, realRegVal);
-            }
-        }*/
+    /*for(int f = 0; f <= 62; f+=2)
+    {
         uint64_t regVal;
         int res = read(fd, &regVal, sizeof(regVal));
         if(res < 0)
             panic("First read call failed! %s\n", strerror(errno));
         regVal = TheISA::gtoh(regVal);
-        uint64_t realRegVal = thread->readNextPC();
-        if(regVal != realRegVal)
-        {
-            DPRINTF(ExecRegDelta,
-                    "Register pc should be %#x but is %#x.\n",
-                    regVal, realRegVal);
-        }
-        res = read(fd, &regVal, sizeof(regVal));
-        if(res < 0)
-            panic("First read call failed! %s\n", strerror(errno));
-        regVal = TheISA::gtoh(regVal);
-        realRegVal = thread->readNextNPC();
+        uint64_t realRegVal = thread->readFloatRegBits(f, 64);
         if(regVal != realRegVal)
         {
-            DPRINTF(ExecRegDelta,
-                    "Register npc should be %#x but is %#x.\n",
-                    regVal, realRegVal);
-        }
-        res = read(fd, &regVal, sizeof(regVal));
-        if(res < 0)
-            panic("First read call failed! %s\n", strerror(errno));
-        regVal = TheISA::gtoh(regVal);
-        realRegVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2);
-        if((regVal & 0xF) != (realRegVal & 0xF))
-        {
-            DPRINTF(ExecRegDelta,
-                    "Register ccr should be %#x but is %#x.\n",
-                    regVal, realRegVal);
+            DPRINTF(ExecRegDelta, "Register f%d should be %#x but is %#x.\n", f, regVal, realRegVal);
         }
-#endif
+    }*/
+    uint64_t regVal;
+    int res = read(fd, &regVal, sizeof(regVal));
+    if(res < 0)
+        panic("First read call failed! %s\n", strerror(errno));
+    regVal = TheISA::gtoh(regVal);
+    uint64_t realRegVal = thread->readNextPC();
+    if(regVal != realRegVal)
+    {
+        DPRINTF(ExecRegDelta,
+                "Register pc should be %#x but is %#x.\n",
+                regVal, realRegVal);
     }
+    res = read(fd, &regVal, sizeof(regVal));
+    if(res < 0)
+        panic("First read call failed! %s\n", strerror(errno));
+    regVal = TheISA::gtoh(regVal);
+    realRegVal = thread->readNextNPC();
+    if(regVal != realRegVal)
+    {
+        DPRINTF(ExecRegDelta,
+                "Register npc should be %#x but is %#x.\n",
+                regVal, realRegVal);
+    }
+    res = read(fd, &regVal, sizeof(regVal));
+    if(res < 0)
+        panic("First read call failed! %s\n", strerror(errno));
+    regVal = TheISA::gtoh(regVal);
+    realRegVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2);
+    if((regVal & 0xF) != (realRegVal & 0xF))
+    {
+        DPRINTF(ExecRegDelta,
+                "Register ccr should be %#x but is %#x.\n",
+                regVal, realRegVal);
+    }
+#endif
 }
 
 /* namespace Trace */ }
index 48395792d08a959d7785c5e4386f42d612d733b2..126077581fdef5d5806dd3fe699d0961b33be0f5 100644 (file)
@@ -36,6 +36,7 @@
 #include "cpu/static_inst.hh"
 #include "sim/host.hh"
 #include "sim/insttracer.hh"
+#include "arch/x86/intregs.hh"
 
 class ThreadContext;
 
@@ -49,12 +50,6 @@ class NativeTraceRecord : public InstRecord
   protected:
     NativeTrace * parent;
 
-    bool
-    checkIntReg(const char * regName, int index, int size);
-
-    bool
-    checkPC(const char * regName, int size);
-
   public:
     NativeTraceRecord(NativeTrace * _parent,
                Tick _when, ThreadContext *_thread,
@@ -73,8 +68,109 @@ class NativeTrace : public InstTracer
 
     ListenSocket native_listener;
 
+    bool checkRcx;
+    bool checkR11;
+    uint64_t oldRcxVal, oldR11Val;
+    uint64_t oldRealRcxVal, oldRealR11Val;
+
+    struct ThreadState {
+        uint64_t rax;
+        uint64_t rcx;
+        uint64_t rdx;
+        uint64_t rbx;
+        uint64_t rsp;
+        uint64_t rbp;
+        uint64_t rsi;
+        uint64_t rdi;
+        uint64_t r8;
+        uint64_t r9;
+        uint64_t r10;
+        uint64_t r11;
+        uint64_t r12;
+        uint64_t r13;
+        uint64_t r14;
+        uint64_t r15;
+        uint64_t rip;
+
+        void update(int fd)
+        {
+            int bytesLeft = sizeof(ThreadState);
+            int bytesRead = 0;
+            do
+            {
+                int res = read(fd, ((char *)this) + bytesRead, bytesLeft);
+                if(res < 0)
+                    panic("Read call failed! %s\n", strerror(errno));
+                bytesLeft -= res;
+                bytesRead += res;
+            } while(bytesLeft);
+            rax = TheISA::gtoh(rax);
+            rcx = TheISA::gtoh(rcx);
+            rdx = TheISA::gtoh(rdx);
+            rbx = TheISA::gtoh(rbx);
+            rsp = TheISA::gtoh(rsp);
+            rbp = TheISA::gtoh(rbp);
+            rsi = TheISA::gtoh(rsi);
+            rdi = TheISA::gtoh(rdi);
+            r8 = TheISA::gtoh(r8);
+            r9 = TheISA::gtoh(r9);
+            r10 = TheISA::gtoh(r10);
+            r11 = TheISA::gtoh(r11);
+            r12 = TheISA::gtoh(r12);
+            r13 = TheISA::gtoh(r13);
+            r14 = TheISA::gtoh(r14);
+            r15 = TheISA::gtoh(r15);
+            rip = TheISA::gtoh(rip);
+        }
+
+        void update(ThreadContext * tc)
+        {
+            rax = tc->readIntReg(X86ISA::INTREG_RAX);
+            rcx = tc->readIntReg(X86ISA::INTREG_RCX);
+            rdx = tc->readIntReg(X86ISA::INTREG_RDX);
+            rbx = tc->readIntReg(X86ISA::INTREG_RBX);
+            rsp = tc->readIntReg(X86ISA::INTREG_RSP);
+            rbp = tc->readIntReg(X86ISA::INTREG_RBP);
+            rsi = tc->readIntReg(X86ISA::INTREG_RSI);
+            rdi = tc->readIntReg(X86ISA::INTREG_RDI);
+            r8 = tc->readIntReg(X86ISA::INTREG_R8);
+            r9 = tc->readIntReg(X86ISA::INTREG_R9);
+            r10 = tc->readIntReg(X86ISA::INTREG_R10);
+            r11 = tc->readIntReg(X86ISA::INTREG_R11);
+            r12 = tc->readIntReg(X86ISA::INTREG_R12);
+            r13 = tc->readIntReg(X86ISA::INTREG_R13);
+            r14 = tc->readIntReg(X86ISA::INTREG_R14);
+            r15 = tc->readIntReg(X86ISA::INTREG_R15);
+            rip = tc->readNextPC();
+        }
+
+    };
+
+    ThreadState nState;
+    ThreadState mState;
+
+
   public:
 
+    template<class T>
+    bool
+    checkReg(const char * regName, T &val, T &realVal)
+    {
+        if(val != realVal)
+        {
+            DPRINTFN("Register %s should be %#x but is %#x.\n",
+                    regName, realVal, val);
+            return false;
+        }
+        return true;
+    }
+
+    bool
+    checkRcxReg(const char * regName, uint64_t &, uint64_t &);
+
+    bool
+    checkR11Reg(const char * regName, uint64_t &, uint64_t &);
+
     NativeTrace(const std::string & name);
 
     NativeTraceRecord *
@@ -88,6 +184,9 @@ class NativeTrace : public InstTracer
                 staticInst, pc, tc->misspeculating());
     }
 
+    void
+    check(ThreadContext *, bool syscall);
+
     friend class NativeTraceRecord;
 };