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:

With these final changes, the patch is OK.



Thanks, Ulrich. This is the final version then.


I'll submit the binutils patch now and when that's accepted, I'll commit this one.

Regards,

--
Carlos Eduardo Seo
Software Engineer
IBM Linux Technology Center
2008-05-14  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 for 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
@@ -599,6 +599,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
@@ -814,6 +817,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
@@ -221,6 +221,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;
@@ -350,6 +351,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 */
@@ -721,6 +723,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,
@@ -2853,6 +2858,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;
 
@@ -630,6 +631,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
@@ -3112,15 +3112,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;
@@ -3128,6 +3127,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
@@ -3143,35 +3144,56 @@ 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;
+	  }
+	regset = gdbarch_regset_from_core_section (gdbarch,
+						   sect_list->sect_name,
+						   sect_list->size);
+	gdb_assert (regset && regset->collect_regset);
+	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 deleted.  */
   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
@@ -2869,6 +2869,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-14  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.
	* Makefile.in: Updated to reflect dependency changes.

Index: src/gdb/i386-linux-tdep.c
===================================================================
--- src.orig/gdb/i386-linux-tdep.c
+++ src/gdb/i386-linux-tdep.c
@@ -35,6 +35,16 @@
 #include "solib-svr4.h"
 #include "symtab.h"
 #include "arch-utils.h"
+#include "regset.h"
+
+/* Supported register note sections.  */
+static struct core_regset_section i386_linux_regset_sections[] =
+{
+  { ".reg", 144 },
+  { ".reg2", 108 },
+  { ".reg-xfp", 512 },
+  { NULL, 0 }
+};
 
 /* Return the name of register REG.  */
 
@@ -448,6 +458,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_linux_regset_sections);
+
   /* Displaced stepping.  */
   set_gdbarch_displaced_step_copy_insn (gdbarch,
                                         simple_displaced_step_copy_insn);
Index: src/gdb/Makefile.in
===================================================================
--- src.orig/gdb/Makefile.in
+++ src/gdb/Makefile.in
@@ -2268,7 +2268,7 @@ i386-linux-tdep.o: i386-linux-tdep.c $(d
 	$(value_h) $(regcache_h) $(inferior_h) $(osabi_h) $(reggroups_h) \
 	$(dwarf2_frame_h) $(gdb_string_h) $(i386_tdep_h) \
 	$(i386_linux_tdep_h) $(glibc_tdep_h) $(solib_svr4_h) $(symtab_h) \
-	$(arch_utils_h)
+	$(arch_utils_h) $(regset_h)
 i386-nat.o: i386-nat.c $(defs_h) $(breakpoint_h) $(command_h) $(gdbcmd_h) \
 	$(target_h)
 i386nbsd-nat.o: i386nbsd-nat.c $(defs_h) $(gdbcore_h) $(regcache_h) \
2008-05-14  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
@@ -489,6 +489,14 @@ ppc64_standard_linkage1_target (struct f
   return ppc64_desc_entry_point (desc);
 }
 
+static struct core_regset_section ppc_linux_regset_sections[] =
+{
+  { ".reg", 268 },
+  { ".reg2", 264 },
+  { ".reg-ppc-vmx", 544 },
+  { NULL, 0}
+};
+
 static CORE_ADDR
 ppc64_standard_linkage2_target (struct frame_info *frame,
 				CORE_ADDR pc, unsigned int *insn)
@@ -1042,6 +1050,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_linux_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]