Update to statetrace. This will break it, but I want to make sure it gets into mercurial.
--HG-- extra : convert_revision : 6960d2f728c85e99e32bf9b752e45b3cb5e30e3e
This commit is contained in:
parent
ff90b8c1aa
commit
b33f4623ab
6 changed files with 114 additions and 88 deletions
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2006 The Regents of The University of Michigan
|
# Copyright (c) 2006-2007 The Regents of The University of Michigan
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -34,4 +34,4 @@ statetrace-native: statetrace.cc tracechild.cc tracechild_arch.cc printer.cc pri
|
||||||
g++ statetrace.cc tracechild.cc tracechild_arch.cc printer.cc -I ./ -I ./arch/ -O3 --static -o statetrace
|
g++ statetrace.cc tracechild.cc tracechild_arch.cc printer.cc -I ./ -I ./arch/ -O3 --static -o statetrace
|
||||||
|
|
||||||
statetrace-sparc: statetrace.cc tracechild.cc tracechild_arch.cc printer.cc printer.hh refcnt.hh regstate.hh tracechild.hh
|
statetrace-sparc: statetrace.cc tracechild.cc tracechild_arch.cc printer.cc printer.hh refcnt.hh regstate.hh tracechild.hh
|
||||||
sparc64-unknown-linux-gnu-g++ statetrace.cc tracechild.cc tracechild_arch.cc printer.cc -I ./ -I ./arch/ -O3 --static -o statetrace
|
sparc64-unknown-linux-gnu-g++ statetrace.cc tracechild.cc tracechild_arch.cc printer.cc -g -I ./ -I ./arch/ -O3 --static -o statetrace
|
||||||
|
|
|
@ -54,8 +54,45 @@ 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)
|
||||||
|
{
|
||||||
|
uint64_t regVal = 0;
|
||||||
|
for(int x = 0; x <= I7; x++)
|
||||||
|
{
|
||||||
|
regVal = getRegVal(x);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
cerr << "Write failed! " << strerror(errno) << endl;
|
||||||
|
tracing = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
regVal = getRegVal(NPC);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
cerr << "Write failed! " << strerror(errno) << endl;
|
||||||
|
tracing = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t getRegs(regs & myregs, fpu & myfpu,
|
int64_t getRegs(regs & myregs, fpu & myfpu,
|
||||||
int64_t * locals, int64_t * inputs, int num)
|
uint64_t * locals, uint64_t * inputs, int num)
|
||||||
{
|
{
|
||||||
assert(num < SparcTraceChild::numregs && num >= 0);
|
assert(num < SparcTraceChild::numregs && num >= 0);
|
||||||
switch(num)
|
switch(num)
|
||||||
|
@ -160,14 +197,19 @@ bool SparcTraceChild::update(int pid)
|
||||||
cerr << "Update failed" << endl;
|
cerr << "Update failed" << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
uint64_t StackPointer = getSP();
|
uint64_t stackPointer = getSP();
|
||||||
const int stackBias = (StackPointer % 1) ? 2047 : 0;
|
uint64_t stackBias = 2047;
|
||||||
|
bool v9 = stackPointer % 2;
|
||||||
for(unsigned int x = 0; x < 8; x++)
|
for(unsigned int x = 0; x < 8; x++)
|
||||||
{
|
{
|
||||||
locals[x] = ptrace(PTRACE_PEEKTEXT, pid,
|
uint64_t localAddr = stackPointer +
|
||||||
StackPointer + stackBias + x * 8, 0);
|
(v9 ? (stackBias + x * 8) : (x * 4));
|
||||||
inputs[x] = ptrace(PTRACE_PEEKTEXT, pid,
|
locals[x] = ptrace(PTRACE_PEEKTEXT, pid, localAddr, 0);
|
||||||
StackPointer + stackBias + x * 8 + (8 * 8), 0);
|
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(ptrace(PTRACE_GETFPREGS, pid, &thefpregs, 0) != 0)
|
if(ptrace(PTRACE_GETFPREGS, pid, &thefpregs, 0) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
@ -366,7 +408,7 @@ ostream & SparcTraceChild::outputStartState(ostream & os)
|
||||||
{
|
{
|
||||||
bool v8 = false;
|
bool v8 = false;
|
||||||
uint64_t sp = getSP();
|
uint64_t sp = getSP();
|
||||||
if(sp % 1)
|
if(sp % 2)
|
||||||
{
|
{
|
||||||
os << "Detected a 64 bit executable.\n";
|
os << "Detected a 64 bit executable.\n";
|
||||||
v8 = false;
|
v8 = false;
|
||||||
|
|
|
@ -72,10 +72,10 @@ private:
|
||||||
regs oldregs;
|
regs oldregs;
|
||||||
fpu thefpregs;
|
fpu thefpregs;
|
||||||
fpu oldfpregs;
|
fpu oldfpregs;
|
||||||
int64_t locals[8];
|
uint64_t locals[8];
|
||||||
int64_t oldLocals[8];
|
uint64_t oldLocals[8];
|
||||||
int64_t inputs[8];
|
uint64_t inputs[8];
|
||||||
int64_t oldInputs[8];
|
uint64_t oldInputs[8];
|
||||||
bool regDiffSinceUpdate[numregs];
|
bool regDiffSinceUpdate[numregs];
|
||||||
|
|
||||||
//This calculates where the pc might go after the current instruction.
|
//This calculates where the pc might go after the current instruction.
|
||||||
|
@ -90,6 +90,8 @@ protected:
|
||||||
public:
|
public:
|
||||||
SparcTraceChild();
|
SparcTraceChild();
|
||||||
|
|
||||||
|
bool sendState(int socket);
|
||||||
|
|
||||||
int getNumRegs()
|
int getNumRegs()
|
||||||
{
|
{
|
||||||
return numregs;
|
return numregs;
|
||||||
|
|
|
@ -35,88 +35,48 @@
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/ptrace.h>
|
#include <sys/ptrace.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include "tracechild.hh"
|
|
||||||
#include "printer.hh"
|
#include "printer.hh"
|
||||||
|
#include "tracechild.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
void printUsage(const char * execName)
|
void printUsage(const char * execName)
|
||||||
{
|
{
|
||||||
cout << execName << " -f <output format file> | -h | -r -- <command> <arguments>" << endl;
|
cout << execName << " -h | -r -- <command> <arguments>" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char * argv[], char * envp[])
|
int main(int argc, char * argv[], char * envp[])
|
||||||
{
|
{
|
||||||
TraceChild * child = genTraceChild();
|
TraceChild * child = genTraceChild();
|
||||||
NestingPrinter printer(child);
|
|
||||||
string args;
|
string args;
|
||||||
int startProgramArgs;
|
int startProgramArgs;
|
||||||
|
|
||||||
//Parse the command line arguments
|
//Parse the command line arguments
|
||||||
bool formatStringSet = false;
|
|
||||||
bool printInitial = false;
|
bool printInitial = false;
|
||||||
bool printTrace = true;
|
bool printTrace = true;
|
||||||
string format;
|
|
||||||
for(int x = 1; x < argc; x++)
|
for(int x = 1; x < argc; x++)
|
||||||
{
|
{
|
||||||
if(!strcmp(argv[x], "-f"))
|
if(!strcmp(argv[x], "-h"))
|
||||||
{
|
|
||||||
if(formatStringSet)
|
|
||||||
{
|
|
||||||
cerr << "Attempted to set format twice!"
|
|
||||||
<< endl;
|
|
||||||
printUsage(argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
formatStringSet = true;
|
|
||||||
x++;
|
|
||||||
if(x >= argc)
|
|
||||||
{
|
|
||||||
cerr << "Incorrect usage.\n" << endl;
|
|
||||||
printUsage(argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
ifstream formatFile(argv[x]);
|
|
||||||
if(!formatFile)
|
|
||||||
{
|
|
||||||
cerr << "Problem opening file "
|
|
||||||
<< argv[x] << "." << endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
format = "";
|
|
||||||
while(formatFile)
|
|
||||||
{
|
|
||||||
string line;
|
|
||||||
getline(formatFile, line);
|
|
||||||
if(formatFile.eof())
|
|
||||||
{
|
|
||||||
format += line;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(!formatFile)
|
|
||||||
{
|
|
||||||
cerr << "Problem reading from file "
|
|
||||||
<< argv[x] << "." << endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
format += line + '\n';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(!strcmp(argv[x], "-h"))
|
|
||||||
{
|
{
|
||||||
printUsage(argv[0]);
|
printUsage(argv[0]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
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"))
|
||||||
{
|
{
|
||||||
|
@ -145,11 +105,6 @@ int main(int argc, char * argv[], char * envp[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*for(unsigned int x = startProgramArgs; x < argc; x++)
|
|
||||||
{
|
|
||||||
cout << "Adding argument " << argv[x];
|
|
||||||
args += string(" ") + argv[x];
|
|
||||||
}*/
|
|
||||||
if(!child->startTracing(argv[startProgramArgs],
|
if(!child->startTracing(argv[startProgramArgs],
|
||||||
argv + startProgramArgs))
|
argv + startProgramArgs))
|
||||||
{
|
{
|
||||||
|
@ -162,26 +117,41 @@ int main(int argc, char * argv[], char * envp[])
|
||||||
}
|
}
|
||||||
if(printTrace)
|
if(printTrace)
|
||||||
{
|
{
|
||||||
if(!formatStringSet)
|
// Connect to m5
|
||||||
|
bool portSet = false;
|
||||||
|
int port;
|
||||||
|
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if(sock < 0)
|
||||||
{
|
{
|
||||||
cerr << "No output format set!" << endl;
|
cerr << "Error opening socket! " << strerror(errno) << endl;
|
||||||
child->stopTracing();
|
return 1;
|
||||||
printUsage(argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
if(!printer.configure(format))
|
struct hostent *server;
|
||||||
|
server = gethostbyname("zower.eecs.umich.edu");
|
||||||
|
if(!server)
|
||||||
{
|
{
|
||||||
cerr << "Problem in the output format" << endl;
|
cerr << "Couldn't get host ip! " << strerror(errno) << endl;
|
||||||
child->stopTracing();
|
return 1;
|
||||||
return 1;
|
}
|
||||||
|
struct sockaddr_in serv_addr;
|
||||||
|
bzero((char *)&serv_addr, sizeof(serv_addr));
|
||||||
|
serv_addr.sin_family = AF_INET;
|
||||||
|
bcopy((char *)server->h_addr,
|
||||||
|
(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)
|
||||||
|
{
|
||||||
|
cerr << "Couldn't connect to server! " << strerror(errno) << endl;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
child->step();
|
child->step();
|
||||||
while(child->isTracing())
|
while(child->isTracing())
|
||||||
{
|
{
|
||||||
cout << printer;
|
if(!child->sendState(sock))
|
||||||
|
break;
|
||||||
child->step();
|
child->step();
|
||||||
}
|
}
|
||||||
cout << printer;
|
|
||||||
}
|
}
|
||||||
if(!child->stopTracing())
|
if(!child->stopTracing())
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,12 +51,23 @@ bool TraceChild::startTracing(const char * pathToFile, char * const argv[])
|
||||||
//program to trace.
|
//program to trace.
|
||||||
|
|
||||||
//Let our parent trace us
|
//Let our parent trace us
|
||||||
ptrace(PTRACE_TRACEME, 0, 0, 0);
|
if(ptrace(PTRACE_TRACEME, 0, 0, 0) == -1)
|
||||||
|
{
|
||||||
|
cout << "Failure calling TRACEME\n";
|
||||||
|
cout << strerror(errno) << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set up an empty environment for the child...
|
||||||
|
//We would want to specify this somehow at some point
|
||||||
|
char * env[] = {NULL};
|
||||||
|
|
||||||
//Start the program to trace
|
//Start the program to trace
|
||||||
execv(pathToFile, argv);
|
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 << strerror(errno) << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
TraceChild() : tracing(false), instructions(0)
|
TraceChild() : tracing(false), instructions(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();
|
||||||
|
|
Loading…
Reference in a new issue