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

@ -55,14 +55,10 @@ const char * AMD64TraceChild::regNames[numregs] = {
//Flags //Flags
"eflags", "eflags",
//MMX //MMX
"mmx0_0", "mmx0_1", "mmx0_0", "mmx0_1", "mmx1_0", "mmx1_1",
"mmx1_0", "mmx1_1", "mmx2_0", "mmx2_1", "mmx3_0", "mmx3_1",
"mmx2_0", "mmx2_1", "mmx4_0", "mmx4_1", "mmx5_0", "mmx5_1",
"mmx3_0", "mmx3_1", "mmx6_0", "mmx6_1", "mmx7_0", "mmx7_1",
"mmx4_0", "mmx4_1",
"mmx5_0", "mmx5_1",
"mmx6_0", "mmx6_1",
"mmx7_0", "mmx7_1",
//XMM //XMM
"xmm0_0", "xmm0_1", "xmm0_2", "xmm0_3", "xmm0_0", "xmm0_1", "xmm0_2", "xmm0_3",
"xmm1_0", "xmm1_1", "xmm1_2", "xmm1_3", "xmm1_0", "xmm1_1", "xmm1_2", "xmm1_3",
@ -81,42 +77,36 @@ const char * AMD64TraceChild::regNames[numregs] = {
"xmm14_0", "xmm14_1", "xmm14_2", "xmm14_3", "xmm14_0", "xmm14_1", "xmm14_2", "xmm14_3",
"xmm15_0", "xmm15_1", "xmm15_2", "xmm15_3"}; "xmm15_0", "xmm15_1", "xmm15_2", "xmm15_3"};
bool AMD64TraceChild::sendState(int socket) bool
AMD64TraceChild::sendState(int socket)
{ {
uint64_t regVal64 = 0; uint64_t regVal64 = 0;
uint32_t regVal32 = 0; uint32_t regVal32 = 0;
for(int x = 0; x <= R15; x++) for (int x = 0; x <= R15; x++) {
{
regVal64 = getRegVal(x); regVal64 = getRegVal(x);
if(write(socket, &regVal64, sizeof(regVal64)) == -1) if (write(socket, &regVal64, sizeof(regVal64)) == -1) {
{
cerr << "Write failed! " << strerror(errno) << endl; cerr << "Write failed! " << strerror(errno) << endl;
tracing = false; tracing = false;
return false; return false;
} }
} }
regVal64 = getRegVal(RIP); regVal64 = getRegVal(RIP);
if(write(socket, &regVal64, sizeof(regVal64)) == -1) if (write(socket, &regVal64, sizeof(regVal64)) == -1) {
{
cerr << "Write failed! " << strerror(errno) << endl; cerr << "Write failed! " << strerror(errno) << endl;
tracing = false; tracing = false;
return false; return false;
} }
for(int x = MMX0_0; x <= MMX7_1; x++) for (int x = MMX0_0; x <= MMX7_1; x++) {
{
regVal32 = getRegVal(x); regVal32 = getRegVal(x);
if(write(socket, &regVal32, sizeof(regVal32)) == -1) if (write(socket, &regVal32, sizeof(regVal32)) == -1) {
{
cerr << "Write failed! " << strerror(errno) << endl; cerr << "Write failed! " << strerror(errno) << endl;
tracing = false; tracing = false;
return false; return false;
} }
} }
for(int x = XMM0_0; x <= XMM15_3; x++) for (int x = XMM0_0; x <= XMM15_3; x++) {
{
regVal32 = getRegVal(x); regVal32 = getRegVal(x);
if(write(socket, &regVal32, sizeof(regVal32)) == -1) if (write(socket, &regVal32, sizeof(regVal32)) == -1) {
{
cerr << "Write failed! " << strerror(errno) << endl; cerr << "Write failed! " << strerror(errno) << endl;
tracing = false; tracing = false;
return false; return false;
@ -125,12 +115,12 @@ bool AMD64TraceChild::sendState(int socket)
return true; return true;
} }
int64_t AMD64TraceChild::getRegs(user_regs_struct & myregs, int64_t
AMD64TraceChild::getRegs(user_regs_struct & myregs,
user_fpregs_struct & myfpregs, int num) user_fpregs_struct & myfpregs, int num)
{ {
assert(num < numregs && num >= 0); assert(num < numregs && num >= 0);
switch(num) switch (num) {
{
//GPRs //GPRs
case RAX: return myregs.rax; case RAX: return myregs.rax;
case RBX: return myregs.rbx; case RBX: return myregs.rbx;
@ -252,48 +242,51 @@ int64_t AMD64TraceChild::getRegs(user_regs_struct & myregs,
} }
} }
bool AMD64TraceChild::update(int pid) bool
AMD64TraceChild::update(int pid)
{ {
oldregs = regs; oldregs = regs;
oldfpregs = fpregs; oldfpregs = fpregs;
if(ptrace(PTRACE_GETREGS, pid, 0, &regs) != 0) if (ptrace(PTRACE_GETREGS, pid, 0, &regs) != 0) {
{
cerr << "update: " << strerror(errno) << endl; cerr << "update: " << strerror(errno) << endl;
return false; return false;
} }
if(ptrace(PTRACE_GETFPREGS, pid, 0, &fpregs) != 0) if (ptrace(PTRACE_GETFPREGS, pid, 0, &fpregs) != 0) {
{
cerr << "update: " << strerror(errno) << endl; cerr << "update: " << strerror(errno) << endl;
return false; return false;
} }
for(unsigned int x = 0; x < numregs; x++) for (unsigned int x = 0; x < numregs; x++)
regDiffSinceUpdate[x] = (getRegVal(x) != getOldRegVal(x)); regDiffSinceUpdate[x] = (getRegVal(x) != getOldRegVal(x));
return true; return true;
} }
AMD64TraceChild::AMD64TraceChild() AMD64TraceChild::AMD64TraceChild()
{ {
for(unsigned int x = 0; x < numregs; x++) for (unsigned int x = 0; x < numregs; x++)
regDiffSinceUpdate[x] = false; regDiffSinceUpdate[x] = false;
} }
int64_t AMD64TraceChild::getRegVal(int num) int64_t
AMD64TraceChild::getRegVal(int num)
{ {
return getRegs(regs, fpregs, num); return getRegs(regs, fpregs, num);
} }
int64_t AMD64TraceChild::getOldRegVal(int num) int64_t
AMD64TraceChild::getOldRegVal(int num)
{ {
return getRegs(oldregs, oldfpregs, num); return getRegs(oldregs, oldfpregs, num);
} }
char * AMD64TraceChild::printReg(int num) char *
AMD64TraceChild::printReg(int num)
{ {
sprintf(printBuffer, "0x%016lX", getRegVal(num)); sprintf(printBuffer, "0x%016lX", getRegVal(num));
return printBuffer; return printBuffer;
} }
ostream & AMD64TraceChild::outputStartState(ostream & os) ostream &
AMD64TraceChild::outputStartState(ostream & os)
{ {
uint64_t sp = getSP(); uint64_t sp = getSP();
uint64_t pc = getPC(); uint64_t pc = getPC();
@ -313,13 +306,12 @@ ostream & AMD64TraceChild::outputStartState(ostream & os)
//Output argv pointers //Output argv pointers
int argCount = 0; int argCount = 0;
uint64_t cargv; uint64_t cargv;
do do {
{
cargv = ptrace(PTRACE_PEEKDATA, pid, sp, 0); cargv = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
sprintf(obuf, "0x%016lx: argv[%d] = 0x%016lx\n", sprintf(obuf, "0x%016lx: argv[%d] = 0x%016lx\n",
sp, argCount++, cargv); sp, argCount++, cargv);
if(cargv) if (cargv)
if(highestInfo < cargv) if (highestInfo < cargv)
highestInfo = cargv; highestInfo = cargv;
os << obuf; os << obuf;
sp += 8; sp += 8;
@ -328,8 +320,7 @@ ostream & AMD64TraceChild::outputStartState(ostream & os)
//Output the envp pointers //Output the envp pointers
int envCount = 0; int envCount = 0;
uint64_t cenvp; uint64_t cenvp;
do do {
{
cenvp = ptrace(PTRACE_PEEKDATA, pid, sp, 0); cenvp = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
sprintf(obuf, "0x%016lx: envp[%d] = 0x%016lx\n", sprintf(obuf, "0x%016lx: envp[%d] = 0x%016lx\n",
sp, envCount++, cenvp); sp, envCount++, cenvp);
@ -337,8 +328,7 @@ ostream & AMD64TraceChild::outputStartState(ostream & os)
sp += 8; sp += 8;
} while(cenvp); } while(cenvp);
uint64_t auxType, auxVal; uint64_t auxType, auxVal;
do do {
{
auxType = ptrace(PTRACE_PEEKDATA, pid, sp, 0); auxType = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
sp += 8; sp += 8;
auxVal = ptrace(PTRACE_PEEKDATA, pid, sp, 0); auxVal = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
@ -352,16 +342,13 @@ ostream & AMD64TraceChild::outputStartState(ostream & os)
uint64_t buf; uint64_t buf;
uint64_t currentStart = sp; uint64_t currentStart = sp;
bool clearedInitialPadding = false; bool clearedInitialPadding = false;
do do {
{
buf = ptrace(PTRACE_PEEKDATA, pid, sp, 0); buf = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
char * cbuf = (char *)&buf; char * cbuf = (char *)&buf;
for(int x = 0; x < sizeof(uint64_t); x++) for (int x = 0; x < sizeof(uint64_t); x++) {
{ if (cbuf[x])
if(cbuf[x])
current += cbuf[x]; current += cbuf[x];
else else {
{
sprintf(obuf, "0x%016lx: \"%s\"\n", sprintf(obuf, "0x%016lx: \"%s\"\n",
currentStart, current.c_str()); currentStart, current.c_str());
os << obuf; os << obuf;
@ -371,23 +358,21 @@ ostream & AMD64TraceChild::outputStartState(ostream & os)
} }
sp += 8; sp += 8;
clearedInitialPadding = clearedInitialPadding || buf != 0; clearedInitialPadding = clearedInitialPadding || buf != 0;
} while(!clearedInitialPadding || buf != 0 || sp <= highestInfo); } while (!clearedInitialPadding || buf != 0 || sp <= highestInfo);
return os; return os;
} }
uint64_t AMD64TraceChild::findSyscall() uint64_t
AMD64TraceChild::findSyscall()
{ {
uint64_t rip = getPC(); uint64_t rip = getPC();
bool foundOpcode = false; bool foundOpcode = false;
bool twoByteOpcode = false; bool twoByteOpcode = false;
for(;;) for (;;) {
{
uint64_t buf = ptrace(PTRACE_PEEKDATA, pid, rip, 0); uint64_t buf = ptrace(PTRACE_PEEKDATA, pid, rip, 0);
for(int i = 0; i < sizeof(uint64_t); i++) for (int i = 0; i < sizeof(uint64_t); i++) {
{
unsigned char byte = buf & 0xFF; unsigned char byte = buf & 0xFF;
if(!foundOpcode) if (!foundOpcode) {
{
if(!(byte == 0x66 || //operand override if(!(byte == 0x66 || //operand override
byte == 0x67 || //address override byte == 0x67 || //address override
byte == 0x2E || //cs byte == 0x2E || //cs
@ -400,28 +385,24 @@ uint64_t AMD64TraceChild::findSyscall()
byte == 0xF2 || //repe byte == 0xF2 || //repe
byte == 0xF3 || //repne byte == 0xF3 || //repne
(byte >= 0x40 && byte <= 0x4F) // REX (byte >= 0x40 && byte <= 0x4F) // REX
)) )) {
{
foundOpcode = true; foundOpcode = true;
} }
} }
if(foundOpcode) if (foundOpcode) {
{ if (twoByteOpcode) {
if(twoByteOpcode)
{
//SYSCALL or SYSENTER //SYSCALL or SYSENTER
if(byte == 0x05 || byte == 0x34) if (byte == 0x05 || byte == 0x34)
return rip + 1; return rip + 1;
else else
return 0; return 0;
} }
if(!twoByteOpcode) if (!twoByteOpcode) {
{ if (byte == 0xCC) // INT3
if(byte == 0xCC) // INT3
return rip + 1; return rip + 1;
else if(byte == 0xCD) // INT with byte immediate else if (byte == 0xCD) // INT with byte immediate
return rip + 2; return rip + 2;
else if(byte == 0x0F) // two byte opcode prefix else if (byte == 0x0F) // two byte opcode prefix
twoByteOpcode = true; twoByteOpcode = true;
else else
return 0; return 0;
@ -433,11 +414,11 @@ uint64_t AMD64TraceChild::findSyscall()
} }
} }
bool AMD64TraceChild::step() bool
AMD64TraceChild::step()
{ {
uint64_t ripAfterSyscall = findSyscall(); uint64_t ripAfterSyscall = findSyscall();
if(ripAfterSyscall) if (ripAfterSyscall) {
{
//Get the original contents of memory //Get the original contents of memory
uint64_t buf = ptrace(PTRACE_PEEKDATA, pid, ripAfterSyscall, 0); uint64_t buf = ptrace(PTRACE_PEEKDATA, pid, ripAfterSyscall, 0);
//Patch the first two bytes of the memory immediately after this with //Patch the first two bytes of the memory immediately after this with
@ -452,13 +433,10 @@ bool AMD64TraceChild::step()
ptraceSingleStep(); ptraceSingleStep();
//Put things back to the way they started //Put things back to the way they started
ptrace(PTRACE_POKEDATA, pid, ripAfterSyscall, buf); ptrace(PTRACE_POKEDATA, pid, ripAfterSyscall, buf);
} } else {
else
{
//Get all the way past repe and repne string instructions in one shot. //Get all the way past repe and repne string instructions in one shot.
uint64_t newPC, origPC = getPC(); uint64_t newPC, origPC = getPC();
do do {
{
ptraceSingleStep(); ptraceSingleStep();
newPC = getPC(); newPC = getPC();
} while(newPC == origPC); } while(newPC == origPC);

View file

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

View file

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

View file

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

View file

@ -49,11 +49,11 @@ char * I386TraceChild::regNames[numregs] = {
//PC //PC
"eip"}; "eip"};
int64_t I386TraceChild::getRegs(user_regs_struct & myregs, int num) int64_t
I386TraceChild::getRegs(user_regs_struct & myregs, int num)
{ {
assert(num < numregs && num >= 0); assert(num < numregs && num >= 0);
switch(num) switch (num) {
{
//GPRs //GPRs
case EAX: return myregs.eax; case EAX: return myregs.eax;
case EBX: return myregs.ebx; case EBX: return myregs.ebx;
@ -80,41 +80,44 @@ int64_t I386TraceChild::getRegs(user_regs_struct & myregs, int num)
} }
} }
bool I386TraceChild::update(int pid) bool
I386TraceChild::update(int pid)
{ {
oldregs = regs; oldregs = regs;
if(ptrace(PTRACE_GETREGS, pid, 0, &regs) != 0) if (ptrace(PTRACE_GETREGS, pid, 0, &regs) != 0)
return false; return false;
for(unsigned int x = 0; x < numregs; x++) for (unsigned int x = 0; x < numregs; x++) {
{ regDiffSinceUpdate[x] = (getRegVal(x) != getOldRegVal(x));
regDiffSinceUpdate[x] =
(getRegVal(x) != getOldRegVal(x));
} }
} }
I386TraceChild::I386TraceChild() I386TraceChild::I386TraceChild()
{ {
for(unsigned int x = 0; x < numregs; x++) for (unsigned int x = 0; x < numregs; x++)
regDiffSinceUpdate[x] = false; regDiffSinceUpdate[x] = false;
} }
int64_t I386TraceChild::getRegVal(int num) int64_t
I386TraceChild::getRegVal(int num)
{ {
return getRegs(regs, num); return getRegs(regs, num);
} }
int64_t I386TraceChild::getOldRegVal(int num) int64_t
I386TraceChild::getOldRegVal(int num)
{ {
return getRegs(oldregs, num); return getRegs(oldregs, num);
} }
char * I386TraceChild::printReg(int num) char *
I386TraceChild::printReg(int num)
{ {
sprintf(printBuffer, "0x%08X", getRegVal(num)); sprintf(printBuffer, "0x%08X", getRegVal(num));
return printBuffer; return printBuffer;
} }
TraceChild * genTraceChild() TraceChild *
genTraceChild()
{ {
return new I386TraceChild; return new I386TraceChild;
} }

View file

@ -41,7 +41,7 @@
class I386TraceChild : public TraceChild class I386TraceChild : public TraceChild
{ {
public: public:
enum RegNum enum RegNum
{ {
//GPRs //GPRs
@ -56,7 +56,7 @@ public:
EIP, EIP,
numregs numregs
}; };
private: private:
char printBuffer [256]; char printBuffer [256];
static char * regNames[numregs]; static char * regNames[numregs];
int64_t getRegs(user_regs_struct & myregs, int num); int64_t getRegs(user_regs_struct & myregs, int num);
@ -64,25 +64,28 @@ private:
user_regs_struct oldregs; user_regs_struct oldregs;
bool regDiffSinceUpdate[numregs]; bool regDiffSinceUpdate[numregs];
protected: protected:
bool update(int pid); bool update(int pid);
public: public:
I386TraceChild(); I386TraceChild();
int getNumRegs() int
getNumRegs()
{ {
return numregs; return numregs;
} }
bool diffSinceUpdate(int num) bool
diffSinceUpdate(int num)
{ {
assert(num < numregs && num >= 0); assert(num < numregs && num >= 0);
return regDiffSinceUpdate[num]; return regDiffSinceUpdate[num];
} }
std::string getRegName(int num) std::string
getRegName(int num)
{ {
assert(num < numregs && num >= 0); assert(num < numregs && num >= 0);
return regNames[num]; return regNames[num];
@ -92,7 +95,8 @@ public:
int64_t getOldRegVal(int num); int64_t getOldRegVal(int num);
uint64_t getPC() {return getRegVal(EIP);} uint64_t getPC() {return getRegVal(EIP);}
uint64_t getSP() {return getRegVal(ESP);} uint64_t getSP() {return getRegVal(ESP);}
std::ostream & outputStartState(std::ostream & output) std::ostream &
outputStartState(std::ostream & output)
{ {
output << "Printing i386 initial state not yet implemented" output << "Printing i386 initial state not yet implemented"
<< std::endl; << std::endl;

View file

@ -54,36 +54,32 @@ string SparcTraceChild::regNames[numregs] = {
//Miscelaneous //Miscelaneous
"fsr", "fprs", "pc", "npc", "y", "cwp", "pstate", "asi", "ccr"}; "fsr", "fprs", "pc", "npc", "y", "cwp", "pstate", "asi", "ccr"};
bool SparcTraceChild::sendState(int socket) bool
SparcTraceChild::sendState(int socket)
{ {
uint64_t regVal = 0; uint64_t regVal = 0;
for(int x = 0; x <= I7; x++) for (int x = 0; x <= I7; x++) {
{
regVal = getRegVal(x); regVal = getRegVal(x);
if(write(socket, &regVal, sizeof(regVal)) == -1) if (write(socket, &regVal, sizeof(regVal)) == -1) {
{
cerr << "Write failed! " << strerror(errno) << endl; cerr << "Write failed! " << strerror(errno) << endl;
tracing = false; tracing = false;
return false; return false;
} }
} }
regVal = getRegVal(PC); regVal = getRegVal(PC);
if(write(socket, &regVal, sizeof(regVal)) == -1) if (write(socket, &regVal, sizeof(regVal)) == -1) {
{
cerr << "Write failed! " << strerror(errno) << endl; cerr << "Write failed! " << strerror(errno) << endl;
tracing = false; tracing = false;
return false; return false;
} }
regVal = getRegVal(NPC); regVal = getRegVal(NPC);
if(write(socket, &regVal, sizeof(regVal)) == -1) if (write(socket, &regVal, sizeof(regVal)) == -1) {
{
cerr << "Write failed! " << strerror(errno) << endl; cerr << "Write failed! " << strerror(errno) << endl;
tracing = false; tracing = false;
return false; return false;
} }
regVal = getRegVal(CCR); regVal = getRegVal(CCR);
if(write(socket, &regVal, sizeof(regVal)) == -1) if (write(socket, &regVal, sizeof(regVal)) == -1) {
{
cerr << "Write failed! " << strerror(errno) << endl; cerr << "Write failed! " << strerror(errno) << endl;
tracing = false; tracing = false;
return false; return false;
@ -91,12 +87,12 @@ bool SparcTraceChild::sendState(int socket)
return true; return true;
} }
int64_t getRegs(regs & myregs, fpu & myfpu, int64_t
uint64_t * locals, uint64_t * inputs, int num) getRegs(regs & myregs, fpu & myfpu, uint64_t * locals,
uint64_t * inputs, int num)
{ {
assert(num < SparcTraceChild::numregs && num >= 0); assert(num < SparcTraceChild::numregs && num >= 0);
switch(num) switch (num) {
{
//Global registers //Global registers
case SparcTraceChild::G0: return 0; case SparcTraceChild::G0: return 0;
case SparcTraceChild::G1: return myregs.r_g1; case SparcTraceChild::G1: return myregs.r_g1;
@ -186,45 +182,45 @@ int64_t getRegs(regs & myregs, fpu & myfpu,
} }
} }
bool SparcTraceChild::update(int pid) bool
SparcTraceChild::update(int pid)
{ {
memcpy(&oldregs, &theregs, sizeof(regs)); memcpy(&oldregs, &theregs, sizeof(regs));
memcpy(&oldfpregs, &thefpregs, sizeof(fpu)); memcpy(&oldfpregs, &thefpregs, sizeof(fpu));
memcpy(oldLocals, locals, 8 * sizeof(uint64_t)); memcpy(oldLocals, locals, 8 * sizeof(uint64_t));
memcpy(oldInputs, inputs, 8 * sizeof(uint64_t)); memcpy(oldInputs, inputs, 8 * sizeof(uint64_t));
if(ptrace(PTRACE_GETREGS, pid, &theregs, 0) != 0) if (ptrace(PTRACE_GETREGS, pid, &theregs, 0) != 0) {
{
cerr << "Update failed" << endl; cerr << "Update failed" << endl;
return false; return false;
} }
uint64_t stackPointer = getSP(); uint64_t stackPointer = getSP();
uint64_t stackBias = 2047; uint64_t stackBias = 2047;
bool v9 = stackPointer % 2; bool v9 = stackPointer % 2;
for(unsigned int x = 0; x < 8; x++) for (unsigned int x = 0; x < 8; x++) {
{
uint64_t localAddr = stackPointer + uint64_t localAddr = stackPointer +
(v9 ? (stackBias + x * 8) : (x * 4)); (v9 ? (stackBias + x * 8) : (x * 4));
locals[x] = ptrace(PTRACE_PEEKTEXT, pid, localAddr, 0); locals[x] = ptrace(PTRACE_PEEKTEXT, pid, localAddr, 0);
if(!v9) locals[x] >>= 32; if (!v9) locals[x] >>= 32;
uint64_t inputAddr = stackPointer + uint64_t inputAddr = stackPointer +
(v9 ? (stackBias + x * 8 + (8 * 8)) : (x * 4 + 8 * 4)); (v9 ? (stackBias + x * 8 + (8 * 8)) : (x * 4 + 8 * 4));
inputs[x] = ptrace(PTRACE_PEEKTEXT, pid, inputAddr, 0); inputs[x] = ptrace(PTRACE_PEEKTEXT, pid, inputAddr, 0);
if(!v9) inputs[x] >>= 32; if (!v9) inputs[x] >>= 32;
} }
if(ptrace(PTRACE_GETFPREGS, pid, &thefpregs, 0) != 0) if (ptrace(PTRACE_GETFPREGS, pid, &thefpregs, 0) != 0)
return false; return false;
for(unsigned int x = 0; x < numregs; x++) for (unsigned int x = 0; x < numregs; x++)
regDiffSinceUpdate[x] = (getRegVal(x) != getOldRegVal(x)); regDiffSinceUpdate[x] = (getRegVal(x) != getOldRegVal(x));
return true; return true;
} }
SparcTraceChild::SparcTraceChild() SparcTraceChild::SparcTraceChild()
{ {
for(unsigned int x = 0; x < numregs; x++) for (unsigned int x = 0; x < numregs; x++)
regDiffSinceUpdate[x] = false; regDiffSinceUpdate[x] = false;
} }
int SparcTraceChild::getTargets(uint32_t inst, uint64_t pc, uint64_t npc, int
SparcTraceChild::getTargets(uint32_t inst, uint64_t pc, uint64_t npc,
uint64_t &target1, uint64_t &target2) uint64_t &target1, uint64_t &target2)
{ {
//We can identify the instruction categories we care about using the top //We can identify the instruction categories we care about using the top
@ -245,28 +241,21 @@ int SparcTraceChild::getTargets(uint32_t inst, uint64_t pc, uint64_t npc,
bool bcc = (cond & 0x7) && bool bcc = (cond & 0x7) &&
(sig == 0x1 || sig == 0x2 || sig == 0x3 || sig == 0x5 || sig == 0x6); (sig == 0x1 || sig == 0x2 || sig == 0x3 || sig == 0x5 || sig == 0x6);
if(annul) if (annul) {
{ if (bcc) {
if(bcc)
{
target1 = npc; target1 = npc;
target2 = npc + 4; target2 = npc + 4;
return 2; return 2;
} } else if(ba) {
else if(ba)
{
//This branches immediately to the effective address of the branch //This branches immediately to the effective address of the branch
//which we'll have to calculate. //which we'll have to calculate.
uint64_t disp = 0; uint64_t disp = 0;
int64_t extender = 0; int64_t extender = 0;
//Figure out how big the displacement field is, and grab the bits //Figure out how big the displacement field is, and grab the bits
if(sig == 0x1 || sig == 0x5) if (sig == 0x1 || sig == 0x5) {
{
disp = inst & ((1 << 19) - 1); disp = inst & ((1 << 19) - 1);
extender = 1 << 18; extender = 1 << 18;
} } else {
else
{
disp = inst & ((1 << 22) - 1); disp = inst & ((1 << 22) - 1);
extender = 1 << 21; extender = 1 << 21;
} }
@ -276,21 +265,19 @@ int SparcTraceChild::getTargets(uint32_t inst, uint64_t pc, uint64_t npc,
//smart enough to turn this into a shift. //smart enough to turn this into a shift.
disp *= 4; disp *= 4;
target1 = pc + disp; target1 = pc + disp;
} } else if(bn)
else if(bn)
target1 = npc + 4; target1 = npc + 4;
else else
target1 = npc; target1 = npc;
return 1; return 1;
} } else {
else
{
target1 = npc; target1 = npc;
return 1; return 1;
} }
} }
bool SparcTraceChild::step() bool
SparcTraceChild::step()
{ {
//Increment the count of the number of instructions executed //Increment the count of the number of instructions executed
instructions++; instructions++;
@ -345,18 +332,17 @@ bool SparcTraceChild::step()
uint64_t newBp1 = origBp1; uint64_t newBp1 = origBp1;
newBp1 &= unalignedBp1 ? highMask : lowMask; newBp1 &= unalignedBp1 ? highMask : lowMask;
newBp1 |= unalignedBp1 ? lowBreakInst : highBreakInst; newBp1 |= unalignedBp1 ? lowBreakInst : highBreakInst;
if(ptrace(PTRACE_POKETEXT, pid, alignedBp1, newBp1) != 0) if (ptrace(PTRACE_POKETEXT, pid, alignedBp1, newBp1) != 0)
cerr << "Poke failed" << endl; cerr << "Poke failed" << endl;
/* /*
* Set the second breakpoint if necessary * Set the second breakpoint if necessary
*/ */
if(numTargets == 2) if (numTargets == 2) {
{
origBp2 = ptrace(PTRACE_PEEKTEXT, pid, alignedBp2, 0); origBp2 = ptrace(PTRACE_PEEKTEXT, pid, alignedBp2, 0);
uint64_t newBp2 = origBp2; uint64_t newBp2 = origBp2;
newBp2 &= unalignedBp2 ? highMask : lowMask; newBp2 &= unalignedBp2 ? highMask : lowMask;
newBp2 |= unalignedBp2 ? lowBreakInst : highBreakInst; newBp2 |= unalignedBp2 ? lowBreakInst : highBreakInst;
if(ptrace(PTRACE_POKETEXT, pid, alignedBp2, newBp2) != 0) if (ptrace(PTRACE_POKETEXT, pid, alignedBp2, newBp2) != 0)
cerr << "Poke failed" << endl; cerr << "Poke failed" << endl;
} }
@ -366,7 +352,7 @@ bool SparcTraceChild::step()
//Note that the "addr" parameter is supposed to be ignored, but in at //Note that the "addr" parameter is supposed to be ignored, but in at
//least one version of the kernel, it must be 1 or it will set what //least one version of the kernel, it must be 1 or it will set what
//pc to continue from //pc to continue from
if(ptrace(PTRACE_CONT, pid, 1, 0) != 0) if (ptrace(PTRACE_CONT, pid, 1, 0) != 0)
cerr << "Cont failed" << endl; cerr << "Cont failed" << endl;
doWait(); doWait();
@ -379,42 +365,42 @@ bool SparcTraceChild::step()
* Put back the original contents of the childs address space in the * Put back the original contents of the childs address space in the
* reverse order. * reverse order.
*/ */
if(numTargets == 2) if (numTargets == 2) {
{ if (ptrace(PTRACE_POKETEXT, pid, alignedBp2, origBp2) != 0)
if(ptrace(PTRACE_POKETEXT, pid, alignedBp2, origBp2) != 0)
cerr << "Poke failed" << endl; cerr << "Poke failed" << endl;
} }
if(ptrace(PTRACE_POKETEXT, pid, alignedBp1, origBp1) != 0) if (ptrace(PTRACE_POKETEXT, pid, alignedBp1, origBp1) != 0)
cerr << "Poke failed" << endl; cerr << "Poke failed" << endl;
} }
int64_t SparcTraceChild::getRegVal(int num) int64_t
SparcTraceChild::getRegVal(int num)
{ {
return getRegs(theregs, thefpregs, locals, inputs, num); return getRegs(theregs, thefpregs, locals, inputs, num);
} }
int64_t SparcTraceChild::getOldRegVal(int num) int64_t
SparcTraceChild::getOldRegVal(int num)
{ {
return getRegs(oldregs, oldfpregs, oldLocals, oldInputs, num); return getRegs(oldregs, oldfpregs, oldLocals, oldInputs, num);
} }
char * SparcTraceChild::printReg(int num) char *
SparcTraceChild::printReg(int num)
{ {
sprintf(printBuffer, "0x%016llx", getRegVal(num)); sprintf(printBuffer, "0x%016llx", getRegVal(num));
return printBuffer; return printBuffer;
} }
ostream & SparcTraceChild::outputStartState(ostream & os) ostream &
SparcTraceChild::outputStartState(ostream & os)
{ {
bool v8 = false; bool v8 = false;
uint64_t sp = getSP(); uint64_t sp = getSP();
if(sp % 2) if (sp % 2) {
{
os << "Detected a 64 bit executable.\n"; os << "Detected a 64 bit executable.\n";
v8 = false; v8 = false;
} } else {
else
{
os << "Detected a 32 bit executable.\n"; os << "Detected a 32 bit executable.\n";
v8 = true; v8 = true;
} }
@ -424,16 +410,14 @@ ostream & SparcTraceChild::outputStartState(ostream & os)
os << obuf; os << obuf;
sprintf(obuf, "Initial program counter = 0x%016llx\n", pc); sprintf(obuf, "Initial program counter = 0x%016llx\n", pc);
os << obuf; os << obuf;
if(!v8) if (!v8) {
{
//Take out the stack bias //Take out the stack bias
sp += 2047; sp += 2047;
} }
//Output the window save area //Output the window save area
for(unsigned int x = 0; x < 16; x++) for (unsigned int x = 0; x < 16; x++) {
{
uint64_t regspot = ptrace(PTRACE_PEEKDATA, pid, sp, 0); uint64_t regspot = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
if(v8) regspot = regspot >> 32; if (v8) regspot = regspot >> 32;
sprintf(obuf, "0x%016llx: Window save %d = 0x%016llx\n", sprintf(obuf, "0x%016llx: Window save %d = 0x%016llx\n",
sp, x+1, regspot); sp, x+1, regspot);
os << obuf; os << obuf;
@ -441,17 +425,16 @@ ostream & SparcTraceChild::outputStartState(ostream & os)
} }
//Output the argument count //Output the argument count
uint64_t cargc = ptrace(PTRACE_PEEKDATA, pid, sp, 0); uint64_t cargc = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
if(v8) cargc = cargc >> 32; if (v8) cargc = cargc >> 32;
sprintf(obuf, "0x%016llx: Argc = 0x%016llx\n", sp, cargc); sprintf(obuf, "0x%016llx: Argc = 0x%016llx\n", sp, cargc);
os << obuf; os << obuf;
sp += v8 ? 4 : 8; sp += v8 ? 4 : 8;
//Output argv pointers //Output argv pointers
int argCount = 0; int argCount = 0;
uint64_t cargv; uint64_t cargv;
do do {
{
cargv = ptrace(PTRACE_PEEKDATA, pid, sp, 0); cargv = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
if(v8) cargv = cargv >> 32; if (v8) cargv = cargv >> 32;
sprintf(obuf, "0x%016llx: argv[%d] = 0x%016llx\n", sprintf(obuf, "0x%016llx: argv[%d] = 0x%016llx\n",
sp, argCount++, cargv); sp, argCount++, cargv);
os << obuf; os << obuf;
@ -460,43 +443,38 @@ ostream & SparcTraceChild::outputStartState(ostream & os)
//Output the envp pointers //Output the envp pointers
int envCount = 0; int envCount = 0;
uint64_t cenvp; uint64_t cenvp;
do do {
{
cenvp = ptrace(PTRACE_PEEKDATA, pid, sp, 0); cenvp = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
if(v8) cenvp = cenvp >> 32; if (v8) cenvp = cenvp >> 32;
sprintf(obuf, "0x%016llx: envp[%d] = 0x%016llx\n", sprintf(obuf, "0x%016llx: envp[%d] = 0x%016llx\n",
sp, envCount++, cenvp); sp, envCount++, cenvp);
os << obuf; os << obuf;
sp += v8 ? 4 : 8; sp += v8 ? 4 : 8;
} while(cenvp); } while (cenvp);
uint64_t auxType, auxVal; uint64_t auxType, auxVal;
do do {
{
auxType = ptrace(PTRACE_PEEKDATA, pid, sp, 0); auxType = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
if(v8) auxType = auxType >> 32; if (v8) auxType = auxType >> 32;
sp += (v8 ? 4 : 8); sp += (v8 ? 4 : 8);
auxVal = ptrace(PTRACE_PEEKDATA, pid, sp, 0); auxVal = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
if(v8) auxVal = auxVal >> 32; if (v8) auxVal = auxVal >> 32;
sp += (v8 ? 4 : 8); sp += (v8 ? 4 : 8);
sprintf(obuf, "0x%016llx: Auxiliary vector = {0x%016llx, 0x%016llx}\n", sprintf(obuf, "0x%016llx: Auxiliary vector = {0x%016llx, 0x%016llx}\n",
sp - 8, auxType, auxVal); sp - 8, auxType, auxVal);
os << obuf; os << obuf;
} while(auxType != 0 || auxVal != 0); } while (auxType != 0 || auxVal != 0);
//Print out the argument strings, environment strings, and file name. //Print out the argument strings, environment strings, and file name.
string current; string current;
uint64_t buf; uint64_t buf;
uint64_t currentStart = sp; uint64_t currentStart = sp;
bool clearedInitialPadding = false; bool clearedInitialPadding = false;
do do {
{
buf = ptrace(PTRACE_PEEKDATA, pid, sp, 0); buf = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
char * cbuf = (char *)&buf; char * cbuf = (char *)&buf;
for(int x = 0; x < sizeof(uint32_t); x++) for (int x = 0; x < sizeof(uint32_t); x++) {
{ if (cbuf[x])
if(cbuf[x])
current += cbuf[x]; current += cbuf[x];
else else {
{
sprintf(obuf, "0x%016llx: \"%s\"\n", sprintf(obuf, "0x%016llx: \"%s\"\n",
currentStart, current.c_str()); currentStart, current.c_str());
os << obuf; os << obuf;
@ -506,11 +484,12 @@ ostream & SparcTraceChild::outputStartState(ostream & os)
} }
sp += (v8 ? 4 : 8); sp += (v8 ? 4 : 8);
clearedInitialPadding = clearedInitialPadding || buf != 0; clearedInitialPadding = clearedInitialPadding || buf != 0;
} while(!clearedInitialPadding || buf != 0); } while (!clearedInitialPadding || buf != 0);
return os; return os;
} }
TraceChild * genTraceChild() TraceChild *
genTraceChild()
{ {
return new SparcTraceChild; return new SparcTraceChild;
} }

View file

@ -45,7 +45,7 @@ struct regs;
class SparcTraceChild : public TraceChild class SparcTraceChild : public TraceChild
{ {
public: public:
enum RegNum enum RegNum
{ {
//Global registers //Global registers
@ -65,7 +65,7 @@ public:
FSR, FPRS, PC, NPC, Y, CWP, PSTATE, ASI, CCR, FSR, FPRS, PC, NPC, Y, CWP, PSTATE, ASI, CCR,
numregs numregs
}; };
private: private:
char printBuffer[256]; char printBuffer[256];
static std::string regNames[numregs]; static std::string regNames[numregs];
regs theregs; regs theregs;
@ -84,26 +84,29 @@ private:
int getTargets(uint32_t inst, uint64_t pc, uint64_t npc, int getTargets(uint32_t inst, uint64_t pc, uint64_t npc,
uint64_t &target1, uint64_t &target2); uint64_t &target1, uint64_t &target2);
protected: protected:
bool update(int pid); bool update(int pid);
public: public:
SparcTraceChild(); SparcTraceChild();
bool sendState(int socket); bool sendState(int socket);
int getNumRegs() int
getNumRegs()
{ {
return numregs; return numregs;
} }
bool diffSinceUpdate(int num) bool
diffSinceUpdate(int num)
{ {
assert(num < numregs && num >= 0); assert(num < numregs && num >= 0);
return regDiffSinceUpdate[num]; return regDiffSinceUpdate[num];
} }
std::string getRegName(int num) std::string
getRegName(int num)
{ {
assert(num < numregs && num >= 0); assert(num < numregs && num >= 0);
return regNames[num]; return regNames[num];
@ -115,12 +118,14 @@ public:
bool step(); bool step();
uint64_t getPC() uint64_t
getPC()
{ {
return getRegVal(PC); return getRegVal(PC);
} }
uint64_t getSP() uint64_t
getSP()
{ {
return getRegVal(O6); return getRegVal(O6);
} }

View file

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

View file

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

View file

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

View file

@ -36,16 +36,17 @@
class RegState class RegState
{ {
protected: protected:
virtual bool update(int pid) = 0; virtual bool update(int pid) = 0;
public: public:
virtual int getNumRegs() = 0; virtual int getNumRegs() = 0;
virtual bool diffSinceUpdate(int num) = 0; virtual bool diffSinceUpdate(int num) = 0;
virtual std::string getRegName(int num) = 0; virtual std::string getRegName(int num) = 0;
virtual int getRegNum(std::string name) virtual int
getRegNum(std::string name)
{ {
int numregs = getNumRegs(); int numregs = getNumRegs();
for(unsigned int x = 0; x < numregs; x++) for (unsigned int x = 0; x < numregs; x++)
if(getRegName(x) == name) if(getRegName(x) == name)
return x; return x;
return -1; return -1;

View file

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

View file

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

View file

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

View file

@ -31,7 +31,6 @@
#if defined __alpha__ #if defined __alpha__
#error "Alpha architecture not implemented" #error "Alpha architecture not implemented"
#elif defined __amd64__ #elif defined __amd64__
// #error "AMD64 architecture not implemented"
#include "arch/tracechild_amd64.cc" #include "arch/tracechild_amd64.cc"
#elif defined __arm__ #elif defined __arm__
#include "arch/tracechild_arm.cc" #include "arch/tracechild_arm.cc"