From eab89a09d26fd39cdbb3ddd826465c8661403b89 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 2 Mar 2011 22:53:11 -0800 Subject: Statetrace: Accomodate cross compiling statetrace with scons. --HG-- rename : util/statetrace/arch/tracechild_amd64.cc => util/statetrace/arch/amd64/tracechild.cc rename : util/statetrace/arch/tracechild_amd64.hh => util/statetrace/arch/amd64/tracechild.hh rename : util/statetrace/arch/tracechild_arm.cc => util/statetrace/arch/arm/tracechild.cc rename : util/statetrace/arch/tracechild_arm.hh => util/statetrace/arch/arm/tracechild.hh rename : util/statetrace/arch/tracechild_i386.cc => util/statetrace/arch/i386/tracechild.cc rename : util/statetrace/arch/tracechild_i386.hh => util/statetrace/arch/i386/tracechild.hh rename : util/statetrace/arch/tracechild_sparc.cc => util/statetrace/arch/sparc/tracechild.cc rename : util/statetrace/arch/tracechild_sparc.hh => util/statetrace/arch/sparc/tracechild.hh rename : util/statetrace/tracechild_arch.cc => util/statetrace/base/arch_check.h rename : util/statetrace/regstate.hh => util/statetrace/base/regstate.hh rename : util/statetrace/statetrace.cc => util/statetrace/base/statetrace.cc rename : util/statetrace/tracechild.cc => util/statetrace/base/tracechild.cc rename : util/statetrace/tracechild.hh => util/statetrace/base/tracechild.hh --- util/statetrace/base/arch_check.h | 78 +++++++++++++++++++ util/statetrace/base/regstate.hh | 46 +++++++++++ util/statetrace/base/statetrace.cc | 156 +++++++++++++++++++++++++++++++++++++ util/statetrace/base/tracechild.cc | 147 ++++++++++++++++++++++++++++++++++ util/statetrace/base/tracechild.hh | 62 +++++++++++++++ 5 files changed, 489 insertions(+) create mode 100644 util/statetrace/base/arch_check.h create mode 100644 util/statetrace/base/regstate.hh create mode 100644 util/statetrace/base/statetrace.cc create mode 100644 util/statetrace/base/tracechild.cc create mode 100644 util/statetrace/base/tracechild.hh (limited to 'util/statetrace/base') diff --git a/util/statetrace/base/arch_check.h b/util/statetrace/base/arch_check.h new file mode 100644 index 000000000..db513a08e --- /dev/null +++ b/util/statetrace/base/arch_check.h @@ -0,0 +1,78 @@ +/* + * 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 + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#if defined __STATETRACE_ALPHA__ + #if !defined __alpha__ + #error "Alpha toolchain required." + #endif +#elif defined __STATETRACE_AMD64__ + #if !defined __amd64__ + #error "Amd64 toolchain required." + #endif +#elif defined __STATETRACE_ARM__ + #if !defined __arm__ + #error "Arm toolchain required." + #endif +#elif defined __STATETRACE_HPPA__ + #if !defined __hppa__ + #error "Hppa toolchain required." + #endif +#elif defined __STATETRACE_I386__ + #if !(defined __i386__ || defined __i486__ || \ + defined __i586__ || defined __i686) + #error "I386 toolchain required." + #endif +#elif defined __STATETRACE_IA64__ + #if !defined __ia64__ + #error "IA64 toolchain required." + #endif +#elif defined __STATETRACE_MIPS__ + #if !defined __mips__ + #error "Mips toolchain required." + #endif +#elif defined __STATETRACE_POWERPC__ + #if !defined __powerpc__ + #error "PowerPC toolchain required." + #endif +#elif defined __STATETRACE_SPARC__ + #if !defined __sparc__ + #error "Sparc toolchain required." + #endif +#elif defined __STATETRACE_SH__ + #if !defined __sh__ + #error "SuperH toolchain required." + #endif +#elif defined __STATETRACE__S390__ + #if !defined __s390__ + #error "System/390 toolchain required." + #endif +#else + #error "Couldn't determine architecture." +#endif diff --git a/util/statetrace/base/regstate.hh b/util/statetrace/base/regstate.hh new file mode 100644 index 000000000..bab3485c6 --- /dev/null +++ b/util/statetrace/base/regstate.hh @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#ifndef REGSTATE_H +#define REGSTATE_H + +#include +#include + +class RegState +{ + protected: + virtual bool update(int pid) = 0; + public: + virtual int64_t getRegVal(int num) = 0; + virtual int64_t getOldRegVal(int num) = 0; +}; + +#endif diff --git a/util/statetrace/base/statetrace.cc b/util/statetrace/base/statetrace.cc new file mode 100644 index 000000000..c01147b86 --- /dev/null +++ b/util/statetrace/base/statetrace.cc @@ -0,0 +1,156 @@ +/* + * 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 + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#include "base/arch_check.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tracechild.hh" + +using namespace std; + +void +printUsage(const char * execName) +{ + cout << execName << " -- " << endl; + cout << "options:" << endl; + cout << " -h print this help" << endl; + cout << " --host remote m5 host to connect to" << endl; + cout << " -i print initial stack state" << endl; + cout << " -nt don't print an instruction trace" << endl; +} + +int +main(int argc, char * argv[], char * envp[]) +{ + TraceChild * child = genTraceChild(); + string args; + int startProgramArgs; + + //Parse the command line arguments + bool printInitial = false; + bool printTrace = true; + string host = "localhost"; + + if (argc == 1) { + printUsage(argv[0]); + return 0; + } + for (int x = 1; x < argc; x++) { + if (!strcmp(argv[x], "-h")) { + printUsage(argv[0]); + return 0; + } + if (!strcmp(argv[x], "--host")) { + x++; + if (x >= argc) { + cerr << "Incorrect usage.\n" << endl; + printUsage(argv[0]); + return 1; + } + host = argv[x]; + } else if (!strcmp(argv[x], "-i")) { + printInitial = true; + } else if (!strcmp(argv[x], "-nt")) { + printTrace = false; + } else if (!strcmp(argv[x], "--")) { + x++; + if (x >= argc) { + cerr << "Incorrect usage.\n" << endl; + printUsage(argv[0]); + return 1; + } + startProgramArgs = x; + break; + } else { + cerr << "Incorrect usage.\n" << endl; + printUsage(argv[0]); + return 1; + } + } + if (!child->startTracing(argv[startProgramArgs], + argv + startProgramArgs)) { + cerr << "Couldn't start target program" << endl; + return 1; + } + child->step(); + if (printInitial) + child->outputStartState(cout); + if (printTrace) { + // Connect to m5 + bool portSet = false; + int port; + int sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) { + cerr << "Error opening socket! " << strerror(errno) << endl; + return 1; + } + struct hostent *server; + server = gethostbyname(host.c_str()); + if (!server) { + 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; + } + while (child->isTracing()) { + if (!child->sendState(sock)) + break; + child->step(); + } + } + if (!child->stopTracing()) { + cerr << "Couldn't stop child" << endl; + return 1; + } + return 0; +} + diff --git a/util/statetrace/base/tracechild.cc b/util/statetrace/base/tracechild.cc new file mode 100644 index 000000000..b5665ff37 --- /dev/null +++ b/util/statetrace/base/tracechild.cc @@ -0,0 +1,147 @@ +/* + * 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 + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#include "tracechild.hh" +#include +#include +#include +#include +#include + +using namespace std; + +bool +TraceChild::startTracing(const char * pathToFile, char * const argv[]) +{ + instructions = 0; + pid = fork(); + if (pid == -1) { + cout << "fork failed" << endl; + return false; + } else if (pid == 0) { + //We're the child. Get things ready and then exec the program to trace. + //Let our parent trace us + if (ptrace(PTRACE_TRACEME, 0, 0, 0) == -1) { + cout << "Failure calling TRACEME\n" << strerror(errno) << endl; + return false; + } + + //Set up an empty environment for the child... We would want to + //specify this somehow at some point + char * env[] = {NULL}; + + //Start the program to trace + execve(pathToFile, argv, env); + + //We should never get here, so this is an error! + cout << "Exec failed\n" << strerror(errno) << endl; + return false; + } + + //From this point forward, we know we're in the parent process. + if (!doWait()) { + cout << "Didn't wait successfully" << endl; + return false; + } + tracing = true; + return true; +} + +bool +TraceChild::stopTracing() +{ + if (ptrace(PTRACE_KILL, pid, 0, 0) != 0) + return false; + tracing = false; + return true; +} + +bool +TraceChild::step() +{ + ptraceSingleStep(); +} + +bool +TraceChild::ptraceSingleStep() +{ + if (!tracing) { + cout << "Not tracing!" << endl; + return false; + } + if (ptrace(PTRACE_SINGLESTEP, pid, 0, 0) != 0) { + switch (errno) { + case EBUSY: cout << "EBUSY" << endl; break; + case EFAULT: cout << "EFAULT" << endl; break; + case EIO: cout << "EIO" << endl; break; + case EPERM: cout << "EPERM" << endl; break; + case ESRCH: cout << "ESRCH" << endl; break; + default: cout << "Unknown error" << endl; break; + } + cout << "Not able to single step!" << endl; + tracing == false; + return false; + } + doWait(); + update(pid); +} + +bool +TraceChild::doWait() +{ + int wait_val; + wait(&wait_val); + if (WIFEXITED(wait_val)) { + cerr << "Program exited! Exit status is " + << WEXITSTATUS(wait_val) << endl; + cerr << "Executed " << instructions + << " instructions." << endl; + tracing = false; + return false; + } + if (WIFSIGNALED(wait_val)) { + if (WTERMSIG(wait_val)) + cerr << "Program terminated by signal " + << WTERMSIG(wait_val) << endl; + if (WCOREDUMP(wait_val)) + cerr << "Program core dumped!" << endl; + tracing = false; + cerr << "Executed " << instructions + << " instructions." << endl; + return false; + } + if (WIFSTOPPED(wait_val) && WSTOPSIG(wait_val) != SIGTRAP) { + cerr << "Program stopped by signal " << WSTOPSIG(wait_val) << endl; + tracing = false; + cerr << "Executed " << instructions << " instructions." << endl; + return false; + } + return true; +} diff --git a/util/statetrace/base/tracechild.hh b/util/statetrace/base/tracechild.hh new file mode 100644 index 000000000..bca04b414 --- /dev/null +++ b/util/statetrace/base/tracechild.hh @@ -0,0 +1,62 @@ +/* + * 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 + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#ifndef TRACECHILD_HH +#define TRACECHILD_HH + +#include "base/regstate.hh" + +class TraceChild : public RegState +{ + protected: + int pid; + uint64_t instructions; + bool tracing; + public: + TraceChild() : tracing(false), instructions(0) + {;} + virtual bool sendState(int socket) = 0; + virtual bool startTracing(const char * pathToFile, char * const argv[]); + virtual bool stopTracing(); + virtual bool step(); + virtual std::ostream & outputStartState(std::ostream & os) = 0; + bool + isTracing() + { + return tracing; + } + protected: + bool ptraceSingleStep(); + bool doWait(); +}; + +TraceChild * genTraceChild(); + +#endif -- cgit v1.2.3