X86/StateTrace: Make m5 and statetrace track mmx and xmm registers, and actually compare xmm.
--HG-- extra : convert_revision : 02c6641200edb133c9bc11f1fdf3c1a0b1c87e77
This commit is contained in:
parent
760240176a
commit
26044dca33
4 changed files with 261 additions and 50 deletions
|
@ -84,6 +84,19 @@ NativeTrace::checkR11Reg(const char * name, uint64_t &mVal, uint64_t &nVal)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
NativeTrace::checkXMM(int num, uint64_t mXmmBuf[], uint64_t nXmmBuf[])
|
||||||
|
{
|
||||||
|
if (mXmmBuf[num * 2] != nXmmBuf[num * 2] ||
|
||||||
|
mXmmBuf[num * 2 + 1] != nXmmBuf[num * 2 + 1]) {
|
||||||
|
DPRINTFN("Register xmm%d should be 0x%016x%016x but is 0x%016x%016x.\n",
|
||||||
|
num, nXmmBuf[num * 2 + 1], nXmmBuf[num * 2],
|
||||||
|
mXmmBuf[num * 2 + 1], mXmmBuf[num * 2]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Trace::NativeTraceRecord::dump()
|
Trace::NativeTraceRecord::dump()
|
||||||
{
|
{
|
||||||
|
@ -127,6 +140,22 @@ Trace::NativeTrace::check(ThreadContext * tc, bool isSyscall)
|
||||||
checkReg("r14", mState.r14, nState.r14);
|
checkReg("r14", mState.r14, nState.r14);
|
||||||
checkReg("r15", mState.r15, nState.r15);
|
checkReg("r15", mState.r15, nState.r15);
|
||||||
checkReg("rip", mState.rip, nState.rip);
|
checkReg("rip", mState.rip, nState.rip);
|
||||||
|
checkXMM(0, mState.xmm, nState.xmm);
|
||||||
|
checkXMM(1, mState.xmm, nState.xmm);
|
||||||
|
checkXMM(2, mState.xmm, nState.xmm);
|
||||||
|
checkXMM(3, mState.xmm, nState.xmm);
|
||||||
|
checkXMM(4, mState.xmm, nState.xmm);
|
||||||
|
checkXMM(5, mState.xmm, nState.xmm);
|
||||||
|
checkXMM(6, mState.xmm, nState.xmm);
|
||||||
|
checkXMM(7, mState.xmm, nState.xmm);
|
||||||
|
checkXMM(8, mState.xmm, nState.xmm);
|
||||||
|
checkXMM(9, mState.xmm, nState.xmm);
|
||||||
|
checkXMM(10, mState.xmm, nState.xmm);
|
||||||
|
checkXMM(11, mState.xmm, nState.xmm);
|
||||||
|
checkXMM(12, mState.xmm, nState.xmm);
|
||||||
|
checkXMM(13, mState.xmm, nState.xmm);
|
||||||
|
checkXMM(14, mState.xmm, nState.xmm);
|
||||||
|
checkXMM(15, mState.xmm, nState.xmm);
|
||||||
#if THE_ISA == SPARC_ISA
|
#if THE_ISA == SPARC_ISA
|
||||||
/*for(int f = 0; f <= 62; f+=2)
|
/*for(int f = 0; f <= 62; f+=2)
|
||||||
{
|
{
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "sim/host.hh"
|
#include "sim/host.hh"
|
||||||
#include "sim/insttracer.hh"
|
#include "sim/insttracer.hh"
|
||||||
#include "arch/x86/intregs.hh"
|
#include "arch/x86/intregs.hh"
|
||||||
|
#include "arch/x86/floatregs.hh"
|
||||||
|
|
||||||
class ThreadContext;
|
class ThreadContext;
|
||||||
|
|
||||||
|
@ -91,6 +92,9 @@ class NativeTrace : public InstTracer
|
||||||
uint64_t r14;
|
uint64_t r14;
|
||||||
uint64_t r15;
|
uint64_t r15;
|
||||||
uint64_t rip;
|
uint64_t rip;
|
||||||
|
//This should be expanded to 16 if x87 registers are considered
|
||||||
|
uint64_t mmx[8];
|
||||||
|
uint64_t xmm[32];
|
||||||
|
|
||||||
void update(int fd)
|
void update(int fd)
|
||||||
{
|
{
|
||||||
|
@ -121,6 +125,11 @@ class NativeTrace : public InstTracer
|
||||||
r14 = TheISA::gtoh(r14);
|
r14 = TheISA::gtoh(r14);
|
||||||
r15 = TheISA::gtoh(r15);
|
r15 = TheISA::gtoh(r15);
|
||||||
rip = TheISA::gtoh(rip);
|
rip = TheISA::gtoh(rip);
|
||||||
|
//This should be expanded if x87 registers are considered
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
mmx[i] = TheISA::gtoh(mmx[i]);
|
||||||
|
for (int i = 0; i < 32; i++)
|
||||||
|
xmm[i] = TheISA::gtoh(xmm[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(ThreadContext * tc)
|
void update(ThreadContext * tc)
|
||||||
|
@ -142,6 +151,11 @@ class NativeTrace : public InstTracer
|
||||||
r14 = tc->readIntReg(X86ISA::INTREG_R14);
|
r14 = tc->readIntReg(X86ISA::INTREG_R14);
|
||||||
r15 = tc->readIntReg(X86ISA::INTREG_R15);
|
r15 = tc->readIntReg(X86ISA::INTREG_R15);
|
||||||
rip = tc->readNextPC();
|
rip = tc->readNextPC();
|
||||||
|
//This should be expanded if x87 registers are considered
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
mmx[i] = tc->readFloatRegBits(X86ISA::FLOATREG_MMX(i));
|
||||||
|
for (int i = 0; i < 32; i++)
|
||||||
|
xmm[i] = tc->readFloatRegBits(X86ISA::FLOATREG_XMM_BASE + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -171,6 +185,9 @@ class NativeTrace : public InstTracer
|
||||||
bool
|
bool
|
||||||
checkR11Reg(const char * regName, uint64_t &, uint64_t &);
|
checkR11Reg(const char * regName, uint64_t &, uint64_t &);
|
||||||
|
|
||||||
|
bool
|
||||||
|
checkXMM(int num, uint64_t mXmmBuf[], uint64_t nXmmBuf[]);
|
||||||
|
|
||||||
NativeTrace(const Params *p);
|
NativeTrace(const Params *p);
|
||||||
|
|
||||||
NativeTraceRecord *
|
NativeTraceRecord *
|
||||||
|
|
|
@ -52,32 +52,80 @@ char * AMD64TraceChild::regNames[numregs] = {
|
||||||
//PC
|
//PC
|
||||||
"rip",
|
"rip",
|
||||||
//Flags
|
//Flags
|
||||||
"eflags"};
|
"eflags",
|
||||||
|
//MMX
|
||||||
|
"mmx0_0", "mmx0_1",
|
||||||
|
"mmx1_0", "mmx1_1",
|
||||||
|
"mmx2_0", "mmx2_1",
|
||||||
|
"mmx3_0", "mmx3_1",
|
||||||
|
"mmx4_0", "mmx4_1",
|
||||||
|
"mmx5_0", "mmx5_1",
|
||||||
|
"mmx6_0", "mmx6_1",
|
||||||
|
"mmx7_0", "mmx7_1",
|
||||||
|
//XMM
|
||||||
|
"xmm0_0", "xmm0_1", "xmm0_2", "xmm0_3",
|
||||||
|
"xmm1_0", "xmm1_1", "xmm1_2", "xmm1_3",
|
||||||
|
"xmm2_0", "xmm2_1", "xmm2_2", "xmm2_3",
|
||||||
|
"xmm3_0", "xmm3_1", "xmm3_2", "xmm3_3",
|
||||||
|
"xmm4_0", "xmm4_1", "xmm4_2", "xmm4_3",
|
||||||
|
"xmm5_0", "xmm5_1", "xmm5_2", "xmm5_3",
|
||||||
|
"xmm6_0", "xmm6_1", "xmm6_2", "xmm6_3",
|
||||||
|
"xmm7_0", "xmm7_1", "xmm7_2", "xmm7_3",
|
||||||
|
"xmm8_0", "xmm8_1", "xmm8_2", "xmm8_3",
|
||||||
|
"xmm9_0", "xmm9_1", "xmm9_2", "xmm9_3",
|
||||||
|
"xmm10_0", "xmm10_1", "xmm10_2", "xmm10_3",
|
||||||
|
"xmm11_0", "xmm11_1", "xmm11_2", "xmm11_3",
|
||||||
|
"xmm12_0", "xmm12_1", "xmm12_2", "xmm12_3",
|
||||||
|
"xmm13_0", "xmm13_1", "xmm13_2", "xmm13_3",
|
||||||
|
"xmm14_0", "xmm14_1", "xmm14_2", "xmm14_3",
|
||||||
|
"xmm15_0", "xmm15_1", "xmm15_2", "xmm15_3"};
|
||||||
|
|
||||||
bool AMD64TraceChild::sendState(int socket)
|
bool AMD64TraceChild::sendState(int socket)
|
||||||
{
|
{
|
||||||
uint64_t regVal = 0;
|
uint64_t regVal64 = 0;
|
||||||
|
uint32_t regVal32 = 0;
|
||||||
for(int x = 0; x <= R15; x++)
|
for(int x = 0; x <= R15; x++)
|
||||||
{
|
{
|
||||||
regVal = getRegVal(x);
|
regVal64 = getRegVal(x);
|
||||||
if(write(socket, ®Val, sizeof(regVal)) == -1)
|
if(write(socket, ®Val64, sizeof(regVal64)) == -1)
|
||||||
{
|
{
|
||||||
cerr << "Write failed! " << strerror(errno) << endl;
|
cerr << "Write failed! " << strerror(errno) << endl;
|
||||||
tracing = false;
|
tracing = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
regVal = getRegVal(RIP);
|
regVal64 = getRegVal(RIP);
|
||||||
if(write(socket, ®Val, sizeof(regVal)) == -1)
|
if(write(socket, ®Val64, sizeof(regVal64)) == -1)
|
||||||
{
|
{
|
||||||
cerr << "Write failed! " << strerror(errno) << endl;
|
cerr << "Write failed! " << strerror(errno) << endl;
|
||||||
tracing = false;
|
tracing = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
for(int x = MMX0_0; x <= MMX7_1; x++)
|
||||||
|
{
|
||||||
|
regVal32 = getRegVal(x);
|
||||||
|
if(write(socket, ®Val32, sizeof(regVal32)) == -1)
|
||||||
|
{
|
||||||
|
cerr << "Write failed! " << strerror(errno) << endl;
|
||||||
|
tracing = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int x = XMM0_0; x <= XMM15_3; x++)
|
||||||
|
{
|
||||||
|
regVal32 = getRegVal(x);
|
||||||
|
if(write(socket, ®Val32, sizeof(regVal32)) == -1)
|
||||||
|
{
|
||||||
|
cerr << "Write failed! " << strerror(errno) << endl;
|
||||||
|
tracing = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t AMD64TraceChild::getRegs(user_regs_struct & myregs, int num)
|
int64_t AMD64TraceChild::getRegs(user_regs_struct & myregs,
|
||||||
|
user_fpregs_struct & myfpregs, int num)
|
||||||
{
|
{
|
||||||
assert(num < numregs && num >= 0);
|
assert(num < numregs && num >= 0);
|
||||||
switch(num)
|
switch(num)
|
||||||
|
@ -115,6 +163,88 @@ int64_t AMD64TraceChild::getRegs(user_regs_struct & myregs, int num)
|
||||||
case RIP: return myregs.rip;
|
case RIP: return myregs.rip;
|
||||||
//Flags
|
//Flags
|
||||||
case EFLAGS: return myregs.eflags;
|
case EFLAGS: return myregs.eflags;
|
||||||
|
//MMX
|
||||||
|
case MMX0_0: return myfpregs.st_space[0];
|
||||||
|
case MMX0_1: return myfpregs.st_space[1];
|
||||||
|
case MMX1_0: return myfpregs.st_space[2];
|
||||||
|
case MMX1_1: return myfpregs.st_space[3];
|
||||||
|
case MMX2_0: return myfpregs.st_space[4];
|
||||||
|
case MMX2_1: return myfpregs.st_space[5];
|
||||||
|
case MMX3_0: return myfpregs.st_space[6];
|
||||||
|
case MMX3_1: return myfpregs.st_space[7];
|
||||||
|
case MMX4_0: return myfpregs.st_space[8];
|
||||||
|
case MMX4_1: return myfpregs.st_space[9];
|
||||||
|
case MMX5_0: return myfpregs.st_space[10];
|
||||||
|
case MMX5_1: return myfpregs.st_space[11];
|
||||||
|
case MMX6_0: return myfpregs.st_space[12];
|
||||||
|
case MMX6_1: return myfpregs.st_space[13];
|
||||||
|
case MMX7_0: return myfpregs.st_space[14];
|
||||||
|
case MMX7_1: return myfpregs.st_space[15];
|
||||||
|
//XMM
|
||||||
|
case XMM0_0: return myfpregs.xmm_space[0];
|
||||||
|
case XMM0_1: return myfpregs.xmm_space[1];
|
||||||
|
case XMM0_2: return myfpregs.xmm_space[2];
|
||||||
|
case XMM0_3: return myfpregs.xmm_space[3];
|
||||||
|
case XMM1_0: return myfpregs.xmm_space[4];
|
||||||
|
case XMM1_1: return myfpregs.xmm_space[5];
|
||||||
|
case XMM1_2: return myfpregs.xmm_space[6];
|
||||||
|
case XMM1_3: return myfpregs.xmm_space[7];
|
||||||
|
case XMM2_0: return myfpregs.xmm_space[8];
|
||||||
|
case XMM2_1: return myfpregs.xmm_space[9];
|
||||||
|
case XMM2_2: return myfpregs.xmm_space[10];
|
||||||
|
case XMM2_3: return myfpregs.xmm_space[11];
|
||||||
|
case XMM3_0: return myfpregs.xmm_space[12];
|
||||||
|
case XMM3_1: return myfpregs.xmm_space[13];
|
||||||
|
case XMM3_2: return myfpregs.xmm_space[14];
|
||||||
|
case XMM3_3: return myfpregs.xmm_space[15];
|
||||||
|
case XMM4_0: return myfpregs.xmm_space[16];
|
||||||
|
case XMM4_1: return myfpregs.xmm_space[17];
|
||||||
|
case XMM4_2: return myfpregs.xmm_space[18];
|
||||||
|
case XMM4_3: return myfpregs.xmm_space[19];
|
||||||
|
case XMM5_0: return myfpregs.xmm_space[20];
|
||||||
|
case XMM5_1: return myfpregs.xmm_space[21];
|
||||||
|
case XMM5_2: return myfpregs.xmm_space[22];
|
||||||
|
case XMM5_3: return myfpregs.xmm_space[23];
|
||||||
|
case XMM6_0: return myfpregs.xmm_space[24];
|
||||||
|
case XMM6_1: return myfpregs.xmm_space[25];
|
||||||
|
case XMM6_2: return myfpregs.xmm_space[26];
|
||||||
|
case XMM6_3: return myfpregs.xmm_space[27];
|
||||||
|
case XMM7_0: return myfpregs.xmm_space[28];
|
||||||
|
case XMM7_1: return myfpregs.xmm_space[29];
|
||||||
|
case XMM7_2: return myfpregs.xmm_space[30];
|
||||||
|
case XMM7_3: return myfpregs.xmm_space[31];
|
||||||
|
case XMM8_0: return myfpregs.xmm_space[32];
|
||||||
|
case XMM8_1: return myfpregs.xmm_space[33];
|
||||||
|
case XMM8_2: return myfpregs.xmm_space[34];
|
||||||
|
case XMM8_3: return myfpregs.xmm_space[35];
|
||||||
|
case XMM9_0: return myfpregs.xmm_space[36];
|
||||||
|
case XMM9_1: return myfpregs.xmm_space[37];
|
||||||
|
case XMM9_2: return myfpregs.xmm_space[38];
|
||||||
|
case XMM9_3: return myfpregs.xmm_space[39];
|
||||||
|
case XMM10_0: return myfpregs.xmm_space[40];
|
||||||
|
case XMM10_1: return myfpregs.xmm_space[41];
|
||||||
|
case XMM10_2: return myfpregs.xmm_space[42];
|
||||||
|
case XMM10_3: return myfpregs.xmm_space[43];
|
||||||
|
case XMM11_0: return myfpregs.xmm_space[44];
|
||||||
|
case XMM11_1: return myfpregs.xmm_space[45];
|
||||||
|
case XMM11_2: return myfpregs.xmm_space[46];
|
||||||
|
case XMM11_3: return myfpregs.xmm_space[47];
|
||||||
|
case XMM12_0: return myfpregs.xmm_space[48];
|
||||||
|
case XMM12_1: return myfpregs.xmm_space[49];
|
||||||
|
case XMM12_2: return myfpregs.xmm_space[50];
|
||||||
|
case XMM12_3: return myfpregs.xmm_space[51];
|
||||||
|
case XMM13_0: return myfpregs.xmm_space[52];
|
||||||
|
case XMM13_1: return myfpregs.xmm_space[53];
|
||||||
|
case XMM13_2: return myfpregs.xmm_space[54];
|
||||||
|
case XMM13_3: return myfpregs.xmm_space[55];
|
||||||
|
case XMM14_0: return myfpregs.xmm_space[56];
|
||||||
|
case XMM14_1: return myfpregs.xmm_space[57];
|
||||||
|
case XMM14_2: return myfpregs.xmm_space[58];
|
||||||
|
case XMM14_3: return myfpregs.xmm_space[59];
|
||||||
|
case XMM15_0: return myfpregs.xmm_space[60];
|
||||||
|
case XMM15_1: return myfpregs.xmm_space[61];
|
||||||
|
case XMM15_2: return myfpregs.xmm_space[62];
|
||||||
|
case XMM15_3: return myfpregs.xmm_space[63];
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -124,11 +254,17 @@ int64_t AMD64TraceChild::getRegs(user_regs_struct & myregs, int num)
|
||||||
bool AMD64TraceChild::update(int pid)
|
bool AMD64TraceChild::update(int pid)
|
||||||
{
|
{
|
||||||
oldregs = regs;
|
oldregs = regs;
|
||||||
|
oldfpregs = fpregs;
|
||||||
if(ptrace(PTRACE_GETREGS, pid, 0, ®s) != 0)
|
if(ptrace(PTRACE_GETREGS, pid, 0, ®s) != 0)
|
||||||
{
|
{
|
||||||
cerr << "update: " << strerror(errno) << endl;
|
cerr << "update: " << strerror(errno) << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if(ptrace(PTRACE_GETFPREGS, pid, 0, &fpregs) != 0)
|
||||||
|
{
|
||||||
|
cerr << "update: " << strerror(errno) << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
for(unsigned int x = 0; x < numregs; x++)
|
for(unsigned int x = 0; x < numregs; x++)
|
||||||
regDiffSinceUpdate[x] = (getRegVal(x) != getOldRegVal(x));
|
regDiffSinceUpdate[x] = (getRegVal(x) != getOldRegVal(x));
|
||||||
return true;
|
return true;
|
||||||
|
@ -142,12 +278,12 @@ AMD64TraceChild::AMD64TraceChild()
|
||||||
|
|
||||||
int64_t AMD64TraceChild::getRegVal(int num)
|
int64_t AMD64TraceChild::getRegVal(int num)
|
||||||
{
|
{
|
||||||
return getRegs(regs, num);
|
return getRegs(regs, fpregs, num);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t AMD64TraceChild::getOldRegVal(int num)
|
int64_t AMD64TraceChild::getOldRegVal(int num)
|
||||||
{
|
{
|
||||||
return getRegs(oldregs, num);
|
return getRegs(oldregs, oldfpregs, num);
|
||||||
}
|
}
|
||||||
|
|
||||||
char * AMD64TraceChild::printReg(int num)
|
char * AMD64TraceChild::printReg(int num)
|
||||||
|
|
|
@ -58,14 +58,43 @@ class AMD64TraceChild : public TraceChild
|
||||||
RIP,
|
RIP,
|
||||||
//Flags
|
//Flags
|
||||||
EFLAGS,
|
EFLAGS,
|
||||||
|
//MMX
|
||||||
|
MMX0_0, MMX0_1,
|
||||||
|
MMX1_0, MMX1_1,
|
||||||
|
MMX2_0, MMX2_1,
|
||||||
|
MMX3_0, MMX3_1,
|
||||||
|
MMX4_0, MMX4_1,
|
||||||
|
MMX5_0, MMX5_1,
|
||||||
|
MMX6_0, MMX6_1,
|
||||||
|
MMX7_0, MMX7_1,
|
||||||
|
//XMM
|
||||||
|
XMM0_0, XMM0_1, XMM0_2, XMM0_3,
|
||||||
|
XMM1_0, XMM1_1, XMM1_2, XMM1_3,
|
||||||
|
XMM2_0, XMM2_1, XMM2_2, XMM2_3,
|
||||||
|
XMM3_0, XMM3_1, XMM3_2, XMM3_3,
|
||||||
|
XMM4_0, XMM4_1, XMM4_2, XMM4_3,
|
||||||
|
XMM5_0, XMM5_1, XMM5_2, XMM5_3,
|
||||||
|
XMM6_0, XMM6_1, XMM6_2, XMM6_3,
|
||||||
|
XMM7_0, XMM7_1, XMM7_2, XMM7_3,
|
||||||
|
XMM8_0, XMM8_1, XMM8_2, XMM8_3,
|
||||||
|
XMM9_0, XMM9_1, XMM9_2, XMM9_3,
|
||||||
|
XMM10_0, XMM10_1, XMM10_2, XMM10_3,
|
||||||
|
XMM11_0, XMM11_1, XMM11_2, XMM11_3,
|
||||||
|
XMM12_0, XMM12_1, XMM12_2, XMM12_3,
|
||||||
|
XMM13_0, XMM13_1, XMM13_2, XMM13_3,
|
||||||
|
XMM14_0, XMM14_1, XMM14_2, XMM14_3,
|
||||||
|
XMM15_0, XMM15_1, XMM15_2, XMM15_3,
|
||||||
numregs
|
numregs
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
char printBuffer [256];
|
char printBuffer [256];
|
||||||
static char * regNames[numregs];
|
static char * regNames[numregs];
|
||||||
int64_t getRegs(user_regs_struct & myregs, int num);
|
int64_t getRegs(user_regs_struct & myregs,
|
||||||
|
user_fpregs_struct &myfpregs,int num);
|
||||||
user_regs_struct regs;
|
user_regs_struct regs;
|
||||||
user_regs_struct oldregs;
|
user_regs_struct oldregs;
|
||||||
|
user_fpregs_struct fpregs;
|
||||||
|
user_fpregs_struct oldfpregs;
|
||||||
bool regDiffSinceUpdate[numregs];
|
bool regDiffSinceUpdate[numregs];
|
||||||
|
|
||||||
uint64_t findSyscall();
|
uint64_t findSyscall();
|
||||||
|
|
Loading…
Reference in a new issue