diff options
author | Andreas Arnez <arnez@linux.vnet.ibm.com> | 2014-09-12 08:42:48 +0000 |
---|---|---|
committer | Andreas Krebbel <krebbel@linux.vnet.ibm.com> | 2014-09-30 09:14:33 +0200 |
commit | 8f0435f75e3c9676d2e177ce055fed3155fd9476 (patch) | |
tree | 08032004cab3c1c432651500560db02af97b86bc /gdb | |
parent | 5aa82d050d61784823767fe3c982b6862fa47391 (diff) | |
download | fsf-binutils-gdb-8f0435f75e3c9676d2e177ce055fed3155fd9476.zip fsf-binutils-gdb-8f0435f75e3c9676d2e177ce055fed3155fd9476.tar.gz fsf-binutils-gdb-8f0435f75e3c9676d2e177ce055fed3155fd9476.tar.bz2 |
Add 'regset' parameter to 'iterate_over_regset_sections_cb'
This adds the 'regset' parameter to the iterator callback.
Consequently the 'regset_from_core_section' method is dropped for all
targets that provide the iterator method.
This change prepares for replacing regset_from_core_section
everywhere, thereby eliminating one gdbarch interface. Since the
iterator is usually no more complex than regset_from_core_section
alone, targets that previously didn't define core_regset_sections will
then gain multi-arch capable core file generation support without
increased complexity.
gdb/ChangeLog:
* gdbarch.sh (iterate_over_regset_sections_cb): Add regset
parameter.
* gdbarch.h: Regenerate.
* corelow.c (sniff_core_bfd): Don't sniff if gdbarch has a regset
iterator.
(get_core_register_section): Add parameter 'regset' and use it, if
set. Add parameter 'min_size' and verify the bfd section size
against it.
(get_core_registers_cb): Add parameter 'regset' and pass it to
get_core_register section. For the "standard" register sections
".reg" and ".reg2", set an appropriate default for human_name.
(get_core_registers): Don't abort when the gdbarch has an iterator
but no regset_from_core_section. Add NULL/0 for parameters
'regset'/'min_size' in calls to get_core_register_section.
* linux-tdep.c (linux_collect_regset_section_cb): Add parameter
'regset' and use it instead of calling the
regset_from_core_section gdbarch method.
* i386-tdep.h (struct gdbarch_tdep): Add field 'fpregset'.
* i386-tdep.c (i386_supply_xstateregset)
(i386_collect_xstateregset, i386_xstateregset): Moved to
i386-linux-tdep.c.
(i386_regset_from_core_section): Drop handling for .reg-xfp and
.reg-xstate.
(i386_gdbarch_init): Set tdep field 'fpregset'. Enable generic
core file support only if the regset iterator hasn't been set.
* i386-linux-tdep.c (i386_linux_supply_xstateregset)
(i386_linux_collect_xstateregset, i386_linux_xstateregset): New.
Moved from i386-tdep.c and renamed to *_linux*.
(i386_linux_iterate_over_regset_sections): Add regset parameter to
each callback invocation. Allow any .reg-xstate size when reading
from a core file.
* amd64-tdep.c (amd64_supply_xstateregset)
(amd64_collect_xstateregset, amd64_xstateregset): Moved to
amd64-linux-tdep.c.
(amd64_regset_from_core_section): Remove.
(amd64_init_abi): Set new tdep field 'fpregset'. No longer
install an amd64-specific regset_from_core_section gdbarch method.
* amd64-linux-tdep.c (amd64_linux_supply_xstateregset)
(amd64_linux_collect_xstateregset, amd64_linux_xstateregset): New.
Moved from amd64-tdep.c and renamed to *_linux*.
(amd64_linux_iterate_over_regset_sections): Add regset parameter
to each callback invocation. Allow any .reg-xstate size when
reading from a core file.
* arm-linux-tdep.c (arm_linux_regset_from_core_section): Remove.
(arm_linux_iterate_over_regset_sections): Add regset parameter to
each callback invocation.
(arm_linux_init_abi): No longer set the regset_from_core_section
gdbarch method.
* ppc-linux-tdep.c (ppc_linux_regset_from_core_section): Remove.
(ppc_linux_iterate_over_regset_sections): Add regset parameter to
each callback invocation.
(ppc_linux_init_abi): No longer set the regset_from_core_section
gdbarch method.
* s390-linux-tdep.c (struct gdbarch_tdep): Remove the fields
gregset, sizeof_gregset, fpregset, and sizeof_fpregset.
(s390_regset_from_core_section): Remove.
(s390_iterate_over_regset_sections): Add regset parameter to each
callback invocation.
(s390_gdbarch_init): No longer set the regset_from_core_section
gdbarch method. Drop initialization of deleted tdep fields.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 63 | ||||
-rw-r--r-- | gdb/amd64-linux-tdep.c | 36 | ||||
-rw-r--r-- | gdb/amd64-tdep.c | 51 | ||||
-rw-r--r-- | gdb/amd64-tdep.h | 2 | ||||
-rw-r--r-- | gdb/arm-linux-tdep.c | 33 | ||||
-rw-r--r-- | gdb/corelow.c | 52 | ||||
-rw-r--r-- | gdb/gdbarch.h | 3 | ||||
-rwxr-xr-x | gdb/gdbarch.sh | 3 | ||||
-rw-r--r-- | gdb/i386-linux-tdep.c | 40 | ||||
-rw-r--r-- | gdb/i386-tdep.c | 42 | ||||
-rw-r--r-- | gdb/i386-tdep.h | 6 | ||||
-rw-r--r-- | gdb/linux-tdep.c | 3 | ||||
-rw-r--r-- | gdb/ppc-linux-tdep.c | 35 | ||||
-rw-r--r-- | gdb/s390-linux-tdep.c | 69 |
14 files changed, 220 insertions, 218 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 589c601..522849a 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,68 @@ 2014-09-30 Andreas Arnez <arnez@linux.vnet.ibm.com> + * gdbarch.sh (iterate_over_regset_sections_cb): Add regset + parameter. + * gdbarch.h: Regenerate. + * corelow.c (sniff_core_bfd): Don't sniff if gdbarch has a regset + iterator. + (get_core_register_section): Add parameter 'regset' and use it, if + set. Add parameter 'min_size' and verify the bfd section size + against it. + (get_core_registers_cb): Add parameter 'regset' and pass it to + get_core_register section. For the "standard" register sections + ".reg" and ".reg2", set an appropriate default for human_name. + (get_core_registers): Don't abort when the gdbarch has an iterator + but no regset_from_core_section. Add NULL/0 for parameters + 'regset'/'min_size' in calls to get_core_register_section. + * linux-tdep.c (linux_collect_regset_section_cb): Add parameter + 'regset' and use it instead of calling the + regset_from_core_section gdbarch method. + * i386-tdep.h (struct gdbarch_tdep): Add field 'fpregset'. + * i386-tdep.c (i386_supply_xstateregset) + (i386_collect_xstateregset, i386_xstateregset): Moved to + i386-linux-tdep.c. + (i386_regset_from_core_section): Drop handling for .reg-xfp and + .reg-xstate. + (i386_gdbarch_init): Set tdep field 'fpregset'. Enable generic + core file support only if the regset iterator hasn't been set. + * i386-linux-tdep.c (i386_linux_supply_xstateregset) + (i386_linux_collect_xstateregset, i386_linux_xstateregset): New. + Moved from i386-tdep.c and renamed to *_linux*. + (i386_linux_iterate_over_regset_sections): Add regset parameter to + each callback invocation. Allow any .reg-xstate size when reading + from a core file. + * amd64-tdep.c (amd64_supply_xstateregset) + (amd64_collect_xstateregset, amd64_xstateregset): Moved to + amd64-linux-tdep.c. + (amd64_regset_from_core_section): Remove. + (amd64_init_abi): Set new tdep field 'fpregset'. No longer + install an amd64-specific regset_from_core_section gdbarch method. + * amd64-linux-tdep.c (amd64_linux_supply_xstateregset) + (amd64_linux_collect_xstateregset, amd64_linux_xstateregset): New. + Moved from amd64-tdep.c and renamed to *_linux*. + (amd64_linux_iterate_over_regset_sections): Add regset parameter + to each callback invocation. Allow any .reg-xstate size when + reading from a core file. + * arm-linux-tdep.c (arm_linux_regset_from_core_section): Remove. + (arm_linux_iterate_over_regset_sections): Add regset parameter to + each callback invocation. + (arm_linux_init_abi): No longer set the regset_from_core_section + gdbarch method. + * ppc-linux-tdep.c (ppc_linux_regset_from_core_section): Remove. + (ppc_linux_iterate_over_regset_sections): Add regset parameter to + each callback invocation. + (ppc_linux_init_abi): No longer set the regset_from_core_section + gdbarch method. + * s390-linux-tdep.c (struct gdbarch_tdep): Remove the fields + gregset, sizeof_gregset, fpregset, and sizeof_fpregset. + (s390_regset_from_core_section): Remove. + (s390_iterate_over_regset_sections): Add regset parameter to each + callback invocation. + (s390_gdbarch_init): No longer set the regset_from_core_section + gdbarch method. Drop initialization of deleted tdep fields. + +2014-09-30 Andreas Arnez <arnez@linux.vnet.ibm.com> + * amd64-linux-tdep.c (amd64_linux_regset_sections): Remove. (amd64_linux_iterate_over_regset_sections): New. (amd64_linux_init_abi_common): Don't install the regset section diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c index 2432bae..edbb1b3 100644 --- a/gdb/amd64-linux-tdep.c +++ b/gdb/amd64-linux-tdep.c @@ -1600,6 +1600,33 @@ amd64_linux_core_read_description (struct gdbarch *gdbarch, } } +/* Similar to amd64_supply_fpregset, but use XSAVE extended state. */ + +static void +amd64_linux_supply_xstateregset (const struct regset *regset, + struct regcache *regcache, int regnum, + const void *xstateregs, size_t len) +{ + amd64_supply_xsave (regcache, regnum, xstateregs); +} + +/* Similar to amd64_collect_fpregset, but use XSAVE extended state. */ + +static void +amd64_linux_collect_xstateregset (const struct regset *regset, + const struct regcache *regcache, + int regnum, void *xstateregs, size_t len) +{ + amd64_collect_xsave (regcache, regnum, xstateregs, 1); +} + +static const struct regset amd64_linux_xstateregset = + { + NULL, + amd64_linux_supply_xstateregset, + amd64_linux_collect_xstateregset + }; + /* Iterate over core file register note sections. */ static void @@ -1608,9 +1635,12 @@ amd64_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, void *cb_data, const struct regcache *regcache) { - cb (".reg", 27 * 8, "general-purpose", cb_data); - cb (".reg2", 512, "floating-point", cb_data); - cb (".reg-xstate", X86_XSTATE_MAX_SIZE, "XSAVE extended state", cb_data); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + cb (".reg", 27 * 8, &i386_gregset, NULL, cb_data); + cb (".reg2", 512, &amd64_fpregset, NULL, cb_data); + cb (".reg-xstate", regcache ? X86_XSTATE_MAX_SIZE : 0, + &amd64_linux_xstateregset, "XSAVE extended state", cb_data); } static void diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index abd9c48..7c8575a 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -2868,53 +2868,10 @@ amd64_collect_fpregset (const struct regset *regset, amd64_collect_fxsave (regcache, regnum, fpregs); } -/* Similar to amd64_supply_fpregset, but use XSAVE extended state. */ - -static void -amd64_supply_xstateregset (const struct regset *regset, - struct regcache *regcache, int regnum, - const void *xstateregs, size_t len) -{ - amd64_supply_xsave (regcache, regnum, xstateregs); -} - -/* Similar to amd64_collect_fpregset, but use XSAVE extended state. */ - -static void -amd64_collect_xstateregset (const struct regset *regset, - const struct regcache *regcache, - int regnum, void *xstateregs, size_t len) -{ - amd64_collect_xsave (regcache, regnum, xstateregs, 1); -} - -static const struct regset amd64_fpregset = +const struct regset amd64_fpregset = { NULL, amd64_supply_fpregset, amd64_collect_fpregset }; - -static const struct regset amd64_xstateregset = - { - NULL, amd64_supply_xstateregset, amd64_collect_xstateregset - }; - -/* Return the appropriate register set for the core section identified - by SECT_NAME and SECT_SIZE. */ - -static const struct regset * -amd64_regset_from_core_section (struct gdbarch *gdbarch, - const char *sect_name, size_t sect_size) -{ - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - - if (strcmp (sect_name, ".reg2") == 0 && sect_size == tdep->sizeof_fpregset) - return &amd64_fpregset; - - if (strcmp (sect_name, ".reg-xstate") == 0) - return &amd64_xstateregset; - - return i386_regset_from_core_section (gdbarch, sect_name, sect_size); -} /* Figure out where the longjmp will land. Slurp the jmp_buf out of @@ -2973,6 +2930,7 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* AMD64 generally uses `fxsave' instead of `fsave' for saving its floating-point registers. */ tdep->sizeof_fpregset = I387_SIZEOF_FXSAVE; + tdep->fpregset = &amd64_fpregset; if (! tdesc_has_registers (tdesc)) tdesc = tdesc_amd64; @@ -3086,11 +3044,6 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) frame_unwind_append_unwinder (gdbarch, &amd64_frame_unwind); frame_base_set_default (gdbarch, &amd64_frame_base); - /* If we have a register mapping, enable the generic core file support. */ - if (tdep->gregset_reg_offset) - set_gdbarch_regset_from_core_section (gdbarch, - amd64_regset_from_core_section); - set_gdbarch_get_longjmp_target (gdbarch, amd64_get_longjmp_target); set_gdbarch_relocate_instruction (gdbarch, amd64_relocate_instruction); diff --git a/gdb/amd64-tdep.h b/gdb/amd64-tdep.h index f1b039e..641eef3 100644 --- a/gdb/amd64-tdep.h +++ b/gdb/amd64-tdep.h @@ -119,6 +119,8 @@ extern void amd64_collect_fxsave (const struct regcache *regcache, int regnum, extern void amd64_collect_xsave (const struct regcache *regcache, int regnum, void *xsave, int gcore); +/* Floating-point register set. */ +extern const struct regset amd64_fpregset; /* Variables exported from amd64-linux-tdep.c. */ extern int amd64_linux_gregset_reg_offset[]; diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c index 22decd5..e3587f3 100644 --- a/gdb/arm-linux-tdep.c +++ b/gdb/arm-linux-tdep.c @@ -731,28 +731,6 @@ static const struct regset arm_linux_vfpregset = NULL, arm_linux_supply_vfp, arm_linux_collect_vfp }; -/* Return the appropriate register set for the core section identified - by SECT_NAME and SECT_SIZE. */ - -static const struct regset * -arm_linux_regset_from_core_section (struct gdbarch *gdbarch, - const char *sect_name, size_t sect_size) -{ - if (strcmp (sect_name, ".reg") == 0 - && sect_size == ARM_LINUX_SIZEOF_GREGSET) - return &arm_linux_gregset; - - if (strcmp (sect_name, ".reg2") == 0 - && sect_size == ARM_LINUX_SIZEOF_NWFPE) - return &arm_linux_fpregset; - - if (strcmp (sect_name, ".reg-arm-vfp") == 0 - && sect_size == ARM_LINUX_SIZEOF_VFP) - return &arm_linux_vfpregset; - - return NULL; -} - /* Iterate over core file register note sections. */ static void @@ -763,13 +741,14 @@ arm_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - cb (".reg", ARM_LINUX_SIZEOF_GREGSET, "general-purpose", cb_data); + cb (".reg", ARM_LINUX_SIZEOF_GREGSET, &arm_linux_gregset, NULL, cb_data); if (tdep->have_vfp_registers) - cb (".reg-arm-vfp", ARM_LINUX_SIZEOF_VFP, "VFP floating-point", - cb_data); + cb (".reg-arm-vfp", ARM_LINUX_SIZEOF_VFP, &arm_linux_vfpregset, + "VFP floating-point", cb_data); else if (tdep->have_fpa_registers) - cb (".reg2", ARM_LINUX_SIZEOF_NWFPE, "FPA floating-point", cb_data); + cb (".reg2", ARM_LINUX_SIZEOF_NWFPE, &arm_linux_fpregset, + "FPA floating-point", cb_data); } /* Determine target description from core file. */ @@ -1457,8 +1436,6 @@ arm_linux_init_abi (struct gdbarch_info info, &arm_kernel_linux_restart_syscall_tramp_frame); /* Core file support. */ - set_gdbarch_regset_from_core_section (gdbarch, - arm_linux_regset_from_core_section); set_gdbarch_iterate_over_regset_sections (gdbarch, arm_linux_iterate_over_regset_sections); set_gdbarch_core_read_description (gdbarch, arm_linux_core_read_description); diff --git a/gdb/corelow.c b/gdb/corelow.c index 7e64e1d..42af7f4 100644 --- a/gdb/corelow.c +++ b/gdb/corelow.c @@ -134,7 +134,9 @@ sniff_core_bfd (bfd *abfd) /* Don't sniff if we have support for register sets in CORE_GDBARCH. */ - if (core_gdbarch && gdbarch_regset_from_core_section_p (core_gdbarch)) + if (core_gdbarch + && (gdbarch_iterate_over_regset_sections_p (core_gdbarch) + || gdbarch_regset_from_core_section_p (core_gdbarch))) return NULL; for (cf = core_file_fns; cf != NULL; cf = cf->next) @@ -489,7 +491,9 @@ core_detach (struct target_ops *ops, const char *args, int from_tty) static void get_core_register_section (struct regcache *regcache, + const struct regset *regset, const char *name, + int min_size, int which, const char *human_name, int required) @@ -517,6 +521,12 @@ get_core_register_section (struct regcache *regcache, } size = bfd_section_size (core_bfd, section); + if (size < min_size) + { + warning (_("Section `%s' in core file too small."), section_name); + return; + } + contents = alloca (size); if (! bfd_get_section_contents (core_bfd, section, contents, (file_ptr) 0, size)) @@ -526,10 +536,9 @@ get_core_register_section (struct regcache *regcache, return; } - if (core_gdbarch && gdbarch_regset_from_core_section_p (core_gdbarch)) + if (regset == NULL + && core_gdbarch && gdbarch_regset_from_core_section_p (core_gdbarch)) { - const struct regset *regset; - regset = gdbarch_regset_from_core_section (core_gdbarch, name, size); if (regset == NULL) @@ -539,7 +548,10 @@ get_core_register_section (struct regcache *regcache, human_name); return; } + } + if (regset != NULL) + { regset->supply_regset (regset, regcache, -1, contents, size); return; } @@ -555,16 +567,28 @@ get_core_register_section (struct regcache *regcache, static void get_core_registers_cb (const char *sect_name, int size, + const struct regset *regset, const char *human_name, void *cb_data) { struct regcache *regcache = (struct regcache *) cb_data; + int required = 0; if (strcmp (sect_name, ".reg") == 0) - get_core_register_section (regcache, sect_name, 0, human_name, 1); + { + required = 1; + if (human_name == NULL) + human_name = "general-purpose"; + } else if (strcmp (sect_name, ".reg2") == 0) - get_core_register_section (regcache, sect_name, 2, human_name, 0); - else - get_core_register_section (regcache, sect_name, 3, human_name, 0); + { + if (human_name == NULL) + human_name = "floating-point"; + } + + /* The 'which' parameter is only used when no regset is provided. + Thus we just set it to -1. */ + get_core_register_section (regcache, regset, sect_name, + size, -1, human_name, required); } /* Get the registers out of a core file. This is the machine- @@ -581,7 +605,9 @@ get_core_registers (struct target_ops *ops, int i; struct gdbarch *gdbarch; - if (!(core_gdbarch && gdbarch_regset_from_core_section_p (core_gdbarch)) + if (!(core_gdbarch + && (gdbarch_iterate_over_regset_sections_p (core_gdbarch) + || gdbarch_regset_from_core_section_p (core_gdbarch))) && (core_vec == NULL || core_vec->core_read_registers == NULL)) { fprintf_filtered (gdb_stderr, @@ -596,10 +622,10 @@ get_core_registers (struct target_ops *ops, (void *) regcache, NULL); else { - get_core_register_section (regcache, - ".reg", 0, "general-purpose", 1); - get_core_register_section (regcache, - ".reg2", 2, "floating-point", 0); + get_core_register_section (regcache, NULL, + ".reg", 0, 0, "general-purpose", 1); + get_core_register_section (regcache, NULL, + ".reg2", 0, 2, "floating-point", 0); } /* Mark all registers not found in the core as unavailable. */ diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index bbda3da..90a63ca 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -82,7 +82,8 @@ typedef int (iterate_over_objfiles_in_search_order_cb_ftype) (struct objfile *objfile, void *cb_data); typedef void (iterate_over_regset_sections_cb) - (const char *sect_name, int size, const char *human_name, void *cb_data); + (const char *sect_name, int size, const struct regset *regset, + const char *human_name, void *cb_data); /* The following are pre-initialized by GDBARCH. */ diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index 80d3eec..293854f 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -1176,7 +1176,8 @@ typedef int (iterate_over_objfiles_in_search_order_cb_ftype) (struct objfile *objfile, void *cb_data); typedef void (iterate_over_regset_sections_cb) - (const char *sect_name, int size, const char *human_name, void *cb_data); + (const char *sect_name, int size, const struct regset *regset, + const char *human_name, void *cb_data); EOF # function typedef's diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c index 4ee6874..7feb21d 100644 --- a/gdb/i386-linux-tdep.c +++ b/gdb/i386-linux-tdep.c @@ -648,6 +648,35 @@ i386_linux_core_read_description (struct gdbarch *gdbarch, return tdesc_i386_mmx_linux; } +/* Similar to i386_supply_fpregset, but use XSAVE extended state. */ + +static void +i386_linux_supply_xstateregset (const struct regset *regset, + struct regcache *regcache, int regnum, + const void *xstateregs, size_t len) +{ + i387_supply_xsave (regcache, regnum, xstateregs); +} + +/* Similar to i386_collect_fpregset, but use XSAVE extended state. */ + +static void +i386_linux_collect_xstateregset (const struct regset *regset, + const struct regcache *regcache, + int regnum, void *xstateregs, size_t len) +{ + i387_collect_xsave (regcache, regnum, xstateregs, 1); +} + +/* Register set definitions. */ + +static const struct regset i386_linux_xstateregset = + { + NULL, + i386_linux_supply_xstateregset, + i386_linux_collect_xstateregset + }; + /* Iterate over core file register note sections. */ static void @@ -658,14 +687,17 @@ i386_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - cb (".reg", 68, "general-purpose", cb_data); + cb (".reg", 68, &i386_gregset, NULL, cb_data); if (tdep->xcr0 & X86_XSTATE_AVX) - cb (".reg-xstate", X86_XSTATE_MAX_SIZE, "XSAVE extended state", cb_data); + /* Use max size for writing, accept any size when reading. */ + cb (".reg-xstate", regcache ? X86_XSTATE_MAX_SIZE : 0, + &i386_linux_xstateregset, "XSAVE extended state", cb_data); else if (tdep->xcr0 & X86_XSTATE_SSE) - cb (".reg-xfp", 512, "extended floating-point", cb_data); + cb (".reg-xfp", 512, &i386_fpregset, "extended floating-point", + cb_data); else - cb (".reg2", 108, "floating-point", cb_data); + cb (".reg2", 108, &i386_fpregset, NULL, cb_data); } /* Linux kernel shows PC value after the 'int $0x80' instruction even if diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 1e68505..8f8cc99 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -3806,26 +3806,6 @@ i386_collect_fpregset (const struct regset *regset, i387_collect_fsave (regcache, regnum, fpregs); } -/* Similar to i386_supply_fpregset, but use XSAVE extended state. */ - -static void -i386_supply_xstateregset (const struct regset *regset, - struct regcache *regcache, int regnum, - const void *xstateregs, size_t len) -{ - i387_supply_xsave (regcache, regnum, xstateregs); -} - -/* Similar to i386_collect_fpregset , but use XSAVE extended state. */ - -static void -i386_collect_xstateregset (const struct regset *regset, - const struct regcache *regcache, - int regnum, void *xstateregs, size_t len) -{ - i387_collect_xsave (regcache, regnum, xstateregs, 1); -} - /* Register set definitions. */ const struct regset i386_gregset = @@ -3833,16 +3813,11 @@ const struct regset i386_gregset = NULL, i386_supply_gregset, i386_collect_gregset }; -static const struct regset i386_fpregset = +const struct regset i386_fpregset = { NULL, i386_supply_fpregset, i386_collect_fpregset }; -static const struct regset i386_xstateregset = - { - NULL, i386_supply_xstateregset, i386_collect_xstateregset - }; - /* Return the appropriate register set for the core section identified by SECT_NAME and SECT_SIZE. */ @@ -3853,15 +3828,10 @@ i386_regset_from_core_section (struct gdbarch *gdbarch, struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); if (strcmp (sect_name, ".reg") == 0 && sect_size == tdep->sizeof_gregset) - return &i386_gregset; - - if ((strcmp (sect_name, ".reg2") == 0 && sect_size == tdep->sizeof_fpregset) - || (strcmp (sect_name, ".reg-xfp") == 0 - && sect_size == I387_SIZEOF_FXSAVE)) - return &i386_fpregset; + return &i386_gregset; - if (strcmp (sect_name, ".reg-xstate") == 0) - return &i386_xstateregset; + if (strcmp (sect_name, ".reg2") == 0 && sect_size == tdep->sizeof_fpregset) + return tdep->fpregset; return NULL; } @@ -8291,6 +8261,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Floating-point registers. */ tdep->sizeof_fpregset = I387_SIZEOF_FSAVE; + tdep->fpregset = &i386_fpregset; /* The default settings include the FPU registers, the MMX registers and the SSE registers. This can be overridden for a specific ABI @@ -8595,7 +8566,8 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* If we have a register mapping, enable the generic core file support, unless it has already been enabled. */ if (tdep->gregset_reg_offset - && !gdbarch_regset_from_core_section_p (gdbarch)) + && !gdbarch_regset_from_core_section_p (gdbarch) + && !gdbarch_iterate_over_regset_sections_p (gdbarch)) set_gdbarch_regset_from_core_section (gdbarch, i386_regset_from_core_section); diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h index e0950a3..db8f4f7 100644 --- a/gdb/i386-tdep.h +++ b/gdb/i386-tdep.h @@ -237,6 +237,9 @@ struct gdbarch_tdep int (*i386_sysenter_record) (struct regcache *regcache); /* Parse syscall args. */ int (*i386_syscall_record) (struct regcache *regcache); + + /* Regsets. */ + const struct regset *fpregset; }; /* Floating-point registers. */ @@ -387,6 +390,9 @@ extern void i386_supply_gregset (const struct regset *regset, /* General-purpose register set. */ extern const struct regset i386_gregset; +/* Floating-point register set. */ +extern const struct regset i386_fpregset; + /* Return the appropriate register set for the core section identified by SECT_NAME and SECT_SIZE. */ extern const struct regset * diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c index 3d8b1fc..fcba93b 100644 --- a/gdb/linux-tdep.c +++ b/gdb/linux-tdep.c @@ -1105,16 +1105,15 @@ struct linux_collect_regset_section_cb_data static void linux_collect_regset_section_cb (const char *sect_name, int size, + const struct regset *regset, const char *human_name, void *cb_data) { - const struct regset *regset; char *buf; struct linux_collect_regset_section_cb_data *data = cb_data; if (data->abort_iteration) return; - regset = gdbarch_regset_from_core_section (data->gdbarch, sect_name, size); gdb_assert (regset && regset->collect_regset); buf = xmalloc (size); diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c index 7ab3255..4d7d051 100644 --- a/gdb/ppc-linux-tdep.c +++ b/gdb/ppc-linux-tdep.c @@ -489,27 +489,6 @@ ppc_linux_fpregset (void) return &ppc32_linux_fpregset; } -static const struct regset * -ppc_linux_regset_from_core_section (struct gdbarch *core_arch, - const char *sect_name, size_t sect_size) -{ - struct gdbarch_tdep *tdep = gdbarch_tdep (core_arch); - if (strcmp (sect_name, ".reg") == 0) - { - if (tdep->wordsize == 4) - return &ppc32_linux_gregset; - else - return &ppc64_linux_gregset; - } - if (strcmp (sect_name, ".reg2") == 0) - return &ppc32_linux_fpregset; - if (strcmp (sect_name, ".reg-ppc-vmx") == 0) - return &ppc32_linux_vrregset; - if (strcmp (sect_name, ".reg-ppc-vsx") == 0) - return &ppc32_linux_vsxregset; - return NULL; -} - /* Iterate over supported core file register note sections. */ static void @@ -522,14 +501,18 @@ ppc_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, int have_altivec = tdep->ppc_vr0_regnum != -1; int have_vsx = tdep->ppc_vsr0_upper_regnum != -1; - cb (".reg", 48 * tdep->wordsize, "general-purpose", cb_data); - cb (".reg2", 264, "floating-point", cb_data); + if (tdep->wordsize == 4) + cb (".reg", 48 * 4, &ppc32_linux_gregset, NULL, cb_data); + else + cb (".reg", 48 * 8, &ppc64_linux_gregset, NULL, cb_data); + + cb (".reg2", 264, &ppc32_linux_fpregset, NULL, cb_data); if (have_altivec) - cb (".reg-ppc-vmx", 544, "ppc Altivec", cb_data); + cb (".reg-ppc-vmx", 544, &ppc32_linux_vrregset, "ppc Altivec", cb_data); if (have_vsx) - cb (".reg-ppc-vsx", 256, "POWER7 VSX", cb_data); + cb (".reg-ppc-vsx", 256, &ppc32_linux_vsxregset, "POWER7 VSX", cb_data); } static void @@ -1385,8 +1368,6 @@ ppc_linux_init_abi (struct gdbarch_info info, set_gdbarch_elfcore_write_linux_prpsinfo (gdbarch, elfcore_write_ppc_linux_prpsinfo32); - set_gdbarch_regset_from_core_section (gdbarch, - ppc_linux_regset_from_core_section); set_gdbarch_core_read_description (gdbarch, ppc_linux_core_read_description); set_gdbarch_iterate_over_regset_sections (gdbarch, ppc_linux_iterate_over_regset_sections); diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c index 840431d..abd2e40 100644 --- a/gdb/s390-linux-tdep.c +++ b/gdb/s390-linux-tdep.c @@ -82,13 +82,6 @@ struct gdbarch_tdep int pc_regnum; int cc_regnum; - /* Core file register sets. */ - const struct regset *gregset; - int sizeof_gregset; - - const struct regset *fpregset; - int sizeof_fpregset; - int have_linux_v1; int have_linux_v2; int have_tdb; @@ -536,36 +529,6 @@ const struct regset s390_tdb_regset = { regcache_collect_regset }; -/* Return the appropriate register set for the core section identified - by SECT_NAME and SECT_SIZE. */ -static const struct regset * -s390_regset_from_core_section (struct gdbarch *gdbarch, - const char *sect_name, size_t sect_size) -{ - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - - if (strcmp (sect_name, ".reg") == 0 && sect_size >= tdep->sizeof_gregset) - return tdep->gregset; - - if (strcmp (sect_name, ".reg2") == 0 && sect_size >= tdep->sizeof_fpregset) - return tdep->fpregset; - - if (strcmp (sect_name, ".reg-s390-high-gprs") == 0 && sect_size >= 16*4) - return &s390_upper_regset; - - if (strcmp (sect_name, ".reg-s390-last-break") == 0 && sect_size >= 8) - return (gdbarch_ptr_bit (gdbarch) == 32 - ? &s390_last_break_regset : &s390x_last_break_regset); - - if (strcmp (sect_name, ".reg-s390-system-call") == 0 && sect_size >= 4) - return &s390_system_call_regset; - - if (strcmp (sect_name, ".reg-s390-tdb") == 0 && sect_size >= 256) - return &s390_tdb_regset; - - return NULL; -} - /* Iterate over supported core file register note sections. */ static void @@ -575,18 +538,25 @@ s390_iterate_over_regset_sections (struct gdbarch *gdbarch, const struct regcache *regcache) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + const int gregset_size = (tdep->abi == ABI_LINUX_S390 ? + s390_sizeof_gregset : s390x_sizeof_gregset); - cb (".reg", tdep->sizeof_gregset, "general-purpose", cb_data); - cb (".reg2", s390_sizeof_fpregset, "floating-point", cb_data); + cb (".reg", gregset_size, &s390_gregset, NULL, cb_data); + cb (".reg2", s390_sizeof_fpregset, &s390_fpregset, NULL, cb_data); if (tdep->abi == ABI_LINUX_S390 && tdep->gpr_full_regnum != -1) - cb (".reg-s390-high-gprs", 16 * 4, "s390 GPR upper halves", cb_data); + cb (".reg-s390-high-gprs", 16 * 4, &s390_upper_regset, + "s390 GPR upper halves", cb_data); if (tdep->have_linux_v1) - cb (".reg-s390-last-break", 8, "s930 last-break address", cb_data); + cb (".reg-s390-last-break", 8, + (gdbarch_ptr_bit (gdbarch) == 32 + ? &s390_last_break_regset : &s390x_last_break_regset), + "s930 last-break address", cb_data); if (tdep->have_linux_v2) - cb (".reg-s390-system-call", 4, "s390 system-call", cb_data); + cb (".reg-s390-system-call", 4, &s390_system_call_regset, + "s390 system-call", cb_data); /* If regcache is set, we are in "write" (gcore) mode. In this case, don't iterate over the TDB unless its registers are @@ -595,7 +565,8 @@ s390_iterate_over_regset_sections (struct gdbarch *gdbarch, && (regcache == NULL || REG_VALID == regcache_register_status (regcache, S390_TDB_DWORD0_REGNUM))) - cb (".reg-s390-tdb", s390_sizeof_tdbregset, "s390 TDB", cb_data); + cb (".reg-s390-tdb", s390_sizeof_tdbregset, &s390_tdb_regset, + "s390 TDB", cb_data); } static const struct target_desc * @@ -3067,8 +3038,6 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_stab_reg_to_regnum (gdbarch, s390_dwarf_reg_to_regnum); set_gdbarch_dwarf2_reg_to_regnum (gdbarch, s390_dwarf_reg_to_regnum); set_gdbarch_value_from_register (gdbarch, s390_value_from_register); - set_gdbarch_regset_from_core_section (gdbarch, - s390_regset_from_core_section); set_gdbarch_core_read_description (gdbarch, s390_core_read_description); set_gdbarch_iterate_over_regset_sections (gdbarch, s390_iterate_over_regset_sections); @@ -3134,11 +3103,6 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) switch (tdep->abi) { case ABI_LINUX_S390: - tdep->gregset = &s390_gregset; - tdep->sizeof_gregset = s390_sizeof_gregset; - tdep->fpregset = &s390_fpregset; - tdep->sizeof_fpregset = s390_sizeof_fpregset; - set_gdbarch_addr_bits_remove (gdbarch, s390_addr_bits_remove); set_solib_svr4_fetch_link_map_offsets (gdbarch, svr4_ilp32_fetch_link_map_offsets); @@ -3147,11 +3111,6 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) break; case ABI_LINUX_ZSERIES: - tdep->gregset = &s390_gregset; - tdep->sizeof_gregset = s390x_sizeof_gregset; - tdep->fpregset = &s390_fpregset; - tdep->sizeof_fpregset = s390_sizeof_fpregset; - set_gdbarch_long_bit (gdbarch, 64); set_gdbarch_long_long_bit (gdbarch, 64); set_gdbarch_ptr_bit (gdbarch, 64); |