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;
const char * AMD64TraceChild::regNames[numregs] = {
//GPRs
"rax", "rbx", "rcx", "rdx",
//Index registers
"rsi", "rdi",
//Base pointer and stack pointer
"rbp", "rsp",
//New 64 bit mode registers
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
//Segmentation registers
"cs", "ds", "es", "fs", "gs", "ss", "fs_base", "gs_base",
//PC
"rip",
//Flags
"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"};
//GPRs
"rax", "rbx", "rcx", "rdx",
//Index registers
"rsi", "rdi",
//Base pointer and stack pointer
"rbp", "rsp",
//New 64 bit mode registers
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
//Segmentation registers
"cs", "ds", "es", "fs", "gs", "ss", "fs_base", "gs_base",
//PC
"rip",
//Flags
"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 regVal64 = 0;
uint32_t regVal32 = 0;
for(int x = 0; x <= R15; x++)
{
for (int x = 0; x <= R15; x++) {
regVal64 = getRegVal(x);
if(write(socket, &regVal64, sizeof(regVal64)) == -1)
{
if (write(socket, &regVal64, sizeof(regVal64)) == -1) {
cerr << "Write failed! " << strerror(errno) << endl;
tracing = false;
return false;
}
}
regVal64 = getRegVal(RIP);
if(write(socket, &regVal64, sizeof(regVal64)) == -1)
{
if (write(socket, &regVal64, sizeof(regVal64)) == -1) {
cerr << "Write failed! " << strerror(errno) << endl;
tracing = false;
return false;
}
for(int x = MMX0_0; x <= MMX7_1; x++)
{
for (int x = MMX0_0; x <= MMX7_1; x++) {
regVal32 = getRegVal(x);
if(write(socket, &regVal32, sizeof(regVal32)) == -1)
{
if (write(socket, &regVal32, sizeof(regVal32)) == -1) {
cerr << "Write failed! " << strerror(errno) << endl;
tracing = false;
return false;
}
}
for(int x = XMM0_0; x <= XMM15_3; x++)
{
for (int x = XMM0_0; x <= XMM15_3; x++) {
regVal32 = getRegVal(x);
if(write(socket, &regVal32, sizeof(regVal32)) == -1)
{
if (write(socket, &regVal32, sizeof(regVal32)) == -1) {
cerr << "Write failed! " << strerror(errno) << endl;
tracing = false;
return false;
@ -125,175 +115,178 @@ bool AMD64TraceChild::sendState(int socket)
return true;
}
int64_t AMD64TraceChild::getRegs(user_regs_struct & myregs,
int64_t
AMD64TraceChild::getRegs(user_regs_struct & myregs,
user_fpregs_struct & myfpregs, int num)
{
assert(num < numregs && num >= 0);
switch(num)
{
//GPRs
case RAX: return myregs.rax;
case RBX: return myregs.rbx;
case RCX: return myregs.rcx;
case RDX: return myregs.rdx;
//Index registers
case RSI: return myregs.rsi;
case RDI: return myregs.rdi;
//Base pointer and stack pointer
case RBP: return myregs.rbp;
case RSP: return myregs.rsp;
//New 64 bit mode registers
case R8: return myregs.r8;
case R9: return myregs.r9;
case R10: return myregs.r10;
case R11: return myregs.r11;
case R12: return myregs.r12;
case R13: return myregs.r13;
case R14: return myregs.r14;
case R15: return myregs.r15;
//Segmentation registers
case CS: return myregs.cs;
case DS: return myregs.ds;
case ES: return myregs.es;
case FS: return myregs.fs;
case GS: return myregs.gs;
case SS: return myregs.ss;
case FS_BASE: return myregs.fs_base;
case GS_BASE: return myregs.gs_base;
//PC
case RIP: return myregs.rip;
//Flags
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:
assert(0);
return 0;
switch (num) {
//GPRs
case RAX: return myregs.rax;
case RBX: return myregs.rbx;
case RCX: return myregs.rcx;
case RDX: return myregs.rdx;
//Index registers
case RSI: return myregs.rsi;
case RDI: return myregs.rdi;
//Base pointer and stack pointer
case RBP: return myregs.rbp;
case RSP: return myregs.rsp;
//New 64 bit mode registers
case R8: return myregs.r8;
case R9: return myregs.r9;
case R10: return myregs.r10;
case R11: return myregs.r11;
case R12: return myregs.r12;
case R13: return myregs.r13;
case R14: return myregs.r14;
case R15: return myregs.r15;
//Segmentation registers
case CS: return myregs.cs;
case DS: return myregs.ds;
case ES: return myregs.es;
case FS: return myregs.fs;
case GS: return myregs.gs;
case SS: return myregs.ss;
case FS_BASE: return myregs.fs_base;
case GS_BASE: return myregs.gs_base;
//PC
case RIP: return myregs.rip;
//Flags
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:
assert(0);
return 0;
}
}
bool AMD64TraceChild::update(int pid)
bool
AMD64TraceChild::update(int pid)
{
oldregs = regs;
oldfpregs = fpregs;
if(ptrace(PTRACE_GETREGS, pid, 0, &regs) != 0)
{
if (ptrace(PTRACE_GETREGS, pid, 0, &regs) != 0) {
cerr << "update: " << strerror(errno) << endl;
return false;
}
if(ptrace(PTRACE_GETFPREGS, pid, 0, &fpregs) != 0)
{
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));
return true;
}
AMD64TraceChild::AMD64TraceChild()
{
for(unsigned int x = 0; x < numregs; x++)
for (unsigned int x = 0; x < numregs; x++)
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));
return printBuffer;
sprintf(printBuffer, "0x%016lX", getRegVal(num));
return printBuffer;
}
ostream & AMD64TraceChild::outputStartState(ostream & os)
ostream &
AMD64TraceChild::outputStartState(ostream & os)
{
uint64_t sp = getSP();
uint64_t pc = getPC();
@ -313,13 +306,12 @@ ostream & AMD64TraceChild::outputStartState(ostream & os)
//Output argv pointers
int argCount = 0;
uint64_t cargv;
do
{
do {
cargv = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
sprintf(obuf, "0x%016lx: argv[%d] = 0x%016lx\n",
sp, argCount++, cargv);
if(cargv)
if(highestInfo < cargv)
if (cargv)
if (highestInfo < cargv)
highestInfo = cargv;
os << obuf;
sp += 8;
@ -328,8 +320,7 @@ ostream & AMD64TraceChild::outputStartState(ostream & os)
//Output the envp pointers
int envCount = 0;
uint64_t cenvp;
do
{
do {
cenvp = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
sprintf(obuf, "0x%016lx: envp[%d] = 0x%016lx\n",
sp, envCount++, cenvp);
@ -337,8 +328,7 @@ ostream & AMD64TraceChild::outputStartState(ostream & os)
sp += 8;
} while(cenvp);
uint64_t auxType, auxVal;
do
{
do {
auxType = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
sp += 8;
auxVal = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
@ -352,16 +342,13 @@ ostream & AMD64TraceChild::outputStartState(ostream & os)
uint64_t buf;
uint64_t currentStart = sp;
bool clearedInitialPadding = false;
do
{
do {
buf = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
char * cbuf = (char *)&buf;
for(int x = 0; x < sizeof(uint64_t); x++)
{
if(cbuf[x])
for (int x = 0; x < sizeof(uint64_t); x++) {
if (cbuf[x])
current += cbuf[x];
else
{
else {
sprintf(obuf, "0x%016lx: \"%s\"\n",
currentStart, current.c_str());
os << obuf;
@ -371,23 +358,21 @@ ostream & AMD64TraceChild::outputStartState(ostream & os)
}
sp += 8;
clearedInitialPadding = clearedInitialPadding || buf != 0;
} while(!clearedInitialPadding || buf != 0 || sp <= highestInfo);
} while (!clearedInitialPadding || buf != 0 || sp <= highestInfo);
return os;
}
uint64_t AMD64TraceChild::findSyscall()
uint64_t
AMD64TraceChild::findSyscall()
{
uint64_t rip = getPC();
bool foundOpcode = false;
bool twoByteOpcode = false;
for(;;)
{
for (;;) {
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;
if(!foundOpcode)
{
if (!foundOpcode) {
if(!(byte == 0x66 || //operand override
byte == 0x67 || //address override
byte == 0x2E || //cs
@ -400,28 +385,24 @@ uint64_t AMD64TraceChild::findSyscall()
byte == 0xF2 || //repe
byte == 0xF3 || //repne
(byte >= 0x40 && byte <= 0x4F) // REX
))
{
)) {
foundOpcode = true;
}
}
if(foundOpcode)
{
if(twoByteOpcode)
{
if (foundOpcode) {
if (twoByteOpcode) {
//SYSCALL or SYSENTER
if(byte == 0x05 || byte == 0x34)
if (byte == 0x05 || byte == 0x34)
return rip + 1;
else
return 0;
}
if(!twoByteOpcode)
{
if(byte == 0xCC) // INT3
if (!twoByteOpcode) {
if (byte == 0xCC) // INT3
return rip + 1;
else if(byte == 0xCD) // INT with byte immediate
else if (byte == 0xCD) // INT with byte immediate
return rip + 2;
else if(byte == 0x0F) // two byte opcode prefix
else if (byte == 0x0F) // two byte opcode prefix
twoByteOpcode = true;
else
return 0;
@ -433,11 +414,11 @@ uint64_t AMD64TraceChild::findSyscall()
}
}
bool AMD64TraceChild::step()
bool
AMD64TraceChild::step()
{
uint64_t ripAfterSyscall = findSyscall();
if(ripAfterSyscall)
{
if (ripAfterSyscall) {
//Get the original contents of memory
uint64_t buf = ptrace(PTRACE_PEEKDATA, pid, ripAfterSyscall, 0);
//Patch the first two bytes of the memory immediately after this with
@ -452,13 +433,10 @@ bool AMD64TraceChild::step()
ptraceSingleStep();
//Put things back to the way they started
ptrace(PTRACE_POKEDATA, pid, ripAfterSyscall, buf);
}
else
{
} else {
//Get all the way past repe and repne string instructions in one shot.
uint64_t newPC, origPC = getPC();
do
{
do {
ptraceSingleStep();
newPC = getPC();
} while(newPC == origPC);
@ -467,5 +445,5 @@ bool AMD64TraceChild::step()
TraceChild * genTraceChild()
{
return new AMD64TraceChild;
return new AMD64TraceChild;
}

View file

@ -108,18 +108,21 @@ class AMD64TraceChild : public TraceChild
bool sendState(int socket);
int getNumRegs()
int
getNumRegs()
{
return numregs;
}
bool diffSinceUpdate(int num)
bool
diffSinceUpdate(int 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];

View file

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

View file

@ -84,18 +84,21 @@ class ARMTraceChild : public TraceChild
ARMTraceChild();
bool sendState(int socket);
int getNumRegs()
int
getNumRegs()
{
return numregs;
}
bool diffSinceUpdate(int num)
bool
diffSinceUpdate(int 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];
@ -106,14 +109,16 @@ class ARMTraceChild : public TraceChild
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);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -37,123 +37,111 @@
using namespace std;
bool TraceChild::startTracing(const char * pathToFile, char * const argv[])
bool
TraceChild::startTracing(const char * pathToFile, char * const argv[])
{
instructions = 0;
pid = fork();
if(pid == -1)
{
cout << "fork failed" << endl;
return false;
}
else if(pid == 0)
{
//We're the child. Get things ready and then exec the
//program to trace.
//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;
instructions = 0;
pid = fork();
if (pid == -1) {
cout << "fork failed" << endl;
return false;
} else if (pid == 0) {
//We're the child. Get things ready and then exec the program to trace.
//Let our parent trace us
if (ptrace(PTRACE_TRACEME, 0, 0, 0) == -1) {
cout << "Failure calling TRACEME\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;
//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" << 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)
return false;
if (ptrace(PTRACE_KILL, pid, 0, 0) != 0)
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;
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;
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;
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
{
protected:
int pid;
uint64_t instructions;
bool tracing;
public:
TraceChild() : tracing(false), instructions(0)
{;}
virtual bool sendState(int socket) = 0;
virtual bool startTracing(const char * pathToFile,
char * const argv[]);
virtual bool stopTracing();
virtual bool step();
virtual uint64_t getPC() = 0;
virtual uint64_t getSP() = 0;
virtual std::ostream & outputStartState(std::ostream & os) = 0;
int getPid()
{
return pid;
}
bool isTracing()
{
return tracing;
}
protected:
bool ptraceSingleStep();
bool doWait();
protected:
int pid;
uint64_t instructions;
bool tracing;
public:
TraceChild() : tracing(false), instructions(0)
{;}
virtual bool sendState(int socket) = 0;
virtual bool startTracing(const char * pathToFile, char * const argv[]);
virtual bool stopTracing();
virtual bool step();
virtual uint64_t getPC() = 0;
virtual uint64_t getSP() = 0;
virtual std::ostream & outputStartState(std::ostream & os) = 0;
int
getPid()
{
return pid;
}
bool
isTracing()
{
return tracing;
}
protected:
bool ptraceSingleStep();
bool doWait();
};
TraceChild * genTraceChild();

View file

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