Statetrace: Clean up style.

This commit is contained in:
Gabe Black 2011-03-02 22:53:10 -08:00
parent 07b507d278
commit 3df970f0de
16 changed files with 856 additions and 917 deletions

View file

@ -40,83 +40,73 @@
using namespace std; using namespace std;
const char * AMD64TraceChild::regNames[numregs] = { const char * AMD64TraceChild::regNames[numregs] = {
//GPRs //GPRs
"rax", "rbx", "rcx", "rdx", "rax", "rbx", "rcx", "rdx",
//Index registers //Index registers
"rsi", "rdi", "rsi", "rdi",
//Base pointer and stack pointer //Base pointer and stack pointer
"rbp", "rsp", "rbp", "rsp",
//New 64 bit mode registers //New 64 bit mode registers
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
//Segmentation registers //Segmentation registers
"cs", "ds", "es", "fs", "gs", "ss", "fs_base", "gs_base", "cs", "ds", "es", "fs", "gs", "ss", "fs_base", "gs_base",
//PC //PC
"rip", "rip",
//Flags //Flags
"eflags", "eflags",
//MMX //MMX
"mmx0_0", "mmx0_1", "mmx0_0", "mmx0_1", "mmx1_0", "mmx1_1",
"mmx1_0", "mmx1_1", "mmx2_0", "mmx2_1", "mmx3_0", "mmx3_1",
"mmx2_0", "mmx2_1", "mmx4_0", "mmx4_1", "mmx5_0", "mmx5_1",
"mmx3_0", "mmx3_1", "mmx6_0", "mmx6_1", "mmx7_0", "mmx7_1",
"mmx4_0", "mmx4_1", //XMM
"mmx5_0", "mmx5_1", "xmm0_0", "xmm0_1", "xmm0_2", "xmm0_3",
"mmx6_0", "mmx6_1", "xmm1_0", "xmm1_1", "xmm1_2", "xmm1_3",
"mmx7_0", "mmx7_1", "xmm2_0", "xmm2_1", "xmm2_2", "xmm2_3",
//XMM "xmm3_0", "xmm3_1", "xmm3_2", "xmm3_3",
"xmm0_0", "xmm0_1", "xmm0_2", "xmm0_3", "xmm4_0", "xmm4_1", "xmm4_2", "xmm4_3",
"xmm1_0", "xmm1_1", "xmm1_2", "xmm1_3", "xmm5_0", "xmm5_1", "xmm5_2", "xmm5_3",
"xmm2_0", "xmm2_1", "xmm2_2", "xmm2_3", "xmm6_0", "xmm6_1", "xmm6_2", "xmm6_3",
"xmm3_0", "xmm3_1", "xmm3_2", "xmm3_3", "xmm7_0", "xmm7_1", "xmm7_2", "xmm7_3",
"xmm4_0", "xmm4_1", "xmm4_2", "xmm4_3", "xmm8_0", "xmm8_1", "xmm8_2", "xmm8_3",
"xmm5_0", "xmm5_1", "xmm5_2", "xmm5_3", "xmm9_0", "xmm9_1", "xmm9_2", "xmm9_3",
"xmm6_0", "xmm6_1", "xmm6_2", "xmm6_3", "xmm10_0", "xmm10_1", "xmm10_2", "xmm10_3",
"xmm7_0", "xmm7_1", "xmm7_2", "xmm7_3", "xmm11_0", "xmm11_1", "xmm11_2", "xmm11_3",
"xmm8_0", "xmm8_1", "xmm8_2", "xmm8_3", "xmm12_0", "xmm12_1", "xmm12_2", "xmm12_3",
"xmm9_0", "xmm9_1", "xmm9_2", "xmm9_3", "xmm13_0", "xmm13_1", "xmm13_2", "xmm13_3",
"xmm10_0", "xmm10_1", "xmm10_2", "xmm10_3", "xmm14_0", "xmm14_1", "xmm14_2", "xmm14_3",
"xmm11_0", "xmm11_1", "xmm11_2", "xmm11_3", "xmm15_0", "xmm15_1", "xmm15_2", "xmm15_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 regVal64 = 0; uint64_t regVal64 = 0;
uint32_t regVal32 = 0; uint32_t regVal32 = 0;
for(int x = 0; x <= R15; x++) for (int x = 0; x <= R15; x++) {
{
regVal64 = getRegVal(x); regVal64 = getRegVal(x);
if(write(socket, &regVal64, sizeof(regVal64)) == -1) if (write(socket, &regVal64, sizeof(regVal64)) == -1) {
{
cerr << "Write failed! " << strerror(errno) << endl; cerr << "Write failed! " << strerror(errno) << endl;
tracing = false; tracing = false;
return false; return false;
} }
} }
regVal64 = getRegVal(RIP); regVal64 = getRegVal(RIP);
if(write(socket, &regVal64, sizeof(regVal64)) == -1) if (write(socket, &regVal64, 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++) for (int x = MMX0_0; x <= MMX7_1; x++) {
{
regVal32 = getRegVal(x); regVal32 = getRegVal(x);
if(write(socket, &regVal32, sizeof(regVal32)) == -1) if (write(socket, &regVal32, sizeof(regVal32)) == -1) {
{
cerr << "Write failed! " << strerror(errno) << endl; cerr << "Write failed! " << strerror(errno) << endl;
tracing = false; tracing = false;
return false; return false;
} }
} }
for(int x = XMM0_0; x <= XMM15_3; x++) for (int x = XMM0_0; x <= XMM15_3; x++) {
{
regVal32 = getRegVal(x); regVal32 = getRegVal(x);
if(write(socket, &regVal32, sizeof(regVal32)) == -1) if (write(socket, &regVal32, sizeof(regVal32)) == -1) {
{
cerr << "Write failed! " << strerror(errno) << endl; cerr << "Write failed! " << strerror(errno) << endl;
tracing = false; tracing = false;
return false; return false;
@ -125,175 +115,178 @@ bool AMD64TraceChild::sendState(int socket)
return true; return true;
} }
int64_t AMD64TraceChild::getRegs(user_regs_struct & myregs, int64_t
AMD64TraceChild::getRegs(user_regs_struct & myregs,
user_fpregs_struct & myfpregs, int num) user_fpregs_struct & myfpregs, int num)
{ {
assert(num < numregs && num >= 0); assert(num < numregs && num >= 0);
switch(num) switch (num) {
{ //GPRs
//GPRs case RAX: return myregs.rax;
case RAX: return myregs.rax; case RBX: return myregs.rbx;
case RBX: return myregs.rbx; case RCX: return myregs.rcx;
case RCX: return myregs.rcx; case RDX: return myregs.rdx;
case RDX: return myregs.rdx; //Index registers
//Index registers case RSI: return myregs.rsi;
case RSI: return myregs.rsi; case RDI: return myregs.rdi;
case RDI: return myregs.rdi; //Base pointer and stack pointer
//Base pointer and stack pointer case RBP: return myregs.rbp;
case RBP: return myregs.rbp; case RSP: return myregs.rsp;
case RSP: return myregs.rsp; //New 64 bit mode registers
//New 64 bit mode registers case R8: return myregs.r8;
case R8: return myregs.r8; case R9: return myregs.r9;
case R9: return myregs.r9; case R10: return myregs.r10;
case R10: return myregs.r10; case R11: return myregs.r11;
case R11: return myregs.r11; case R12: return myregs.r12;
case R12: return myregs.r12; case R13: return myregs.r13;
case R13: return myregs.r13; case R14: return myregs.r14;
case R14: return myregs.r14; case R15: return myregs.r15;
case R15: return myregs.r15; //Segmentation registers
//Segmentation registers case CS: return myregs.cs;
case CS: return myregs.cs; case DS: return myregs.ds;
case DS: return myregs.ds; case ES: return myregs.es;
case ES: return myregs.es; case FS: return myregs.fs;
case FS: return myregs.fs; case GS: return myregs.gs;
case GS: return myregs.gs; case SS: return myregs.ss;
case SS: return myregs.ss; case FS_BASE: return myregs.fs_base;
case FS_BASE: return myregs.fs_base; case GS_BASE: return myregs.gs_base;
case GS_BASE: return myregs.gs_base; //PC
//PC case RIP: return myregs.rip;
case RIP: return myregs.rip; //Flags
//Flags case EFLAGS: return myregs.eflags;
case EFLAGS: return myregs.eflags; //MMX
//MMX case MMX0_0: return myfpregs.st_space[0];
case MMX0_0: return myfpregs.st_space[0]; case MMX0_1: return myfpregs.st_space[1];
case MMX0_1: return myfpregs.st_space[1]; case MMX1_0: return myfpregs.st_space[2];
case MMX1_0: return myfpregs.st_space[2]; case MMX1_1: return myfpregs.st_space[3];
case MMX1_1: return myfpregs.st_space[3]; case MMX2_0: return myfpregs.st_space[4];
case MMX2_0: return myfpregs.st_space[4]; case MMX2_1: return myfpregs.st_space[5];
case MMX2_1: return myfpregs.st_space[5]; case MMX3_0: return myfpregs.st_space[6];
case MMX3_0: return myfpregs.st_space[6]; case MMX3_1: return myfpregs.st_space[7];
case MMX3_1: return myfpregs.st_space[7]; case MMX4_0: return myfpregs.st_space[8];
case MMX4_0: return myfpregs.st_space[8]; case MMX4_1: return myfpregs.st_space[9];
case MMX4_1: return myfpregs.st_space[9]; case MMX5_0: return myfpregs.st_space[10];
case MMX5_0: return myfpregs.st_space[10]; case MMX5_1: return myfpregs.st_space[11];
case MMX5_1: return myfpregs.st_space[11]; case MMX6_0: return myfpregs.st_space[12];
case MMX6_0: return myfpregs.st_space[12]; case MMX6_1: return myfpregs.st_space[13];
case MMX6_1: return myfpregs.st_space[13]; case MMX7_0: return myfpregs.st_space[14];
case MMX7_0: return myfpregs.st_space[14]; case MMX7_1: return myfpregs.st_space[15];
case MMX7_1: return myfpregs.st_space[15]; //XMM
//XMM case XMM0_0: return myfpregs.xmm_space[0];
case XMM0_0: return myfpregs.xmm_space[0]; case XMM0_1: return myfpregs.xmm_space[1];
case XMM0_1: return myfpregs.xmm_space[1]; case XMM0_2: return myfpregs.xmm_space[2];
case XMM0_2: return myfpregs.xmm_space[2]; case XMM0_3: return myfpregs.xmm_space[3];
case XMM0_3: return myfpregs.xmm_space[3]; case XMM1_0: return myfpregs.xmm_space[4];
case XMM1_0: return myfpregs.xmm_space[4]; case XMM1_1: return myfpregs.xmm_space[5];
case XMM1_1: return myfpregs.xmm_space[5]; case XMM1_2: return myfpregs.xmm_space[6];
case XMM1_2: return myfpregs.xmm_space[6]; case XMM1_3: return myfpregs.xmm_space[7];
case XMM1_3: return myfpregs.xmm_space[7]; case XMM2_0: return myfpregs.xmm_space[8];
case XMM2_0: return myfpregs.xmm_space[8]; case XMM2_1: return myfpregs.xmm_space[9];
case XMM2_1: return myfpregs.xmm_space[9]; case XMM2_2: return myfpregs.xmm_space[10];
case XMM2_2: return myfpregs.xmm_space[10]; case XMM2_3: return myfpregs.xmm_space[11];
case XMM2_3: return myfpregs.xmm_space[11]; case XMM3_0: return myfpregs.xmm_space[12];
case XMM3_0: return myfpregs.xmm_space[12]; case XMM3_1: return myfpregs.xmm_space[13];
case XMM3_1: return myfpregs.xmm_space[13]; case XMM3_2: return myfpregs.xmm_space[14];
case XMM3_2: return myfpregs.xmm_space[14]; case XMM3_3: return myfpregs.xmm_space[15];
case XMM3_3: return myfpregs.xmm_space[15]; case XMM4_0: return myfpregs.xmm_space[16];
case XMM4_0: return myfpregs.xmm_space[16]; case XMM4_1: return myfpregs.xmm_space[17];
case XMM4_1: return myfpregs.xmm_space[17]; case XMM4_2: return myfpregs.xmm_space[18];
case XMM4_2: return myfpregs.xmm_space[18]; case XMM4_3: return myfpregs.xmm_space[19];
case XMM4_3: return myfpregs.xmm_space[19]; case XMM5_0: return myfpregs.xmm_space[20];
case XMM5_0: return myfpregs.xmm_space[20]; case XMM5_1: return myfpregs.xmm_space[21];
case XMM5_1: return myfpregs.xmm_space[21]; case XMM5_2: return myfpregs.xmm_space[22];
case XMM5_2: return myfpregs.xmm_space[22]; case XMM5_3: return myfpregs.xmm_space[23];
case XMM5_3: return myfpregs.xmm_space[23]; case XMM6_0: return myfpregs.xmm_space[24];
case XMM6_0: return myfpregs.xmm_space[24]; case XMM6_1: return myfpregs.xmm_space[25];
case XMM6_1: return myfpregs.xmm_space[25]; case XMM6_2: return myfpregs.xmm_space[26];
case XMM6_2: return myfpregs.xmm_space[26]; case XMM6_3: return myfpregs.xmm_space[27];
case XMM6_3: return myfpregs.xmm_space[27]; case XMM7_0: return myfpregs.xmm_space[28];
case XMM7_0: return myfpregs.xmm_space[28]; case XMM7_1: return myfpregs.xmm_space[29];
case XMM7_1: return myfpregs.xmm_space[29]; case XMM7_2: return myfpregs.xmm_space[30];
case XMM7_2: return myfpregs.xmm_space[30]; case XMM7_3: return myfpregs.xmm_space[31];
case XMM7_3: return myfpregs.xmm_space[31]; case XMM8_0: return myfpregs.xmm_space[32];
case XMM8_0: return myfpregs.xmm_space[32]; case XMM8_1: return myfpregs.xmm_space[33];
case XMM8_1: return myfpregs.xmm_space[33]; case XMM8_2: return myfpregs.xmm_space[34];
case XMM8_2: return myfpregs.xmm_space[34]; case XMM8_3: return myfpregs.xmm_space[35];
case XMM8_3: return myfpregs.xmm_space[35]; case XMM9_0: return myfpregs.xmm_space[36];
case XMM9_0: return myfpregs.xmm_space[36]; case XMM9_1: return myfpregs.xmm_space[37];
case XMM9_1: return myfpregs.xmm_space[37]; case XMM9_2: return myfpregs.xmm_space[38];
case XMM9_2: return myfpregs.xmm_space[38]; case XMM9_3: return myfpregs.xmm_space[39];
case XMM9_3: return myfpregs.xmm_space[39]; case XMM10_0: return myfpregs.xmm_space[40];
case XMM10_0: return myfpregs.xmm_space[40]; case XMM10_1: return myfpregs.xmm_space[41];
case XMM10_1: return myfpregs.xmm_space[41]; case XMM10_2: return myfpregs.xmm_space[42];
case XMM10_2: return myfpregs.xmm_space[42]; case XMM10_3: return myfpregs.xmm_space[43];
case XMM10_3: return myfpregs.xmm_space[43]; case XMM11_0: return myfpregs.xmm_space[44];
case XMM11_0: return myfpregs.xmm_space[44]; case XMM11_1: return myfpregs.xmm_space[45];
case XMM11_1: return myfpregs.xmm_space[45]; case XMM11_2: return myfpregs.xmm_space[46];
case XMM11_2: return myfpregs.xmm_space[46]; case XMM11_3: return myfpregs.xmm_space[47];
case XMM11_3: return myfpregs.xmm_space[47]; case XMM12_0: return myfpregs.xmm_space[48];
case XMM12_0: return myfpregs.xmm_space[48]; case XMM12_1: return myfpregs.xmm_space[49];
case XMM12_1: return myfpregs.xmm_space[49]; case XMM12_2: return myfpregs.xmm_space[50];
case XMM12_2: return myfpregs.xmm_space[50]; case XMM12_3: return myfpregs.xmm_space[51];
case XMM12_3: return myfpregs.xmm_space[51]; case XMM13_0: return myfpregs.xmm_space[52];
case XMM13_0: return myfpregs.xmm_space[52]; case XMM13_1: return myfpregs.xmm_space[53];
case XMM13_1: return myfpregs.xmm_space[53]; case XMM13_2: return myfpregs.xmm_space[54];
case XMM13_2: return myfpregs.xmm_space[54]; case XMM13_3: return myfpregs.xmm_space[55];
case XMM13_3: return myfpregs.xmm_space[55]; case XMM14_0: return myfpregs.xmm_space[56];
case XMM14_0: return myfpregs.xmm_space[56]; case XMM14_1: return myfpregs.xmm_space[57];
case XMM14_1: return myfpregs.xmm_space[57]; case XMM14_2: return myfpregs.xmm_space[58];
case XMM14_2: return myfpregs.xmm_space[58]; case XMM14_3: return myfpregs.xmm_space[59];
case XMM14_3: return myfpregs.xmm_space[59]; case XMM15_0: return myfpregs.xmm_space[60];
case XMM15_0: return myfpregs.xmm_space[60]; case XMM15_1: return myfpregs.xmm_space[61];
case XMM15_1: return myfpregs.xmm_space[61]; case XMM15_2: return myfpregs.xmm_space[62];
case XMM15_2: return myfpregs.xmm_space[62]; case XMM15_3: return myfpregs.xmm_space[63];
case XMM15_3: return myfpregs.xmm_space[63]; default:
default: assert(0);
assert(0); return 0;
return 0;
} }
} }
bool AMD64TraceChild::update(int pid) bool
AMD64TraceChild::update(int pid)
{ {
oldregs = regs; oldregs = regs;
oldfpregs = fpregs; oldfpregs = fpregs;
if(ptrace(PTRACE_GETREGS, pid, 0, &regs) != 0) if (ptrace(PTRACE_GETREGS, pid, 0, &regs) != 0) {
{
cerr << "update: " << strerror(errno) << endl; cerr << "update: " << strerror(errno) << endl;
return false; return false;
} }
if(ptrace(PTRACE_GETFPREGS, pid, 0, &fpregs) != 0) if (ptrace(PTRACE_GETFPREGS, pid, 0, &fpregs) != 0) {
{
cerr << "update: " << strerror(errno) << endl; cerr << "update: " << strerror(errno) << endl;
return false; 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;
} }
AMD64TraceChild::AMD64TraceChild() AMD64TraceChild::AMD64TraceChild()
{ {
for(unsigned int x = 0; x < numregs; x++) for (unsigned int x = 0; x < numregs; x++)
regDiffSinceUpdate[x] = false; regDiffSinceUpdate[x] = false;
} }
int64_t AMD64TraceChild::getRegVal(int num) int64_t
AMD64TraceChild::getRegVal(int num)
{ {
return getRegs(regs, fpregs, num); return getRegs(regs, fpregs, num);
} }
int64_t AMD64TraceChild::getOldRegVal(int num) int64_t
AMD64TraceChild::getOldRegVal(int num)
{ {
return getRegs(oldregs, oldfpregs, num); return getRegs(oldregs, oldfpregs, num);
} }
char * AMD64TraceChild::printReg(int num) char *
AMD64TraceChild::printReg(int num)
{ {
sprintf(printBuffer, "0x%016lX", getRegVal(num)); sprintf(printBuffer, "0x%016lX", getRegVal(num));
return printBuffer; return printBuffer;
} }
ostream & AMD64TraceChild::outputStartState(ostream & os) ostream &
AMD64TraceChild::outputStartState(ostream & os)
{ {
uint64_t sp = getSP(); uint64_t sp = getSP();
uint64_t pc = getPC(); uint64_t pc = getPC();
@ -313,13 +306,12 @@ ostream & AMD64TraceChild::outputStartState(ostream & os)
//Output argv pointers //Output argv pointers
int argCount = 0; int argCount = 0;
uint64_t cargv; uint64_t cargv;
do do {
{
cargv = ptrace(PTRACE_PEEKDATA, pid, sp, 0); cargv = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
sprintf(obuf, "0x%016lx: argv[%d] = 0x%016lx\n", sprintf(obuf, "0x%016lx: argv[%d] = 0x%016lx\n",
sp, argCount++, cargv); sp, argCount++, cargv);
if(cargv) if (cargv)
if(highestInfo < cargv) if (highestInfo < cargv)
highestInfo = cargv; highestInfo = cargv;
os << obuf; os << obuf;
sp += 8; sp += 8;
@ -328,8 +320,7 @@ ostream & AMD64TraceChild::outputStartState(ostream & os)
//Output the envp pointers //Output the envp pointers
int envCount = 0; int envCount = 0;
uint64_t cenvp; uint64_t cenvp;
do do {
{
cenvp = ptrace(PTRACE_PEEKDATA, pid, sp, 0); cenvp = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
sprintf(obuf, "0x%016lx: envp[%d] = 0x%016lx\n", sprintf(obuf, "0x%016lx: envp[%d] = 0x%016lx\n",
sp, envCount++, cenvp); sp, envCount++, cenvp);
@ -337,8 +328,7 @@ ostream & AMD64TraceChild::outputStartState(ostream & os)
sp += 8; sp += 8;
} while(cenvp); } while(cenvp);
uint64_t auxType, auxVal; uint64_t auxType, auxVal;
do do {
{
auxType = ptrace(PTRACE_PEEKDATA, pid, sp, 0); auxType = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
sp += 8; sp += 8;
auxVal = ptrace(PTRACE_PEEKDATA, pid, sp, 0); auxVal = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
@ -352,16 +342,13 @@ ostream & AMD64TraceChild::outputStartState(ostream & os)
uint64_t buf; uint64_t buf;
uint64_t currentStart = sp; uint64_t currentStart = sp;
bool clearedInitialPadding = false; bool clearedInitialPadding = false;
do do {
{
buf = ptrace(PTRACE_PEEKDATA, pid, sp, 0); buf = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
char * cbuf = (char *)&buf; char * cbuf = (char *)&buf;
for(int x = 0; x < sizeof(uint64_t); x++) for (int x = 0; x < sizeof(uint64_t); x++) {
{ if (cbuf[x])
if(cbuf[x])
current += cbuf[x]; current += cbuf[x];
else else {
{
sprintf(obuf, "0x%016lx: \"%s\"\n", sprintf(obuf, "0x%016lx: \"%s\"\n",
currentStart, current.c_str()); currentStart, current.c_str());
os << obuf; os << obuf;
@ -371,23 +358,21 @@ ostream & AMD64TraceChild::outputStartState(ostream & os)
} }
sp += 8; sp += 8;
clearedInitialPadding = clearedInitialPadding || buf != 0; clearedInitialPadding = clearedInitialPadding || buf != 0;
} while(!clearedInitialPadding || buf != 0 || sp <= highestInfo); } while (!clearedInitialPadding || buf != 0 || sp <= highestInfo);
return os; return os;
} }
uint64_t AMD64TraceChild::findSyscall() uint64_t
AMD64TraceChild::findSyscall()
{ {
uint64_t rip = getPC(); uint64_t rip = getPC();
bool foundOpcode = false; bool foundOpcode = false;
bool twoByteOpcode = false; bool twoByteOpcode = false;
for(;;) for (;;) {
{
uint64_t buf = ptrace(PTRACE_PEEKDATA, pid, rip, 0); uint64_t buf = ptrace(PTRACE_PEEKDATA, pid, rip, 0);
for(int i = 0; i < sizeof(uint64_t); i++) for (int i = 0; i < sizeof(uint64_t); i++) {
{
unsigned char byte = buf & 0xFF; unsigned char byte = buf & 0xFF;
if(!foundOpcode) if (!foundOpcode) {
{
if(!(byte == 0x66 || //operand override if(!(byte == 0x66 || //operand override
byte == 0x67 || //address override byte == 0x67 || //address override
byte == 0x2E || //cs byte == 0x2E || //cs
@ -400,28 +385,24 @@ uint64_t AMD64TraceChild::findSyscall()
byte == 0xF2 || //repe byte == 0xF2 || //repe
byte == 0xF3 || //repne byte == 0xF3 || //repne
(byte >= 0x40 && byte <= 0x4F) // REX (byte >= 0x40 && byte <= 0x4F) // REX
)) )) {
{
foundOpcode = true; foundOpcode = true;
} }
} }
if(foundOpcode) if (foundOpcode) {
{ if (twoByteOpcode) {
if(twoByteOpcode)
{
//SYSCALL or SYSENTER //SYSCALL or SYSENTER
if(byte == 0x05 || byte == 0x34) if (byte == 0x05 || byte == 0x34)
return rip + 1; return rip + 1;
else else
return 0; return 0;
} }
if(!twoByteOpcode) if (!twoByteOpcode) {
{ if (byte == 0xCC) // INT3
if(byte == 0xCC) // INT3
return rip + 1; return rip + 1;
else if(byte == 0xCD) // INT with byte immediate else if (byte == 0xCD) // INT with byte immediate
return rip + 2; return rip + 2;
else if(byte == 0x0F) // two byte opcode prefix else if (byte == 0x0F) // two byte opcode prefix
twoByteOpcode = true; twoByteOpcode = true;
else else
return 0; return 0;
@ -433,11 +414,11 @@ uint64_t AMD64TraceChild::findSyscall()
} }
} }
bool AMD64TraceChild::step() bool
AMD64TraceChild::step()
{ {
uint64_t ripAfterSyscall = findSyscall(); uint64_t ripAfterSyscall = findSyscall();
if(ripAfterSyscall) if (ripAfterSyscall) {
{
//Get the original contents of memory //Get the original contents of memory
uint64_t buf = ptrace(PTRACE_PEEKDATA, pid, ripAfterSyscall, 0); uint64_t buf = ptrace(PTRACE_PEEKDATA, pid, ripAfterSyscall, 0);
//Patch the first two bytes of the memory immediately after this with //Patch the first two bytes of the memory immediately after this with
@ -452,13 +433,10 @@ bool AMD64TraceChild::step()
ptraceSingleStep(); ptraceSingleStep();
//Put things back to the way they started //Put things back to the way they started
ptrace(PTRACE_POKEDATA, pid, ripAfterSyscall, buf); ptrace(PTRACE_POKEDATA, pid, ripAfterSyscall, buf);
} } else {
else
{
//Get all the way past repe and repne string instructions in one shot. //Get all the way past repe and repne string instructions in one shot.
uint64_t newPC, origPC = getPC(); uint64_t newPC, origPC = getPC();
do do {
{
ptraceSingleStep(); ptraceSingleStep();
newPC = getPC(); newPC = getPC();
} while(newPC == origPC); } while(newPC == origPC);
@ -467,5 +445,5 @@ bool AMD64TraceChild::step()
TraceChild * genTraceChild() TraceChild * genTraceChild()
{ {
return new AMD64TraceChild; return new AMD64TraceChild;
} }

View file

@ -108,18 +108,21 @@ class AMD64TraceChild : public TraceChild
bool sendState(int socket); bool sendState(int socket);
int getNumRegs() int
getNumRegs()
{ {
return numregs; return numregs;
} }
bool diffSinceUpdate(int num) bool
diffSinceUpdate(int num)
{ {
assert(num < numregs && num >= 0); assert(num < numregs && num >= 0);
return regDiffSinceUpdate[num]; return regDiffSinceUpdate[num];
} }
std::string getRegName(int num) std::string
getRegName(int num)
{ {
assert(num < numregs && num >= 0); assert(num < numregs && num >= 0);
return regNames[num]; return regNames[num];

View file

@ -68,7 +68,8 @@ ARMTraceChild::ARMTraceChild()
} }
} }
bool ARMTraceChild::sendState(int socket) bool
ARMTraceChild::sendState(int socket)
{ {
uint32_t regVal = 0; uint32_t regVal = 0;
uint32_t message[numregs + 1]; uint32_t message[numregs + 1];
@ -98,43 +99,48 @@ bool ARMTraceChild::sendState(int socket)
return true; return true;
} }
uint32_t ARMTraceChild::getRegs(user_regs &myregs, int num) uint32_t
ARMTraceChild::getRegs(user_regs &myregs, int num)
{ {
assert(num < numregs && num >= 0); assert(num < numregs && num >= 0);
return myregs.uregs[num]; return myregs.uregs[num];
} }
bool ARMTraceChild::update(int pid) bool
ARMTraceChild::update(int pid)
{ {
oldregs = regs; oldregs = regs;
if(ptrace(PTRACE_GETREGS, pid, 0, &regs) != 0) if (ptrace(PTRACE_GETREGS, pid, 0, &regs) != 0) {
{
cerr << "update: " << strerror(errno) << endl; cerr << "update: " << strerror(errno) << endl;
return false; 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;
} }
int64_t ARMTraceChild::getRegVal(int num) int64_t
ARMTraceChild::getRegVal(int num)
{ {
return getRegs(regs, num); return getRegs(regs, num);
} }
int64_t ARMTraceChild::getOldRegVal(int num) int64_t
ARMTraceChild::getOldRegVal(int num)
{ {
return getRegs(oldregs, num); return getRegs(oldregs, num);
} }
char * ARMTraceChild::printReg(int num) char *
ARMTraceChild::printReg(int num)
{ {
sprintf(printBuffer, "0x%08X", (uint32_t)getRegVal(num)); sprintf(printBuffer, "0x%08X", (uint32_t)getRegVal(num));
return printBuffer; return printBuffer;
} }
ostream & ARMTraceChild::outputStartState(ostream & os) ostream &
ARMTraceChild::outputStartState(ostream & os)
{ {
uint32_t sp = getSP(); uint32_t sp = getSP();
uint32_t pc = getPC(); uint32_t pc = getPC();
@ -154,8 +160,7 @@ ostream & ARMTraceChild::outputStartState(ostream & os)
//Output argv pointers //Output argv pointers
int argCount = 0; int argCount = 0;
int32_t cargv; int32_t cargv;
do do {
{
cargv = ptrace(PTRACE_PEEKDATA, pid, sp, 0); cargv = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
sprintf(obuf, "0x%08x: argv[%d] = 0x%08x\n", sprintf(obuf, "0x%08x: argv[%d] = 0x%08x\n",
sp, argCount++, cargv); sp, argCount++, cargv);
@ -169,8 +174,7 @@ ostream & ARMTraceChild::outputStartState(ostream & os)
//Output the envp pointers //Output the envp pointers
int envCount = 0; int envCount = 0;
uint32_t cenvp; uint32_t cenvp;
do do {
{
cenvp = ptrace(PTRACE_PEEKDATA, pid, sp, 0); cenvp = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
sprintf(obuf, "0x%08x: envp[%d] = 0x%08x\n", sprintf(obuf, "0x%08x: envp[%d] = 0x%08x\n",
sp, envCount++, cenvp); sp, envCount++, cenvp);
@ -178,8 +182,7 @@ ostream & ARMTraceChild::outputStartState(ostream & os)
sp += 4; sp += 4;
} while(cenvp); } while(cenvp);
uint32_t auxType, auxVal; uint32_t auxType, auxVal;
do do {
{
auxType = ptrace(PTRACE_PEEKDATA, pid, sp, 0); auxType = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
sp += 4; sp += 4;
auxVal = ptrace(PTRACE_PEEKDATA, pid, sp, 0); auxVal = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
@ -193,16 +196,13 @@ ostream & ARMTraceChild::outputStartState(ostream & os)
uint32_t buf; uint32_t buf;
uint32_t currentStart = sp; uint32_t currentStart = sp;
bool clearedInitialPadding = false; bool clearedInitialPadding = false;
do do {
{
buf = ptrace(PTRACE_PEEKDATA, pid, sp, 0); buf = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
char * cbuf = (char *)&buf; char * cbuf = (char *)&buf;
for(int x = 0; x < sizeof(uint32_t); x++) for (int x = 0; x < sizeof(uint32_t); x++) {
{ if (cbuf[x])
if(cbuf[x])
current += cbuf[x]; current += cbuf[x];
else else {
{
sprintf(obuf, "0x%08x: \"%s\"\n", sprintf(obuf, "0x%08x: \"%s\"\n",
currentStart, current.c_str()); currentStart, current.c_str());
os << obuf; os << obuf;
@ -216,7 +216,8 @@ ostream & ARMTraceChild::outputStartState(ostream & os)
return os; return os;
} }
bool ARMTraceChild::step() bool
ARMTraceChild::step()
{ {
const uint32_t bkpt_inst = 0xe7f001f0; const uint32_t bkpt_inst = 0xe7f001f0;
@ -258,7 +259,8 @@ bool ARMTraceChild::step()
} }
TraceChild * genTraceChild() TraceChild *
genTraceChild()
{ {
return new ARMTraceChild; return new ARMTraceChild;
} }

View file

@ -84,18 +84,21 @@ class ARMTraceChild : public TraceChild
ARMTraceChild(); ARMTraceChild();
bool sendState(int socket); bool sendState(int socket);
int getNumRegs() int
getNumRegs()
{ {
return numregs; return numregs;
} }
bool diffSinceUpdate(int num) bool
diffSinceUpdate(int num)
{ {
assert(num < numregs && num >= 0); assert(num < numregs && num >= 0);
return regDiffSinceUpdate[num]; return regDiffSinceUpdate[num];
} }
std::string getRegName(int num) std::string
getRegName(int num)
{ {
assert(num < numregs && num >= 0); assert(num < numregs && num >= 0);
return regNames[num]; return regNames[num];
@ -106,14 +109,16 @@ class ARMTraceChild : public TraceChild
bool step(); bool step();
uint64_t getPC() uint64_t
getPC()
{ {
return getRegVal(PC); return getRegVal(PC);
} }
uint64_t getSP() uint64_t
getSP()
{ {
return getRegVal(SP); return getRegVal(SP);
} }
char * printReg(int num); char * printReg(int num);

View file

@ -38,83 +38,86 @@
using namespace std; using namespace std;
char * I386TraceChild::regNames[numregs] = { char * I386TraceChild::regNames[numregs] = {
//GPRs //GPRs
"eax", "ebx", "ecx", "edx", "eax", "ebx", "ecx", "edx",
//Index registers //Index registers
"esi", "edi", "esi", "edi",
//Base pointer and stack pointer //Base pointer and stack pointer
"ebp", "esp", "ebp", "esp",
//Segmentation registers //Segmentation registers
"cs", "ds", "es", "fs", "gs", "ss", "cs", "ds", "es", "fs", "gs", "ss",
//PC //PC
"eip"}; "eip"};
int64_t I386TraceChild::getRegs(user_regs_struct & myregs, int num) int64_t
I386TraceChild::getRegs(user_regs_struct & myregs, int num)
{ {
assert(num < numregs && num >= 0); assert(num < numregs && num >= 0);
switch(num) switch (num) {
{ //GPRs
//GPRs case EAX: return myregs.eax;
case EAX: return myregs.eax; case EBX: return myregs.ebx;
case EBX: return myregs.ebx; case ECX: return myregs.ecx;
case ECX: return myregs.ecx; case EDX: return myregs.edx;
case EDX: return myregs.edx; //Index registers
//Index registers case ESI: return myregs.esi;
case ESI: return myregs.esi; case EDI: return myregs.edi;
case EDI: return myregs.edi; //Base pointer and stack pointer
//Base pointer and stack pointer case EBP: return myregs.ebp;
case EBP: return myregs.ebp; case ESP: return myregs.esp;
case ESP: return myregs.esp; //Segmentation registers
//Segmentation registers case CS: return myregs.cs;
case CS: return myregs.cs; case DS: return myregs.ds;
case DS: return myregs.ds; case ES: return myregs.es;
case ES: return myregs.es; case FS: return myregs.fs;
case FS: return myregs.fs; case GS: return myregs.gs;
case GS: return myregs.gs; case SS: return myregs.ss;
case SS: return myregs.ss; //PC
//PC case EIP: return myregs.eip;
case EIP: return myregs.eip; default:
default: assert(0);
assert(0); return 0;
return 0; }
}
} }
bool I386TraceChild::update(int pid) bool
I386TraceChild::update(int pid)
{ {
oldregs = regs; oldregs = regs;
if(ptrace(PTRACE_GETREGS, pid, 0, &regs) != 0) if (ptrace(PTRACE_GETREGS, pid, 0, &regs) != 0)
return false; 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));
}
} }
I386TraceChild::I386TraceChild() I386TraceChild::I386TraceChild()
{ {
for(unsigned int x = 0; x < numregs; x++) for (unsigned int x = 0; x < numregs; x++)
regDiffSinceUpdate[x] = false; regDiffSinceUpdate[x] = false;
} }
int64_t I386TraceChild::getRegVal(int num) int64_t
I386TraceChild::getRegVal(int num)
{ {
return getRegs(regs, num); return getRegs(regs, num);
} }
int64_t I386TraceChild::getOldRegVal(int num) int64_t
I386TraceChild::getOldRegVal(int num)
{ {
return getRegs(oldregs, num); return getRegs(oldregs, num);
} }
char * I386TraceChild::printReg(int num) char *
I386TraceChild::printReg(int num)
{ {
sprintf(printBuffer, "0x%08X", getRegVal(num)); sprintf(printBuffer, "0x%08X", getRegVal(num));
return printBuffer; return printBuffer;
} }
TraceChild * genTraceChild() TraceChild *
genTraceChild()
{ {
return new I386TraceChild; return new I386TraceChild;
} }

View file

@ -41,65 +41,69 @@
class I386TraceChild : public TraceChild class I386TraceChild : public TraceChild
{ {
public: public:
enum RegNum enum RegNum
{ {
//GPRs //GPRs
EAX, EBX, ECX, EDX, EAX, EBX, ECX, EDX,
//Index registers //Index registers
ESI, EDI, ESI, EDI,
//Base pointer and stack pointer //Base pointer and stack pointer
EBP, ESP, EBP, ESP,
//Segmentation registers //Segmentation registers
CS, DS, ES, FS, GS, SS, CS, DS, ES, FS, GS, SS,
//PC //PC
EIP, EIP,
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, int num);
user_regs_struct regs; user_regs_struct regs;
user_regs_struct oldregs; user_regs_struct oldregs;
bool regDiffSinceUpdate[numregs]; bool regDiffSinceUpdate[numregs];
protected: protected:
bool update(int pid); bool update(int pid);
public: public:
I386TraceChild(); I386TraceChild();
int getNumRegs() int
{ getNumRegs()
return numregs; {
} return numregs;
}
bool diffSinceUpdate(int num) bool
{ diffSinceUpdate(int num)
assert(num < numregs && num >= 0); {
return regDiffSinceUpdate[num]; assert(num < numregs && num >= 0);
} return regDiffSinceUpdate[num];
}
std::string getRegName(int num) std::string
{ getRegName(int num)
assert(num < numregs && num >= 0); {
return regNames[num]; assert(num < numregs && num >= 0);
} return regNames[num];
}
int64_t getRegVal(int num); int64_t getRegVal(int num);
int64_t getOldRegVal(int num); int64_t getOldRegVal(int num);
uint64_t getPC() {return getRegVal(EIP);} uint64_t getPC() {return getRegVal(EIP);}
uint64_t getSP() {return getRegVal(ESP);} uint64_t getSP() {return getRegVal(ESP);}
std::ostream & outputStartState(std::ostream & output) std::ostream &
{ outputStartState(std::ostream & output)
output << "Printing i386 initial state not yet implemented" {
<< std::endl; output << "Printing i386 initial state not yet implemented"
return output; << std::endl;
} return output;
}
char * printReg(int num); char * printReg(int num);
}; };
#endif #endif

View file

@ -54,36 +54,32 @@ string SparcTraceChild::regNames[numregs] = {
//Miscelaneous //Miscelaneous
"fsr", "fprs", "pc", "npc", "y", "cwp", "pstate", "asi", "ccr"}; "fsr", "fprs", "pc", "npc", "y", "cwp", "pstate", "asi", "ccr"};
bool SparcTraceChild::sendState(int socket) bool
SparcTraceChild::sendState(int socket)
{ {
uint64_t regVal = 0; uint64_t regVal = 0;
for(int x = 0; x <= I7; x++) for (int x = 0; x <= I7; x++) {
{
regVal = getRegVal(x); regVal = getRegVal(x);
if(write(socket, &regVal, sizeof(regVal)) == -1) if (write(socket, &regVal, sizeof(regVal)) == -1) {
{
cerr << "Write failed! " << strerror(errno) << endl; cerr << "Write failed! " << strerror(errno) << endl;
tracing = false; tracing = false;
return false; return false;
} }
} }
regVal = getRegVal(PC); regVal = getRegVal(PC);
if(write(socket, &regVal, sizeof(regVal)) == -1) if (write(socket, &regVal, sizeof(regVal)) == -1) {
{
cerr << "Write failed! " << strerror(errno) << endl; cerr << "Write failed! " << strerror(errno) << endl;
tracing = false; tracing = false;
return false; return false;
} }
regVal = getRegVal(NPC); regVal = getRegVal(NPC);
if(write(socket, &regVal, sizeof(regVal)) == -1) if (write(socket, &regVal, sizeof(regVal)) == -1) {
{
cerr << "Write failed! " << strerror(errno) << endl; cerr << "Write failed! " << strerror(errno) << endl;
tracing = false; tracing = false;
return false; return false;
} }
regVal = getRegVal(CCR); regVal = getRegVal(CCR);
if(write(socket, &regVal, sizeof(regVal)) == -1) if (write(socket, &regVal, sizeof(regVal)) == -1) {
{
cerr << "Write failed! " << strerror(errno) << endl; cerr << "Write failed! " << strerror(errno) << endl;
tracing = false; tracing = false;
return false; return false;
@ -91,141 +87,141 @@ bool SparcTraceChild::sendState(int socket)
return true; return true;
} }
int64_t getRegs(regs & myregs, fpu & myfpu, int64_t
uint64_t * locals, uint64_t * inputs, int num) getRegs(regs & myregs, fpu & myfpu, uint64_t * locals,
uint64_t * inputs, int num)
{ {
assert(num < SparcTraceChild::numregs && num >= 0); assert(num < SparcTraceChild::numregs && num >= 0);
switch(num) switch (num) {
{ //Global registers
//Global registers case SparcTraceChild::G0: return 0;
case SparcTraceChild::G0: return 0; case SparcTraceChild::G1: return myregs.r_g1;
case SparcTraceChild::G1: return myregs.r_g1; case SparcTraceChild::G2: return myregs.r_g2;
case SparcTraceChild::G2: return myregs.r_g2; case SparcTraceChild::G3: return myregs.r_g3;
case SparcTraceChild::G3: return myregs.r_g3; case SparcTraceChild::G4: return myregs.r_g4;
case SparcTraceChild::G4: return myregs.r_g4; case SparcTraceChild::G5: return myregs.r_g5;
case SparcTraceChild::G5: return myregs.r_g5; case SparcTraceChild::G6: return myregs.r_g6;
case SparcTraceChild::G6: return myregs.r_g6; case SparcTraceChild::G7: return myregs.r_g7;
case SparcTraceChild::G7: return myregs.r_g7; //Output registers
//Output registers case SparcTraceChild::O0: return myregs.r_o0;
case SparcTraceChild::O0: return myregs.r_o0; case SparcTraceChild::O1: return myregs.r_o1;
case SparcTraceChild::O1: return myregs.r_o1; case SparcTraceChild::O2: return myregs.r_o2;
case SparcTraceChild::O2: return myregs.r_o2; case SparcTraceChild::O3: return myregs.r_o3;
case SparcTraceChild::O3: return myregs.r_o3; case SparcTraceChild::O4: return myregs.r_o4;
case SparcTraceChild::O4: return myregs.r_o4; case SparcTraceChild::O5: return myregs.r_o5;
case SparcTraceChild::O5: return myregs.r_o5; case SparcTraceChild::O6: return myregs.r_o6;
case SparcTraceChild::O6: return myregs.r_o6; case SparcTraceChild::O7: return myregs.r_o7;
case SparcTraceChild::O7: return myregs.r_o7; //Local registers
//Local registers case SparcTraceChild::L0: return locals[0];
case SparcTraceChild::L0: return locals[0]; case SparcTraceChild::L1: return locals[1];
case SparcTraceChild::L1: return locals[1]; case SparcTraceChild::L2: return locals[2];
case SparcTraceChild::L2: return locals[2]; case SparcTraceChild::L3: return locals[3];
case SparcTraceChild::L3: return locals[3]; case SparcTraceChild::L4: return locals[4];
case SparcTraceChild::L4: return locals[4]; case SparcTraceChild::L5: return locals[5];
case SparcTraceChild::L5: return locals[5]; case SparcTraceChild::L6: return locals[6];
case SparcTraceChild::L6: return locals[6]; case SparcTraceChild::L7: return locals[7];
case SparcTraceChild::L7: return locals[7]; //Input registers
//Input registers case SparcTraceChild::I0: return inputs[0];
case SparcTraceChild::I0: return inputs[0]; case SparcTraceChild::I1: return inputs[1];
case SparcTraceChild::I1: return inputs[1]; case SparcTraceChild::I2: return inputs[2];
case SparcTraceChild::I2: return inputs[2]; case SparcTraceChild::I3: return inputs[3];
case SparcTraceChild::I3: return inputs[3]; case SparcTraceChild::I4: return inputs[4];
case SparcTraceChild::I4: return inputs[4]; case SparcTraceChild::I5: return inputs[5];
case SparcTraceChild::I5: return inputs[5]; case SparcTraceChild::I6: return inputs[6];
case SparcTraceChild::I6: return inputs[6]; case SparcTraceChild::I7: return inputs[7];
case SparcTraceChild::I7: return inputs[7]; //Floating point
//Floating point case SparcTraceChild::F0: return myfpu.f_fpstatus.fpu_fr[0];
case SparcTraceChild::F0: return myfpu.f_fpstatus.fpu_fr[0]; case SparcTraceChild::F2: return myfpu.f_fpstatus.fpu_fr[1];
case SparcTraceChild::F2: return myfpu.f_fpstatus.fpu_fr[1]; case SparcTraceChild::F4: return myfpu.f_fpstatus.fpu_fr[2];
case SparcTraceChild::F4: return myfpu.f_fpstatus.fpu_fr[2]; case SparcTraceChild::F6: return myfpu.f_fpstatus.fpu_fr[3];
case SparcTraceChild::F6: return myfpu.f_fpstatus.fpu_fr[3]; case SparcTraceChild::F8: return myfpu.f_fpstatus.fpu_fr[4];
case SparcTraceChild::F8: return myfpu.f_fpstatus.fpu_fr[4]; case SparcTraceChild::F10: return myfpu.f_fpstatus.fpu_fr[5];
case SparcTraceChild::F10: return myfpu.f_fpstatus.fpu_fr[5]; case SparcTraceChild::F12: return myfpu.f_fpstatus.fpu_fr[6];
case SparcTraceChild::F12: return myfpu.f_fpstatus.fpu_fr[6]; case SparcTraceChild::F14: return myfpu.f_fpstatus.fpu_fr[7];
case SparcTraceChild::F14: return myfpu.f_fpstatus.fpu_fr[7]; case SparcTraceChild::F16: return myfpu.f_fpstatus.fpu_fr[8];
case SparcTraceChild::F16: return myfpu.f_fpstatus.fpu_fr[8]; case SparcTraceChild::F18: return myfpu.f_fpstatus.fpu_fr[9];
case SparcTraceChild::F18: return myfpu.f_fpstatus.fpu_fr[9]; case SparcTraceChild::F20: return myfpu.f_fpstatus.fpu_fr[10];
case SparcTraceChild::F20: return myfpu.f_fpstatus.fpu_fr[10]; case SparcTraceChild::F22: return myfpu.f_fpstatus.fpu_fr[11];
case SparcTraceChild::F22: return myfpu.f_fpstatus.fpu_fr[11]; case SparcTraceChild::F24: return myfpu.f_fpstatus.fpu_fr[12];
case SparcTraceChild::F24: return myfpu.f_fpstatus.fpu_fr[12]; case SparcTraceChild::F26: return myfpu.f_fpstatus.fpu_fr[13];
case SparcTraceChild::F26: return myfpu.f_fpstatus.fpu_fr[13]; case SparcTraceChild::F28: return myfpu.f_fpstatus.fpu_fr[14];
case SparcTraceChild::F28: return myfpu.f_fpstatus.fpu_fr[14]; case SparcTraceChild::F30: return myfpu.f_fpstatus.fpu_fr[15];
case SparcTraceChild::F30: return myfpu.f_fpstatus.fpu_fr[15]; case SparcTraceChild::F32: return myfpu.f_fpstatus.fpu_fr[16];
case SparcTraceChild::F32: return myfpu.f_fpstatus.fpu_fr[16]; case SparcTraceChild::F34: return myfpu.f_fpstatus.fpu_fr[17];
case SparcTraceChild::F34: return myfpu.f_fpstatus.fpu_fr[17]; case SparcTraceChild::F36: return myfpu.f_fpstatus.fpu_fr[18];
case SparcTraceChild::F36: return myfpu.f_fpstatus.fpu_fr[18]; case SparcTraceChild::F38: return myfpu.f_fpstatus.fpu_fr[19];
case SparcTraceChild::F38: return myfpu.f_fpstatus.fpu_fr[19]; case SparcTraceChild::F40: return myfpu.f_fpstatus.fpu_fr[20];
case SparcTraceChild::F40: return myfpu.f_fpstatus.fpu_fr[20]; case SparcTraceChild::F42: return myfpu.f_fpstatus.fpu_fr[21];
case SparcTraceChild::F42: return myfpu.f_fpstatus.fpu_fr[21]; case SparcTraceChild::F44: return myfpu.f_fpstatus.fpu_fr[22];
case SparcTraceChild::F44: return myfpu.f_fpstatus.fpu_fr[22]; case SparcTraceChild::F46: return myfpu.f_fpstatus.fpu_fr[23];
case SparcTraceChild::F46: return myfpu.f_fpstatus.fpu_fr[23]; case SparcTraceChild::F48: return myfpu.f_fpstatus.fpu_fr[24];
case SparcTraceChild::F48: return myfpu.f_fpstatus.fpu_fr[24]; case SparcTraceChild::F50: return myfpu.f_fpstatus.fpu_fr[25];
case SparcTraceChild::F50: return myfpu.f_fpstatus.fpu_fr[25]; case SparcTraceChild::F52: return myfpu.f_fpstatus.fpu_fr[26];
case SparcTraceChild::F52: return myfpu.f_fpstatus.fpu_fr[26]; case SparcTraceChild::F54: return myfpu.f_fpstatus.fpu_fr[27];
case SparcTraceChild::F54: return myfpu.f_fpstatus.fpu_fr[27]; case SparcTraceChild::F56: return myfpu.f_fpstatus.fpu_fr[28];
case SparcTraceChild::F56: return myfpu.f_fpstatus.fpu_fr[28]; case SparcTraceChild::F58: return myfpu.f_fpstatus.fpu_fr[29];
case SparcTraceChild::F58: return myfpu.f_fpstatus.fpu_fr[29]; case SparcTraceChild::F60: return myfpu.f_fpstatus.fpu_fr[30];
case SparcTraceChild::F60: return myfpu.f_fpstatus.fpu_fr[30]; case SparcTraceChild::F62: return myfpu.f_fpstatus.fpu_fr[31];
case SparcTraceChild::F62: return myfpu.f_fpstatus.fpu_fr[31]; //Miscelaneous
//Miscelaneous case SparcTraceChild::FSR: return myfpu.f_fpstatus.Fpu_fsr;
case SparcTraceChild::FSR: return myfpu.f_fpstatus.Fpu_fsr; case SparcTraceChild::FPRS: return myregs.r_fprs;
case SparcTraceChild::FPRS: return myregs.r_fprs; case SparcTraceChild::PC: return myregs.r_tpc;
case SparcTraceChild::PC: return myregs.r_tpc; case SparcTraceChild::NPC: return myregs.r_tnpc;
case SparcTraceChild::NPC: return myregs.r_tnpc; case SparcTraceChild::Y: return myregs.r_y;
case SparcTraceChild::Y: return myregs.r_y; case SparcTraceChild::CWP:
case SparcTraceChild::CWP: return (myregs.r_tstate >> 0) & ((1 << 5) - 1);
return (myregs.r_tstate >> 0) & ((1 << 5) - 1); case SparcTraceChild::PSTATE:
case SparcTraceChild::PSTATE: return (myregs.r_tstate >> 8) & ((1 << 13) - 1);
return (myregs.r_tstate >> 8) & ((1 << 13) - 1); case SparcTraceChild::ASI:
case SparcTraceChild::ASI: return (myregs.r_tstate >> 24) & ((1 << 8) - 1);
return (myregs.r_tstate >> 24) & ((1 << 8) - 1); case SparcTraceChild::CCR:
case SparcTraceChild::CCR: return (myregs.r_tstate >> 32) & ((1 << 8) - 1);
return (myregs.r_tstate >> 32) & ((1 << 8) - 1); default:
default: assert(0);
assert(0); return 0;
return 0;
} }
} }
bool SparcTraceChild::update(int pid) bool
SparcTraceChild::update(int pid)
{ {
memcpy(&oldregs, &theregs, sizeof(regs)); memcpy(&oldregs, &theregs, sizeof(regs));
memcpy(&oldfpregs, &thefpregs, sizeof(fpu)); memcpy(&oldfpregs, &thefpregs, sizeof(fpu));
memcpy(oldLocals, locals, 8 * sizeof(uint64_t)); memcpy(oldLocals, locals, 8 * sizeof(uint64_t));
memcpy(oldInputs, inputs, 8 * sizeof(uint64_t)); memcpy(oldInputs, inputs, 8 * sizeof(uint64_t));
if(ptrace(PTRACE_GETREGS, pid, &theregs, 0) != 0) if (ptrace(PTRACE_GETREGS, pid, &theregs, 0) != 0) {
{
cerr << "Update failed" << endl; cerr << "Update failed" << endl;
return false; return false;
} }
uint64_t stackPointer = getSP(); uint64_t stackPointer = getSP();
uint64_t stackBias = 2047; uint64_t stackBias = 2047;
bool v9 = stackPointer % 2; bool v9 = stackPointer % 2;
for(unsigned int x = 0; x < 8; x++) for (unsigned int x = 0; x < 8; x++) {
{
uint64_t localAddr = stackPointer + uint64_t localAddr = stackPointer +
(v9 ? (stackBias + x * 8) : (x * 4)); (v9 ? (stackBias + x * 8) : (x * 4));
locals[x] = ptrace(PTRACE_PEEKTEXT, pid, localAddr, 0); locals[x] = ptrace(PTRACE_PEEKTEXT, pid, localAddr, 0);
if(!v9) locals[x] >>= 32; if (!v9) locals[x] >>= 32;
uint64_t inputAddr = stackPointer + uint64_t inputAddr = stackPointer +
(v9 ? (stackBias + x * 8 + (8 * 8)) : (x * 4 + 8 * 4)); (v9 ? (stackBias + x * 8 + (8 * 8)) : (x * 4 + 8 * 4));
inputs[x] = ptrace(PTRACE_PEEKTEXT, pid, inputAddr, 0); inputs[x] = ptrace(PTRACE_PEEKTEXT, pid, inputAddr, 0);
if(!v9) inputs[x] >>= 32; if (!v9) inputs[x] >>= 32;
} }
if(ptrace(PTRACE_GETFPREGS, pid, &thefpregs, 0) != 0) if (ptrace(PTRACE_GETFPREGS, pid, &thefpregs, 0) != 0)
return false; 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;
} }
SparcTraceChild::SparcTraceChild() SparcTraceChild::SparcTraceChild()
{ {
for(unsigned int x = 0; x < numregs; x++) for (unsigned int x = 0; x < numregs; x++)
regDiffSinceUpdate[x] = false; regDiffSinceUpdate[x] = false;
} }
int SparcTraceChild::getTargets(uint32_t inst, uint64_t pc, uint64_t npc, int
uint64_t &target1, uint64_t &target2) SparcTraceChild::getTargets(uint32_t inst, uint64_t pc, uint64_t npc,
uint64_t &target1, uint64_t &target2)
{ {
//We can identify the instruction categories we care about using the top //We can identify the instruction categories we care about using the top
//10 bits of the instruction, excluding the annul bit in the 3rd most //10 bits of the instruction, excluding the annul bit in the 3rd most
@ -245,28 +241,21 @@ int SparcTraceChild::getTargets(uint32_t inst, uint64_t pc, uint64_t npc,
bool bcc = (cond & 0x7) && bool bcc = (cond & 0x7) &&
(sig == 0x1 || sig == 0x2 || sig == 0x3 || sig == 0x5 || sig == 0x6); (sig == 0x1 || sig == 0x2 || sig == 0x3 || sig == 0x5 || sig == 0x6);
if(annul) if (annul) {
{ if (bcc) {
if(bcc)
{
target1 = npc; target1 = npc;
target2 = npc + 4; target2 = npc + 4;
return 2; return 2;
} } else if(ba) {
else if(ba)
{
//This branches immediately to the effective address of the branch //This branches immediately to the effective address of the branch
//which we'll have to calculate. //which we'll have to calculate.
uint64_t disp = 0; uint64_t disp = 0;
int64_t extender = 0; int64_t extender = 0;
//Figure out how big the displacement field is, and grab the bits //Figure out how big the displacement field is, and grab the bits
if(sig == 0x1 || sig == 0x5) if (sig == 0x1 || sig == 0x5) {
{
disp = inst & ((1 << 19) - 1); disp = inst & ((1 << 19) - 1);
extender = 1 << 18; extender = 1 << 18;
} } else {
else
{
disp = inst & ((1 << 22) - 1); disp = inst & ((1 << 22) - 1);
extender = 1 << 21; extender = 1 << 21;
} }
@ -276,21 +265,19 @@ int SparcTraceChild::getTargets(uint32_t inst, uint64_t pc, uint64_t npc,
//smart enough to turn this into a shift. //smart enough to turn this into a shift.
disp *= 4; disp *= 4;
target1 = pc + disp; target1 = pc + disp;
} } else if(bn)
else if(bn)
target1 = npc + 4; target1 = npc + 4;
else else
target1 = npc; target1 = npc;
return 1; return 1;
} } else {
else
{
target1 = npc; target1 = npc;
return 1; return 1;
} }
} }
bool SparcTraceChild::step() bool
SparcTraceChild::step()
{ {
//Increment the count of the number of instructions executed //Increment the count of the number of instructions executed
instructions++; instructions++;
@ -345,18 +332,17 @@ bool SparcTraceChild::step()
uint64_t newBp1 = origBp1; uint64_t newBp1 = origBp1;
newBp1 &= unalignedBp1 ? highMask : lowMask; newBp1 &= unalignedBp1 ? highMask : lowMask;
newBp1 |= unalignedBp1 ? lowBreakInst : highBreakInst; newBp1 |= unalignedBp1 ? lowBreakInst : highBreakInst;
if(ptrace(PTRACE_POKETEXT, pid, alignedBp1, newBp1) != 0) if (ptrace(PTRACE_POKETEXT, pid, alignedBp1, newBp1) != 0)
cerr << "Poke failed" << endl; cerr << "Poke failed" << endl;
/* /*
* Set the second breakpoint if necessary * Set the second breakpoint if necessary
*/ */
if(numTargets == 2) if (numTargets == 2) {
{
origBp2 = ptrace(PTRACE_PEEKTEXT, pid, alignedBp2, 0); origBp2 = ptrace(PTRACE_PEEKTEXT, pid, alignedBp2, 0);
uint64_t newBp2 = origBp2; uint64_t newBp2 = origBp2;
newBp2 &= unalignedBp2 ? highMask : lowMask; newBp2 &= unalignedBp2 ? highMask : lowMask;
newBp2 |= unalignedBp2 ? lowBreakInst : highBreakInst; newBp2 |= unalignedBp2 ? lowBreakInst : highBreakInst;
if(ptrace(PTRACE_POKETEXT, pid, alignedBp2, newBp2) != 0) if (ptrace(PTRACE_POKETEXT, pid, alignedBp2, newBp2) != 0)
cerr << "Poke failed" << endl; cerr << "Poke failed" << endl;
} }
@ -366,7 +352,7 @@ bool SparcTraceChild::step()
//Note that the "addr" parameter is supposed to be ignored, but in at //Note that the "addr" parameter is supposed to be ignored, but in at
//least one version of the kernel, it must be 1 or it will set what //least one version of the kernel, it must be 1 or it will set what
//pc to continue from //pc to continue from
if(ptrace(PTRACE_CONT, pid, 1, 0) != 0) if (ptrace(PTRACE_CONT, pid, 1, 0) != 0)
cerr << "Cont failed" << endl; cerr << "Cont failed" << endl;
doWait(); doWait();
@ -379,42 +365,42 @@ bool SparcTraceChild::step()
* Put back the original contents of the childs address space in the * Put back the original contents of the childs address space in the
* reverse order. * reverse order.
*/ */
if(numTargets == 2) if (numTargets == 2) {
{ if (ptrace(PTRACE_POKETEXT, pid, alignedBp2, origBp2) != 0)
if(ptrace(PTRACE_POKETEXT, pid, alignedBp2, origBp2) != 0)
cerr << "Poke failed" << endl; cerr << "Poke failed" << endl;
} }
if(ptrace(PTRACE_POKETEXT, pid, alignedBp1, origBp1) != 0) if (ptrace(PTRACE_POKETEXT, pid, alignedBp1, origBp1) != 0)
cerr << "Poke failed" << endl; cerr << "Poke failed" << endl;
} }
int64_t SparcTraceChild::getRegVal(int num) int64_t
SparcTraceChild::getRegVal(int num)
{ {
return getRegs(theregs, thefpregs, locals, inputs, num); return getRegs(theregs, thefpregs, locals, inputs, num);
} }
int64_t SparcTraceChild::getOldRegVal(int num) int64_t
SparcTraceChild::getOldRegVal(int num)
{ {
return getRegs(oldregs, oldfpregs, oldLocals, oldInputs, num); return getRegs(oldregs, oldfpregs, oldLocals, oldInputs, num);
} }
char * SparcTraceChild::printReg(int num) char *
SparcTraceChild::printReg(int num)
{ {
sprintf(printBuffer, "0x%016llx", getRegVal(num)); sprintf(printBuffer, "0x%016llx", getRegVal(num));
return printBuffer; return printBuffer;
} }
ostream & SparcTraceChild::outputStartState(ostream & os) ostream &
SparcTraceChild::outputStartState(ostream & os)
{ {
bool v8 = false; bool v8 = false;
uint64_t sp = getSP(); uint64_t sp = getSP();
if(sp % 2) if (sp % 2) {
{
os << "Detected a 64 bit executable.\n"; os << "Detected a 64 bit executable.\n";
v8 = false; v8 = false;
} } else {
else
{
os << "Detected a 32 bit executable.\n"; os << "Detected a 32 bit executable.\n";
v8 = true; v8 = true;
} }
@ -424,16 +410,14 @@ ostream & SparcTraceChild::outputStartState(ostream & os)
os << obuf; os << obuf;
sprintf(obuf, "Initial program counter = 0x%016llx\n", pc); sprintf(obuf, "Initial program counter = 0x%016llx\n", pc);
os << obuf; os << obuf;
if(!v8) if (!v8) {
{
//Take out the stack bias //Take out the stack bias
sp += 2047; sp += 2047;
} }
//Output the window save area //Output the window save area
for(unsigned int x = 0; x < 16; x++) for (unsigned int x = 0; x < 16; x++) {
{
uint64_t regspot = ptrace(PTRACE_PEEKDATA, pid, sp, 0); uint64_t regspot = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
if(v8) regspot = regspot >> 32; if (v8) regspot = regspot >> 32;
sprintf(obuf, "0x%016llx: Window save %d = 0x%016llx\n", sprintf(obuf, "0x%016llx: Window save %d = 0x%016llx\n",
sp, x+1, regspot); sp, x+1, regspot);
os << obuf; os << obuf;
@ -441,17 +425,16 @@ ostream & SparcTraceChild::outputStartState(ostream & os)
} }
//Output the argument count //Output the argument count
uint64_t cargc = ptrace(PTRACE_PEEKDATA, pid, sp, 0); uint64_t cargc = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
if(v8) cargc = cargc >> 32; if (v8) cargc = cargc >> 32;
sprintf(obuf, "0x%016llx: Argc = 0x%016llx\n", sp, cargc); sprintf(obuf, "0x%016llx: Argc = 0x%016llx\n", sp, cargc);
os << obuf; os << obuf;
sp += v8 ? 4 : 8; sp += v8 ? 4 : 8;
//Output argv pointers //Output argv pointers
int argCount = 0; int argCount = 0;
uint64_t cargv; uint64_t cargv;
do do {
{
cargv = ptrace(PTRACE_PEEKDATA, pid, sp, 0); cargv = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
if(v8) cargv = cargv >> 32; if (v8) cargv = cargv >> 32;
sprintf(obuf, "0x%016llx: argv[%d] = 0x%016llx\n", sprintf(obuf, "0x%016llx: argv[%d] = 0x%016llx\n",
sp, argCount++, cargv); sp, argCount++, cargv);
os << obuf; os << obuf;
@ -460,43 +443,38 @@ ostream & SparcTraceChild::outputStartState(ostream & os)
//Output the envp pointers //Output the envp pointers
int envCount = 0; int envCount = 0;
uint64_t cenvp; uint64_t cenvp;
do do {
{
cenvp = ptrace(PTRACE_PEEKDATA, pid, sp, 0); cenvp = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
if(v8) cenvp = cenvp >> 32; if (v8) cenvp = cenvp >> 32;
sprintf(obuf, "0x%016llx: envp[%d] = 0x%016llx\n", sprintf(obuf, "0x%016llx: envp[%d] = 0x%016llx\n",
sp, envCount++, cenvp); sp, envCount++, cenvp);
os << obuf; os << obuf;
sp += v8 ? 4 : 8; sp += v8 ? 4 : 8;
} while(cenvp); } while (cenvp);
uint64_t auxType, auxVal; uint64_t auxType, auxVal;
do do {
{
auxType = ptrace(PTRACE_PEEKDATA, pid, sp, 0); auxType = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
if(v8) auxType = auxType >> 32; if (v8) auxType = auxType >> 32;
sp += (v8 ? 4 : 8); sp += (v8 ? 4 : 8);
auxVal = ptrace(PTRACE_PEEKDATA, pid, sp, 0); auxVal = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
if(v8) auxVal = auxVal >> 32; if (v8) auxVal = auxVal >> 32;
sp += (v8 ? 4 : 8); sp += (v8 ? 4 : 8);
sprintf(obuf, "0x%016llx: Auxiliary vector = {0x%016llx, 0x%016llx}\n", sprintf(obuf, "0x%016llx: Auxiliary vector = {0x%016llx, 0x%016llx}\n",
sp - 8, auxType, auxVal); sp - 8, auxType, auxVal);
os << obuf; os << obuf;
} while(auxType != 0 || auxVal != 0); } while (auxType != 0 || auxVal != 0);
//Print out the argument strings, environment strings, and file name. //Print out the argument strings, environment strings, and file name.
string current; string current;
uint64_t buf; uint64_t buf;
uint64_t currentStart = sp; uint64_t currentStart = sp;
bool clearedInitialPadding = false; bool clearedInitialPadding = false;
do do {
{
buf = ptrace(PTRACE_PEEKDATA, pid, sp, 0); buf = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
char * cbuf = (char *)&buf; char * cbuf = (char *)&buf;
for(int x = 0; x < sizeof(uint32_t); x++) for (int x = 0; x < sizeof(uint32_t); x++) {
{ if (cbuf[x])
if(cbuf[x])
current += cbuf[x]; current += cbuf[x];
else else {
{
sprintf(obuf, "0x%016llx: \"%s\"\n", sprintf(obuf, "0x%016llx: \"%s\"\n",
currentStart, current.c_str()); currentStart, current.c_str());
os << obuf; os << obuf;
@ -506,11 +484,12 @@ ostream & SparcTraceChild::outputStartState(ostream & os)
} }
sp += (v8 ? 4 : 8); sp += (v8 ? 4 : 8);
clearedInitialPadding = clearedInitialPadding || buf != 0; clearedInitialPadding = clearedInitialPadding || buf != 0;
} while(!clearedInitialPadding || buf != 0); } while (!clearedInitialPadding || buf != 0);
return os; return os;
} }
TraceChild * genTraceChild() TraceChild *
genTraceChild()
{ {
return new SparcTraceChild; return new SparcTraceChild;
} }

View file

@ -45,89 +45,94 @@ struct regs;
class SparcTraceChild : public TraceChild class SparcTraceChild : public TraceChild
{ {
public: public:
enum RegNum enum RegNum
{ {
//Global registers //Global registers
G0, G1, G2, G3, G4, G5, G6, G7, G0, G1, G2, G3, G4, G5, G6, G7,
//Output registers //Output registers
O0, O1, O2, O3, O4, O5, O6, O7, O0, O1, O2, O3, O4, O5, O6, O7,
//Local registers //Local registers
L0, L1, L2, L3, L4, L5, L6, L7, L0, L1, L2, L3, L4, L5, L6, L7,
//Input registers //Input registers
I0, I1, I2, I3, I4, I5, I6, I7, I0, I1, I2, I3, I4, I5, I6, I7,
//Floating point //Floating point
F0, F2, F4, F6, F8, F10, F12, F14, F0, F2, F4, F6, F8, F10, F12, F14,
F16, F18, F20, F22, F24, F26, F28, F30, F16, F18, F20, F22, F24, F26, F28, F30,
F32, F34, F36, F38, F40, F42, F44, F46, F32, F34, F36, F38, F40, F42, F44, F46,
F48, F50, F52, F54, F56, F58, F60, F62, F48, F50, F52, F54, F56, F58, F60, F62,
//Miscelaneous //Miscelaneous
FSR, FPRS, PC, NPC, Y, CWP, PSTATE, ASI, CCR, FSR, FPRS, PC, NPC, Y, CWP, PSTATE, ASI, CCR,
numregs numregs
}; };
private: private:
char printBuffer[256]; char printBuffer[256];
static std::string regNames[numregs]; static std::string regNames[numregs];
regs theregs; regs theregs;
regs oldregs; regs oldregs;
fpu thefpregs; fpu thefpregs;
fpu oldfpregs; fpu oldfpregs;
uint64_t locals[8]; uint64_t locals[8];
uint64_t oldLocals[8]; uint64_t oldLocals[8];
uint64_t inputs[8]; uint64_t inputs[8];
uint64_t oldInputs[8]; uint64_t oldInputs[8];
bool regDiffSinceUpdate[numregs]; bool regDiffSinceUpdate[numregs];
//This calculates where the pc might go after the current instruction. //This calculates where the pc might go after the current instruction.
//while this equals npc for most instructions, it doesn't for all of //while this equals npc for most instructions, it doesn't for all of
//them. The return value is the number of actual potential targets. //them. The return value is the number of actual potential targets.
int getTargets(uint32_t inst, uint64_t pc, uint64_t npc, int getTargets(uint32_t inst, uint64_t pc, uint64_t npc,
uint64_t &target1, uint64_t &target2); uint64_t &target1, uint64_t &target2);
protected: protected:
bool update(int pid); bool update(int pid);
public: public:
SparcTraceChild(); SparcTraceChild();
bool sendState(int socket); bool sendState(int socket);
int getNumRegs() int
{ getNumRegs()
return numregs; {
} return numregs;
}
bool diffSinceUpdate(int num) bool
{ diffSinceUpdate(int num)
assert(num < numregs && num >= 0); {
return regDiffSinceUpdate[num]; assert(num < numregs && num >= 0);
} return regDiffSinceUpdate[num];
}
std::string getRegName(int num) std::string
{ getRegName(int num)
assert(num < numregs && num >= 0); {
return regNames[num]; assert(num < numregs && num >= 0);
} return regNames[num];
}
int64_t getRegVal(int num); int64_t getRegVal(int num);
int64_t getOldRegVal(int num); int64_t getOldRegVal(int num);
bool step(); bool step();
uint64_t getPC() uint64_t
{ getPC()
return getRegVal(PC); {
} return getRegVal(PC);
}
uint64_t getSP() uint64_t
{ getSP()
return getRegVal(O6); {
} return getRegVal(O6);
}
char * printReg(int num); char * printReg(int num);
std::ostream & outputStartState(std::ostream & os); std::ostream & outputStartState(std::ostream & os);
}; };
#endif #endif

View file

@ -42,12 +42,13 @@ int findEndOfNestingPrinter(string, int);
PrinterType findSub(string, int &, int &); PrinterType findSub(string, int &, int &);
//This is pretty easy. Just find the closing parenthesis. //This is pretty easy. Just find the closing parenthesis.
int findEndOfRegPrinter(string config, int startPos) int
findEndOfRegPrinter(string config, int startPos)
{ {
int pos = config.find(")", startPos); int pos = config.find(")", startPos);
if(pos == string::npos) if (pos == string::npos) {
{ cerr << "Couldn't find the closing " <<
cerr << "Couldn't find the closing parenthesis for a reg printer" << endl; "parenthesis for a reg printer" << endl;
return 0; return 0;
} }
return pos; return pos;
@ -55,32 +56,31 @@ int findEndOfRegPrinter(string config, int startPos)
//This is a little harder. We need to make sure we don't //This is a little harder. We need to make sure we don't
//grab an ending parenthesis that belongs to the nesting printer. //grab an ending parenthesis that belongs to the nesting printer.
int findEndOfNestingPrinter(string config, int startPos) int
findEndOfNestingPrinter(string config, int startPos)
{ {
int length = config.length(); int length = config.length();
int pos = startPos; int pos = startPos;
int endPos = length; int endPos = length;
int parenPos = config.find(")", pos); int parenPos = config.find(")", pos);
//If we didn't find an ending parenthesis at all, we're in trouble //If we didn't find an ending parenthesis at all, we're in trouble
if(parenPos == string::npos) if (parenPos == string::npos) {
{ cerr << "Couldn't find the closing " <<
cerr << "Couldn't find the closing parenthesis for a nesting printer on the first try" << endl; "parenthesis for a nesting printer on the first try" << endl;
return 0; return 0;
} }
//Keep pulling out embedded stuff until we can't any more //Keep pulling out embedded stuff until we can't any more
//we need to make sure we aren't skipping over the parenthesis //we need to make sure we aren't skipping over the parenthesis
//that ends -this- printer. //that ends -this- printer.
PrinterType type = findSub(config, pos, endPos); PrinterType type = findSub(config, pos, endPos);
if(type == PRINTER_ERROR) if (type == PRINTER_ERROR)
return 0; return 0;
while(type != PRINTER_NONE && endPos >= parenPos) while (type != PRINTER_NONE && endPos >= parenPos) {
{
//Find the next closest ending parenthesis since we passed //Find the next closest ending parenthesis since we passed
//up the last one //up the last one
parenPos = config.find(")", endPos + 1); parenPos = config.find(")", endPos + 1);
//If we didn't find one, we're in trouble //If we didn't find one, we're in trouble
if(parenPos == string::npos) if (parenPos == string::npos) {
{
cerr << "Couldn't find the closing parenthesis for a nested printer on later tries" << endl; cerr << "Couldn't find the closing parenthesis for a nested printer on later tries" << endl;
return 0; return 0;
} }
@ -90,7 +90,7 @@ int findEndOfNestingPrinter(string config, int startPos)
//Reset endPos so we search to the end of config //Reset endPos so we search to the end of config
endPos = length; endPos = length;
type = findSub(config, pos, endPos); type = findSub(config, pos, endPos);
if(type == PRINTER_ERROR) if (type == PRINTER_ERROR)
return 0; return 0;
} }
//We ran out of embedded items, and we didn't pass up our last //We ran out of embedded items, and we didn't pass up our last
@ -103,7 +103,8 @@ int findEndOfNestingPrinter(string config, int startPos)
//startPos and endPos are set to the beginning and end of the sub printer //startPos and endPos are set to the beginning and end of the sub printer
//On entry, the search starts at index startPos and ends at either index //On entry, the search starts at index startPos and ends at either index
//endPos or a closing parenthesis, whichever comes first //endPos or a closing parenthesis, whichever comes first
PrinterType findSub(string config, int & startPos, int & endPos) PrinterType
findSub(string config, int & startPos, int & endPos)
{ {
int length = config.length(); int length = config.length();
//Figure out where the different types of sub printers may start //Figure out where the different types of sub printers may start
@ -111,28 +112,26 @@ PrinterType findSub(string config, int & startPos, int & endPos)
int nestingPos = config.find("~(", startPos); int nestingPos = config.find("~(", startPos);
//If a type of printer wasn't found, say it was found too far away. //If a type of printer wasn't found, say it was found too far away.
//This simplifies things later //This simplifies things later
if(regPos == string::npos) if (regPos == string::npos)
regPos = endPos; regPos = endPos;
if(nestingPos == string::npos) if (nestingPos == string::npos)
nestingPos = endPos; nestingPos = endPos;
//If we find a closing paren, that marks the //If we find a closing paren, that marks the
//end of the region we're searching. //end of the region we're searching.
int closingPos = config.find(")", startPos); int closingPos = config.find(")", startPos);
if(closingPos != string::npos && if (closingPos != string::npos &&
closingPos < regPos && closingPos < regPos &&
closingPos < nestingPos) closingPos < nestingPos)
return PRINTER_NONE; return PRINTER_NONE;
//If we didn't find anything close enough, say so. //If we didn't find anything close enough, say so.
if(regPos >= endPos && nestingPos >= endPos) if (regPos >= endPos && nestingPos >= endPos)
return PRINTER_NONE; return PRINTER_NONE;
//At this point, we know that one of the options starts legally //At this point, we know that one of the options starts legally
//We need to find which one is first and return that //We need to find which one is first and return that
if(regPos < nestingPos) if (regPos < nestingPos) {
{
int regEnd = findEndOfRegPrinter(config, regPos + 2); int regEnd = findEndOfRegPrinter(config, regPos + 2);
//If we couldn't find the end... //If we couldn't find the end...
if(!regEnd) if (!regEnd) {
{
cerr << "Couldn't find the end of the reg printer" << endl; cerr << "Couldn't find the end of the reg printer" << endl;
return PRINTER_ERROR; return PRINTER_ERROR;
} }
@ -140,13 +139,10 @@ PrinterType findSub(string config, int & startPos, int & endPos)
startPos = regPos; startPos = regPos;
endPos = regEnd; endPos = regEnd;
return PRINTER_REG; return PRINTER_REG;
} } else {
else
{
int nestingEnd = findEndOfNestingPrinter(config, nestingPos + 2); int nestingEnd = findEndOfNestingPrinter(config, nestingPos + 2);
//If we couldn't find the end... //If we couldn't find the end...
if(!nestingEnd) if (!nestingEnd) {
{
cerr << "Couldn't find the end of the nesting printer" << endl; cerr << "Couldn't find the end of the nesting printer" << endl;
return PRINTER_ERROR; return PRINTER_ERROR;
} }
@ -159,7 +155,8 @@ PrinterType findSub(string config, int & startPos, int & endPos)
} }
//Set up a nesting printer. This printer can contain sub printers //Set up a nesting printer. This printer can contain sub printers
bool NestingPrinter::configure(string config) bool
NestingPrinter::configure(string config)
{ {
//Clear out any old stuff //Clear out any old stuff
constStrings.clear(); constStrings.clear();
@ -170,14 +167,13 @@ bool NestingPrinter::configure(string config)
int lastEndPos = -1; int lastEndPos = -1;
//Try to find a sub printer //Try to find a sub printer
PrinterType type = findSub(config, startPos, endPos); PrinterType type = findSub(config, startPos, endPos);
if(type == PRINTER_ERROR) if (type == PRINTER_ERROR) {
{
cerr << "Problem finding first sub printer" << endl; cerr << "Problem finding first sub printer" << endl;
return false; return false;
} }
while(type != PRINTER_NONE) while (type != PRINTER_NONE) {
{ string prefix = config.substr(lastEndPos + 1,
string prefix = config.substr(lastEndPos + 1, startPos - lastEndPos - 1); startPos - lastEndPos - 1);
lastEndPos = endPos; lastEndPos = endPos;
constStrings.push_back(prefix); constStrings.push_back(prefix);
string subConfig, subString; string subConfig, subString;
@ -185,15 +181,13 @@ bool NestingPrinter::configure(string config)
//Set up the register printer //Set up the register printer
RegPrinter * regPrinter = new RegPrinter(child); RegPrinter * regPrinter = new RegPrinter(child);
NestingPrinter * nestingPrinter = new NestingPrinter(child); NestingPrinter * nestingPrinter = new NestingPrinter(child);
switch(type) switch (type) {
{
//If we found a plain register printer //If we found a plain register printer
case PRINTER_REG: case PRINTER_REG:
numPrinters++; numPrinters++;
//Get the register name //Get the register name
subConfig = config.substr(startPos + 2, endPos - startPos - 2); subConfig = config.substr(startPos + 2, endPos - startPos - 2);
if(!regPrinter->configure(subConfig)) if (!regPrinter->configure(subConfig)) {
{
delete regPrinter; delete regPrinter;
cerr << "Error configuring reg printer" << endl; cerr << "Error configuring reg printer" << endl;
return false; return false;
@ -207,26 +201,23 @@ bool NestingPrinter::configure(string config)
subConfig = config.substr(startPos + 2, endPos - startPos - 2); subConfig = config.substr(startPos + 2, endPos - startPos - 2);
lastCommaPos = string::npos; lastCommaPos = string::npos;
commaPos = subConfig.find(","); commaPos = subConfig.find(",");
if(commaPos == string::npos) if (commaPos == string::npos)
return false; return false;
childSwitchVar = child->getRegNum(subConfig.substr(0, commaPos)); childSwitchVar = child->getRegNum(subConfig.substr(0, commaPos));
if(childSwitchVar == -1) if (childSwitchVar == -1) {
{
cerr << "Couldn't configure switching variable!" << endl; cerr << "Couldn't configure switching variable!" << endl;
return false; return false;
} }
//Eat up remaining arguments //Eat up remaining arguments
while(commaPos != string::npos) while (commaPos != string::npos) {
{
lastCommaPos = commaPos; lastCommaPos = commaPos;
commaPos = subConfig.find(",", commaPos + 1); commaPos = subConfig.find(",", commaPos + 1);
} }
if(lastCommaPos != string::npos) if (lastCommaPos != string::npos) {
{ subConfig = subConfig.substr(lastCommaPos + 1,
subConfig = subConfig.substr(lastCommaPos + 1, subConfig.length() - lastCommaPos - 1); subConfig.length() - lastCommaPos - 1);
} }
if(!nestingPrinter->configure(subConfig)) if (!nestingPrinter->configure(subConfig)) {
{
delete nestingPrinter; delete nestingPrinter;
cerr << "Error configuring nesting printer" << endl; cerr << "Error configuring nesting printer" << endl;
return false; return false;
@ -242,8 +233,7 @@ bool NestingPrinter::configure(string config)
startPos = endPos + 1; startPos = endPos + 1;
endPos = length; endPos = length;
type = findSub(config, startPos, endPos); type = findSub(config, startPos, endPos);
if(type == PRINTER_ERROR) if (type == PRINTER_ERROR) {
{
cerr << "Unable to find subprinters on later tries" << endl; cerr << "Unable to find subprinters on later tries" << endl;
return false; return false;
} }
@ -254,12 +244,12 @@ bool NestingPrinter::configure(string config)
return true; return true;
} }
bool RegPrinter::configure(string config) bool
RegPrinter::configure(string config)
{ {
//Figure out what our register number is based on the name we're given //Figure out what our register number is based on the name we're given
int num = child->getRegNum(config); int num = child->getRegNum(config);
if(num == -1) if (num == -1) {
{
cerr << "Couldn't find register " << config << endl; cerr << "Couldn't find register " << config << endl;
return false; return false;
} }
@ -267,13 +257,12 @@ bool RegPrinter::configure(string config)
return true; return true;
} }
ostream & NestingPrinter::writeOut(ostream & os) ostream &
NestingPrinter::writeOut(ostream & os)
{ {
if(switchVar == -1 || child->diffSinceUpdate(switchVar)) if (switchVar == -1 || child->diffSinceUpdate(switchVar)) {
{
int x; int x;
for(x = 0; x < numPrinters; x++) for (x = 0; x < numPrinters; x++) {
{
os << constStrings[x]; os << constStrings[x];
os << printers[x]; os << printers[x];
} }
@ -282,7 +271,8 @@ ostream & NestingPrinter::writeOut(ostream & os)
return os; return os;
} }
ostream & RegPrinter::writeOut(ostream & os) ostream &
RegPrinter::writeOut(ostream & os)
{ {
os << child->printReg(intRegNum); os << child->printReg(intRegNum);
return os; return os;

View file

@ -79,12 +79,14 @@ class RegPrinter : public PrinterObject
PrinterObject(newChild), intRegNum(num) PrinterObject(newChild), intRegNum(num)
{;} {;}
void regNum(int num) void
regNum(int num)
{ {
intRegNum = num; intRegNum = num;
} }
int regNum() int
regNum()
{ {
return intRegNum; return intRegNum;
} }
@ -94,14 +96,14 @@ class RegPrinter : public PrinterObject
std::ostream & writeOut(std::ostream & os); std::ostream & writeOut(std::ostream & os);
}; };
static inline std::ostream & operator << (std::ostream & os, static inline std::ostream &
PrinterObject & printer) operator << (std::ostream & os, PrinterObject & printer)
{ {
return printer.writeOut(os); return printer.writeOut(os);
} }
static inline std::ostream & operator << (std::ostream & os, static inline std::ostream &
PrinterPointer & printer) operator << (std::ostream & os, PrinterPointer & printer)
{ {
return printer->writeOut(os); return printer->writeOut(os);
} }

View file

@ -55,18 +55,21 @@ class RefCountingPtr
protected: protected:
T *data; T *data;
void copy(T *d) void
copy(T *d)
{ {
data = d; data = d;
if (data) if (data)
data->incref(); data->incref();
} }
void del() void
del()
{ {
if (data) if (data)
data->decref(); data->decref();
} }
void set(T *d) void
set(T *d)
{ {
if (data == d) if (data == d)
return; return;

View file

@ -36,23 +36,24 @@
class RegState class RegState
{ {
protected: protected:
virtual bool update(int pid) = 0; virtual bool update(int pid) = 0;
public: public:
virtual int getNumRegs() = 0; virtual int getNumRegs() = 0;
virtual bool diffSinceUpdate(int num) = 0; virtual bool diffSinceUpdate(int num) = 0;
virtual std::string getRegName(int num) = 0; virtual std::string getRegName(int num) = 0;
virtual int getRegNum(std::string name) virtual int
{ getRegNum(std::string name)
int numregs = getNumRegs(); {
for(unsigned int x = 0; x < numregs; x++) int numregs = getNumRegs();
if(getRegName(x) == name) for (unsigned int x = 0; x < numregs; x++)
return x; if(getRegName(x) == name)
return -1; return x;
} return -1;
virtual int64_t getRegVal(int num) = 0; }
virtual int64_t getOldRegVal(int num) = 0; virtual int64_t getRegVal(int num) = 0;
virtual char * printReg(int num) = 0; virtual int64_t getOldRegVal(int num) = 0;
virtual char * printReg(int num) = 0;
}; };
#endif #endif

View file

@ -47,7 +47,8 @@
using namespace std; using namespace std;
void printUsage(const char * execName) void
printUsage(const char * execName)
{ {
cout << execName << " <options> -- <command> <arguments>" << endl; cout << execName << " <options> -- <command> <arguments>" << endl;
cout << "options:" << endl; cout << "options:" << endl;
@ -58,7 +59,8 @@ void printUsage(const char * execName)
cout << " -nt don't print an instruction trace" << endl; cout << " -nt don't print an instruction trace" << endl;
} }
int main(int argc, char * argv[], char * envp[]) int
main(int argc, char * argv[], char * envp[])
{ {
TraceChild * child = genTraceChild(); TraceChild * child = genTraceChild();
string args; string args;
@ -73,87 +75,64 @@ int main(int argc, char * argv[], char * envp[])
printUsage(argv[0]); printUsage(argv[0]);
return 0; return 0;
} }
for(int x = 1; x < argc; x++) for (int x = 1; x < argc; x++) {
{ if (!strcmp(argv[x], "-h")) {
if(!strcmp(argv[x], "-h"))
{
printUsage(argv[0]); printUsage(argv[0]);
return 0; return 0;
} }
if(!strcmp(argv[x], "--host")) if (!strcmp(argv[x], "--host")) {
{
x++; x++;
if(x >= argc) if (x >= argc) {
{
cerr << "Incorrect usage.\n" << endl; cerr << "Incorrect usage.\n" << endl;
printUsage(argv[0]); printUsage(argv[0]);
return 1; return 1;
} }
host = argv[x]; host = argv[x];
} } else if (!strcmp(argv[x], "-r")) {
else if(!strcmp(argv[x], "-r"))
{
cout << "Legal register names:" << endl; cout << "Legal register names:" << endl;
int numRegs = child->getNumRegs(); int numRegs = child->getNumRegs();
for(unsigned int x = 0; x < numRegs; x++) for (unsigned int x = 0; x < numRegs; x++)
{
cout << "\t" << child->getRegName(x) << endl; cout << "\t" << child->getRegName(x) << endl;
}
return 0; return 0;
} } else if (!strcmp(argv[x], "-i")) {
else if(!strcmp(argv[x], "-i"))
{
printInitial = true; printInitial = true;
} } else if (!strcmp(argv[x], "-nt")) {
else if(!strcmp(argv[x], "-nt"))
{
printTrace = false; printTrace = false;
} } else if (!strcmp(argv[x], "--")) {
else if(!strcmp(argv[x], "--"))
{
x++; x++;
if(x >= argc) if (x >= argc) {
{
cerr << "Incorrect usage.\n" << endl; cerr << "Incorrect usage.\n" << endl;
printUsage(argv[0]); printUsage(argv[0]);
return 1; return 1;
} }
startProgramArgs = x; startProgramArgs = x;
break; break;
} } else {
else
{
cerr << "Incorrect usage.\n" << endl; cerr << "Incorrect usage.\n" << endl;
printUsage(argv[0]); printUsage(argv[0]);
return 1; return 1;
} }
} }
if(!child->startTracing(argv[startProgramArgs], if (!child->startTracing(argv[startProgramArgs],
argv + startProgramArgs)) argv + startProgramArgs)) {
{
cerr << "Couldn't start target program" << endl; cerr << "Couldn't start target program" << endl;
return 1; return 1;
} }
child->step(); child->step();
if(printInitial) if (printInitial)
{
child->outputStartState(cout); child->outputStartState(cout);
} if (printTrace) {
if(printTrace)
{
// Connect to m5 // Connect to m5
bool portSet = false; bool portSet = false;
int port; int port;
int sock = socket(AF_INET, SOCK_STREAM, 0); int sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock < 0) if (sock < 0) {
{
cerr << "Error opening socket! " << strerror(errno) << endl; cerr << "Error opening socket! " << strerror(errno) << endl;
return 1; return 1;
} }
struct hostent *server; struct hostent *server;
server = gethostbyname(host.c_str()); server = gethostbyname(host.c_str());
if(!server) if (!server) {
{
cerr << "Couldn't get host ip! " << strerror(errno) << endl; cerr << "Couldn't get host ip! " << strerror(errno) << endl;
return 1; return 1;
} }
@ -164,22 +143,19 @@ int main(int argc, char * argv[], char * envp[])
(char *)&serv_addr.sin_addr.s_addr, (char *)&serv_addr.sin_addr.s_addr,
server->h_length); server->h_length);
serv_addr.sin_port = htons(8000); serv_addr.sin_port = htons(8000);
if(connect(sock, (sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) if (connect(sock, (sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
{
cerr << "Couldn't connect to server! " << strerror(errno) << endl; cerr << "Couldn't connect to server! " << strerror(errno) << endl;
return 1; return 1;
} }
while(child->isTracing()) while (child->isTracing()) {
{ if (!child->sendState(sock))
if(!child->sendState(sock)) break;
break; child->step();
child->step();
} }
} }
if(!child->stopTracing()) if (!child->stopTracing()) {
{ cerr << "Couldn't stop child" << endl;
cerr << "Couldn't stop child" << endl; return 1;
return 1;
} }
return 0; return 0;
} }

View file

@ -37,123 +37,111 @@
using namespace std; using namespace std;
bool TraceChild::startTracing(const char * pathToFile, char * const argv[]) bool
TraceChild::startTracing(const char * pathToFile, char * const argv[])
{ {
instructions = 0; instructions = 0;
pid = fork(); pid = fork();
if(pid == -1) if (pid == -1) {
{ cout << "fork failed" << endl;
cout << "fork failed" << endl; return false;
return false; } else if (pid == 0) {
} //We're the child. Get things ready and then exec the program to trace.
else if(pid == 0) //Let our parent trace us
{ if (ptrace(PTRACE_TRACEME, 0, 0, 0) == -1) {
//We're the child. Get things ready and then exec the cout << "Failure calling TRACEME\n" << strerror(errno) << endl;
//program to trace. return false;
//Let our parent trace us
if(ptrace(PTRACE_TRACEME, 0, 0, 0) == -1)
{
cout << "Failure calling TRACEME\n";
cout << strerror(errno) << endl;
return false;
}
//Set up an empty environment for the child...
//We would want to specify this somehow at some point
char * env[] = {NULL};
//Start the program to trace
execve(pathToFile, argv, env);
//We should never get here, so this is an error!
cout << "Exec failed\n";
cout << strerror(errno) << endl;
return false;
} }
//From this point forward, we know we're in the parent process. //Set up an empty environment for the child... We would want to
if(!doWait()) //specify this somehow at some point
{ char * env[] = {NULL};
cout << "Didn't wait successfully" << endl;
return false; //Start the program to trace
} execve(pathToFile, argv, env);
tracing = true;
return true; //We should never get here, so this is an error!
cout << "Exec failed\n" << strerror(errno) << endl;
return false;
}
//From this point forward, we know we're in the parent process.
if (!doWait()) {
cout << "Didn't wait successfully" << endl;
return false;
}
tracing = true;
return true;
} }
bool TraceChild::stopTracing() bool
TraceChild::stopTracing()
{ {
if(ptrace(PTRACE_KILL, pid, 0, 0) != 0) if (ptrace(PTRACE_KILL, pid, 0, 0) != 0)
return false; return false;
tracing = false;
return true;
}
bool
TraceChild::step()
{
ptraceSingleStep();
}
bool
TraceChild::ptraceSingleStep()
{
if (!tracing) {
cout << "Not tracing!" << endl;
return false;
}
if (ptrace(PTRACE_SINGLESTEP, pid, 0, 0) != 0) {
switch (errno) {
case EBUSY: cout << "EBUSY" << endl; break;
case EFAULT: cout << "EFAULT" << endl; break;
case EIO: cout << "EIO" << endl; break;
case EPERM: cout << "EPERM" << endl; break;
case ESRCH: cout << "ESRCH" << endl; break;
default: cout << "Unknown error" << endl; break;
}
cout << "Not able to single step!" << endl;
tracing == false;
return false;
}
doWait();
update(pid);
}
bool
TraceChild::doWait()
{
int wait_val;
wait(&wait_val);
if (WIFEXITED(wait_val)) {
cerr << "Program exited! Exit status is "
<< WEXITSTATUS(wait_val) << endl;
cerr << "Executed " << instructions
<< " instructions." << endl;
tracing = false; tracing = false;
return true; return false;
} }
if (WIFSIGNALED(wait_val)) {
bool TraceChild::step() if (WTERMSIG(wait_val))
{ cerr << "Program terminated by signal "
ptraceSingleStep(); << WTERMSIG(wait_val) << endl;
} if (WCOREDUMP(wait_val))
cerr << "Program core dumped!" << endl;
bool TraceChild::ptraceSingleStep() tracing = false;
{ cerr << "Executed " << instructions
if(!tracing) << " instructions." << endl;
{ return false;
cout << "Not tracing!" << endl; }
return false; if (WIFSTOPPED(wait_val) && WSTOPSIG(wait_val) != SIGTRAP) {
} cerr << "Program stopped by signal " << WSTOPSIG(wait_val) << endl;
if(ptrace(PTRACE_SINGLESTEP, pid, 0, 0) != 0) tracing = false;
{ cerr << "Executed " << instructions << " instructions." << endl;
switch(errno) return false;
{ }
case EBUSY: cout << "EBUSY" << endl; break; return true;
case EFAULT: cout << "EFAULT" << endl; break;
case EIO: cout << "EIO" << endl; break;
case EPERM: cout << "EPERM" << endl; break;
case ESRCH: cout << "ESRCH" << endl; break;
default: cout << "Unknown error" << endl; break;
}
cout << "Not able to single step!" << endl;
tracing == false;
return false;
}
doWait();
update(pid);
}
bool TraceChild::doWait()
{
int wait_val;
wait(&wait_val);
if(WIFEXITED(wait_val))
{
cerr << "Program exited! Exit status is "
<< WEXITSTATUS(wait_val) << endl;
cerr << "Executed " << instructions
<< " instructions." << endl;
tracing = false;
return false;
}
if(WIFSIGNALED(wait_val))
{
if(WTERMSIG(wait_val))
cerr << "Program terminated by signal "
<< WTERMSIG(wait_val) << endl;
if(WCOREDUMP(wait_val))
cerr << "Program core dumped!" << endl;
tracing = false;
cerr << "Executed " << instructions
<< " instructions." << endl;
return false;
}
if(WIFSTOPPED(wait_val) && WSTOPSIG(wait_val) != SIGTRAP)
{
cerr << "Program stopped by signal "
<< WSTOPSIG(wait_val) << endl;
tracing = false;
cerr << "Executed " << instructions
<< " instructions." << endl;
return false;
}
return true;
} }

View file

@ -35,32 +35,33 @@
class TraceChild : public RegState class TraceChild : public RegState
{ {
protected: protected:
int pid; int pid;
uint64_t instructions; uint64_t instructions;
bool tracing; bool tracing;
public: public:
TraceChild() : tracing(false), instructions(0) TraceChild() : tracing(false), instructions(0)
{;} {;}
virtual bool sendState(int socket) = 0; virtual bool sendState(int socket) = 0;
virtual bool startTracing(const char * pathToFile, virtual bool startTracing(const char * pathToFile, char * const argv[]);
char * const argv[]); virtual bool stopTracing();
virtual bool stopTracing(); virtual bool step();
virtual bool step(); virtual uint64_t getPC() = 0;
virtual uint64_t getPC() = 0; virtual uint64_t getSP() = 0;
virtual uint64_t getSP() = 0; virtual std::ostream & outputStartState(std::ostream & os) = 0;
virtual std::ostream & outputStartState(std::ostream & os) = 0; int
int getPid() getPid()
{ {
return pid; return pid;
} }
bool isTracing() bool
{ isTracing()
return tracing; {
} return tracing;
protected: }
bool ptraceSingleStep(); protected:
bool doWait(); bool ptraceSingleStep();
bool doWait();
}; };
TraceChild * genTraceChild(); TraceChild * genTraceChild();

View file

@ -29,29 +29,28 @@
*/ */
#if defined __alpha__ #if defined __alpha__
#error "Alpha architecture not implemented" #error "Alpha architecture not implemented"
#elif defined __amd64__ #elif defined __amd64__
// #error "AMD64 architecture not implemented" #include "arch/tracechild_amd64.cc"
#include "arch/tracechild_amd64.cc"
#elif defined __arm__ #elif defined __arm__
#include "arch/tracechild_arm.cc" #include "arch/tracechild_arm.cc"
#elif defined __hppa__ #elif defined __hppa__
#error "Hppa architecture not implemented" #error "Hppa architecture not implemented"
#elif defined __i386__ || defined __i486__ || \ #elif defined __i386__ || defined __i486__ || \
defined __i586__ || defined __i686 defined __i586__ || defined __i686
#include "arch/tracechild_i386.cc" #include "arch/tracechild_i386.cc"
#elif defined __ia64__ #elif defined __ia64__
#error "IA64 architecture not implemented" #error "IA64 architecture not implemented"
#elif defined __mips__ #elif defined __mips__
#error "Mips architecture not implemented" #error "Mips architecture not implemented"
#elif defined __powerpc__ #elif defined __powerpc__
#error "PowerPC architecture not implemented" #error "PowerPC architecture not implemented"
#elif defined __sparc__ #elif defined __sparc__
#include "arch/tracechild_sparc.cc" #include "arch/tracechild_sparc.cc"
#elif defined __sh__ #elif defined __sh__
#include "SuperH architecture not implemented" #include "SuperH architecture not implemented"
#elif defined __s390__ #elif defined __s390__
#include "System/390 architecture not implemented" #include "System/390 architecture not implemented"
#else #else
#error "Couldn't determine architecture" #error "Couldn't determine architecture"
#endif #endif