aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorAndreas Arnez <arnez@linux.vnet.ibm.com>2014-09-12 08:42:48 +0000
committerAndreas Krebbel <krebbel@linux.vnet.ibm.com>2014-09-30 09:14:33 +0200
commit8f0435f75e3c9676d2e177ce055fed3155fd9476 (patch)
tree08032004cab3c1c432651500560db02af97b86bc /gdb
parent5aa82d050d61784823767fe3c982b6862fa47391 (diff)
downloadfsf-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/ChangeLog63
-rw-r--r--gdb/amd64-linux-tdep.c36
-rw-r--r--gdb/amd64-tdep.c51
-rw-r--r--gdb/amd64-tdep.h2
-rw-r--r--gdb/arm-linux-tdep.c33
-rw-r--r--gdb/corelow.c52
-rw-r--r--gdb/gdbarch.h3
-rwxr-xr-xgdb/gdbarch.sh3
-rw-r--r--gdb/i386-linux-tdep.c40
-rw-r--r--gdb/i386-tdep.c42
-rw-r--r--gdb/i386-tdep.h6
-rw-r--r--gdb/linux-tdep.c3
-rw-r--r--gdb/ppc-linux-tdep.c35
-rw-r--r--gdb/s390-linux-tdep.c69
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);