summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKorey Sewell <ksewell@umich.edu>2009-07-31 10:40:42 -0400
committerKorey Sewell <ksewell@umich.edu>2009-07-31 10:40:42 -0400
commitaa75b9a7a7489bf86c4e6d406ff612e596ddff96 (patch)
tree58a6816583a21c19c181e32bff10bf74aa9ad15f
parent60063cc700912666fa8b7968d692d00a1e82cb67 (diff)
parent3dd3de5feb31055a48acb39575da25a9cea2626d (diff)
downloadgem5-aa75b9a7a7489bf86c4e6d406ff612e596ddff96.tar.xz
merge mips fix and statetrace changes
-rw-r--r--src/arch/arm/ArmNativeTrace.py37
-rw-r--r--src/arch/arm/SConscript3
-rw-r--r--src/arch/arm/isa.hh6
-rw-r--r--src/arch/arm/isa/decoder.isa26
-rw-r--r--src/arch/arm/isa/formats/pred.isa6
-rw-r--r--src/arch/arm/isa/operands.isa8
-rw-r--r--src/arch/arm/linux/linux.hh73
-rw-r--r--src/arch/arm/linux/process.cc10
-rw-r--r--src/arch/arm/miscregs.hh3
-rw-r--r--src/arch/arm/nativetrace.cc183
-rw-r--r--src/arch/arm/nativetrace.hh112
-rw-r--r--src/arch/arm/process.cc240
-rwxr-xr-xsrc/arch/mips/mt.hh2
-rw-r--r--src/base/loader/elf_object.cc4
-rw-r--r--src/base/loader/object_file.hh3
-rw-r--r--src/cpu/NativeTrace.py4
-rw-r--r--src/cpu/nativetrace.cc2
-rw-r--r--src/cpu/nativetrace.hh8
-rw-r--r--src/cpu/simple_thread.hh5
-rw-r--r--src/sim/process.cc4
-rw-r--r--src/sim/process.hh4
-rwxr-xr-xtests/quick/00.hello/ref/arm/linux/simple-atomic/simerr4
-rwxr-xr-xtests/quick/00.hello/ref/arm/linux/simple-atomic/simout9
-rw-r--r--tests/quick/00.hello/ref/arm/linux/simple-atomic/stats.txt22
-rwxr-xr-xtests/test-progs/hello/bin/arm/linux/hellobin558673 -> 565961 bytes
-rw-r--r--util/statetrace/Makefile31
-rw-r--r--util/statetrace/arch/tracechild_arm.cc236
-rw-r--r--util/statetrace/arch/tracechild_arm.hh113
-rw-r--r--util/statetrace/statetrace.cc32
-rw-r--r--util/statetrace/tracechild.cc12
-rw-r--r--util/statetrace/tracechild_arch.cc2
31 files changed, 1076 insertions, 128 deletions
diff --git a/src/arch/arm/ArmNativeTrace.py b/src/arch/arm/ArmNativeTrace.py
new file mode 100644
index 000000000..0a76913e3
--- /dev/null
+++ b/src/arch/arm/ArmNativeTrace.py
@@ -0,0 +1,37 @@
+# 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: Gabe Black
+
+from m5.SimObject import SimObject
+from m5.params import *
+from NativeTrace import NativeTrace
+
+class ArmNativeTrace(NativeTrace):
+ type = 'ArmNativeTrace'
+ cxx_class = 'Trace::ArmNativeTrace'
+ stop_on_pc_error = Param.Bool(True,
+ "Stop M5 if it and statetrace's pcs are different")
diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript
index 519435489..55ecabdc3 100644
--- a/src/arch/arm/SConscript
+++ b/src/arch/arm/SConscript
@@ -39,11 +39,14 @@ if env['TARGET_ISA'] == 'arm':
Source('insts/mem.cc')
Source('insts/pred_inst.cc')
Source('insts/static_inst.cc')
+ Source('nativetrace.cc')
Source('pagetable.cc')
Source('tlb.cc')
Source('vtophys.cc')
+ SimObject('ArmNativeTrace.py')
SimObject('ArmTLB.py')
+
TraceFlag('Arm')
if env['FULL_SYSTEM']:
diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh
index 39acc9c08..2315afa9e 100644
--- a/src/arch/arm/isa.hh
+++ b/src/arch/arm/isa.hh
@@ -48,7 +48,11 @@ namespace ArmISA
public:
void clear()
{
- // Unknown startup state currently
+ memset(miscRegs, 0, sizeof(miscRegs));
+ CPSR cpsr = 0;
+ cpsr.mode = MODE_USER;
+ miscRegs[MISCREG_CPSR] = cpsr;
+ //XXX We need to initialize the rest of the state.
}
MiscReg
diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa
index 76d584858..a999b52e9 100644
--- a/src/arch/arm/isa/decoder.isa
+++ b/src/arch/arm/isa/decoder.isa
@@ -113,8 +113,7 @@ format DataOp {
0x1: decode OPCODE {
0x9: BranchExchange::bx({{ }});
0xb: PredOp::clz({{
- unsigned lsb = findLsbSet(Rm);
- Rd = (lsb > 31) ? 32 : lsb;
+ Rd = ((Rm == 0) ? 32 : (31 - findMsbSet(Rm)));
}});
}
0x2: decode OPCODE {
@@ -319,6 +318,10 @@ format DataOp {
0x12,0x16,0x1a,0x1e: ArmMacroFMOp::sfm_pw({{ }});
0x13,0x17,0x1b,0x1f: ArmMacroFMOp::lfm_pw({{ }});
}
+ 0xb: decode LOADOP {
+ 0x0: WarnUnimpl::fstmx();
+ 0x1: WarnUnimpl::fldmx();
+ }
}
0x7: decode OPCODE_24 {
0: decode CPNUM {
@@ -417,12 +420,29 @@ format DataOp {
}
}
}
+ 0xa: decode MISC_OPCODE {
+ 0x1: decode MEDIA_OPCODE {
+ 0xf: decode RN {
+ 0x0: FloatOp::fmrx_fpsid({{ Rd = Fpsid; }});
+ 0x1: FloatOp::fmrx_fpscr({{ Rd = Fpscr; }});
+ 0x8: FloatOp::fmrx_fpexc({{ Rd = Fpexc; }});
+ }
+ 0xe: decode RN {
+ 0x0: FloatOp::fmxr_fpsid({{ Fpsid = Rd; }});
+ 0x1: FloatOp::fmxr_fpscr({{ Fpscr = Rd; }});
+ 0x8: FloatOp::fmxr_fpexc({{ Fpexc = Rd; }});
+ }
+ }
+ }
}
format PredOp {
// ARM System Call (SoftWare Interrupt)
1: swi({{ if (testPredicate(Cpsr, condCode))
{
- xc->syscall(IMMED_23_0);
+ if (IMMED_23_0)
+ xc->syscall(IMMED_23_0);
+ else
+ xc->syscall(R7);
}
}});
}
diff --git a/src/arch/arm/isa/formats/pred.isa b/src/arch/arm/isa/formats/pred.isa
index 50e162f3d..e90788c91 100644
--- a/src/arch/arm/isa/formats/pred.isa
+++ b/src/arch/arm/isa/formats/pred.isa
@@ -105,7 +105,8 @@ let {{
def getCcCode(flagtype):
icReg = icImm = iv = ''
if flagtype == "none":
- icReg = icImm = iv = '1'
+ icReg = icImm = 'Cpsr<29:>'
+ iv = 'Cpsr<28:>'
elif flagtype == "add":
icReg = icImm = 'findCarry(32, resTemp, Rn, op2)'
iv = 'findOverflow(32, resTemp, Rn, op2)'
@@ -125,7 +126,8 @@ let {{
def getImmCcCode(flagtype):
ivValue = icValue = ''
if flagtype == "none":
- icValue = ivValue = '1'
+ icValue = 'Cpsr<29:>'
+ ivValue = 'Cpsr<28:>'
elif flagtype == "add":
icValue = 'findCarry(32, resTemp, Rn, rotated_imm)'
ivValue = 'findOverflow(32, resTemp, Rn, rotated_imm)'
diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa
index fa41918c1..ac7427dad 100644
--- a/src/arch/arm/isa/operands.isa
+++ b/src/arch/arm/isa/operands.isa
@@ -57,6 +57,7 @@ def operands {{
'Rm': ('IntReg', 'uw', 'RM', 'IsInteger', 2, maybePCRead, maybePCWrite),
'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 3, maybePCRead, maybePCWrite),
'Rn': ('IntReg', 'uw', 'RN', 'IsInteger', 4, maybePCRead, maybePCWrite),
+ 'R7': ('IntReg', 'uw', '7', 'IsInteger', 5),
#Destination register for load/store double instructions
'Rdo': ('IntReg', 'uw', '(RD & ~1)', 'IsInteger', 4, maybePCRead, maybePCWrite),
@@ -81,7 +82,10 @@ def operands {{
'Cpsr': ('ControlReg', 'uw', 'MISCREG_CPSR', 'IsInteger', 40),
'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', 'IsInteger', 41),
- 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 42),
- 'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 43),
+ 'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', 'IsInteger', 42),
+ 'Fpscr': ('ControlReg', 'uw', 'MISCREG_FPSCR', 'IsInteger', 43),
+ 'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', 'IsInteger', 44),
+ 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 45),
+ 'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 46)
}};
diff --git a/src/arch/arm/linux/linux.hh b/src/arch/arm/linux/linux.hh
index 16bcee47a..d99fa8e49 100644
--- a/src/arch/arm/linux/linux.hh
+++ b/src/arch/arm/linux/linux.hh
@@ -66,18 +66,7 @@ class ArmLinux : public Linux
//@}
/// For mmap().
- static const unsigned TGT_MAP_ANONYMOUS = 0x800;
-
- //@{
- /// For getsysinfo().
- static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string
- static const unsigned GSI_CPU_INFO = 59; //!< CPU information
- static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type
- static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine
- static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system
- static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB
- static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz
- //@}
+ static const unsigned TGT_MAP_ANONYMOUS = 0x20;
//@{
/// For getrusage().
@@ -87,13 +76,8 @@ class ArmLinux : public Linux
//@}
//@{
- /// For setsysinfo().
- static const unsigned SSI_IEEE_FP_CONTROL = 14; //!< ieee_set_fp_control()
- //@}
-
- //@{
/// ioctl() command codes.
- static const unsigned TIOCGETP_ = 0x40067408;
+ static const unsigned TIOCGETP_ = 0x5401;
static const unsigned TIOCSETP_ = 0x80067409;
static const unsigned TIOCSETN_ = 0x8006740a;
static const unsigned TIOCSETC_ = 0x80067411;
@@ -114,15 +98,56 @@ class ArmLinux : public Linux
TGT_RLIMIT_DATA = 2,
TGT_RLIMIT_STACK = 3,
TGT_RLIMIT_CORE = 4,
- TGT_RLIMIT_NOFILE = 5,
- TGT_RLIMIT_AS = 6,
- TGT_RLIMIT_RSS = 7,
- TGT_RLIMIT_VMEM = 7,
- TGT_RLIMIT_NPROC = 8,
- TGT_RLIMIT_MEMLOCK = 9,
+ TGT_RLIMIT_RSS = 5,
+ TGT_RLIMIT_NPROC = 6,
+ TGT_RLIMIT_NOFILE = 7,
+ TGT_RLIMIT_MEMLOCK = 8,
+ TGT_RLIMIT_AS = 9,
TGT_RLIMIT_LOCKS = 10
};
+ typedef struct {
+ uint32_t st_dev;
+ uint32_t st_ino;
+ uint16_t st_mode;
+ uint16_t st_nlink;
+ uint16_t st_uid;
+ uint16_t st_gid;
+ uint32_t st_rdev;
+ uint32_t st_size;
+ uint32_t st_blksize;
+ uint32_t st_blocks;
+ uint32_t st_atimeX;
+ uint32_t st_atime_nsec;
+ uint32_t st_mtimeX;
+ uint32_t st_mtime_nsec;
+ uint32_t st_ctimeX;
+ uint32_t st_ctime_nsec;
+ } tgt_stat;
+
+ typedef struct {
+ uint64_t st_dev;
+ uint8_t __pad0[4];
+ uint32_t __st_ino;
+ uint32_t st_mode;
+ uint32_t st_nlink;
+ uint32_t st_uid;
+ uint32_t st_gid;
+ uint64_t st_rdev;
+ uint8_t __pad3[4];
+ int64_t __attribute__ ((aligned (8))) st_size;
+ uint32_t st_blksize;
+ uint64_t __attribute__ ((aligned (8))) st_blocks;
+ uint32_t st_atimeX;
+ uint32_t st_atime_nsec;
+ uint32_t st_mtimeX;
+ uint32_t st_mtime_nsec;
+ uint32_t st_ctimeX;
+ uint32_t st_ctime_nsec;
+ uint64_t st_ino;
+ } tgt_stat64;
+
+
};
#endif
diff --git a/src/arch/arm/linux/process.cc b/src/arch/arm/linux/process.cc
index 7158acfff..56e3588a7 100644
--- a/src/arch/arm/linux/process.cc
+++ b/src/arch/arm/linux/process.cc
@@ -106,7 +106,7 @@ SyscallDesc ArmLinuxProcess::syscallDescs[] = {
/* 40 */ SyscallDesc("rmdir", unimplementedFunc),
/* 41 */ SyscallDesc("dup", unimplementedFunc),
/* 42 */ SyscallDesc("pipe", unimplementedFunc),
- /* 43 */ SyscallDesc("times", unimplementedFunc),
+ /* 43 */ SyscallDesc("times", ignoreFunc),
/* 44 */ SyscallDesc("prof", unimplementedFunc),
/* 45 */ SyscallDesc("brk", brkFunc),
/* 46 */ SyscallDesc("setgid", unimplementedFunc),
@@ -260,7 +260,7 @@ SyscallDesc ArmLinuxProcess::syscallDescs[] = {
/* 194 */ SyscallDesc("ftruncate64", unimplementedFunc),
/* 195 */ SyscallDesc("stat64", unimplementedFunc),
/* 196 */ SyscallDesc("lstat64", lstat64Func<ArmLinux>),
- /* 197 */ SyscallDesc("fstat64", fstatFunc<ArmLinux>),
+ /* 197 */ SyscallDesc("fstat64", fstat64Func<ArmLinux>),
/* 198 */ SyscallDesc("lchown", unimplementedFunc),
/* 199 */ SyscallDesc("getuid", getuidFunc),
/* 200 */ SyscallDesc("getgid", getgidFunc),
@@ -418,7 +418,6 @@ setTLSFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
uint32_t tlsPtr = process->getSyscallArg(tc, 0);
- TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
tc->getMemPort()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0,
(uint8_t *)&tlsPtr, sizeof(tlsPtr));
@@ -448,7 +447,8 @@ ArmLinuxProcess::getDesc(int callnum)
// Angel SWI syscalls are unsupported in this release
if (callnum == 0x123456) {
panic("Attempt to execute an ANGEL_SWI system call (newlib-related)");
- } else if ((callnum & 0x00f00000) == 0x00900000) {
+ } else if ((callnum & 0x00f00000) == 0x00900000 ||
+ (callnum & 0xf0000) == 0xf0000) {
callnum &= 0x000fffff;
if ((callnum & 0x0f0000) == 0xf0000) {
callnum -= 0x0f0001;
@@ -496,7 +496,7 @@ ArmLinuxProcess::startup()
{
0x00, 0x30, 0x92, 0xe5, //ldr r3, [r2]
0x00, 0x30, 0x53, 0xe0, //subs r3, r3, r0
- 0x00, 0x10, 0x92, 0x05, //streq r1, [r2]
+ 0x00, 0x10, 0x82, 0x05, //streq r1, [r2]
0x03, 0x00, 0xa0, 0xe1, //mov r0, r3
0x0e, 0xf0, 0xa0, 0xe1 //usr_ret lr
};
diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh
index 42065b0fd..3180669de 100644
--- a/src/arch/arm/miscregs.hh
+++ b/src/arch/arm/miscregs.hh
@@ -62,6 +62,9 @@ namespace ArmISA
MISCREG_SPSR_UND,
MISCREG_SPSR_ABT,
MISCREG_FPSR,
+ MISCREG_FPSID,
+ MISCREG_FPSCR,
+ MISCREG_FPEXC,
NUM_MISCREGS
};
diff --git a/src/arch/arm/nativetrace.cc b/src/arch/arm/nativetrace.cc
new file mode 100644
index 000000000..1ad9e1a19
--- /dev/null
+++ b/src/arch/arm/nativetrace.cc
@@ -0,0 +1,183 @@
+/*
+ * 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
+ */
+
+#include "arch/arm/isa_traits.hh"
+#include "arch/arm/miscregs.hh"
+#include "arch/arm/nativetrace.hh"
+#include "cpu/thread_context.hh"
+#include "params/ArmNativeTrace.hh"
+
+namespace Trace {
+
+#if TRACING_ON
+static const char *regNames[] = {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "fp", "r12", "sp", "lr", "pc",
+ "cpsr"
+};
+#endif
+
+void
+Trace::ArmNativeTrace::ThreadState::update(NativeTrace *parent)
+{
+ oldState = state[current];
+ current = (current + 1) % 2;
+ newState = state[current];
+
+ memcpy(newState, oldState, sizeof(state[0]));
+
+ uint32_t diffVector;
+ parent->read(&diffVector, sizeof(diffVector));
+ diffVector = ArmISA::gtoh(diffVector);
+
+ int changes = 0;
+ for (int i = 0; i < STATE_NUMVALS; i++) {
+ if (diffVector & 0x1) {
+ changed[i] = true;
+ changes++;
+ } else {
+ changed[i] = false;
+ }
+ diffVector >>= 1;
+ }
+
+ uint32_t values[changes];
+ parent->read(values, sizeof(values));
+ int pos = 0;
+ for (int i = 0; i < STATE_NUMVALS; i++) {
+ if (changed[i]) {
+ newState[i] = ArmISA::gtoh(values[pos++]);
+ changed[i] = (newState[i] != oldState[i]);
+ }
+ }
+}
+
+void
+Trace::ArmNativeTrace::ThreadState::update(ThreadContext *tc)
+{
+ oldState = state[current];
+ current = (current + 1) % 2;
+ newState = state[current];
+
+ // Regular int regs
+ for (int i = 0; i < 15; i++) {
+ newState[i] = tc->readIntReg(i);
+ changed[i] = (oldState[i] != newState[i]);
+ }
+
+ //R15, aliased with the PC
+ newState[STATE_PC] = tc->readNextPC();
+ changed[STATE_PC] = (newState[STATE_PC] != oldState[STATE_PC]);
+
+ //CPSR
+ newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR);
+ changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]);
+}
+
+void
+Trace::ArmNativeTrace::check(NativeTraceRecord *record)
+{
+ ThreadContext *tc = record->getThread();
+ // This area is read only on the target. It can't stop there to tell us
+ // what's going on, so we should skip over anything there also.
+ if (tc->readNextPC() > 0xffff0000)
+ return;
+ nState.update(this);
+ mState.update(tc);
+
+ bool errorFound = false;
+ // Regular int regs
+ for (int i = 0; i < STATE_NUMVALS; i++) {
+ if (nState.changed[i] || mState.changed[i]) {
+ const char *vergence = " ";
+ bool oldMatch = (mState.oldState[i] == nState.oldState[i]);
+ bool newMatch = (mState.newState[i] == nState.newState[i]);
+ if (oldMatch && newMatch) {
+ // The more things change, the more they stay the same.
+ continue;
+ } else if (oldMatch && !newMatch) {
+ vergence = "<>";
+ } else if (!oldMatch && newMatch) {
+ vergence = "><";
+ }
+ errorFound = true;
+ if (!nState.changed[i]) {
+ DPRINTF(ExecRegDelta, "%s [%5s] "\
+ "Native: %#010x "\
+ "M5: %#010x => %#010x\n",
+ vergence, regNames[i],
+ nState.newState[i],
+ mState.oldState[i], mState.newState[i]);
+ } else if (!mState.changed[i]) {
+ DPRINTF(ExecRegDelta, "%s [%5s] "\
+ "Native: %#010x => %#010x "\
+ "M5: %#010x \n",
+ vergence, regNames[i],
+ nState.oldState[i], nState.newState[i],
+ mState.newState[i]);
+ } else {
+ DPRINTF(ExecRegDelta, "%s [%5s] "\
+ "Native: %#010x => %#010x "\
+ "M5: %#010x => %#010x\n",
+ vergence, regNames[i],
+ nState.oldState[i], nState.newState[i],
+ mState.oldState[i], mState.newState[i]);
+ }
+ }
+ }
+ if (errorFound) {
+ StaticInstPtr inst = record->getStaticInst();
+ assert(inst);
+ bool ran = true;
+ if (inst->isMicroop()) {
+ ran = false;
+ inst = record->getMacroStaticInst();
+ }
+ assert(inst);
+ record->traceInst(inst, ran);
+
+ bool pcError = (mState.newState[STATE_PC] !=
+ nState.newState[STATE_PC]);
+ if (stopOnPCError && pcError)
+ panic("Native trace detected an error in control flow!");
+ }
+}
+
+} /* namespace Trace */
+
+////////////////////////////////////////////////////////////////////////
+//
+// ExeTracer Simulation Object
+//
+Trace::ArmNativeTrace *
+ArmNativeTraceParams::create()
+{
+ return new Trace::ArmNativeTrace(this);
+};
diff --git a/src/arch/arm/nativetrace.hh b/src/arch/arm/nativetrace.hh
new file mode 100644
index 000000000..7467e3378
--- /dev/null
+++ b/src/arch/arm/nativetrace.hh
@@ -0,0 +1,112 @@
+/*
+ * 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 __ARCH_ARM_NATIVETRACE_HH__
+#define __ARCH_ARM_NATIVETRACE_HH__
+
+#include "base/types.hh"
+#include "cpu/nativetrace.hh"
+#include "params/ArmNativeTrace.hh"
+
+namespace Trace {
+
+class ArmNativeTrace : public NativeTrace
+{
+ public:
+ enum StateID {
+ STATE_R0,
+ STATE_R1,
+ STATE_R2,
+ STATE_R3,
+ STATE_R4,
+ STATE_R5,
+ STATE_R6,
+ STATE_R7,
+ STATE_R8,
+ STATE_R9,
+ STATE_R10,
+ STATE_R11,
+ STATE_FP = STATE_R11,
+ STATE_R12,
+ STATE_R13,
+ STATE_SP = STATE_R13,
+ STATE_R14,
+ STATE_LR = STATE_R14,
+ STATE_R15,
+ STATE_PC = STATE_R15,
+ STATE_CPSR,
+ STATE_NUMVALS
+ };
+
+ protected:
+ struct ThreadState {
+ bool changed[STATE_NUMVALS];
+ uint32_t state[2][STATE_NUMVALS];
+ uint32_t *newState;
+ uint32_t *oldState;
+ int current;
+ void update(NativeTrace *parent);
+ void update(ThreadContext *tc);
+
+ ThreadState()
+ {
+ for (int i = 0; i < STATE_NUMVALS; i++) {
+ changed[i] = false;
+ state[0][i] = state[1][i] = 0;
+ current = 0;
+ newState = state[0];
+ oldState = state[1];
+ }
+ }
+ };
+
+ ThreadState nState, mState;
+
+ bool stopOnPCError;
+
+ public:
+ typedef ArmNativeTraceParams Params;
+
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+
+ ArmNativeTrace(const Params *p) :
+ NativeTrace(p), stopOnPCError(p->stop_on_pc_error)
+ {}
+
+ void check(NativeTraceRecord *record);
+};
+
+} /* namespace Trace */
+
+#endif // __ARCH_ARM_NATIVETRACE_HH__
diff --git a/src/arch/arm/process.cc b/src/arch/arm/process.cc
index 365d5b22c..cd7cc9736 100644
--- a/src/arch/arm/process.cc
+++ b/src/arch/arm/process.cc
@@ -46,7 +46,7 @@ using namespace ArmISA;
ArmLiveProcess::ArmLiveProcess(LiveProcessParams *params, ObjectFile *objFile)
: LiveProcess(params, objFile)
{
- stack_base = 0xc0000000L;
+ stack_base = 0xbf000000L;
// Set pointer for next thread stack. Reserve 8M for main stack.
next_thread_stack_base = stack_base - (8 * 1024 * 1024);
@@ -88,73 +88,239 @@ ArmLiveProcess::copyStringArray32(std::vector<std::string> &strings,
void
ArmLiveProcess::argsInit(int intSize, int pageSize)
{
+ typedef AuxVector<uint32_t> auxv_t;
+ std::vector<auxv_t> auxv;
+
+ string filename;
+ if (argv.size() < 1)
+ filename = "";
+ else
+ filename = argv[0];
+
+ //We want 16 byte alignment
+ uint64_t align = 16;
+
// Overloaded argsInit so that we can fine-tune for ARM architecture
Process::startup();
// load object file into target memory
objFile->loadSections(initVirtMem);
- // Calculate how much space we need for arg & env arrays.
- int argv_array_size = intSize * (argv.size() + 1);
- int envp_array_size = intSize * (envp.size() + 1);
- int arg_data_size = 0;
- for (int i = 0; i < argv.size(); ++i) {
- arg_data_size += argv[i].size() + 1;
+ enum ArmCpuFeature {
+ Arm_Swp = 1 << 0,
+ Arm_Half = 1 << 1,
+ Arm_Thumb = 1 << 2,
+ Arm_26Bit = 1 << 3,
+ Arm_FastMult = 1 << 4,
+ Arm_Fpa = 1 << 5,
+ Arm_Vfp = 1 << 6,
+ Arm_Edsp = 1 << 7,
+ Arm_Java = 1 << 8,
+ Arm_Iwmmxt = 1 << 9,
+ Arm_Crunch = 1 << 10
+ };
+
+ //Setup the auxilliary vectors. These will already have endian conversion.
+ //Auxilliary vectors are loaded only for elf formatted executables.
+ ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
+ if (elfObject) {
+ uint32_t features =
+ Arm_Swp |
+ Arm_Half |
+ Arm_Thumb |
+// Arm_26Bit |
+ Arm_FastMult |
+// Arm_Fpa |
+ Arm_Vfp |
+ Arm_Edsp |
+ Arm_Java |
+// Arm_Iwmmxt |
+// Arm_Crunch |
+ 0;
+
+ //Bits which describe the system hardware capabilities
+ //XXX Figure out what these should be
+ auxv.push_back(auxv_t(M5_AT_HWCAP, features));
+ //The system page size
+ auxv.push_back(auxv_t(M5_AT_PAGESZ, ArmISA::VMPageSize));
+ //Frequency at which times() increments
+ auxv.push_back(auxv_t(M5_AT_CLKTCK, 0x64));
+ // For statically linked executables, this is the virtual address of the
+ // program header tables if they appear in the executable image
+ auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable()));
+ // This is the size of a program header entry from the elf file.
+ auxv.push_back(auxv_t(M5_AT_PHENT, elfObject->programHeaderSize()));
+ // This is the number of program headers from the original elf file.
+ auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount()));
+ //This is the address of the elf "interpreter", It should be set
+ //to 0 for regular executables. It should be something else
+ //(not sure what) for dynamic libraries.
+ auxv.push_back(auxv_t(M5_AT_BASE, 0));
+
+ //XXX Figure out what this should be.
+ auxv.push_back(auxv_t(M5_AT_FLAGS, 0));
+ //The entry point to the program
+ auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint()));
+ //Different user and group IDs
+ auxv.push_back(auxv_t(M5_AT_UID, uid()));
+ auxv.push_back(auxv_t(M5_AT_EUID, euid()));
+ auxv.push_back(auxv_t(M5_AT_GID, gid()));
+ auxv.push_back(auxv_t(M5_AT_EGID, egid()));
+ //Whether to enable "secure mode" in the executable
+ auxv.push_back(auxv_t(M5_AT_SECURE, 0));
+ //The filename of the program
+ auxv.push_back(auxv_t(M5_AT_EXECFN, 0));
+ //The string "v51" with unknown meaning
+ auxv.push_back(auxv_t(M5_AT_PLATFORM, 0));
}
+
+ //Figure out how big the initial stack nedes to be
+
+ // A sentry NULL void pointer at the top of the stack.
+ int sentry_size = intSize;
+
+ string platform = "v51";
+ int platform_size = platform.size() + 1;
+
+ // The aux vectors are put on the stack in two groups. The first group are
+ // the vectors that are generated as the elf is loaded. The second group
+ // are the ones that were computed ahead of time and include the platform
+ // string.
+ int aux_data_size = filename.size() + 1;
+
int env_data_size = 0;
for (int i = 0; i < envp.size(); ++i) {
env_data_size += envp[i].size() + 1;
}
+ int arg_data_size = 0;
+ for (int i = 0; i < argv.size(); ++i) {
+ arg_data_size += argv[i].size() + 1;
+ }
- int space_needed =
- argv_array_size + envp_array_size + arg_data_size + env_data_size;
- if (space_needed < 16*1024)
- space_needed = 16*1024;
+ int info_block_size =
+ sentry_size + env_data_size + arg_data_size +
+ aux_data_size + platform_size;
+
+ //Each auxilliary vector is two 4 byte words
+ int aux_array_size = intSize * 2 * (auxv.size() + 1);
+
+ int envp_array_size = intSize * (envp.size() + 1);
+ int argv_array_size = intSize * (argv.size() + 1);
+
+ int argc_size = intSize;
+
+ //Figure out the size of the contents of the actual initial frame
+ int frame_size =
+ info_block_size +
+ aux_array_size +
+ envp_array_size +
+ argv_array_size +
+ argc_size;
+
+ //There needs to be padding after the auxiliary vector data so that the
+ //very bottom of the stack is aligned properly.
+ int partial_size = frame_size;
+ int aligned_partial_size = roundUp(partial_size, align);
+ int aux_padding = aligned_partial_size - partial_size;
+
+ int space_needed = frame_size + aux_padding;
- // set bottom of stack
stack_min = stack_base - space_needed;
- // align it
- stack_min = roundDown(stack_min, pageSize);
+ stack_min = roundDown(stack_min, align);
stack_size = stack_base - stack_min;
+
// map memory
- pTable->allocate(stack_min, roundUp(stack_size, pageSize));
+ pTable->allocate(roundDown(stack_min, pageSize),
+ roundUp(stack_size, pageSize));
// map out initial stack contents
- Addr argv_array_base = stack_min + intSize; // room for argc
- Addr envp_array_base = argv_array_base + argv_array_size;
- Addr arg_data_base = envp_array_base + envp_array_size;
- Addr env_data_base = arg_data_base + arg_data_size;
+ uint32_t sentry_base = stack_base - sentry_size;
+ uint32_t aux_data_base = sentry_base - aux_data_size;
+ uint32_t env_data_base = aux_data_base - env_data_size;
+ uint32_t arg_data_base = env_data_base - arg_data_size;
+ uint32_t platform_base = arg_data_base - platform_size;
+ uint32_t auxv_array_base = platform_base - aux_array_size - aux_padding;
+ uint32_t envp_array_base = auxv_array_base - envp_array_size;
+ uint32_t argv_array_base = envp_array_base - argv_array_size;
+ uint32_t argc_base = argv_array_base - argc_size;
+
+ DPRINTF(Stack, "The addresses of items on the initial stack:\n");
+ DPRINTF(Stack, "0x%x - aux data\n", aux_data_base);
+ DPRINTF(Stack, "0x%x - env data\n", env_data_base);
+ DPRINTF(Stack, "0x%x - arg data\n", arg_data_base);
+ DPRINTF(Stack, "0x%x - platform base\n", platform_base);
+ DPRINTF(Stack, "0x%x - auxv array\n", auxv_array_base);
+ DPRINTF(Stack, "0x%x - envp array\n", envp_array_base);
+ DPRINTF(Stack, "0x%x - argv array\n", argv_array_base);
+ DPRINTF(Stack, "0x%x - argc \n", argc_base);
+ DPRINTF(Stack, "0x%x - stack min\n", stack_min);
// write contents to stack
- uint64_t argc = argv.size();
- if (intSize == 8)
- argc = htog((uint64_t)argc);
- else if (intSize == 4)
- argc = htog((uint32_t)argc);
- else
- panic("Unknown int size");
- initVirtMem->writeBlob(stack_min, (uint8_t*)&argc, intSize);
+ // figure out argc
+ uint32_t argc = argv.size();
+ uint32_t guestArgc = ArmISA::htog(argc);
- copyStringArray32(argv, argv_array_base, arg_data_base, initVirtMem);
- copyStringArray32(envp, envp_array_base, env_data_base, initVirtMem);
+ //Write out the sentry void *
+ uint32_t sentry_NULL = 0;
+ initVirtMem->writeBlob(sentry_base,
+ (uint8_t*)&sentry_NULL, sentry_size);
- /*
- //uint8_t insns[] = {0xe5, 0x9f, 0x00, 0x08, 0xe1, 0xa0, 0xf0, 0x0e};
- uint8_t insns[] = {0x08, 0x00, 0x9f, 0xe5, 0x0e, 0xf0, 0xa0, 0xe1};
+ //Fix up the aux vectors which point to other data
+ for (int i = auxv.size() - 1; i >= 0; i--) {
+ if (auxv[i].a_type == M5_AT_PLATFORM) {
+ auxv[i].a_val = platform_base;
+ initVirtMem->writeString(platform_base, platform.c_str());
+ } else if (auxv[i].a_type == M5_AT_EXECFN) {
+ auxv[i].a_val = aux_data_base;
+ initVirtMem->writeString(aux_data_base, filename.c_str());
+ }
+ }
- initVirtMem->writeBlob(0xffff0fe0, insns, 8);
- */
+ //Copy the aux stuff
+ for(int x = 0; x < auxv.size(); x++)
+ {
+ initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize,
+ (uint8_t*)&(auxv[x].a_type), intSize);
+ initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize,
+ (uint8_t*)&(auxv[x].a_val), intSize);
+ }
+ //Write out the terminating zeroed auxilliary vector
+ const uint64_t zero = 0;
+ initVirtMem->writeBlob(auxv_array_base + 2 * intSize * auxv.size(),
+ (uint8_t*)&zero, 2 * intSize);
- ThreadContext *tc = system->getThreadContext(contextIds[0]);
+ copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
+ copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
+
+ initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize);
- tc->setIntReg(ArgumentReg1, argc);
- tc->setIntReg(ArgumentReg2, argv_array_base);
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
+ //Set the stack pointer register
tc->setIntReg(StackPointerReg, stack_min);
+ //A pointer to a function to run when the program exits. We'll set this
+ //to zero explicitly to make sure this isn't used.
+ tc->setIntReg(ArgumentReg0, 0);
+ //Set argument regs 1 and 2 to argv[0] and envp[0] respectively
+ if (argv.size() > 0) {
+ tc->setIntReg(ArgumentReg1, arg_data_base + arg_data_size -
+ argv[argv.size() - 1].size() - 1);
+ } else {
+ tc->setIntReg(ArgumentReg1, 0);
+ }
+ if (envp.size() > 0) {
+ tc->setIntReg(ArgumentReg2, env_data_base + env_data_size -
+ envp[envp.size() - 1].size() - 1);
+ } else {
+ tc->setIntReg(ArgumentReg2, 0);
+ }
Addr prog_entry = objFile->entryPoint();
tc->setPC(prog_entry);
tc->setNextPC(prog_entry + sizeof(MachInst));
+
+ //Align the "stack_min" to a page boundary.
+ stack_min = roundDown(stack_min, pageSize);
}
ArmISA::IntReg
diff --git a/src/arch/mips/mt.hh b/src/arch/mips/mt.hh
index 3cb81c201..7217c335e 100755
--- a/src/arch/mips/mt.hh
+++ b/src/arch/mips/mt.hh
@@ -118,7 +118,7 @@ forkThread(TC *tc, Fault &fault, int Rd_bits, int Rs, int Rt)
tc->readRegOtherThread(MISCREG_TC_BIND + Ctrl_Base_DepTag, tid);
TCBindReg tcBind = tc->readMiscRegNoEffect(MISCREG_TC_BIND);
- if (tidTCBind.curVPE = tcBind.curVPE) {
+ if (tidTCBind.curVPE == tcBind.curVPE) {
TCStatusReg tidTCStatus =
tc->readRegOtherThread(MISCREG_TC_STATUS +
diff --git a/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc
index 16fc698dd..15ad88f76 100644
--- a/src/base/loader/elf_object.cc
+++ b/src/base/loader/elf_object.cc
@@ -107,7 +107,6 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
{
case ELFOSABI_LINUX:
- case ELFOSABI_ARM:
opSys = ObjectFile::Linux;
break;
case ELFOSABI_SOLARIS:
@@ -116,6 +115,9 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
case ELFOSABI_TRU64:
opSys = ObjectFile::Tru64;
break;
+ case ELFOSABI_ARM:
+ opSys = ObjectFile::LinuxArmOABI;
+ break;
default:
opSys = ObjectFile::UnknownOpSys;
}
diff --git a/src/base/loader/object_file.hh b/src/base/loader/object_file.hh
index 73df5caf6..e511451b7 100644
--- a/src/base/loader/object_file.hh
+++ b/src/base/loader/object_file.hh
@@ -59,7 +59,8 @@ class ObjectFile
UnknownOpSys,
Tru64,
Linux,
- Solaris
+ Solaris,
+ LinuxArmOABI
};
protected:
diff --git a/src/cpu/NativeTrace.py b/src/cpu/NativeTrace.py
index 7fd240543..dba6de067 100644
--- a/src/cpu/NativeTrace.py
+++ b/src/cpu/NativeTrace.py
@@ -28,9 +28,9 @@
from m5.SimObject import SimObject
from m5.params import *
-from InstTracer import InstTracer
+from ExeTracer import ExeTracer
-class NativeTrace(InstTracer):
+class NativeTrace(ExeTracer):
abstract = True
type = 'NativeTrace'
cxx_class = 'Trace::NativeTrace'
diff --git a/src/cpu/nativetrace.cc b/src/cpu/nativetrace.cc
index 47c58434f..8c17eb825 100644
--- a/src/cpu/nativetrace.cc
+++ b/src/cpu/nativetrace.cc
@@ -38,7 +38,7 @@ using namespace std;
namespace Trace {
NativeTrace::NativeTrace(const Params *p)
- : InstTracer(p)
+ : ExeTracer(p)
{
if (ListenSocket::allDisabled())
fatal("All listeners are disabled!");
diff --git a/src/cpu/nativetrace.hh b/src/cpu/nativetrace.hh
index 34869f263..6ad6b0242 100644
--- a/src/cpu/nativetrace.hh
+++ b/src/cpu/nativetrace.hh
@@ -37,8 +37,8 @@
#include "base/socket.hh"
#include "base/trace.hh"
#include "base/types.hh"
+#include "cpu/exetrace.hh"
#include "cpu/static_inst.hh"
-#include "sim/insttracer.hh"
class ThreadContext;
@@ -46,7 +46,7 @@ namespace Trace {
class NativeTrace;
-class NativeTraceRecord : public InstRecord
+class NativeTraceRecord : public ExeTracerRecord
{
protected:
NativeTrace * parent;
@@ -56,7 +56,7 @@ class NativeTraceRecord : public InstRecord
Tick _when, ThreadContext *_thread,
const StaticInstPtr _staticInst, Addr _pc, bool spec,
const StaticInstPtr _macroStaticInst = NULL, MicroPC _upc = 0)
- : InstRecord(_when, _thread, _staticInst, _pc, spec,
+ : ExeTracerRecord(_when, _thread, _staticInst, _pc, spec,
_macroStaticInst, _upc),
parent(_parent)
{
@@ -65,7 +65,7 @@ class NativeTraceRecord : public InstRecord
void dump();
};
-class NativeTrace : public InstTracer
+class NativeTrace : public ExeTracer
{
protected:
int fd;
diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh
index d9d624e77..8a44eba37 100644
--- a/src/cpu/simple_thread.hh
+++ b/src/cpu/simple_thread.hh
@@ -262,7 +262,9 @@ class SimpleThread : public ThreadState
{
int flatIndex = isa.flattenIntIndex(reg_idx);
assert(flatIndex < TheISA::NumIntRegs);
- return intRegs[flatIndex];
+ uint64_t regVal = intRegs[flatIndex];
+ DPRINTF(IntRegs, "Reading int reg %d as %#x.\n", reg_idx, regVal);
+ return regVal;
}
FloatReg readFloatReg(int reg_idx)
@@ -283,6 +285,7 @@ class SimpleThread : public ThreadState
{
int flatIndex = isa.flattenIntIndex(reg_idx);
assert(flatIndex < TheISA::NumIntRegs);
+ DPRINTF(IntRegs, "Setting int reg %d to %#x.\n", reg_idx, val);
intRegs[flatIndex] = val;
}
diff --git a/src/sim/process.cc b/src/sim/process.cc
index c12101069..55bd2f209 100644
--- a/src/sim/process.cc
+++ b/src/sim/process.cc
@@ -748,7 +748,9 @@ LiveProcess::create(LiveProcessParams * params)
case ObjectFile::Linux:
process = new ArmLinuxProcess(params, objFile);
break;
-
+ case ObjectFile::LinuxArmOABI:
+ fatal("M5 does not support ARM OABI binaries. Please recompile with an"
+ " EABI compiler.");
default:
fatal("Unknown/unsupported operating system.");
}
diff --git a/src/sim/process.hh b/src/sim/process.hh
index 0d5421dcd..05a48071a 100644
--- a/src/sim/process.hh
+++ b/src/sim/process.hh
@@ -295,6 +295,10 @@ class LiveProcess : public Process
M5_AT_CLKTCK = 17,
M5_AT_SECURE = 23,
+ M5_BASE_PLATFORM = 24,
+ M5_AT_RANDOM = 25,
+
+ M5_AT_EXECFN = 31,
M5_AT_VECTOR_SIZE = 44
};
diff --git a/tests/quick/00.hello/ref/arm/linux/simple-atomic/simerr b/tests/quick/00.hello/ref/arm/linux/simple-atomic/simerr
index a2692a6c9..7c23c610e 100755
--- a/tests/quick/00.hello/ref/arm/linux/simple-atomic/simerr
+++ b/tests/quick/00.hello/ref/arm/linux/simple-atomic/simerr
@@ -1,5 +1,5 @@
warn: Sockets disabled, not accepting gdb connections
For more information see: http://www.m5sim.org/warn/d946bea6
-warn: allowing mmap of file @ fd 4294967295. This will break if not /dev/zero.
-For more information see: http://www.m5sim.org/warn/3a2134f6
+warn: instruction 'fstmx' unimplemented
+For more information see: http://www.m5sim.org/warn/21b09adb
hack: be nice to actually delete the event here
diff --git a/tests/quick/00.hello/ref/arm/linux/simple-atomic/simout b/tests/quick/00.hello/ref/arm/linux/simple-atomic/simout
index 40fbf355d..15f79c280 100755
--- a/tests/quick/00.hello/ref/arm/linux/simple-atomic/simout
+++ b/tests/quick/00.hello/ref/arm/linux/simple-atomic/simout
@@ -5,13 +5,12 @@ The Regents of The University of Michigan
All Rights Reserved
-M5 compiled Jun 9 2009 23:46:33
-M5 revision 6639f3c716a6 6238 default qtip tip armreg.patch qbase
-M5 started Jun 9 2009 23:53:49
+M5 compiled Jul 27 2009 00:45:04
+M5 revision 44a3d32f3217 6414 default qtip tip runnableagainstatupdate.patch
+M5 started Jul 27 2009 00:45:05
M5 executing on fajita
command line: build/ARM_SE/m5.fast -d build/ARM_SE/tests/fast/quick/00.hello/arm/linux/simple-atomic -re tests/run.py build/ARM_SE/tests/fast/quick/00.hello/arm/linux/simple-atomic
Global frequency set at 1000000000000 ticks per second
info: Entering event queue @ 0. Starting simulation...
-info: Increasing stack size by one page.
Hello world!
-Exiting @ tick 2299000 because target called exit()
+Exiting @ tick 2748500 because target called exit()
diff --git a/tests/quick/00.hello/ref/arm/linux/simple-atomic/stats.txt b/tests/quick/00.hello/ref/arm/linux/simple-atomic/stats.txt
index 5a17d118e..ece84babb 100644
--- a/tests/quick/00.hello/ref/arm/linux/simple-atomic/stats.txt
+++ b/tests/quick/00.hello/ref/arm/linux/simple-atomic/stats.txt
@@ -1,13 +1,13 @@
---------- Begin Simulation Statistics ----------
-host_inst_rate 79163 # Simulator instruction rate (inst/s)
-host_mem_usage 189980 # Number of bytes of host memory used
-host_seconds 0.06 # Real time elapsed on the host
-host_tick_rate 39442081 # Simulator tick rate (ticks/s)
+host_inst_rate 9392 # Simulator instruction rate (inst/s)
+host_mem_usage 189932 # Number of bytes of host memory used
+host_seconds 0.59 # Real time elapsed on the host
+host_tick_rate 4693453 # Simulator tick rate (ticks/s)
sim_freq 1000000000000 # Frequency of simulated ticks
-sim_insts 4598 # Number of instructions simulated
-sim_seconds 0.000002 # Number of seconds simulated
-sim_ticks 2299000 # Number of ticks simulated
+sim_insts 5498 # Number of instructions simulated
+sim_seconds 0.000003 # Number of seconds simulated
+sim_ticks 2748500 # Number of ticks simulated
system.cpu.dtb.accesses 0 # DTB accesses
system.cpu.dtb.hits 0 # DTB hits
system.cpu.dtb.misses 0 # DTB misses
@@ -28,9 +28,9 @@ system.cpu.itb.write_accesses 0 # DT
system.cpu.itb.write_hits 0 # DTB write hits
system.cpu.itb.write_misses 0 # DTB write misses
system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles
-system.cpu.numCycles 4599 # number of cpu cycles simulated
-system.cpu.num_insts 4598 # Number of instructions executed
-system.cpu.num_refs 1851 # Number of memory references
-system.cpu.workload.PROG:num_syscalls 14 # Number of system calls
+system.cpu.numCycles 5498 # number of cpu cycles simulated
+system.cpu.num_insts 5498 # Number of instructions executed
+system.cpu.num_refs 2127 # Number of memory references
+system.cpu.workload.PROG:num_syscalls 13 # Number of system calls
---------- End Simulation Statistics ----------
diff --git a/tests/test-progs/hello/bin/arm/linux/hello b/tests/test-progs/hello/bin/arm/linux/hello
index 818e17048..831ea7ee8 100755
--- a/tests/test-progs/hello/bin/arm/linux/hello
+++ b/tests/test-progs/hello/bin/arm/linux/hello
Binary files differ
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..b52c0694a
--- /dev/null
+++ b/util/statetrace/arch/tracechild_arm.cc
@@ -0,0 +1,236 @@
+/*
+ * 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++) {
+ memset(&regs, 0, sizeof(regs));
+ memset(&oldregs, 0, sizeof(regs));
+ regDiffSinceUpdate[x] = false;
+ }
+}
+
+bool ARMTraceChild::sendState(int socket)
+{
+ uint32_t regVal = 0;
+ uint32_t message[numregs + 1];
+ int pos = 1;
+ message[0] = 0;
+ for (int x = 0; x < numregs; x++) {
+ if (regDiffSinceUpdate[x]) {
+ message[0] = message[0] | (1 << x);
+ message[pos++] = getRegVal(x);
+ }
+ }
+
+ size_t sent = 0;
+ size_t toSend = pos * sizeof(message[0]);
+ uint8_t *messagePtr = (uint8_t *)message;
+ while (toSend != 0) {
+ sent = write(socket, messagePtr, toSend);
+ if (sent == -1) {
+ cerr << "Write failed! " << strerror(errno) << endl;
+ tracing = false;
+ return false;
+ }
+ toSend -= sent;
+ messagePtr += sent;
+ }
+
+ 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 = 0xe7f001f0;
+
+ uint32_t lr = getRegVal(14);
+ uint32_t pc = getPC();
+ uint32_t lrOp;
+
+ // Since ARM uses software breakpoints behind the scenes, they don't work
+ // in read only areas like the page of routines provided by the kernel. The
+ // link register generally holds the address the process wants to the
+ // kernel to return to after it's done, so we'll install a software
+ // breakpoint there. If the lr happens to point to the next instruction
+ // we'll leave out our breakpoint to avoid an infinite loop. This isn't a
+ // fool proof strategy, but it should work well in all the reasonable
+ // scenarios I can think of right now.
+
+ if (pc != lr) {
+ lrOp = ptrace(PTRACE_PEEKDATA, pid, lr, 0);
+ ptrace(PTRACE_POKEDATA, pid, lr, bkpt_inst);
+ }
+ ptraceSingleStep();
+ if (pc != lr) {
+ ptrace(PTRACE_POKEDATA, pid, lr, lrOp);
+ }
+}
+
+
+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/statetrace.cc b/util/statetrace/statetrace.cc
index 5f7224b25..e2762ac2c 100644
--- a/util/statetrace/statetrace.cc
+++ b/util/statetrace/statetrace.cc
@@ -28,19 +28,19 @@
* Authors: Gabe Black
*/
-#include <iostream>
+#include <cstring>
+#include <errno.h>
#include <fstream>
+#include <iostream>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <stdio.h>
#include <string>
+#include <sys/ptrace.h>
+#include <sys/socket.h>
#include <sys/types.h>
#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 "printer.hh"
#include "tracechild.hh"
@@ -61,6 +61,7 @@ int main(int argc, char * argv[], char * envp[])
//Parse the command line arguments
bool printInitial = false;
bool printTrace = true;
+ string host = "localhost";
for(int x = 1; x < argc; x++)
{
if(!strcmp(argv[x], "-h"))
@@ -68,6 +69,17 @@ int main(int argc, char * argv[], char * envp[])
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], "-r"))
{
cout << "Legal register names:" << endl;
@@ -111,6 +123,7 @@ int main(int argc, char * argv[], char * envp[])
cerr << "Couldn't start target program" << endl;
return 1;
}
+ child->step();
if(printInitial)
{
child->outputStartState(cout);
@@ -127,7 +140,7 @@ int main(int argc, char * argv[], char * envp[])
return 1;
}
struct hostent *server;
- server = gethostbyname("localhost");
+ server = gethostbyname(host.c_str());
if(!server)
{
cerr << "Couldn't get host ip! " << strerror(errno) << endl;
@@ -145,7 +158,6 @@ int main(int argc, char * argv[], char * envp[])
cerr << "Couldn't connect to server! " << strerror(errno) << endl;
return 1;
}
- child->step();
while(child->isTracing())
{
if(!child->sendState(sock))
diff --git a/util/statetrace/tracechild.cc b/util/statetrace/tracechild.cc
index 603429829..85f42addd 100644
--- a/util/statetrace/tracechild.cc
+++ b/util/statetrace/tracechild.cc
@@ -29,10 +29,11 @@
*/
#include "tracechild.hh"
-#include <sys/wait.h>
-#include <sys/ptrace.h>
-#include <iostream>
+#include <cstring>
#include <errno.h>
+#include <iostream>
+#include <sys/ptrace.h>
+#include <sys/wait.h>
using namespace std;
@@ -78,11 +79,6 @@ bool TraceChild::startTracing(const char * pathToFile, char * const argv[])
return false;
}
tracing = true;
- if(!update(pid))
- {
- cout << "Didn't update successfully!" << endl;
- return false;
- }
return true;
}
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__ || \