Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/gnu/dist/gdb/gdb Handle the case when control transfer instr...



details:   https://anonhg.NetBSD.org/src/rev/dd43cb41a32e
branches:  trunk
changeset: 586791:dd43cb41a32e
user:      uwe <uwe%NetBSD.org@localhost>
date:      Mon Jan 02 17:35:55 2006 +0000

description:
Handle the case when control transfer instruction jumps to its own
delay slot (e.g. PLT entries use such code).  We can not set the
breakpoint there, as trapa is illegal in the delay slot.  Set the
breakpoint to the next instruction instead.  We are guaranteed to
arrive there, as control transfers are illegal in the delay slot.

diffstat:

 gnu/dist/gdb/gdb/shnbsd-tdep.c |  35 +++++++++++++++++++++++++++++------
 1 files changed, 29 insertions(+), 6 deletions(-)

diffs (90 lines):

diff -r 74679ae9a78b -r dd43cb41a32e gnu/dist/gdb/gdb/shnbsd-tdep.c
--- a/gnu/dist/gdb/gdb/shnbsd-tdep.c    Mon Jan 02 16:45:44 2006 +0000
+++ b/gnu/dist/gdb/gdb/shnbsd-tdep.c    Mon Jan 02 17:35:55 2006 +0000
@@ -266,8 +266,19 @@
   int displacement;
   int reg;
   CORE_ADDR next_pc;
+  int delay_slot;
 
   insn = read_memory_integer (pc, sizeof (insn));
+  delay_slot = 0;
+
+  /* As we cannot step through the delay slot, we break at the target
+     address of the control transfer.  One tricky case is when the
+     target of the jump is the delay slot of that same instruction
+     (e.g. PLT entries use such code).  In that case we cannot set the
+     break to the target, as trapa is illegal in the delay slot.  Set
+     break to the next instruction instead, we are guaranteed to
+     arrive there, as control transfers are illegal in the delay
+     slot. */
 
   /* BT, BF, BT/S, BF/S */
   if (CONDITIONAL_BRANCH_P(insn))
@@ -280,8 +291,8 @@
        {
          displacement = shnbsd_displacement_8 (insn);
 
-         /* XXX: cannot step through delay slot, so break at the target */
          next_pc = pc + 4 + (displacement << 1);
+         delay_slot = CONDITIONAL_BRANCH_SLOT_P(insn);
        }
     }
 
@@ -289,32 +300,40 @@
   else if (BRANCH_P(insn))
     {
       displacement = shnbsd_displacement_12 (insn);
-      /* XXX: cannot step through delay slot, so break at the target */
+
       next_pc = pc + 4 + (displacement << 1);
+      delay_slot = 1;
     }
 
   /* BRAF, BSRF */
   else if (BRANCH_FAR_P(insn))
     {
       displacement = read_register (BRANCH_FAR_REG(insn));
-      /* XXX: cannot step through delay slot, so break at the target */
+
       next_pc = pc + 4 + displacement;
+      delay_slot = 1;
     }
 
   /* JMP, JSR */
   else if (JUMP_P(insn))
     {
-      /* XXX: cannot step through delay slot, so break at the target */
       next_pc = read_register (JUMP_REG(insn));
+      delay_slot = 1;
     }
 
   /* RTS */
   else if (insn == RTS_INSN)
-    next_pc = read_register (gdbarch_tdep (current_gdbarch)->PR_REGNUM);
+    {
+      next_pc = read_register (gdbarch_tdep (current_gdbarch)->PR_REGNUM);
+      delay_slot = 1;
+    }
 
   /* RTE - XXX: privileged */
   else if (insn == RTE_INSN)
-    next_pc = read_register (gdbarch_tdep (current_gdbarch)->SPC_REGNUM);
+    {
+      next_pc = read_register (gdbarch_tdep (current_gdbarch)->SPC_REGNUM);
+      delay_slot = 1;
+    }
 
   /* TRAPA */
   else if (TRAPA_P(insn))
@@ -324,6 +343,10 @@
   else
     next_pc = pc + 2;
 
+  /* jumping to our own delay slot? */
+  if (delay_slot && next_pc == pc + 2)
+    next_pc += 2;
+
   return next_pc;
 }
 



Home | Main Index | Thread Index | Old Index