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]

Re: [RFC] Add support for PPC Altivec registers in gcore




Ulrich Weigand wrote:
I would suggest to place the definition in utils.c (next to
gdb_print_host_address), and a prototype in defs.h (next to
the prototype for gdb_print_host_address).  As gdbarch.c
does include defs.h, it will find it here ...


Ok, done.


I also separated the ppc and x86 implementations from the main gcore stuff, to make it easier to analyze.

Is this close to what you had in mind?

Thanks,

--
Carlos Eduardo Seo
Software Engineer
IBM Linux Technology Center
2008-05-07  Carlos Eduardo Seo  <cseo@linux.vnet.ibm.com>

	* gdbarch.sh: Added new gdbarch struct
	core_regset_sections.
	* gdbarch.c: Refreshed.
	* gdbarch.h: Refreshed.
	* regset.h (core_regset_section): Declared.
	* linux-nat.c (linux_nat_do_thread_registers): Added
	support to the new gdbarch struct core_regset_sections.
	* utils.c (host_address_to_string): New function.
	* defs.h (host_address_to_string): New prototype.

Index: src/gdb/gdbarch.sh
===================================================================
--- src.orig/gdb/gdbarch.sh
+++ src/gdb/gdbarch.sh
@@ -600,6 +600,9 @@ F:CORE_ADDR:fetch_pointer_argument:struc
 # name SECT_NAME and size SECT_SIZE.
 M:const struct regset *:regset_from_core_section:const char *sect_name, size_t sect_size:sect_name, sect_size
 
+# Supported register notes in a core file
+v:struct core_regset_section *:core_regset_sections:const char *name, int len::::::host_address_to_string (gdbarch->core_regset_sections)
+
 # Read offset OFFSET of TARGET_OBJECT_LIBRARIES formatted shared libraries list from
 # core file into buffer READBUF with length LEN.
 M:LONGEST:core_xfer_shared_libraries:gdb_byte *readbuf, ULONGEST offset, LONGEST len:readbuf, offset, len
@@ -815,6 +818,7 @@ struct obstack;
 struct bp_target_info;
 struct target_desc;
 struct displaced_step_closure;
+struct core_regset_section;
 
 extern struct gdbarch *current_gdbarch;
 EOF
Index: src/gdb/gdbarch.c
===================================================================
--- src.orig/gdb/gdbarch.c
+++ src/gdb/gdbarch.c
@@ -222,6 +222,7 @@ struct gdbarch
   gdbarch_register_reggroup_p_ftype *register_reggroup_p;
   gdbarch_fetch_pointer_argument_ftype *fetch_pointer_argument;
   gdbarch_regset_from_core_section_ftype *regset_from_core_section;
+  struct core_regset_section * core_regset_sections;
   gdbarch_core_xfer_shared_libraries_ftype *core_xfer_shared_libraries;
   int vtable_function_descriptors;
   int vbit_in_delta;
@@ -352,6 +353,7 @@ struct gdbarch startup_gdbarch =
   default_register_reggroup_p,  /* register_reggroup_p */
   0,  /* fetch_pointer_argument */
   0,  /* regset_from_core_section */
+  0,  /* core_regset_sections */
   0,  /* core_xfer_shared_libraries */
   0,  /* vtable_function_descriptors */
   0,  /* vbit_in_delta */
@@ -725,6 +727,9 @@ gdbarch_dump (struct gdbarch *gdbarch, s
                       "gdbarch_dump: core_read_description = <0x%lx>\n",
                       (long) gdbarch->core_read_description);
   fprintf_unfiltered (file,
+                      "gdbarch_dump: core_regset_sections = %s\n",
+                      host_address_to_string (gdbarch->core_regset_sections));
+  fprintf_unfiltered (file,
                       "gdbarch_dump: gdbarch_core_xfer_shared_libraries_p() = %d\n",
                       gdbarch_core_xfer_shared_libraries_p (gdbarch));
   fprintf_unfiltered (file,
@@ -2877,6 +2882,22 @@ set_gdbarch_regset_from_core_section (st
   gdbarch->regset_from_core_section = regset_from_core_section;
 }
 
+struct core_regset_section *
+gdbarch_core_regset_sections (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_core_regset_sections called\n");
+  return gdbarch->core_regset_sections;
+}
+
+void
+set_gdbarch_core_regset_sections (struct gdbarch *gdbarch,
+                                  struct core_regset_section * core_regset_sections)
+{
+  gdbarch->core_regset_sections = core_regset_sections;
+}
+
 int
 gdbarch_core_xfer_shared_libraries_p (struct gdbarch *gdbarch)
 {
Index: src/gdb/gdbarch.h
===================================================================
--- src.orig/gdb/gdbarch.h
+++ src/gdb/gdbarch.h
@@ -51,6 +51,7 @@ struct obstack;
 struct bp_target_info;
 struct target_desc;
 struct displaced_step_closure;
+struct core_regset_section;
 
 extern struct gdbarch *current_gdbarch;
 
@@ -634,6 +635,11 @@ typedef const struct regset * (gdbarch_r
 extern const struct regset * gdbarch_regset_from_core_section (struct gdbarch *gdbarch, const char *sect_name, size_t sect_size);
 extern void set_gdbarch_regset_from_core_section (struct gdbarch *gdbarch, gdbarch_regset_from_core_section_ftype *regset_from_core_section);
 
+/* Supported register notes in a core file */
+
+extern struct core_regset_section * gdbarch_core_regset_sections (struct gdbarch *gdbarch);
+extern void set_gdbarch_core_regset_sections (struct gdbarch *gdbarch, struct core_regset_section * core_regset_sections);
+
 /* Read offset OFFSET of TARGET_OBJECT_LIBRARIES formatted shared libraries list from
    core file into buffer READBUF with length LEN. */
 
Index: src/gdb/regset.h
===================================================================
--- src.orig/gdb/regset.h
+++ src/gdb/regset.h
@@ -23,6 +23,13 @@
 struct gdbarch;
 struct regcache;
 
+/* Data structure for the supported register notes in a core file  */
+struct core_regset_section
+{
+  const char *sect_name;
+  int size;
+};
+
 /* Data structure describing a register set.  */
 
 typedef void (supply_regset_ftype) (const struct regset *, struct regcache *,
Index: src/gdb/linux-nat.c
===================================================================
--- src.orig/gdb/linux-nat.c
+++ src/gdb/linux-nat.c
@@ -3124,15 +3124,14 @@ linux_nat_do_thread_registers (bfd *obfd
 {
   gdb_gregset_t gregs;
   gdb_fpregset_t fpregs;
-#ifdef FILL_FPXREGSET
-  gdb_fpxregset_t fpxregs;
-#endif
   unsigned long lwp = ptid_get_lwp (ptid);
   struct regcache *regcache = get_thread_regcache (ptid);
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   const struct regset *regset;
   int core_regset_p;
   struct cleanup *old_chain;
+  struct core_regset_section *sect_list;
+  char *gdb_regset;
 
   old_chain = save_inferior_ptid ();
   inferior_ptid = ptid;
@@ -3140,6 +3139,8 @@ linux_nat_do_thread_registers (bfd *obfd
   do_cleanups (old_chain);
 
   core_regset_p = gdbarch_regset_from_core_section_p (gdbarch);
+  sect_list = gdbarch_core_regset_sections (gdbarch);
+
   if (core_regset_p
       && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg",
 						     sizeof (gregs))) != NULL
@@ -3155,35 +3156,59 @@ linux_nat_do_thread_registers (bfd *obfd
 					       lwp,
 					       stop_signal, &gregs);
 
-  if (core_regset_p
-      && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg2",
-						     sizeof (fpregs))) != NULL
-      && regset->collect_regset != NULL)
-    regset->collect_regset (regset, regcache, -1,
-			    &fpregs, sizeof (fpregs));
+  /* The loop below uses the new struct core_regset_section, which stores
+     the supported section names and sizes for the core file. Note that
+     note PRSTATUS needs to be treated specially. But the other notes are
+     structurally the same, so they can benefit from the new struct.  */
+  if (core_regset_p && sect_list != NULL)
+    while (sect_list->sect_name != NULL)
+      {
+	/* .reg was already handled above  */
+	if (strcmp (sect_list->sect_name, ".reg") == 0)
+	  {
+	    sect_list++;
+	    continue;
+	  }
+	if ((regset = gdbarch_regset_from_core_section (gdbarch,
+							sect_list->sect_name,
+							sect_list->size))
+	     != NULL && regset->collect_regset != NULL)
+	  {
+	    gdb_regset = xmalloc (sect_list->size);
+	    regset->collect_regset (regset, regcache, -1,
+				    gdb_regset, sect_list->size);
+	    note_data = (char *) elfcore_write_register_note (obfd,
+							      note_data,
+							      note_size,
+							      sect_list->sect_name,
+							      gdb_regset,
+							      sect_list->size);
+	    xfree (gdb_regset);
+	  }
+	  sect_list++;
+      }
+
+  /* For architectures that does not have the struct core_regset_section implemented,
+     we use the old method. When all the architectures have the new support, the code
+     below should be deprecated. The FILL_FPXREGSET fallback was removed since i386
+     has the new method implemented.  */
   else
-    fill_fpregset (regcache, &fpregs, -1);
-
-  note_data = (char *) elfcore_write_prfpreg (obfd,
-					      note_data,
-					      note_size,
-					      &fpregs, sizeof (fpregs));
+    {
+      if (core_regset_p
+          && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg2",
+							 sizeof (fpregs))) != NULL
+	  && regset->collect_regset != NULL)
+	regset->collect_regset (regset, regcache, -1,
+				&fpregs, sizeof (fpregs));
+      else
+	fill_fpregset (regcache, &fpregs, -1);
 
-#ifdef FILL_FPXREGSET
-  if (core_regset_p
-      && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg-xfp",
-						     sizeof (fpxregs))) != NULL
-      && regset->collect_regset != NULL)
-    regset->collect_regset (regset, regcache, -1,
-			    &fpxregs, sizeof (fpxregs));
-  else
-    fill_fpxregset (regcache, &fpxregs, -1);
+      note_data = (char *) elfcore_write_prfpreg (obfd,
+						  note_data,
+						  note_size,
+						  &fpregs, sizeof (fpregs));
+    }
 
-  note_data = (char *) elfcore_write_prxfpreg (obfd,
-					       note_data,
-					       note_size,
-					       &fpxregs, sizeof (fpxregs));
-#endif
   return note_data;
 }
 
Index: src/gdb/utils.c
===================================================================
--- src.orig/gdb/utils.c
+++ src/gdb/utils.c
@@ -1075,7 +1075,6 @@ gdb_print_host_address (const void *addr
 
   fprintf_filtered (stream, "0x%lx", (unsigned long) addr);
 }
-
 
 /* This function supports the query, nquery, and yquery functions.
    Ask user a y-or-n question and return 0 if answer is no, 1 if
@@ -2869,6 +2868,14 @@ string_to_core_addr (const char *my_stri
   return addr;
 }
 
+const char *
+host_address_to_string (const void *addr)
+{
+  char *str = get_cell ();
+  sprintf (str, "0x%lx", (unsigned long) addr);
+  return str;
+}
+
 char *
 gdb_realpath (const char *filename)
 {
Index: src/gdb/defs.h
===================================================================
--- src.orig/gdb/defs.h
+++ src/gdb/defs.h
@@ -470,6 +470,8 @@ extern void fputstrn_unfiltered (const c
 /* Display the host ADDR on STREAM formatted as ``0x%x''. */
 extern void gdb_print_host_address (const void *addr, struct ui_file *stream);
 
+extern const char *host_address_to_string (const void *addr);
+
 /* Convert a CORE_ADDR into a HEX string.  paddr() is like %08lx.
    paddr_nz() is like %lx.  paddr_u() is like %lu. paddr_width() is
    for ``%*''. */
2008-05-07  Carlos Eduardo Seo  <cseo@linux.vnet.ibm.com>

	* i386-linux-tdep.c (i386_regset_rections): New register
	sections list for i386.
	  (i386_linux_init_abi): Initialized new gdbarch struct
	  core_regset_sections.

Index: src/gdb/i386-linux-tdep.c
===================================================================
--- src.orig/gdb/i386-linux-tdep.c
+++ src/gdb/i386-linux-tdep.c
@@ -35,6 +35,18 @@
 #include "solib-svr4.h"
 #include "symtab.h"
 #include "arch-utils.h"
+#include "regset.h"
+
+/* Supported register note sections  */
+static struct core_regset_section i386_regset_sections[] =
+{
+  { ".reg", 144 },
+  { ".reg2", 108 },
+#ifdef FILL_FPXREGSET
+  { ".reg-xfp", 512 },
+#endif
+  { NULL, 0 }
+};
 
 /* Return the name of register REG.  */
 
@@ -448,6 +460,9 @@ i386_linux_init_abi (struct gdbarch_info
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
                                              svr4_fetch_objfile_link_map);
 
+  /* Install supported register note sections  */
+  set_gdbarch_core_regset_sections (gdbarch, i386_regset_sections);
+
   /* Displaced stepping.  */
   set_gdbarch_displaced_step_copy_insn (gdbarch,
                                         simple_displaced_step_copy_insn);
2008-05-08  Carlos Eduardo Seo  <cseo@linux.vnet.ibm.com>

	* ppc-linux-tdep.c (ppc_regset_sections): Register
	sections list for ppc.
	  (ppc_linux_init_abi): Initialized new gdbarch struct
	core_regset_sections

Index: src/gdb/ppc-linux-tdep.c
===================================================================
--- src.orig/gdb/ppc-linux-tdep.c
+++ src/gdb/ppc-linux-tdep.c
@@ -45,6 +45,14 @@
 #include "features/rs6000/powerpc-altivec64l.c"
 #include "features/rs6000/powerpc-e500l.c"
 
+static struct core_regset_section ppc_regset_sections[] =
+{
+  { ".reg", 268 },
+  { ".reg2", 264 },
+  { ".reg-ppc-vmx", 544 },
+  { NULL, 0}
+};
+
 static CORE_ADDR
 ppc_linux_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
 {
@@ -1081,6 +1089,9 @@ ppc_linux_init_abi (struct gdbarch_info 
   set_gdbarch_regset_from_core_section (gdbarch, ppc_linux_regset_from_core_section);
   set_gdbarch_core_read_description (gdbarch, ppc_linux_core_read_description);
 
+  /* Supported register sections.  */
+  set_gdbarch_core_regset_sections (gdbarch, ppc_regset_sections);
+
   /* Enable TLS support.  */
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
                                              svr4_fetch_objfile_link_map);

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