* gdbarch.sh: Added new gdbarch struct
authorCarlos Eduardo Seo <cseo@linux.vnet.ibm.com>
Sat, 24 May 2008 16:32:01 +0000 (16:32 +0000)
committerCarlos Eduardo Seo <cseo@linux.vnet.ibm.com>
Sat, 24 May 2008 16:32:01 +0000 (16:32 +0000)
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.
* 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.
* ppc-linux-tdep.c (ppc_regset_sections): Register
sections list for ppc.
  (ppc_linux_init_abi): Initialized new gdbarch struct
  core_regset_sections

gdb/ChangeLog
gdb/Makefile.in
gdb/defs.h
gdb/gdbarch.c
gdb/gdbarch.h
gdb/gdbarch.sh
gdb/i386-linux-tdep.c
gdb/linux-nat.c
gdb/ppc-linux-tdep.c
gdb/regset.h
gdb/utils.c

index 11af398..e0c8c40 100644 (file)
@@ -1,3 +1,24 @@
+2008-05-24  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.
+       * 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.
+       * ppc-linux-tdep.c (ppc_regset_sections): Register
+       sections list for ppc.
+         (ppc_linux_init_abi): Initialized new gdbarch struct
+         core_regset_sections
+
 2008-05-24  Andreas Schwab  <schwab@suse.de>
 
        * linespec.c (decode_objc): Save current language around call to
index fc2fe6a..1e1fc3c 100644 (file)
@@ -2268,7 +2268,7 @@ i386-linux-tdep.o: i386-linux-tdep.c $(defs_h) $(gdbcore_h) $(frame_h) \
        $(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) \
index 3f53925..9069156 100644 (file)
@@ -470,6 +470,8 @@ extern void fputstrn_unfiltered (const char *str, int n, int quotr, struct ui_fi
 /* 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 ``%*''. */
index f7478c4..6594b35 100644 (file)
@@ -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, struct ui_file *file)
                       "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 (struct gdbarch *gdbarch,
   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 ca8f9d4..44d1f2d 100644 (file)
@@ -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_regset_from_core_section_ftype) (struct g
 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 2942548..a38ba03 100755 (executable)
@@ -599,6 +599,9 @@ F:CORE_ADDR:fetch_pointer_argument:struct frame_info *frame, int argi, struct ty
 # 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 e3e79e1..5284f4a 100644 (file)
 #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 info, struct gdbarch *gdbarch)
   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 091e641..47dac59 100644 (file)
@@ -3112,15 +3112,14 @@ linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid,
 {
   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, ptid_t ptid,
   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, ptid_t ptid,
                                               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));
-  else
-    fill_fpregset (regcache, &fpregs, -1);
-
-  note_data = (char *) elfcore_write_prfpreg (obfd,
-                                             note_data,
-                                             note_size,
-                                             &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++;
+      }
 
-#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));
+  /* 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_fpxregset (regcache, &fpxregs, -1);
+    {
+      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);
+
+      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 abc25ed..5051cbf 100644 (file)
@@ -489,6 +489,14 @@ ppc64_standard_linkage1_target (struct frame_info *frame,
   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 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 2d11b85..0f894b2 100644 (file)
 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 d9953a0..76ea6b1 100644 (file)
@@ -2869,6 +2869,14 @@ string_to_core_addr (const char *my_string)
   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)
 {