merge mips fix and statetrace changes
This commit is contained in:
37
src/arch/arm/ArmNativeTrace.py
Normal file
37
src/arch/arm/ArmNativeTrace.py
Normal file
@@ -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")
|
||||
@@ -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']:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}});
|
||||
}
|
||||
|
||||
@@ -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)'
|
||||
|
||||
@@ -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)
|
||||
|
||||
}};
|
||||
|
||||
@@ -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().
|
||||
@@ -86,14 +75,9 @@ class ArmLinux : public Linux
|
||||
static const int TGT_RUSAGE_BOTH = -2;
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/// 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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -62,6 +62,9 @@ namespace ArmISA
|
||||
MISCREG_SPSR_UND,
|
||||
MISCREG_SPSR_ABT,
|
||||
MISCREG_FPSR,
|
||||
MISCREG_FPSID,
|
||||
MISCREG_FPSCR,
|
||||
MISCREG_FPEXC,
|
||||
NUM_MISCREGS
|
||||
};
|
||||
|
||||
|
||||
183
src/arch/arm/nativetrace.cc
Normal file
183
src/arch/arm/nativetrace.cc
Normal file
@@ -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);
|
||||
};
|
||||
112
src/arch/arm/nativetrace.hh
Normal file
112
src/arch/arm/nativetrace.hh
Normal file
@@ -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__
|
||||
@@ -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);
|
||||
|
||||
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);
|
||||
|
||||
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||
|
||||
tc->setIntReg(ArgumentReg1, argc);
|
||||
tc->setIntReg(ArgumentReg2, argv_array_base);
|
||||
//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
|
||||
|
||||
@@ -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 +
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,8 @@ class ObjectFile
|
||||
UnknownOpSys,
|
||||
Tru64,
|
||||
Linux,
|
||||
Solaris
|
||||
Solaris,
|
||||
LinuxArmOABI
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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!");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.");
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 ----------
|
||||
|
||||
Binary file not shown.
@@ -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
|
||||
|
||||
236
util/statetrace/arch/tracechild_arm.cc
Normal file
236
util/statetrace/arch/tracechild_arm.cc
Normal file
@@ -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(®s, 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, ®s) != 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;
|
||||
}
|
||||
|
||||
113
util/statetrace/arch/tracechild_arm.hh
Normal file
113
util/statetrace/arch/tracechild_arm.hh
Normal file
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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__ || \
|
||||
|
||||
Reference in New Issue
Block a user