This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [RFC] Add support for PPC Altivec registers in gcore
- From: Carlos Eduardo Seo <cseo at linux dot vnet dot ibm dot com>
- To: Ulrich Weigand <uweigand at de dot ibm dot com>
- Cc: GDB Patches Mailing List <gdb-patches at sourceware dot org>
- Date: Wed, 26 Mar 2008 22:51:24 -0300
- Subject: Re: [RFC] Add support for PPC Altivec registers in gcore
- Openpgp: id=8BFFA900
- References: <200803171906.m2HJ6YCB030691@d12av02.megacenter.de.ibm.com>
Ulrich Weigand wrote:
+v:struct core_regset_section *:core_regset_sections:const char *name, int len::::default_regset_sections::(char *) '0'
Not '0' -- just 0. (That *is* a difference!)
Yes, I know. But gcc 4.x will complain about reading through a null
pointer if I use 0.
I'm attaching a new patch with the modifications you suggested. If
you're OK with that, only this small issue remains. :)
Regards,
--
Carlos Eduardo Seo
Software Engineer
IBM Linux Technology Center
2008-03-26 Carlos Eduardo Seo <cseo@linux.vnet.ibm.com>
* gdbarch.c: Refreshed.
* gdbarch.h: Refreshed.
* gdbarch.sh: Added new gdbarch struct core_regset_sections.
* regset.h (core_regset_section): Declare.
* ppc-linux-tdep.c: (ppc_regset_sections): Register
sections list for ppc.
(ppc_linux_init_abi): Initialized new gdbarch struct
core_regset_sections.
* linux-nat.c (linux_nat_do_thread_registers): Added
support to the new gdbarch struct core_regset_sections.
* i386-linux-tdep.c (i386_regset_sections): Register
sections list for i386.
(i386_linux_init_abi): Initialized new gdbarch struct
core_regset_sections.
* arch-utils.c (default_regset_sections): Declare.
* arch-utils.h (default_regset_sections): Declare.
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;
@@ -344,6 +345,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 */
@@ -582,6 +584,8 @@ verify_gdbarch (struct gdbarch *gdbarch)
/* Skip verify of register_reggroup_p, invalid_p == 0 */
/* Skip verify of fetch_pointer_argument, has predicate */
/* Skip verify of regset_from_core_section, has predicate */
+ if (gdbarch->core_regset_sections == 0)
+ gdbarch->core_regset_sections = default_regset_sections;
/* Skip verify of core_xfer_shared_libraries, has predicate */
/* Skip verify of vtable_function_descriptors, invalid_p == 0 */
/* Skip verify of vbit_in_delta, invalid_p == 0 */
@@ -694,6 +698,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",
+ (char *) '0');
+ fprintf_unfiltered (file,
"gdbarch_dump: gdbarch_core_xfer_shared_libraries_p() = %d\n",
gdbarch_core_xfer_shared_libraries_p (gdbarch));
fprintf_unfiltered (file,
@@ -2810,6 +2817,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
@@ -50,6 +50,7 @@ struct target_ops;
struct obstack;
struct bp_target_info;
struct target_desc;
+struct core_regset_section;
extern struct gdbarch *current_gdbarch;
@@ -626,6 +627,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 core files. */
+
+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/gdbarch.sh
===================================================================
--- src.orig/gdb/gdbarch.sh
+++ src/gdb/gdbarch.sh
@@ -594,6 +594,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 core files.
+v:struct core_regset_section *:core_regset_sections:const char *name, int len::::default_regset_sections::(char *) '0'
+
# 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
@@ -729,6 +732,7 @@ struct target_ops;
struct obstack;
struct bp_target_info;
struct target_desc;
+struct core_regset_section;
extern struct gdbarch *current_gdbarch;
EOF
Index: src/gdb/regset.h
===================================================================
--- src.orig/gdb/regset.h
+++ src/gdb/regset.h
@@ -20,6 +20,12 @@
#ifndef REGSET_H
#define REGSET_H 1
+struct core_regset_section
+{
+ const char *sect_name;
+ int size;
+};
+
struct gdbarch;
struct regcache;
Index: src/gdb/ppc-linux-tdep.c
===================================================================
--- src.orig/gdb/ppc-linux-tdep.c
+++ src/gdb/ppc-linux-tdep.c
@@ -37,6 +37,16 @@
#include "trad-frame.h"
#include "frame-unwind.h"
#include "tramp-frame.h"
+#include <sys/procfs.h>
+#include "gregset.h"
+
+static struct core_regset_section ppc_regset_sections[] =
+{
+ { ".reg", sizeof (gdb_gregset_t) },
+ { ".reg2", sizeof (gdb_fpregset_t) },
+ { ".reg-ppc-vmx", 544 },
+ { NULL, 0 }
+};
static CORE_ADDR
ppc_linux_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
@@ -950,6 +960,10 @@ ppc_linux_init_abi (struct gdbarch_info
tramp_frame_prepend_unwinder (gdbarch, &ppc64_linux_sigaction_tramp_frame);
tramp_frame_prepend_unwinder (gdbarch, &ppc64_linux_sighandler_tramp_frame);
}
+
+ /* Register sections. */
+ set_gdbarch_core_regset_sections (gdbarch, ppc_regset_sections);
+
set_gdbarch_regset_from_core_section (gdbarch, ppc_linux_regset_from_core_section);
/* Enable TLS support. */
Index: src/gdb/linux-nat.c
===================================================================
--- src.orig/gdb/linux-nat.c
+++ src/gdb/linux-nat.c
@@ -2987,15 +2987,15 @@ 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;
@@ -3003,6 +3003,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
@@ -3018,35 +3020,46 @@ 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));
- else
- fill_fpregset (regcache, &fpregs, -1);
-
- note_data = (char *) elfcore_write_prfpreg (obfd,
- note_data,
- note_size,
- &fpregs, sizeof (fpregs));
-
-#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_prxfpreg (obfd,
- note_data,
- note_size,
- &fpxregs, sizeof (fpxregs));
-#endif
+ /* 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)
+ while ((++sect_list)->sect_name != NULL)
+ {
+ /* .reg was already handled above */
+ if (strcmp (sect_list->sect_name, ".reg") == 0)
+ 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);
+ }
+ /* For the architectures that need a fill_fpregset fallback */
+ else
+ {
+ if (strcmp (sect_list->sect_name, ".reg2") == 0)
+ {
+ fill_fpregset (regcache, &fpregs, -1);
+ note_data = (char *) elfcore_write_prfpreg (obfd,
+ note_data,
+ note_size,
+ &fpregs, sizeof (fpregs));
+ }
+ }
+ }
return note_data;
}
Index: src/gdb/i386-linux-tdep.c
===================================================================
--- src.orig/gdb/i386-linux-tdep.c
+++ src/gdb/i386-linux-tdep.c
@@ -28,12 +28,24 @@
#include "reggroups.h"
#include "dwarf2-frame.h"
#include "gdb_string.h"
-
+#include <sys/procfs.h>
+#include "gregset.h"
#include "i386-tdep.h"
#include "i386-linux-tdep.h"
#include "glibc-tdep.h"
#include "solib-svr4.h"
#include "symtab.h"
+#include "regset.h"
+
+static struct core_regset_section i386_regset_sections[] =
+{
+ { ".reg", sizeof (gdb_gregset_t) },
+ { ".reg2", sizeof (gdb_fpregset_t) },
+#ifdef FILL_FPXREGSET
+ { ".reg-xfp", sizeof (gdb_fpxregset_t) },
+#endif
+ { NULL, 0 }
+};
/* Return the name of register REG. */
@@ -446,6 +458,10 @@ i386_linux_init_abi (struct gdbarch_info
/* Enable TLS support. */
set_gdbarch_fetch_tls_load_module_address (gdbarch,
svr4_fetch_objfile_link_map);
+
+ /* Register sections. */
+ set_gdbarch_core_regset_sections (gdbarch, i386_regset_sections);
+
}
/* Provide a prototype to silence -Wmissing-prototypes. */
Index: src/gdb/arch-utils.c
===================================================================
--- src.orig/gdb/arch-utils.c
+++ src/gdb/arch-utils.c
@@ -31,11 +31,19 @@
#include "gdbcore.h"
#include "osabi.h"
#include "target-descriptions.h"
-
+#include <sys/procfs.h>
+#include "gregset.h"
#include "version.h"
+#include "regset.h"
#include "floatformat.h"
+struct core_regset_section default_regset_sections[] =
+{
+ { ".reg", sizeof (gdb_gregset_t) },
+ { ".reg2", sizeof (gdb_fpregset_t) },
+ { NULL, 0 }
+};
int
legacy_register_sim_regno (struct gdbarch *gdbarch, int regnum)
Index: src/gdb/arch-utils.h
===================================================================
--- src.orig/gdb/arch-utils.h
+++ src/gdb/arch-utils.h
@@ -21,11 +21,16 @@
#ifndef GDBARCH_UTILS_H
#define GDBARCH_UTILS_H
+#include "regset.h"
+
struct gdbarch;
struct frame_info;
struct minimal_symbol;
struct type;
struct gdbarch_info;
+struct core_regset_section;
+
+extern struct core_regset_section default_regset_sections[];
/* gdbarch trace variable */
extern int gdbarch_debug;
Index: src/gdb/Makefile.in
===================================================================
--- src.orig/gdb/Makefile.in
+++ src/gdb/Makefile.in
@@ -1892,7 +1892,7 @@ annotate.o: annotate.c $(defs_h) $(annot
arch-utils.o: arch-utils.c $(defs_h) $(arch_utils_h) $(buildsym_h) \
$(gdbcmd_h) $(inferior_h) $(gdb_string_h) $(regcache_h) \
$(gdb_assert_h) $(sim_regno_h) $(gdbcore_h) $(osabi_h) $(version_h) \
- $(floatformat_h) $(target_descriptions_h)
+ $(floatformat_h) $(target_descriptions_h) $(gregset_h) $(regset_h)
arm-linux-nat.o: arm-linux-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) \
$(gdb_string_h) $(regcache_h) $(arm_tdep_h) $(gregset_h) \
$(target_h) $(linux_nat_h) $(gdb_proc_service_h) $(arm_linux_tdep_h) \
@@ -2228,7 +2228,8 @@ i386-linux-nat.o: i386-linux-nat.c $(def
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)
+ $(i386_linux_tdep_h) $(glibc_tdep_h) $(solib_svr4_h) $(symtab_h) \
+ $(gregset_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) \