This is the mail archive of the gdb-patches@sourceware.org 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]

[commit] Fix gdb -c for MIPS N32 core files


If you run "gdb -c core" without a binary, for a MIPS GNU/Linux N32
core file, GDB will print you a pretty error message: "bad register
size".  The core file doesn't specify a machine, so mips_isa_regsize
defaults to 4-byte GPRs.  It does specify an ABI, but we deliberately
don't use that for the "ISA regsize".

My first try to fix this used the ABI flag for core files.  But
there's something better: we know exactly what size the registers
are in the core file.  All we need is to communicate this from
mips-linux-tdep.c to mips-tdep.c at the appropriate time.

I added a new gdbarch method which is called when loading a core
file, to determine target properties from the core file.  This
will let us display only the registers present in the core
file, if we want to.

Tested on mips-linux and by hand on mips64 N32; then checked in.

-- 
Daniel Jacobowitz
CodeSourcery

2007-09-10  Daniel Jacobowitz  <dan@codesourcery.com>

	* arch-utils.c (gdbarch_info_fill): Also try core_bfd.
	* corelow.c (core_read_description): New.
	(init_core_ops): Set to_read_description.
	* gdbarch.sh: Add gdbarch_core_read_description.
	* mips-linux-tdep.c (mips_linux_core_read_description): New.
	(mips_linux_init_abi): Call set_gdbarch_core_read_description.
	* mips-tdep.c (mips_tdesc_gp32, mips_tdesc_gp64): New.
	(mips_register_g_packet_guesses): Use them.
	(_initialize_mips_tdep): Initialize them.
	* mips-tdep.h (mips_tdesc_gp32, mips_tdesc_gp64): Declare.
	* gdbarch.h, gdbarch.c: Regenerated.

Index: gdb/arch-utils.c
===================================================================
RCS file: /scratch/gcc/repos/src/src/gdb/arch-utils.c,v
retrieving revision 1.157
diff -u -p -r1.157 arch-utils.c
--- gdb/arch-utils.c	23 Aug 2007 18:08:26 -0000	1.157
+++ gdb/arch-utils.c	7 Sep 2007 16:58:39 -0000
@@ -661,6 +661,8 @@ gdbarch_info_fill (struct gdbarch_info *
   /* Check for the current file.  */
   if (info->abfd == NULL)
     info->abfd = exec_bfd;
+  if (info->abfd == NULL)
+    info->abfd = core_bfd;
 
   /* Check for the current target description.  */
   if (info->target_desc == NULL)
Index: gdb/corelow.c
===================================================================
RCS file: /scratch/gcc/repos/src/src/gdb/corelow.c,v
retrieving revision 1.66
diff -u -p -r1.66 corelow.c
--- gdb/corelow.c	3 Sep 2007 23:06:35 -0000	1.66
+++ gdb/corelow.c	7 Sep 2007 15:56:02 -0000
@@ -635,6 +635,20 @@ core_file_thread_alive (ptid_t tid)
   return 1;
 }
 
+/* Ask the current architecture what it knows about this core file.
+   That will be used, in turn, to pick a better architecture.  This
+   wrapper could be avoided if targets got a chance to specialize
+   core_ops.  */
+
+static const struct target_desc *
+core_read_description (struct target_ops *target)
+{
+  if (gdbarch_core_read_description_p (current_gdbarch))
+    return gdbarch_core_read_description (current_gdbarch, target, core_bfd);
+
+  return NULL;
+}
+
 /* Fill in core_ops with its defined operations and properties.  */
 
 static void
@@ -656,6 +670,7 @@ init_core_ops (void)
   core_ops.to_remove_breakpoint = ignore;
   core_ops.to_create_inferior = find_default_create_inferior;
   core_ops.to_thread_alive = core_file_thread_alive;
+  core_ops.to_read_description = core_read_description;
   core_ops.to_stratum = core_stratum;
   core_ops.to_has_memory = 1;
   core_ops.to_has_stack = 1;
Index: gdb/gdbarch.c
===================================================================
RCS file: /scratch/gcc/repos/src/src/gdb/gdbarch.c,v
retrieving revision 1.403
diff -u -p -r1.403 gdbarch.c
--- gdb/gdbarch.c	3 Sep 2007 23:06:35 -0000	1.403
+++ gdb/gdbarch.c	7 Sep 2007 16:16:40 -0000
@@ -230,6 +230,7 @@ struct gdbarch
   int vbit_in_delta;
   gdbarch_skip_permanent_breakpoint_ftype *skip_permanent_breakpoint;
   gdbarch_overlay_update_ftype *overlay_update;
+  gdbarch_core_read_description_ftype *core_read_description;
 };
 
 
@@ -352,6 +353,7 @@ struct gdbarch startup_gdbarch =
   0,  /* vbit_in_delta */
   0,  /* skip_permanent_breakpoint */
   0,  /* overlay_update */
+  0,  /* core_read_description */
   /* startup_gdbarch() */
 };
 
@@ -599,6 +601,7 @@ verify_gdbarch (struct gdbarch *current_
   /* Skip verify of vbit_in_delta, invalid_p == 0 */
   /* Skip verify of skip_permanent_breakpoint, has predicate */
   /* Skip verify of overlay_update, has predicate */
+  /* Skip verify of core_read_description, has predicate */
   buf = ui_file_xstrdup (log, &dummy);
   make_cleanup (xfree, buf);
   if (strlen (buf) > 0)
@@ -714,6 +717,12 @@ gdbarch_dump (struct gdbarch *current_gd
                       "gdbarch_dump: convert_register_p = <0x%lx>\n",
                       (long) current_gdbarch->convert_register_p);
   fprintf_unfiltered (file,
+                      "gdbarch_dump: gdbarch_core_read_description_p() = %d\n",
+                      gdbarch_core_read_description_p (current_gdbarch));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: core_read_description = <0x%lx>\n",
+                      (long) current_gdbarch->core_read_description);
+  fprintf_unfiltered (file,
                       "gdbarch_dump: gdbarch_core_xfer_shared_libraries_p() = %d\n",
                       gdbarch_core_xfer_shared_libraries_p (current_gdbarch));
   fprintf_unfiltered (file,
@@ -3001,6 +3010,30 @@ set_gdbarch_overlay_update (struct gdbar
   gdbarch->overlay_update = overlay_update;
 }
 
+int
+gdbarch_core_read_description_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->core_read_description != NULL;
+}
+
+const struct target_desc *
+gdbarch_core_read_description (struct gdbarch *gdbarch, struct target_ops *target, bfd *abfd)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->core_read_description != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_core_read_description called\n");
+  return gdbarch->core_read_description (gdbarch, target, abfd);
+}
+
+void
+set_gdbarch_core_read_description (struct gdbarch *gdbarch,
+                                   gdbarch_core_read_description_ftype core_read_description)
+{
+  gdbarch->core_read_description = core_read_description;
+}
+
 
 /* Keep a registry of per-architecture data-pointers required by GDB
    modules. */
Index: gdb/gdbarch.h
===================================================================
RCS file: /scratch/gcc/repos/src/src/gdb/gdbarch.h,v
retrieving revision 1.359
diff -u -p -r1.359 gdbarch.h
--- gdb/gdbarch.h	3 Sep 2007 23:06:35 -0000	1.359
+++ gdb/gdbarch.h	7 Sep 2007 16:16:21 -0000
@@ -687,6 +687,12 @@ typedef void (gdbarch_overlay_update_fty
 extern void gdbarch_overlay_update (struct gdbarch *gdbarch, struct obj_section *osect);
 extern void set_gdbarch_overlay_update (struct gdbarch *gdbarch, gdbarch_overlay_update_ftype *overlay_update);
 
+extern int gdbarch_core_read_description_p (struct gdbarch *gdbarch);
+
+typedef const struct target_desc * (gdbarch_core_read_description_ftype) (struct gdbarch *gdbarch, struct target_ops *target, bfd *abfd);
+extern const struct target_desc * gdbarch_core_read_description (struct gdbarch *gdbarch, struct target_ops *target, bfd *abfd);
+extern void set_gdbarch_core_read_description (struct gdbarch *gdbarch, gdbarch_core_read_description_ftype *core_read_description);
+
 extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch);
 
 
Index: gdb/gdbarch.sh
===================================================================
RCS file: /scratch/gcc/repos/src/src/gdb/gdbarch.sh,v
retrieving revision 1.441
diff -u -p -r1.441 gdbarch.sh
--- gdb/gdbarch.sh	3 Sep 2007 23:06:35 -0000	1.441
+++ gdb/gdbarch.sh	7 Sep 2007 16:16:06 -0000
@@ -652,6 +652,8 @@ F::void:skip_permanent_breakpoint:struct
 
 # Refresh overlay mapped state for section OSECT.
 F::void:overlay_update:struct obj_section *osect:osect
+
+M::const struct target_desc *:core_read_description:struct target_ops *target, bfd *abfd:target, abfd
 EOF
 }
 
Index: gdb/mips-linux-tdep.c
===================================================================
RCS file: /scratch/gcc/repos/src/src/gdb/mips-linux-tdep.c,v
retrieving revision 1.64
diff -u -p -r1.64 mips-linux-tdep.c
--- gdb/mips-linux-tdep.c	23 Aug 2007 18:08:36 -0000	1.64
+++ gdb/mips-linux-tdep.c	7 Sep 2007 16:44:39 -0000
@@ -573,6 +573,28 @@ static struct core_fns regset_core_fns =
   NULL					/* next */
 };
 
+static const struct target_desc *
+mips_linux_core_read_description (struct gdbarch *gdbarch,
+				  struct target_ops *target,
+				  bfd *abfd)
+{
+  asection *section = bfd_get_section_by_name (abfd, ".reg");
+  if (! section)
+    return NULL;
+
+  switch (bfd_section_size (abfd, section))
+    {
+    case sizeof (mips_elf_gregset_t):
+      return mips_tdesc_gp32;
+
+    case sizeof (mips64_elf_gregset_t):
+      return mips_tdesc_gp64;
+
+    default:
+      return NULL;
+    }
+}
+
 
 /* Check the code at PC for a dynamic linker lazy resolution stub.
    Because they aren't in the .plt section, we pattern-match on the
@@ -1160,6 +1182,9 @@ mips_linux_init_abi (struct gdbarch_info
 
   set_gdbarch_write_pc (gdbarch, mips_linux_write_pc);
 
+  set_gdbarch_core_read_description (gdbarch,
+				     mips_linux_core_read_description);
+
   if (tdesc_data)
     {
       const struct tdesc_feature *feature;
Index: gdb/mips-tdep.c
===================================================================
RCS file: /scratch/gcc/repos/src/src/gdb/mips-tdep.c,v
retrieving revision 1.443
diff -u -p -r1.443 mips-tdep.c
--- gdb/mips-tdep.c	23 Aug 2007 18:08:36 -0000	1.443
+++ gdb/mips-tdep.c	7 Sep 2007 16:43:43 -0000
@@ -165,6 +165,9 @@ static int mips_debug = 0;
 #define PROPERTY_GP32 "internal: transfers-32bit-registers"
 #define PROPERTY_GP64 "internal: transfers-64bit-registers"
 
+struct target_desc *mips_tdesc_gp32;
+struct target_desc *mips_tdesc_gp64;
+
 /* MIPS specific per-architecture information */
 struct gdbarch_tdep
 {
@@ -4866,30 +4869,16 @@ global_mips_abi (void)
 static void
 mips_register_g_packet_guesses (struct gdbarch *gdbarch)
 {
-  static struct target_desc *tdesc_gp32, *tdesc_gp64;
-
-  if (tdesc_gp32 == NULL)
-    {
-      /* Create feature sets with the appropriate properties.  The values
-	 are not important.  */
-
-      tdesc_gp32 = allocate_target_description ();
-      set_tdesc_property (tdesc_gp32, PROPERTY_GP32, "");
-
-      tdesc_gp64 = allocate_target_description ();
-      set_tdesc_property (tdesc_gp64, PROPERTY_GP64, "");
-    }
-
   /* If the size matches the set of 32-bit or 64-bit integer registers,
      assume that's what we've got.  */
-  register_remote_g_packet_guess (gdbarch, 38 * 4, tdesc_gp32);
-  register_remote_g_packet_guess (gdbarch, 38 * 8, tdesc_gp64);
+  register_remote_g_packet_guess (gdbarch, 38 * 4, mips_tdesc_gp32);
+  register_remote_g_packet_guess (gdbarch, 38 * 8, mips_tdesc_gp64);
 
   /* If the size matches the full set of registers GDB traditionally
      knows about, including floating point, for either 32-bit or
      64-bit, assume that's what we've got.  */
-  register_remote_g_packet_guess (gdbarch, 90 * 4, tdesc_gp32);
-  register_remote_g_packet_guess (gdbarch, 90 * 8, tdesc_gp64);
+  register_remote_g_packet_guess (gdbarch, 90 * 4, mips_tdesc_gp32);
+  register_remote_g_packet_guess (gdbarch, 90 * 8, mips_tdesc_gp64);
 
   /* Otherwise we don't have a useful guess.  */
 }
@@ -5696,6 +5685,14 @@ _initialize_mips_tdep (void)
 
   mips_pdr_data = register_objfile_data ();
 
+  /* Create feature sets with the appropriate properties.  The values
+     are not important.  */
+  mips_tdesc_gp32 = allocate_target_description ();
+  set_tdesc_property (mips_tdesc_gp32, PROPERTY_GP32, "");
+
+  mips_tdesc_gp64 = allocate_target_description ();
+  set_tdesc_property (mips_tdesc_gp64, PROPERTY_GP64, "");
+
   /* Add root prefix command for all "set mips"/"show mips" commands */
   add_prefix_cmd ("mips", no_class, set_mips_command,
 		  _("Various MIPS specific commands."),
Index: gdb/mips-tdep.h
===================================================================
RCS file: /scratch/gcc/repos/src/src/gdb/mips-tdep.h,v
retrieving revision 1.25
diff -u -p -r1.25 mips-tdep.h
--- gdb/mips-tdep.h	23 Aug 2007 18:08:36 -0000	1.25
+++ gdb/mips-tdep.h	7 Sep 2007 16:43:49 -0000
@@ -102,4 +102,9 @@ extern int mips_pc_is_mips16 (bfd_vma me
 /* Return the currently configured (or set) saved register size. */
 extern unsigned int mips_abi_regsize (struct gdbarch *gdbarch);
 
+/* Target descriptions which only indicate the size of general
+   registers.  */
+extern struct target_desc *mips_tdesc_gp32;
+extern struct target_desc *mips_tdesc_gp64;
+
 #endif /* MIPS_TDEP_H */


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