aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog6
-rw-r--r--gdb/config/mips/tm-mips.h3
-rw-r--r--gdb/mips-tdep.c27
3 files changed, 36 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index e1e5cb8..88fe975 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,11 @@
2001-07-05 Daniel Jacobowitz <drow@mvista.com>
+ * mips-tdep.c (mips_software_single_step): New function.
+ * config/mips/tm-mips.h: Add prototype for
+ mips_software_single_step.
+
+2001-07-05 Daniel Jacobowitz <drow@mvista.com>
+
* ppc-linux-nat.c (supply_gregset): Use elf_greg_t instead
of greg_t.
(fill_gregset): Likewise.
diff --git a/gdb/config/mips/tm-mips.h b/gdb/config/mips/tm-mips.h
index a207950..a865e96 100644
--- a/gdb/config/mips/tm-mips.h
+++ b/gdb/config/mips/tm-mips.h
@@ -502,3 +502,6 @@ extern void mips_set_processor_type_command (char *, int);
/* MIPS sign extends addresses */
#define POINTER_TO_ADDRESS(TYPE,BUF) (signed_pointer_to_address (TYPE, BUF))
#define ADDRESS_TO_POINTER(TYPE,BUF,ADDR) (address_to_signed_pointer (TYPE, BUF, ADDR))
+
+/* Single step based on where the current instruction will take us. */
+extern void mips_software_single_step (enum target_signal, int);
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index c56d97e..d83c4d1 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -1379,6 +1379,33 @@ mips_addr_bits_remove (CORE_ADDR addr)
return addr;
}
+/* mips_software_single_step() is called just before we want to resume
+ the inferior, if we want to single-step it but there is no hardware
+ or kernel single-step support (MIPS on Linux for example). We find
+ the target of the coming instruction and breakpoint it.
+
+ single_step is also called just after the inferior stops. If we had
+ set up a simulated single-step, we undo our damage. */
+
+void
+mips_software_single_step (enum target_signal sig, int insert_breakpoints_p)
+{
+ static CORE_ADDR next_pc;
+ typedef char binsn_quantum[BREAKPOINT_MAX];
+ static binsn_quantum break_mem;
+ CORE_ADDR pc;
+
+ if (insert_breakpoints_p)
+ {
+ pc = read_register (PC_REGNUM);
+ next_pc = mips_next_pc (pc);
+
+ target_insert_breakpoint (next_pc, break_mem);
+ }
+ else
+ target_remove_breakpoint (next_pc, break_mem);
+}
+
static void
mips_init_frame_pc_first (int fromleaf, struct frame_info *prev)
{