This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFA: make sim interface use gdbarch methods for collect/supply


At the moment, remote-sim.c's gdbsim_fetch_register and
gdbsim_store_register functions assume that the simulator's register
set (as visible via sim_fetch_register and sim_store_register)
corresponds exactly to GDB's raw register set.  This patch is meant to
remove that assumption.

Tested on i686-pc-linux-gnu x powerpc-eabispe (sim).

2004-06-30  Jim Blandy  <jimb@redhat.com>

	Don't assume that the sim's register set and GDB's raw register
	set have the same layout.
	* gdbarch.sh (sim_supply_register, sim_collect_register): New
	methods.  Have gdbarch.c #include regcache.h.
	* gdbarch.c, gdbarch.h: Regenerate.
	* remote-sim.c (gdbsim_fetch_register): Pass the register value
	collected from the sim to GDB via the new gdbarch methods.
	* Makefile.in (gdbarch.o): Update dependencies.

diff -rc gdb/gdbarch.c gdb/gdbarch.c
*** gdb/gdbarch.c	2004-06-22 12:30:54.000000000 -0500
--- gdb/gdbarch.c	2004-06-28 19:01:47.000000000 -0500
***************
*** 48,53 ****
--- 48,54 ----
  #include "gdb_string.h"
  #include "gdb-events.h"
  #include "reggroups.h"
+ #include "regcache.h"
  #include "osabi.h"
  #include "gdb_obstack.h"
  
***************
*** 166,171 ****
--- 167,174 ----
    gdbarch_print_float_info_ftype *print_float_info;
    gdbarch_print_vector_info_ftype *print_vector_info;
    gdbarch_register_sim_regno_ftype *register_sim_regno;
+   gdbarch_sim_supply_register_ftype *sim_supply_register;
+   gdbarch_sim_collect_register_ftype *sim_collect_register;
    gdbarch_register_bytes_ok_ftype *register_bytes_ok;
    gdbarch_cannot_fetch_register_ftype *cannot_fetch_register;
    gdbarch_cannot_store_register_ftype *cannot_store_register;
***************
*** 312,317 ****
--- 315,322 ----
    0,  /* print_float_info */
    0,  /* print_vector_info */
    0,  /* register_sim_regno */
+   0,  /* sim_supply_register */
+   0,  /* sim_collect_register */
    0,  /* register_bytes_ok */
    0,  /* cannot_fetch_register */
    0,  /* cannot_store_register */
***************
*** 452,457 ****
--- 457,464 ----
    current_gdbarch->call_dummy_location = AT_ENTRY_POINT;
    current_gdbarch->print_registers_info = default_print_registers_info;
    current_gdbarch->register_sim_regno = legacy_register_sim_regno;
+   current_gdbarch->sim_supply_register = regcache_raw_supply;
+   current_gdbarch->sim_collect_register = regcache_raw_collect;
    current_gdbarch->cannot_fetch_register = cannot_register_not;
    current_gdbarch->cannot_store_register = cannot_register_not;
    current_gdbarch->convert_register_p = generic_convert_register_p;
***************
*** 590,595 ****
--- 597,604 ----
    /* Skip verify of print_float_info, has predicate */
    /* Skip verify of print_vector_info, has predicate */
    /* Skip verify of register_sim_regno, invalid_p == 0 */
+   /* Skip verify of sim_supply_register, invalid_p == 0 */
+   /* Skip verify of sim_collect_register, invalid_p == 0 */
    /* Skip verify of register_bytes_ok, has predicate */
    /* Skip verify of cannot_fetch_register, invalid_p == 0 */
    /* Skip verify of cannot_store_register, invalid_p == 0 */
***************
*** 1907,1912 ****
--- 1916,1939 ----
    fprintf_unfiltered (file,
                        "gdbarch_dump: short_bit = %s\n",
                        paddr_d (current_gdbarch->short_bit));
+ #ifdef SIM_COLLECT_REGISTER
+   fprintf_unfiltered (file,
+                       "gdbarch_dump: %s # %s\n",
+                       "SIM_COLLECT_REGISTER(regcache, gdb_regno, buf)",
+                       XSTRING (SIM_COLLECT_REGISTER (regcache, gdb_regno, buf)));
+ #endif
+   fprintf_unfiltered (file,
+                       "gdbarch_dump: sim_collect_register = <0x%lx>\n",
+                       (long) current_gdbarch->sim_collect_register);
+ #ifdef SIM_SUPPLY_REGISTER
+   fprintf_unfiltered (file,
+                       "gdbarch_dump: %s # %s\n",
+                       "SIM_SUPPLY_REGISTER(regcache, gdb_regno, buf)",
+                       XSTRING (SIM_SUPPLY_REGISTER (regcache, gdb_regno, buf)));
+ #endif
+   fprintf_unfiltered (file,
+                       "gdbarch_dump: sim_supply_register = <0x%lx>\n",
+                       (long) current_gdbarch->sim_supply_register);
  #ifdef SKIP_PROLOGUE
    fprintf_unfiltered (file,
                        "gdbarch_dump: %s # %s\n",
***************
*** 3080,3085 ****
--- 3107,3146 ----
    gdbarch->register_sim_regno = register_sim_regno;
  }
  
+ void
+ gdbarch_sim_supply_register (struct gdbarch *gdbarch, struct regcache *regcache, int gdb_regno, const void *buf)
+ {
+   gdb_assert (gdbarch != NULL);
+   gdb_assert (gdbarch->sim_supply_register != NULL);
+   if (gdbarch_debug >= 2)
+     fprintf_unfiltered (gdb_stdlog, "gdbarch_sim_supply_register called\n");
+   gdbarch->sim_supply_register (regcache, gdb_regno, buf);
+ }
+ 
+ void
+ set_gdbarch_sim_supply_register (struct gdbarch *gdbarch,
+                                  gdbarch_sim_supply_register_ftype sim_supply_register)
+ {
+   gdbarch->sim_supply_register = sim_supply_register;
+ }
+ 
+ void
+ gdbarch_sim_collect_register (struct gdbarch *gdbarch, const struct regcache *regcache, int gdb_regno, void *buf)
+ {
+   gdb_assert (gdbarch != NULL);
+   gdb_assert (gdbarch->sim_collect_register != NULL);
+   if (gdbarch_debug >= 2)
+     fprintf_unfiltered (gdb_stdlog, "gdbarch_sim_collect_register called\n");
+   gdbarch->sim_collect_register (regcache, gdb_regno, buf);
+ }
+ 
+ void
+ set_gdbarch_sim_collect_register (struct gdbarch *gdbarch,
+                                   gdbarch_sim_collect_register_ftype sim_collect_register)
+ {
+   gdbarch->sim_collect_register = sim_collect_register;
+ }
+ 
  int
  gdbarch_register_bytes_ok_p (struct gdbarch *gdbarch)
  {
diff -rc gdb/gdbarch.h gdb/gdbarch.h
*** gdb/gdbarch.h	2004-06-22 12:30:54.000000000 -0500
--- gdb/gdbarch.h	2004-06-28 19:01:47.000000000 -0500
***************
*** 820,826 ****
  extern void gdbarch_print_vector_info (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, const char *args);
  extern void set_gdbarch_print_vector_info (struct gdbarch *gdbarch, gdbarch_print_vector_info_ftype *print_vector_info);
  
! /* MAP a GDB RAW register number onto a simulator register number.  See
     also include/...-sim.h. */
  
  typedef int (gdbarch_register_sim_regno_ftype) (int reg_nr);
--- 820,830 ----
  extern void gdbarch_print_vector_info (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, const char *args);
  extern void set_gdbarch_print_vector_info (struct gdbarch *gdbarch, gdbarch_print_vector_info_ftype *print_vector_info);
  
! /* The register set as implemented by the simulator may not line up
!    exactly with GDB's view of the raw register set.  The following
!    macros allow an architecture to make the appropriate adjustments to
!    register contents as they pass between GDB and the simulator.
!    Map a GDB RAW register number onto a simulator register number.  See
     also include/...-sim.h. */
  
  typedef int (gdbarch_register_sim_regno_ftype) (int reg_nr);
***************
*** 833,838 ****
--- 837,868 ----
  #define REGISTER_SIM_REGNO(reg_nr) (gdbarch_register_sim_regno (current_gdbarch, reg_nr))
  #endif
  
+ /* Supply the value of GDB_REGNO, in BUF, to REGCACHE.  GDB_REGNO is a
+    GDB register number, not a simulator register number. */
+ 
+ typedef void (gdbarch_sim_supply_register_ftype) (struct regcache *regcache, int gdb_regno, const void *buf);
+ extern void gdbarch_sim_supply_register (struct gdbarch *gdbarch, struct regcache *regcache, int gdb_regno, const void *buf);
+ extern void set_gdbarch_sim_supply_register (struct gdbarch *gdbarch, gdbarch_sim_supply_register_ftype *sim_supply_register);
+ #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SIM_SUPPLY_REGISTER)
+ #error "Non multi-arch definition of SIM_SUPPLY_REGISTER"
+ #endif
+ #if !defined (SIM_SUPPLY_REGISTER)
+ #define SIM_SUPPLY_REGISTER(regcache, gdb_regno, buf) (gdbarch_sim_supply_register (current_gdbarch, regcache, gdb_regno, buf))
+ #endif
+ 
+ /* Collect the value of GDB_REGNO from REGCACHE and place it in BUF.
+    GDB_REGNO is a GDB register number, not a simulator register number. */
+ 
+ typedef void (gdbarch_sim_collect_register_ftype) (const struct regcache *regcache, int gdb_regno, void *buf);
+ extern void gdbarch_sim_collect_register (struct gdbarch *gdbarch, const struct regcache *regcache, int gdb_regno, void *buf);
+ extern void set_gdbarch_sim_collect_register (struct gdbarch *gdbarch, gdbarch_sim_collect_register_ftype *sim_collect_register);
+ #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SIM_COLLECT_REGISTER)
+ #error "Non multi-arch definition of SIM_COLLECT_REGISTER"
+ #endif
+ #if !defined (SIM_COLLECT_REGISTER)
+ #define SIM_COLLECT_REGISTER(regcache, gdb_regno, buf) (gdbarch_sim_collect_register (current_gdbarch, regcache, gdb_regno, buf))
+ #endif
+ 
  #if defined (REGISTER_BYTES_OK)
  /* Legacy for systems yet to multi-arch REGISTER_BYTES_OK */
  #if !defined (REGISTER_BYTES_OK_P)
diff -rc gdb/gdbarch.sh gdb/gdbarch.sh
*** gdb/gdbarch.sh	2004-06-22 12:45:18.000000000 -0500
--- gdb/gdbarch.sh	2004-06-28 19:01:47.000000000 -0500
***************
*** 516,524 ****
  m::void:print_registers_info:struct ui_file *file, struct frame_info *frame, int regnum, int all:file, frame, regnum, all:::default_print_registers_info::0
  M::void:print_float_info:struct ui_file *file, struct frame_info *frame, const char *args:file, frame, args
  M::void:print_vector_info:struct ui_file *file, struct frame_info *frame, const char *args:file, frame, args
! # MAP a GDB RAW register number onto a simulator register number.  See
  # also include/...-sim.h.
  f:=:int:register_sim_regno:int reg_nr:reg_nr:::legacy_register_sim_regno::0
  F:=:int:register_bytes_ok:long nr_bytes:nr_bytes
  f:=:int:cannot_fetch_register:int regnum:regnum:::cannot_register_not::0
  f:=:int:cannot_store_register:int regnum:regnum:::cannot_register_not::0
--- 516,539 ----
  m::void:print_registers_info:struct ui_file *file, struct frame_info *frame, int regnum, int all:file, frame, regnum, all:::default_print_registers_info::0
  M::void:print_float_info:struct ui_file *file, struct frame_info *frame, const char *args:file, frame, args
  M::void:print_vector_info:struct ui_file *file, struct frame_info *frame, const char *args:file, frame, args
! 
! # The register set as implemented by the simulator may not line up
! # exactly with GDB's view of the raw register set.  The following
! # macros allow an architecture to make the appropriate adjustments to
! # register contents as they pass between GDB and the simulator.
! 
! # Map a GDB RAW register number onto a simulator register number.  See
  # also include/...-sim.h.
  f:=:int:register_sim_regno:int reg_nr:reg_nr:::legacy_register_sim_regno::0
+ 
+ # Supply the value of GDB_REGNO, in BUF, to REGCACHE.  GDB_REGNO is a
+ # GDB register number, not a simulator register number.
+ f:=:void:sim_supply_register:struct regcache *regcache, int gdb_regno, const void *buf:regcache, gdb_regno, buf:::regcache_raw_supply::0
+ 
+ # Collect the value of GDB_REGNO from REGCACHE and place it in BUF.
+ # GDB_REGNO is a GDB register number, not a simulator register number.
+ f:=:void:sim_collect_register:const struct regcache *regcache, int gdb_regno, void *buf:regcache, gdb_regno, buf:::regcache_raw_collect::0
+ 
  F:=:int:register_bytes_ok:long nr_bytes:nr_bytes
  f:=:int:cannot_fetch_register:int regnum:regnum:::cannot_register_not::0
  f:=:int:cannot_store_register:int regnum:regnum:::cannot_register_not::0
***************
*** 1228,1233 ****
--- 1243,1249 ----
  #include "gdb_string.h"
  #include "gdb-events.h"
  #include "reggroups.h"
+ #include "regcache.h"
  #include "osabi.h"
  #include "gdb_obstack.h"
  
diff -rc gdb/Makefile.in gdb/Makefile.in
*** gdb/Makefile.in	2004-06-28 18:39:59.000000000 -0500
--- gdb/Makefile.in	2004-06-28 19:01:47.000000000 -0500
***************
*** 1833,1839 ****
  	$(gdb_assert_h)
  gdbarch.o: gdbarch.c $(defs_h) $(arch_utils_h) $(gdbcmd_h) $(inferior_h) \
  	$(symcat_h) $(floatformat_h) $(gdb_assert_h) $(gdb_string_h) \
! 	$(gdb_events_h) $(reggroups_h) $(osabi_h) $(gdb_obstack_h)
  gdb.o: gdb.c $(defs_h) $(main_h) $(gdb_string_h) $(interps_h)
  gdb-events.o: gdb-events.c $(defs_h) $(gdb_events_h) $(gdbcmd_h)
  gdbtypes.o: gdbtypes.c $(defs_h) $(gdb_string_h) $(bfd_h) $(symtab_h) \
--- 1833,1840 ----
  	$(gdb_assert_h)
  gdbarch.o: gdbarch.c $(defs_h) $(arch_utils_h) $(gdbcmd_h) $(inferior_h) \
  	$(symcat_h) $(floatformat_h) $(gdb_assert_h) $(gdb_string_h) \
! 	$(gdb_events_h) $(reggroups_h) $(regcache_h) $(osabi_h) \
! 	$(gdb_obstack_h) 
  gdb.o: gdb.c $(defs_h) $(main_h) $(gdb_string_h) $(interps_h)
  gdb-events.o: gdb-events.c $(defs_h) $(gdb_events_h) $(gdbcmd_h)
  gdbtypes.o: gdbtypes.c $(defs_h) $(gdb_string_h) $(bfd_h) $(symtab_h) \
diff -rc gdb/remote-sim.c gdb/remote-sim.c
*** gdb/remote-sim.c	2004-06-28 18:54:34.000000000 -0500
--- gdb/remote-sim.c	2004-06-28 18:59:58.000000000 -0500
***************
*** 312,331 ****
      default:
        {
  	static int warn_user = 1;
  	char buf[MAX_REGISTER_SIZE];
  	int nr_bytes;
! 	gdb_assert (regno >= 0 && regno < NUM_REGS);
  	memset (buf, 0, MAX_REGISTER_SIZE);
! 	nr_bytes = sim_fetch_register (gdbsim_desc,
! 				       REGISTER_SIM_REGNO (regno),
! 				       buf, DEPRECATED_REGISTER_RAW_SIZE (regno));
! 	if (nr_bytes > 0 && nr_bytes != DEPRECATED_REGISTER_RAW_SIZE (regno) && warn_user)
  	  {
! 	    fprintf_unfiltered (gdb_stderr,
! 				"Size of register %s (%d/%d) incorrect (%d instead of %d))",
! 				REGISTER_NAME (regno),
! 				regno, REGISTER_SIM_REGNO (regno),
! 				nr_bytes, DEPRECATED_REGISTER_RAW_SIZE (regno));
  	    warn_user = 0;
  	  }
  	/* FIXME: cagney/2002-05-27: Should check `nr_bytes == 0'
--- 312,338 ----
      default:
        {
  	static int warn_user = 1;
+         int sim_regno = REGISTER_SIM_REGNO (regno);
  	char buf[MAX_REGISTER_SIZE];
  	int nr_bytes;
! 	gdb_assert (sim_regno >= 0 && sim_regno < NUM_REGS + NUM_PSEUDO_REGS);
  	memset (buf, 0, MAX_REGISTER_SIZE);
! 	nr_bytes
!           = sim_fetch_register (gdbsim_desc, sim_regno, buf,
!                                 DEPRECATED_REGISTER_RAW_SIZE (sim_regno));
! 	if (nr_bytes > 0
!             && nr_bytes != DEPRECATED_REGISTER_RAW_SIZE (sim_regno)
!             && warn_user)
  	  {
!             fprintf_unfiltered (gdb_stderr,
!                                 "GDB expected %d bytes for %s (%d)",
!                                 DEPRECATED_REGISTER_RAW_SIZE (sim_regno),
!                                 REGISTER_NAME (sim_regno), sim_regno);
!             if (sim_regno != regno)
!               fprintf_unfiltered (gdb_stderr, ", fetched for %s (%d)",
!                                   REGISTER_NAME (regno), regno);
!             fprintf_unfiltered (gdb_stderr, ", but sim provided %d",
!                                 nr_bytes);
  	    warn_user = 0;
  	  }
  	/* FIXME: cagney/2002-05-27: Should check `nr_bytes == 0'
***************
*** 333,344 ****
  	   which registers are fetchable.  */
  	/* Else if (nr_bytes < 0): an old simulator, that doesn't
  	   think to return the register size.  Just assume all is ok.  */
! 	supply_register (regno, buf);
  	if (sr_get_debug ())
  	  {
! 	    printf_filtered ("gdbsim_fetch_register: %d", regno);
  	    /* FIXME: We could print something more intelligible.  */
! 	    dump_mem (buf, DEPRECATED_REGISTER_RAW_SIZE (regno));
  	  }
  	break;
        }
--- 340,351 ----
  	   which registers are fetchable.  */
  	/* Else if (nr_bytes < 0): an old simulator, that doesn't
  	   think to return the register size.  Just assume all is ok.  */
! 	SIM_SUPPLY_REGISTER (current_regcache, regno, buf);
  	if (sr_get_debug ())
  	  {
! 	    printf_filtered ("gdbsim_fetch_register: %d", sim_regno);
  	    /* FIXME: We could print something more intelligible.  */
! 	    dump_mem (buf, DEPRECATED_REGISTER_RAW_SIZE (sim_regno));
  	  }
  	break;
        }
***************
*** 357,369 ****
      }
    else if (REGISTER_SIM_REGNO (regno) >= 0)
      {
        char tmp[MAX_REGISTER_SIZE];
        int nr_bytes;
!       deprecated_read_register_gen (regno, tmp);
!       nr_bytes = sim_store_register (gdbsim_desc,
! 				     REGISTER_SIM_REGNO (regno),
! 				     tmp, DEPRECATED_REGISTER_RAW_SIZE (regno));
!       if (nr_bytes > 0 && nr_bytes != DEPRECATED_REGISTER_RAW_SIZE (regno))
  	internal_error (__FILE__, __LINE__,
  			"Register size different to expected");
        /* FIXME: cagney/2002-05-27: Should check `nr_bytes == 0'
--- 364,376 ----
      }
    else if (REGISTER_SIM_REGNO (regno) >= 0)
      {
+       int sim_regno = REGISTER_SIM_REGNO (regno);
        char tmp[MAX_REGISTER_SIZE];
        int nr_bytes;
!       SIM_COLLECT_REGISTER (current_regcache, regno, tmp);
!       nr_bytes = sim_store_register (gdbsim_desc, sim_regno, tmp,
!                                      DEPRECATED_REGISTER_RAW_SIZE (sim_regno));
!       if (nr_bytes > 0 && nr_bytes != DEPRECATED_REGISTER_RAW_SIZE (sim_regno))
  	internal_error (__FILE__, __LINE__,
  			"Register size different to expected");
        /* FIXME: cagney/2002-05-27: Should check `nr_bytes == 0'
***************
*** 371,379 ****
  	 which registers are fetchable.  */
        if (sr_get_debug ())
  	{
! 	  printf_filtered ("gdbsim_store_register: %d", regno);
  	  /* FIXME: We could print something more intelligible.  */
! 	  dump_mem (tmp, DEPRECATED_REGISTER_RAW_SIZE (regno));
  	}
      }
  }
--- 378,386 ----
  	 which registers are fetchable.  */
        if (sr_get_debug ())
  	{
! 	  printf_filtered ("gdbsim_store_register: %d", sim_regno);
  	  /* FIXME: We could print something more intelligible.  */
! 	  dump_mem (tmp, DEPRECATED_REGISTER_RAW_SIZE (sim_regno));
  	}
      }
  }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]