Merge zizzer.eecs.umich.edu:/bk/newmem

into  zower.eecs.umich.edu:/home/gblack/m5/newmem-statetrace

--HG--
extra : convert_revision : c886266320e6c1352e359d5abf6fb3a804f81451
This commit is contained in:
Gabe Black 2007-03-15 06:10:59 -04:00
commit 47c8d9d346
6 changed files with 114 additions and 88 deletions

View file

@ -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

View file

@ -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, &regVal, sizeof(regVal)) == -1)
{
cerr << "Write failed! " << strerror(errno) << endl;
tracing = false;
return false;
}
}
regVal = getRegVal(PC);
if(write(socket, &regVal, sizeof(regVal)) == -1)
{
cerr << "Write failed! " << strerror(errno) << endl;
tracing = false;
return false;
}
regVal = getRegVal(NPC);
if(write(socket, &regVal, sizeof(regVal)) == -1)
{
cerr << "Write failed! " << strerror(errno) << endl;
tracing = false;
return false;
}
regVal = getRegVal(CCR);
if(write(socket, &regVal, 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;

View file

@ -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;

View file

@ -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())
{ {

View file

@ -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;
} }

View file

@ -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();