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, ®Val64, sizeof(regVal64)) == -1)
- {
+ if (write(socket, ®Val64, sizeof(regVal64)) == -1) {
cerr << "Write failed! " << strerror(errno) << endl;
tracing = false;
return false;
}
}
regVal64 = getRegVal(RIP);
- if(write(socket, ®Val64, sizeof(regVal64)) == -1)
- {
+ if (write(socket, ®Val64, 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, ®Val32, sizeof(regVal32)) == -1)
- {
+ if (write(socket, ®Val32, sizeof(regVal32)) == -1) {
cerr << "Write failed! " << strerror(errno) << endl;
tracing = false;
return false;
}
}
- for(int x = XMM0_0; x <= XMM15_3; x++)
- {
+ for (int x = XMM0_0; x <= XMM15_3; x++) {
regVal32 = getRegVal(x);
- if(write(socket, ®Val32, sizeof(regVal32)) == -1)
- {
+ if (write(socket, ®Val32, sizeof(regVal32)) == -1) {
cerr << "Write failed! " << strerror(errno) << endl;
tracing = false;
return false;
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, ®s) != 0)
- {
+ if (ptrace(PTRACE_GETREGS, pid, 0, ®s) != 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();
//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;
//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);
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);
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;
}
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
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;
}
}
-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
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);
TraceChild * genTraceChild()
{
- return new AMD64TraceChild;
+ return new AMD64TraceChild;
}
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];
}
}
-bool ARMTraceChild::sendState(int socket)
+bool
+ARMTraceChild::sendState(int socket)
{
uint32_t regVal = 0;
uint32_t message[numregs + 1];
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, ®s) != 0)
- {
+ if (ptrace(PTRACE_GETREGS, pid, 0, ®s) != 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();
//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);
//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);
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);
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;
return os;
}
-bool ARMTraceChild::step()
+bool
+ARMTraceChild::step()
{
const uint32_t bkpt_inst = 0xe7f001f0;
}
-TraceChild * genTraceChild()
+TraceChild *
+genTraceChild()
{
return new ARMTraceChild;
}
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];
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);
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, ®s) != 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, ®s) != 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;
}
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
//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, ®Val, sizeof(regVal)) == -1)
- {
+ if (write(socket, ®Val, sizeof(regVal)) == -1) {
cerr << "Write failed! " << strerror(errno) << endl;
tracing = false;
return false;
}
}
regVal = getRegVal(PC);
- if(write(socket, ®Val, sizeof(regVal)) == -1)
- {
+ if (write(socket, ®Val, sizeof(regVal)) == -1) {
cerr << "Write failed! " << strerror(errno) << endl;
tracing = false;
return false;
}
regVal = getRegVal(NPC);
- if(write(socket, ®Val, sizeof(regVal)) == -1)
- {
+ if (write(socket, ®Val, sizeof(regVal)) == -1) {
cerr << "Write failed! " << strerror(errno) << endl;
tracing = false;
return false;
}
regVal = getRegVal(CCR);
- if(write(socket, ®Val, sizeof(regVal)) == -1)
- {
+ if (write(socket, ®Val, sizeof(regVal)) == -1) {
cerr << "Write failed! " << strerror(errno) << endl;
tracing = false;
return false;
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
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;
}
//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++;
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;
}
//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();
* 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;
}
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;
}
//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;
//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;
}
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;
}
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];
-
- //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);
-
-public:
- SparcTraceChild();
-
- bool sendState(int socket);
-
- int getNumRegs()
- {
- return numregs;
- }
-
- 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];
- }
-
- int64_t getRegVal(int num);
-
- int64_t getOldRegVal(int num);
-
- bool step();
-
- uint64_t getPC()
- {
- return getRegVal(PC);
- }
-
- uint64_t getSP()
- {
- return getRegVal(O6);
- }
-
- char * printReg(int num);
-
- std::ostream & outputStartState(std::ostream & os);
+ 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);
+
+ protected:
+ bool update(int pid);
+
+ public:
+ SparcTraceChild();
+
+ bool sendState(int socket);
+
+ int
+ getNumRegs()
+ {
+ return numregs;
+ }
+
+ 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];
+ }
+
+ int64_t getRegVal(int num);
+
+ int64_t getOldRegVal(int num);
+
+ bool step();
+
+ uint64_t
+ getPC()
+ {
+ return getRegVal(PC);
+ }
+
+ uint64_t
+ getSP()
+ {
+ return getRegVal(O6);
+ }
+
+ char * printReg(int num);
+
+ std::ostream & outputStartState(std::ostream & os);
};
#endif
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;
//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;
}
//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
//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
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;
}
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;
}
}
//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();
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;
//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;
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;
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;
}
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;
}
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];
}
return os;
}
-ostream & RegPrinter::writeOut(ostream & os)
+ostream &
+RegPrinter::writeOut(ostream & os)
{
os << child->printReg(intRegNum);
return os;
PrinterObject(newChild), intRegNum(num)
{;}
- void regNum(int num)
+ void
+ regNum(int num)
{
intRegNum = num;
}
- int regNum()
+ int
+ regNum()
{
return intRegNum;
}
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);
}
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;
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
using namespace std;
-void printUsage(const char * execName)
+void
+printUsage(const char * execName)
{
cout << execName << " <options> -- <command> <arguments>" << endl;
cout << "options:" << 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();
string args;
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;
}
(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;
}
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;
+ 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;
}
- 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};
- //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);
- //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;
+ }
- //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.
- if(!doWait())
- {
- cout << "Didn't wait successfully" << endl;
- return false;
- }
- tracing = true;
- return true;
+ //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;
- tracing = false;
- return true;
+ if (ptrace(PTRACE_KILL, pid, 0, 0) != 0)
+ return false;
+ tracing = false;
+ return true;
}
-bool TraceChild::step()
+bool
+TraceChild::step()
{
- ptraceSingleStep();
+ ptraceSingleStep();
}
-bool TraceChild::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;
+ 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;
}
- doWait();
- update(pid);
+ cout << "Not able to single step!" << endl;
+ tracing == false;
+ return false;
+ }
+ doWait();
+ update(pid);
}
-bool TraceChild::doWait()
+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;
+ 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;
}
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();
*/
#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