From patchwork Fri Sep 12 15:39:32 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Arnez X-Patchwork-Id: 2820 Received: (qmail 16345 invoked by alias); 12 Sep 2014 18:32:03 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 16329 invoked by uid 89); 12 Sep 2014 18:32:03 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.4 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: e06smtp12.uk.ibm.com Received: from e06smtp12.uk.ibm.com (HELO e06smtp12.uk.ibm.com) (195.75.94.108) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Fri, 12 Sep 2014 18:32:00 +0000 Received: from /spool/local by e06smtp12.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 12 Sep 2014 19:31:56 +0100 Received: from d06dlp03.portsmouth.uk.ibm.com (9.149.20.15) by e06smtp12.uk.ibm.com (192.168.101.142) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 12 Sep 2014 16:39:59 +0100 Received: from b06cxnps3074.portsmouth.uk.ibm.com (d06relay09.portsmouth.uk.ibm.com [9.149.109.194]) by d06dlp03.portsmouth.uk.ibm.com (Postfix) with ESMTP id 8EC511B08051 for ; Fri, 12 Sep 2014 16:41:03 +0100 (BST) Received: from d06av06.portsmouth.uk.ibm.com (d06av06.portsmouth.uk.ibm.com [9.149.37.217]) by b06cxnps3074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id s8CFdwVh20119718 for ; Fri, 12 Sep 2014 15:39:58 GMT Received: from d06av06.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av06.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id s8CAcMeY014798 for ; Fri, 12 Sep 2014 06:38:23 -0400 Received: from br87z6lw.boeblingen.de.ibm.com (dyn-9-152-212-196.boeblingen.de.ibm.com [9.152.212.196]) by d06av06.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id s8CAcL6e014757; Fri, 12 Sep 2014 06:38:22 -0400 From: Andreas Arnez To: gdb-patches@sourceware.org Cc: Ulrich Weigand , Kevin Buettner , Mark Kettenis , Richard Earnshaw Subject: [PATCH 02/26] Add 'regset' parameter to 'iterate_over_regset_sections_cb' Date: Fri, 12 Sep 2014 17:39:32 +0200 Message-Id: <1410536396-25524-3-git-send-email-arnez@linux.vnet.ibm.com> In-Reply-To: <1410536396-25524-1-git-send-email-arnez@linux.vnet.ibm.com> References: <1410536396-25524-1-git-send-email-arnez@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 14091215-8372-0000-0000-000001274612 X-IsSubscribed: yes 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. --- gdb/amd64-linux-tdep.c | 36 +++++++++++++++++++++++--- gdb/amd64-tdep.c | 51 ++----------------------------------- gdb/amd64-tdep.h | 2 ++ gdb/arm-linux-tdep.c | 33 ++++-------------------- gdb/corelow.c | 52 +++++++++++++++++++++++++++---------- gdb/gdbarch.h | 3 ++- gdb/gdbarch.sh | 3 ++- gdb/i386-linux-tdep.c | 40 ++++++++++++++++++++++++++--- gdb/i386-tdep.c | 42 +++++------------------------- gdb/i386-tdep.h | 6 +++++ gdb/linux-tdep.c | 3 +-- gdb/ppc-linux-tdep.c | 35 ++++++------------------- gdb/s390-linux-tdep.c | 69 ++++++++++---------------------------------------- 13 files changed, 157 insertions(+), 218 deletions(-) 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);