summaryrefslogtreecommitdiff
path: root/util/statetrace
diff options
context:
space:
mode:
authorAli Saidi <saidi@eecs.umich.edu>2009-07-27 00:53:39 -0700
committerAli Saidi <saidi@eecs.umich.edu>2009-07-27 00:53:39 -0700
commit081b6fe9db97bf3d9e49428dc5e19f27b141a642 (patch)
tree9a8ebef8a1384976b76416e9e31bb0f363786b23 /util/statetrace
parent6835dbce340dcf5c651093229f2decd7f38943e6 (diff)
downloadgem5-081b6fe9db97bf3d9e49428dc5e19f27b141a642.tar.xz
ARM: Add ARM support to statetrace.
Diffstat (limited to 'util/statetrace')
-rw-r--r--util/statetrace/Makefile31
-rw-r--r--util/statetrace/arch/tracechild_arm.cc215
-rw-r--r--util/statetrace/arch/tracechild_arm.hh113
-rw-r--r--util/statetrace/tracechild_arch.cc2
4 files changed, 355 insertions, 6 deletions
diff --git a/util/statetrace/Makefile b/util/statetrace/Makefile
index 2abc06d8e..438828981 100644
--- a/util/statetrace/Makefile
+++ b/util/statetrace/Makefile
@@ -26,12 +26,31 @@
#
# Authors: Gabe Black
-.PHONY: statetrace
+CXX := g++
+INCLUDES := -I ./ -I ./arch
+CXXFLAGS := -O3 -ggdb
-statetrace: statetrace-native
+define build-obj
+$(CXX) -c $(patsubst %.o,%.cc,$@) -o $@ $(INCLUDES) $(CXXFLAGS)
+endef
-statetrace-native: statetrace.cc tracechild.cc tracechild_arch.cc printer.cc printer.hh refcnt.hh regstate.hh tracechild.hh
- g++ statetrace.cc tracechild.cc tracechild_arch.cc printer.cc -I ./ -I ./arch/ -O3 --static -o statetrace
+define final-link
+$(CXX) $(INCLUDES) $(CXXFLAGS) -o $@ $^
+endef
-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 -g -I ./ -I ./arch/ -O3 --static -o statetrace
+all: statetrace
+
+printer.o: printer.cc printer.hh tracechild.hh refcnt.hh regstate.hh
+ $(build-obj)
+statetrace.o: statetrace.cc printer.hh tracechild.hh refcnt.hh regstate.hh
+ $(build-obj)
+tracechild.o: tracechild.cc tracechild.hh regstate.hh
+ $(build-obj)
+tracechild_arch.o: statetrace.cc printer.hh tracechild.hh refcnt.hh regstate.hh arch/tracechild_arm.hh arch/tracechild_arm.cc arch/tracechild_i386.hh arch/tracechild_i386.cc arch/tracechild_amd64.cc arch/tracechild_amd64.hh arch/tracechild_sparc.cc arch/tracechild_sparc.hh
+ $(build-obj)
+
+statetrace: printer.o statetrace.o tracechild.o tracechild_arch.o
+ $(final-link)
+
+clean:
+ rm -f *.o statetrace
diff --git a/util/statetrace/arch/tracechild_arm.cc b/util/statetrace/arch/tracechild_arm.cc
new file mode 100644
index 000000000..fc2eb3e24
--- /dev/null
+++ b/util/statetrace/arch/tracechild_arm.cc
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2006-2009 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: Ali Saidi
+ * Gabe Black
+ */
+
+#include <iostream>
+#include <errno.h>
+#include <stdint.h>
+#include <cstring>
+
+#include "tracechild_arm.hh"
+
+using namespace std;
+
+const char* ARMTraceChild::regNames[numregs] = {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "fp", "r12", "sp", "lr", "pc",
+ "cpsr" };
+
+
+ARMTraceChild::ARMTraceChild()
+{
+ for (int x = 0; x < numregs; x++)
+ regDiffSinceUpdate[x] = false;
+}
+
+bool ARMTraceChild::sendState(int socket)
+{
+ uint32_t regVal = 0;
+ for(int x = 0; x < numregs; x++)
+ {
+ regVal = getRegVal(x);
+ if(write(socket, &regVal, sizeof(regVal)) == -1)
+ {
+ cerr << "Write failed! " << strerror(errno) << endl;
+ tracing = false;
+ return false;
+ }
+
+ }
+
+ return true;
+}
+
+uint32_t ARMTraceChild::getRegs(user_regs &myregs, int num)
+{
+ assert(num < numregs && num >= 0);
+ return myregs.uregs[num];
+}
+
+bool ARMTraceChild::update(int pid)
+{
+ oldregs = regs;
+ if(ptrace(PTRACE_GETREGS, pid, 0, &regs) != 0)
+ {
+ cerr << "update: " << strerror(errno) << endl;
+ return false;
+ }
+
+ for(unsigned int x = 0; x < numregs; x++)
+ regDiffSinceUpdate[x] = (getRegVal(x) != getOldRegVal(x));
+ return true;
+}
+
+int64_t ARMTraceChild::getRegVal(int num)
+{
+ return getRegs(regs, num);
+}
+
+int64_t ARMTraceChild::getOldRegVal(int num)
+{
+ return getRegs(oldregs, num);
+}
+
+char * ARMTraceChild::printReg(int num)
+{
+ sprintf(printBuffer, "0x%08X", (uint32_t)getRegVal(num));
+ return printBuffer;
+}
+
+ostream & ARMTraceChild::outputStartState(ostream & os)
+{
+ uint32_t sp = getSP();
+ uint32_t pc = getPC();
+ uint32_t highestInfo = 0;
+ char obuf[1024];
+ sprintf(obuf, "Initial stack pointer = 0x%08x\n", sp);
+ os << obuf;
+ sprintf(obuf, "Initial program counter = 0x%08x\n", pc);
+ os << obuf;
+
+ //Output the argument count
+ int32_t cargc = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
+ sprintf(obuf, "0x%08x: Argc = 0x%08x\n", sp, cargc);
+ os << obuf;
+ sp += 4;
+
+ //Output argv pointers
+ int argCount = 0;
+ int32_t cargv;
+ do
+ {
+ cargv = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
+ sprintf(obuf, "0x%08x: argv[%d] = 0x%08x\n",
+ sp, argCount++, cargv);
+ if(cargv)
+ if(highestInfo < cargv)
+ highestInfo = cargv;
+ os << obuf;
+ sp += 4;
+ } while(cargv);
+
+ //Output the envp pointers
+ int envCount = 0;
+ uint32_t cenvp;
+ do
+ {
+ cenvp = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
+ sprintf(obuf, "0x%08x: envp[%d] = 0x%08x\n",
+ sp, envCount++, cenvp);
+ os << obuf;
+ sp += 4;
+ } while(cenvp);
+ uint32_t auxType, auxVal;
+ do
+ {
+ auxType = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
+ sp += 4;
+ auxVal = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
+ sp += 4;
+ sprintf(obuf, "0x%08x: Auxiliary vector = {0x%08x, 0x%08x}\n",
+ sp - 8, auxType, auxVal);
+ os << obuf;
+ } while(auxType != 0 || auxVal != 0);
+ //Print out the argument strings, environment strings, and file name.
+ string current;
+ uint32_t buf;
+ uint32_t currentStart = sp;
+ bool clearedInitialPadding = false;
+ do
+ {
+ buf = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
+ char * cbuf = (char *)&buf;
+ for(int x = 0; x < sizeof(uint32_t); x++)
+ {
+ if(cbuf[x])
+ current += cbuf[x];
+ else
+ {
+ sprintf(obuf, "0x%08x: \"%s\"\n",
+ currentStart, current.c_str());
+ os << obuf;
+ current = "";
+ currentStart = sp + x + 1;
+ }
+ }
+ sp += 4;
+ clearedInitialPadding = clearedInitialPadding || buf != 0;
+ } while(!clearedInitialPadding || buf != 0 || sp <= highestInfo);
+ return os;
+}
+
+bool ARMTraceChild::step()
+{
+
+ const uint32_t bkpt_inst = 0xE1200070;
+ const uint32_t bkpt_mask = 0xFFF000F0;
+
+ const uint32_t swi_inst = 0x0F0000000;
+ const uint32_t swi_mask = 0x0F0000000;
+
+ uint32_t next_op = ptrace(PTRACE_PEEKDATA, pid, getPC(), 0);
+ if ((next_op & swi_mask) == swi_inst) {
+ ptrace(PTRACE_POKEDATA, pid, next_op + sizeof(uint32_t), bkpt_inst);
+ ptraceSingleStep();
+ ptrace(PTRACE_POKEDATA, pid, next_op + sizeof(uint32_t), next_op);
+ }
+ else
+ {
+ ptraceSingleStep();
+ }
+}
+
+
+TraceChild * genTraceChild()
+{
+ return new ARMTraceChild;
+}
+
diff --git a/util/statetrace/arch/tracechild_arm.hh b/util/statetrace/arch/tracechild_arm.hh
new file mode 100644
index 000000000..9e1af6a8d
--- /dev/null
+++ b/util/statetrace/arch/tracechild_arm.hh
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2009 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: Ali Saidi
+ * Gabe Black
+ */
+
+#ifndef TRACECHILD_ARM_HH
+#define TRACECHILD_ARM_HH
+
+#include <cassert>
+#include <string>
+#include <sys/user.h>
+#include <sys/ptrace.h>
+#include "tracechild.hh"
+
+
+class ARMTraceChild : public TraceChild
+{
+ public:
+ enum RegNum
+ {
+ // r0 - r3 argument, temp, caller save
+ // r4 - r10 callee save
+ // r11 - FP
+ // r12 - temp
+ // r13 - stack
+ // r14 - link
+ // r15 - pc
+ R0, R1, R2, R3, R4, R5, R6, R7,
+ R8, R9, R10, FP, R12, SP, LR, PC,
+ CPSR,
+ numregs
+ };
+ private:
+ char printBuffer[256];
+ static const char *regNames[numregs];
+ uint32_t getRegs(user_regs& myregs, int num);
+ user_regs regs;
+ user_regs oldregs;
+ bool regDiffSinceUpdate[numregs];
+
+ protected:
+ bool update(int pid);
+
+ public:
+ ARMTraceChild();
+ bool sendState(int socket);
+
+ int getNumRegs()
+ {
+ return numregs;
+ }
+
+ bool diffSinceUpdate(int num)
+ {
+ assert(num < numregs && num >= 0);
+ return regDiffSinceUpdate[num];
+ }
+
+ std::string getRegName(int num)
+ {
+ assert(num < numregs && num >= 0);
+ return regNames[num];
+ }
+
+ int64_t getRegVal(int num);
+ int64_t getOldRegVal(int num);
+
+ bool step();
+
+ uint64_t getPC()
+ {
+ return getRegVal(PC);
+ }
+
+ uint64_t getSP()
+ {
+ return getRegVal(SP);
+ }
+
+ char * printReg(int num);
+
+ std::ostream & outputStartState(std::ostream & os);
+
+};
+
+#endif
+
diff --git a/util/statetrace/tracechild_arch.cc b/util/statetrace/tracechild_arch.cc
index 570a12b54..345de46e8 100644
--- a/util/statetrace/tracechild_arch.cc
+++ b/util/statetrace/tracechild_arch.cc
@@ -33,6 +33,8 @@
#elif defined __amd64__
// #error "AMD64 architecture not implemented"
#include "arch/tracechild_amd64.cc"
+#elif defined __arm__
+ #include "arch/tracechild_arm.cc"
#elif defined __hppa__
#error "Hppa architecture not implemented"
#elif defined __i386__ || defined __i486__ || \