2004-11-23 Randolph Chung <tausq@debian.org>
authorRandolph Chung <tausq@debian.org>
Tue, 23 Nov 2004 21:05:23 +0000 (21:05 +0000)
committerRandolph Chung <tausq@debian.org>
Tue, 23 Nov 2004 21:05:23 +0000 (21:05 +0000)
* arch-utils.c (generic_instruction_nullified): New.
* arch-utils.h (generic_instruction_nullified): New.
* gdbarch.sh (instruction_nullified): New method.
* gdbarch.c: Regenerate.
* gdbarch.h: Regenerate.
* infrun.c (INSTRUCTION_NULLIFIED): Delete.
(handle_inferior_event): Replace INSTRUCTION_NULLIFIED with calls to
new gdbarch method.
* config/pa/tm-hppa.h (INSTRUCTION_NULLIFIED): Delete definition.
* hppa-tdep.c (hppa_instruction_nullified): Remove prototype and make
static.  Rewrite to work directly off the passed regcache.
(hppa_gdbarch_init): Set instruction_nullified method.

gdb/ChangeLog
gdb/arch-utils.c
gdb/arch-utils.h
gdb/config/pa/tm-hppa.h
gdb/gdbarch.c
gdb/gdbarch.h
gdb/gdbarch.sh
gdb/hppa-tdep.c
gdb/infrun.c

index 64b52691f7dd1956ea4e93538d550ce4b0fc308b..83ecf1abbac0de7cf3a68c2853282a81d4faf65f 100644 (file)
@@ -1,3 +1,18 @@
+2004-11-23  Randolph Chung  <tausq@debian.org>
+
+       * arch-utils.c (generic_instruction_nullified): New.
+       * arch-utils.h (generic_instruction_nullified): New.
+       * gdbarch.sh (instruction_nullified): New method.
+       * gdbarch.c: Regenerate.
+       * gdbarch.h: Regenerate.
+       * infrun.c (INSTRUCTION_NULLIFIED): Delete.
+       (handle_inferior_event): Replace INSTRUCTION_NULLIFIED with calls to
+       new gdbarch method.
+       * config/pa/tm-hppa.h (INSTRUCTION_NULLIFIED): Delete definition.
+       * hppa-tdep.c (hppa_instruction_nullified): Remove prototype and make
+       static.  Rewrite to work directly off the passed regcache.
+       (hppa_gdbarch_init): Set instruction_nullified method.
+
 2004-11-23  Joel Brobecker  <brobecker@gnat.com>
 
        * sparc-tdep.c (sparc_is_unimp_insn): New function.
index 6fc8511395da2bf857de509f942e746820594368..431b24263d3d1b8a46ca2c29bc3bfbced43ccc4c 100644 (file)
@@ -325,6 +325,13 @@ default_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
   return 0;
 }
 
+int
+generic_instruction_nullified (struct gdbarch *gdbarch,
+                              struct regcache *regcache)
+{
+  return 0;
+}
+
 \f
 /* Functions to manipulate the endianness of the target.  */
 
index ac17cfef6fdd28f41033a092ec2f91ddb464b7d9..6045ac0acc1b4eabb4dd6b53b89e762e2d78ea4d 100644 (file)
@@ -117,6 +117,9 @@ extern int generic_convert_register_p (int regnum, struct type *type);
 extern int default_stabs_argument_has_addr (struct gdbarch *gdbarch,
                                            struct type *type);
 
+extern int generic_instruction_nullified (struct gdbarch *gdbarch,
+                                         struct regcache *regcache);
+
 /* For compatibility with older architectures, returns
    (LEGACY_SIM_REGNO_IGNORE) when the register doesn't have a valid
    name.  */
index 2f77fcd15da285ba05364a25368adf924c74d23c..8bf2535cb13398448774047fc242b0b8ec531836 100644 (file)
@@ -28,9 +28,3 @@
 
 extern int hppa_pc_requires_run_before_use (CORE_ADDR pc);
 #define DEPRECATED_PC_REQUIRES_RUN_BEFORE_USE(pc) hppa_pc_requires_run_before_use (pc)
-
-/* PA specific macro to see if the current instruction is nullified. */
-#ifndef INSTRUCTION_NULLIFIED
-extern int hppa_instruction_nullified (void);
-#define INSTRUCTION_NULLIFIED hppa_instruction_nullified ()
-#endif
index c277e912eee89a8120c9339647bbc5f3320a74df..efc6bd7336108b224da3917eca46dc40117b7edb 100644 (file)
@@ -212,6 +212,7 @@ struct gdbarch
   gdbarch_smash_text_address_ftype *smash_text_address;
   gdbarch_software_single_step_ftype *software_single_step;
   gdbarch_single_step_through_delay_ftype *single_step_through_delay;
+  gdbarch_instruction_nullified_ftype *instruction_nullified;
   gdbarch_print_insn_ftype *print_insn;
   gdbarch_skip_trampoline_code_ftype *skip_trampoline_code;
   gdbarch_skip_solib_resolver_ftype *skip_solib_resolver;
@@ -338,6 +339,7 @@ struct gdbarch startup_gdbarch =
   0,  /* smash_text_address */
   0,  /* software_single_step */
   0,  /* single_step_through_delay */
+  generic_instruction_nullified,  /* instruction_nullified */
   0,  /* print_insn */
   0,  /* skip_trampoline_code */
   generic_skip_solib_resolver,  /* skip_solib_resolver */
@@ -435,6 +437,7 @@ gdbarch_alloc (const struct gdbarch_info *info,
   current_gdbarch->convert_from_func_ptr_addr = convert_from_func_ptr_addr_identity;
   current_gdbarch->addr_bits_remove = core_addr_identity;
   current_gdbarch->smash_text_address = core_addr_identity;
+  current_gdbarch->instruction_nullified = generic_instruction_nullified;
   current_gdbarch->skip_trampoline_code = generic_skip_trampoline_code;
   current_gdbarch->skip_solib_resolver = generic_skip_solib_resolver;
   current_gdbarch->in_solib_return_trampoline = generic_in_solib_return_trampoline;
@@ -591,6 +594,7 @@ verify_gdbarch (struct gdbarch *current_gdbarch)
   /* Skip verify of smash_text_address, invalid_p == 0 */
   /* Skip verify of software_single_step, has predicate */
   /* Skip verify of single_step_through_delay, has predicate */
+  /* Skip verify of instruction_nullified, invalid_p == 0 */
   if (current_gdbarch->print_insn == 0)
     fprintf_unfiltered (log, "\n\tprint_insn");
   /* Skip verify of skip_trampoline_code, invalid_p == 0 */
@@ -1195,6 +1199,9 @@ gdbarch_dump (struct gdbarch *current_gdbarch, struct ui_file *file)
   fprintf_unfiltered (file,
                       "gdbarch_dump: inner_than = <0x%lx>\n",
                       (long) current_gdbarch->inner_than);
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: instruction_nullified = <0x%lx>\n",
+                      (long) current_gdbarch->instruction_nullified);
 #ifdef TARGET_INT_BIT
   fprintf_unfiltered (file,
                       "gdbarch_dump: TARGET_INT_BIT # %s\n",
@@ -3365,6 +3372,23 @@ set_gdbarch_single_step_through_delay (struct gdbarch *gdbarch,
   gdbarch->single_step_through_delay = single_step_through_delay;
 }
 
+int
+gdbarch_instruction_nullified (struct gdbarch *gdbarch, struct regcache *regcache)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->instruction_nullified != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_instruction_nullified called\n");
+  return gdbarch->instruction_nullified (gdbarch, regcache);
+}
+
+void
+set_gdbarch_instruction_nullified (struct gdbarch *gdbarch,
+                                   gdbarch_instruction_nullified_ftype instruction_nullified)
+{
+  gdbarch->instruction_nullified = instruction_nullified;
+}
+
 int
 gdbarch_print_insn (struct gdbarch *gdbarch, bfd_vma vma, struct disassemble_info *info)
 {
index 4ab8ea50afa5c427845b659e8af201f5bada52b7..b59f6e76fa0d799ef0e1bf6cec20363672e96538 100644 (file)
@@ -1227,6 +1227,16 @@ typedef int (gdbarch_single_step_through_delay_ftype) (struct gdbarch *gdbarch,
 extern int gdbarch_single_step_through_delay (struct gdbarch *gdbarch, struct frame_info *frame);
 extern void set_gdbarch_single_step_through_delay (struct gdbarch *gdbarch, gdbarch_single_step_through_delay_ftype *single_step_through_delay);
 
+/* On some systems, the PC may be left pointing at an instruction that won't
+   actually be executed.  This is usually indicated by a bit in the PSW.  If
+   we find ourselves in such a state, then we step the target beyond the
+   nullified instruction before returning control to gdb.
+   Return non-zero if the processor is about to execute a nullified instruction. */
+
+typedef int (gdbarch_instruction_nullified_ftype) (struct gdbarch *gdbarch, struct regcache *regcache);
+extern int gdbarch_instruction_nullified (struct gdbarch *gdbarch, struct regcache *regcache);
+extern void set_gdbarch_instruction_nullified (struct gdbarch *gdbarch, gdbarch_instruction_nullified_ftype *instruction_nullified);
+
 /* FIXME: cagney/2003-08-28: Need to find a better way of selecting the
    disassembler.  Perhaps objdump can handle it? */
 
index aa0cd62cf259b7b7c20483cc79e64c5f226b6d05..14abd74f8a65788cbb7583bb0d492023a7b28413 100755 (executable)
@@ -614,6 +614,12 @@ F:=:void:software_single_step:enum target_signal sig, int insert_breakpoints_p:s
 # Return non-zero if the processor is executing a delay slot and a
 # further single-step is needed before the instruction finishes.
 M::int:single_step_through_delay:struct frame_info *frame:frame
+# On some systems, the PC may be left pointing at an instruction that won't
+# actually be executed.  This is usually indicated by a bit in the PSW.  If
+# we find ourselves in such a state, then we step the target beyond the
+# nullified instruction before returning control to gdb.
+# Return non-zero if the processor is about to execute a nullified instruction.
+m::int:instruction_nullified:struct regcache *regcache:regcache::generic_instruction_nullified::0
 # FIXME: cagney/2003-08-28: Need to find a better way of selecting the
 # disassembler.  Perhaps objdump can handle it?
 f:TARGET_PRINT_INSN:int:print_insn:bfd_vma vma, struct disassemble_info *info:vma, info::0:
index f4cca55a34e42f8ab49f943a77ee06ab1a408dca..fb6e7ebea7907c7a4abeccfc2540e3a344914ec9 100644 (file)
@@ -71,7 +71,6 @@ const struct objfile_data *hppa_objfile_priv_data = NULL;
 /* FIXME: brobecker 2002-11-07: We will likely be able to make the
    following functions static, once we hppa is partially multiarched.  */
 int hppa_pc_requires_run_before_use (CORE_ADDR pc);
-int hppa_instruction_nullified (void);
 
 /* Handle 32/64-bit struct return conventions.  */
 
@@ -2292,14 +2291,18 @@ hppa_pc_requires_run_before_use (CORE_ADDR pc)
   return (!target_has_stack && (pc & 0xFF000000));
 }
 
-int
-hppa_instruction_nullified (void)
+static int
+hppa_instruction_nullified (struct gdbarch *gdbarch, struct regcache *regcache)
 {
-  /* brobecker 2002/11/07: Couldn't we use a ULONGEST here? It would
-     avoid the type cast.  I'm leaving it as is for now as I'm doing
-     semi-mechanical multiarching-related changes.  */
-  const int ipsw = (int) read_register (HPPA_IPSW_REGNUM);
-  const int flags = (int) read_register (HPPA_FLAGS_REGNUM);
+  ULONGEST tmp, ipsw, flags;
+
+  regcache_cooked_read (regcache, HPPA_IPSW_REGNUM, &tmp);
+  ipsw = extract_unsigned_integer (&tmp, 
+                                  register_size (gdbarch, HPPA_IPSW_REGNUM));
+
+  regcache_cooked_read (regcache, HPPA_FLAGS_REGNUM, &tmp);
+  flags = extract_unsigned_integer (&tmp, 
+                                   register_size (gdbarch, HPPA_FLAGS_REGNUM));
 
   return ((ipsw & 0x00200000) && !(flags & 0x2));
 }
@@ -2570,6 +2573,7 @@ hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       
   set_gdbarch_breakpoint_from_pc (gdbarch, hppa_breakpoint_from_pc);
   set_gdbarch_pseudo_register_read (gdbarch, hppa_pseudo_register_read);
+  set_gdbarch_instruction_nullified (gdbarch, hppa_instruction_nullified);
 
   /* Frame unwind methods.  */
   set_gdbarch_unwind_dummy_id (gdbarch, hppa_unwind_dummy_id);
index dde000fcd28ce803c0aa4c40c9337a80cd1cbf28..fcbfd6c79b02e572816103ceaaf3b0926aae1861 100644 (file)
@@ -163,16 +163,6 @@ static int debug_infrun = 0;
 #define SOLIB_IN_DYNAMIC_LINKER(pid,pc) 0
 #endif
 
-/* On some systems, the PC may be left pointing at an instruction that  won't
-   actually be executed.  This is usually indicated by a bit in the PSW.  If
-   we find ourselves in such a state, then we step the target beyond the
-   nullified instruction before returning control to the user so as to avoid
-   confusion. */
-
-#ifndef INSTRUCTION_NULLIFIED
-#define INSTRUCTION_NULLIFIED 0
-#endif
-
 /* We can't step off a permanent breakpoint in the ordinary way, because we
    can't remove it.  Instead, we have to advance the PC to the next
    instruction.  This macro should expand to a pointer to a function that
@@ -1741,14 +1731,15 @@ handle_inferior_event (struct execution_control_state *ecs)
     }
 
   /* If PC is pointing at a nullified instruction, then step beyond
-     it so that the user won't be confused when GDB appears to be ready
-     to execute it. */
+     it before deciding what to do.  This is required when we are stepping
+     through a function where the last instruction is a branch with a
+     nullified instruction in the delay slot that belongs to the next
+     line (which may be in a different function altogether).  */
 
-  /*      if (INSTRUCTION_NULLIFIED && currently_stepping (ecs)) */
-  if (INSTRUCTION_NULLIFIED)
+  if (gdbarch_instruction_nullified (current_gdbarch, current_regcache))
     {
       if (debug_infrun)
-       printf_unfiltered ("infrun: INSTRUCTION_NULLIFIED\n");
+       printf_unfiltered ("infrun: instruction nullified\n");
       registers_changed ();
       target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);