2008-03-10 Carlos Eduardo Seo * 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 +#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) @@ -946,6 +956,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 @@ -2631,6 +2631,8 @@ linux_nat_do_thread_registers (bfd *obfd 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; @@ -2638,6 +2640,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 @@ -2653,35 +2657,31 @@ 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 && sect_list != NULL) + while ((++sect_list)->sect_name != NULL) + { + 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); + } + } 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 +#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 +#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 @@ -20,13 +20,15 @@ #ifndef GDBARCH_UTILS_H #define GDBARCH_UTILS_H - +#include "regset.h" struct gdbarch; struct frame_info; struct minimal_symbol; struct type; struct gdbarch_info; +extern struct core_regset_section default_regset_sections[]; + /* gdbarch trace variable */ extern int gdbarch_debug;