From e42524af020792a558888c8bf8f094b332a56f03 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 1 Aug 2007 12:01:51 -0700 Subject: [PATCH] X86: Reorganize the native tracing code. 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 | 173 +++++++++++++++++++++-------------------- src/cpu/nativetrace.hh | 111 ++++++++++++++++++++++++-- 2 files changed, 193 insertions(+), 91 deletions(-) diff --git a/src/cpu/nativetrace.cc b/src/cpu/nativetrace.cc index 90a0e1a62..fe524e245 100644 --- a/src/cpu/nativetrace.cc +++ b/src/cpu/nativetrace.cc @@ -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, ®Val, 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, ®Val, 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, ®Val, 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, ®Val, sizeof(regVal)); if(res < 0) panic("First read call failed! %s\n", strerror(errno)); regVal = TheISA::gtoh(regVal); - uint64_t realRegVal = thread->readNextPC(); + uint64_t realRegVal = thread->readFloatRegBits(f, 64); if(regVal != realRegVal) { - DPRINTF(ExecRegDelta, - "Register pc should be %#x but is %#x.\n", - regVal, realRegVal); + DPRINTF(ExecRegDelta, "Register f%d should be %#x but is %#x.\n", f, regVal, realRegVal); } - res = read(fd, ®Val, 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, ®Val, 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 + }*/ + uint64_t regVal; + int res = read(fd, ®Val, 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, ®Val, 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, ®Val, 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 */ } diff --git a/src/cpu/nativetrace.hh b/src/cpu/nativetrace.hh index 48395792d..126077581 100644 --- a/src/cpu/nativetrace.hh +++ b/src/cpu/nativetrace.hh @@ -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 + 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; };