-# Copyright (c) 2006 The Regents of The University of Michigan
+# Copyright (c) 2006-2007 The Regents of The University of Michigan
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
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
- 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
//Miscelaneous
"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 * locals, int64_t * inputs, int num)
+ uint64_t * locals, uint64_t * inputs, int num)
{
assert(num < SparcTraceChild::numregs && num >= 0);
switch(num)
cerr << "Update failed" << endl;
return false;
}
- uint64_t StackPointer = getSP();
- const int stackBias = (StackPointer % 1) ? 2047 : 0;
+ uint64_t stackPointer = getSP();
+ uint64_t stackBias = 2047;
+ bool v9 = stackPointer % 2;
for(unsigned int x = 0; x < 8; x++)
{
- locals[x] = ptrace(PTRACE_PEEKTEXT, pid,
- StackPointer + stackBias + x * 8, 0);
- inputs[x] = ptrace(PTRACE_PEEKTEXT, pid,
- StackPointer + stackBias + x * 8 + (8 * 8), 0);
+ uint64_t localAddr = stackPointer +
+ (v9 ? (stackBias + x * 8) : (x * 4));
+ locals[x] = ptrace(PTRACE_PEEKTEXT, pid, localAddr, 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)
return false;
{
bool v8 = false;
uint64_t sp = getSP();
- if(sp % 1)
+ if(sp % 2)
{
os << "Detected a 64 bit executable.\n";
v8 = false;
regs oldregs;
fpu thefpregs;
fpu oldfpregs;
- int64_t locals[8];
- int64_t oldLocals[8];
- int64_t inputs[8];
- int64_t oldInputs[8];
+ 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.
public:
SparcTraceChild();
+ bool sendState(int socket);
+
int getNumRegs()
{
return numregs;
#include <sys/wait.h>
#include <sys/ptrace.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 "tracechild.hh"
using namespace std;
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[])
{
TraceChild * child = genTraceChild();
- NestingPrinter printer(child);
string args;
int startProgramArgs;
//Parse the command line arguments
- bool formatStringSet = false;
bool printInitial = false;
bool printTrace = true;
- string format;
for(int x = 1; x < argc; x++)
{
- if(!strcmp(argv[x], "-f"))
- {
- 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"))
+ if(!strcmp(argv[x], "-h"))
{
printUsage(argv[0]);
return 0;
}
else if(!strcmp(argv[x], "-r"))
{
- cout << "Legal register names:" << endl;
- int numRegs = child->getNumRegs();
- for(unsigned int x = 0; x < numRegs; x++)
- {
- cout << "\t" << child->getRegName(x) << endl;
- }
- return 0;
+ cout << "Legal register names:" << endl;
+ int numRegs = child->getNumRegs();
+ for(unsigned int x = 0; x < numRegs; x++)
+ {
+ cout << "\t" << child->getRegName(x) << endl;
+ }
+ return 0;
}
else if(!strcmp(argv[x], "-i"))
{
return 1;
}
}
- /*for(unsigned int x = startProgramArgs; x < argc; x++)
- {
- cout << "Adding argument " << argv[x];
- args += string(" ") + argv[x];
- }*/
if(!child->startTracing(argv[startProgramArgs],
argv + startProgramArgs))
{
}
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;
- child->stopTracing();
- printUsage(argv[0]);
- return 1;
+ cerr << "Error opening socket! " << strerror(errno) << endl;
+ return 1;
}
- if(!printer.configure(format))
+ struct hostent *server;
+ server = gethostbyname("zower.eecs.umich.edu");
+ if(!server)
{
- cerr << "Problem in the output format" << endl;
- child->stopTracing();
- return 1;
+ cerr << "Couldn't get host ip! " << strerror(errno) << endl;
+ 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();
while(child->isTracing())
{
- cout << printer;
+ if(!child->sendState(sock))
+ break;
child->step();
}
- cout << printer;
}
if(!child->stopTracing())
{
//program to trace.
//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
- execv(pathToFile, argv);
+ execve(pathToFile, argv, env);
//We should never get here, so this is an error!
+ cout << "Exec failed\n";
+ cout << strerror(errno) << endl;
return false;
}
public:
TraceChild() : tracing(false), instructions(0)
{;}
+ virtual bool sendState(int socket) = 0;
virtual bool startTracing(const char * pathToFile,
char * const argv[]);
virtual bool stopTracing();