changeset fbc8d1e996d9 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=fbc8d1e996d9
description:
ARM: Make sure the target process doesn't run away from statetrace.
diffstat:
2 files changed, 25 insertions(+), 14 deletions(-)
src/arch/arm/nativetrace.cc | 7 ++++++-
util/statetrace/arch/tracechild_arm.cc | 32 +++++++++++++++++++-------------
diffs (63 lines):
diff -r 425703ea71c9 -r fbc8d1e996d9 src/arch/arm/nativetrace.cc
--- a/src/arch/arm/nativetrace.cc Wed Jul 29 00:09:46 2009 -0700
+++ b/src/arch/arm/nativetrace.cc Wed Jul 29 00:14:43 2009 -0700
@@ -104,8 +104,13 @@
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(record->getThread());
+ mState.update(tc);
bool errorFound = false;
// Regular int regs
diff -r 425703ea71c9 -r fbc8d1e996d9 util/statetrace/arch/tracechild_arm.cc
--- a/util/statetrace/arch/tracechild_arm.cc Wed Jul 29 00:09:46 2009 -0700
+++ b/util/statetrace/arch/tracechild_arm.cc Wed Jul 29 00:14:43 2009 -0700
@@ -203,22 +203,28 @@
bool ARMTraceChild::step()
{
+ const uint32_t bkpt_inst = 0xe7f001f0;
- const uint32_t bkpt_inst = 0xE1200070;
- const uint32_t bkpt_mask = 0xFFF000F0;
+ uint32_t lr = getRegVal(14);
+ uint32_t pc = getPC();
+ uint32_t lrOp;
- const uint32_t swi_inst = 0x0F0000000;
- const uint32_t swi_mask = 0x0F0000000;
+ // 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.
- uint32_t next_op = ptrace(PTRACE_PEEKDATA, pid, getPC(), 0);
- if ((next_op & swi_mask) == swi_inst) {
- ptrace(PTRACE_POKEDATA, pid, next_op + sizeof(uint32_t), bkpt_inst);
- ptraceSingleStep();
- ptrace(PTRACE_POKEDATA, pid, next_op + sizeof(uint32_t), next_op);
- }
- else
- {
- ptraceSingleStep();
+ 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);
}
}
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev