From patchwork Tue Jan 22 18:42:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Baldwin X-Patchwork-Id: 31165 Received: (qmail 85795 invoked by alias); 22 Jan 2019 18:43:47 -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 85687 invoked by uid 89); 22 Jan 2019 18:43:47 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.2 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS, SPF_SOFTFAIL autolearn=ham version=3.3.2 spammy=John, Protection, gap, SYSTEM X-HELO: mail.baldwin.cx Received: from bigwig.baldwin.cx (HELO mail.baldwin.cx) (96.47.65.170) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 22 Jan 2019 18:43:42 +0000 Received: from ralph.com (ralph.baldwin.cx [66.234.199.215]) by mail.baldwin.cx (Postfix) with ESMTPSA id 0F1A710AFD2 for ; Tue, 22 Jan 2019 13:43:39 -0500 (EST) From: John Baldwin To: gdb-patches@sourceware.org Subject: [PATCH 1/9] Support the fs_base and gs_base registers on i386. Date: Tue, 22 Jan 2019 10:42:54 -0800 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-IsSubscribed: yes As on amd64, these registers hold the base address of the fs and gs segments, respectively. For i386 these two registers are 32 bits. gdb/ChangeLog: * amd64-fbsd-nat.c (amd64_fbsd_nat_target::read_description): Update calls to i386_target_description to add 'segments' parameter. * amd64-tdep.c (amd64_init_abi): Set tdep->fsbase_regnum. Don't add segment base registers. * arch/i386.c (i386_create_target_description): Add 'segments' parameter to enable segment base registers. * arch/i386.h (i386_create_target_description): Likewise. * features/i386/32bit-segments.xml: New file. * features/i386/32bit-segments.c: Generate. * i386-fbsd-nat.c (i386_fbsd_nat_target::read_description): Update call to i386_target_description to add 'segments' parameter. * i386-fbsd-tdep.c (i386fbsd_core_read_description): Likewise. * i386-go32-tdep.c (i386_go32_init_abi): Likewise. * i386-linux-tdep.c (i386_linux_read_description): Likewise. * i386-tdep.c (i386_validate_tdesc_p): Add segment base registers if feature is present. (i386_gdbarch_init): Pass I386_NUM_REGS to set_gdbarch_num_regs. Add 'segments' parameter to call to i386_target_description. (i386_target_description): Add 'segments' parameter to enable segment base registers. (_initialize_i386_tdep) [GDB_SELF_TEST]: Add 'segments' parameter to call to i386_target_description. * i386-tdep.h (struct gdbarch_tdep): Add 'fsbase_regnum'. (enum i386_regnum): Add I386_FSBASE_REGNUM and I386_GSBASE_REGNUM. Define I386_NUM_REGS. (i386_target_description): Add 'segments' parameter to enable segment base registers. gdb/gdbserver/ChangeLog: * linux-x86-tdesc.c (i386_linux_read_description): Update call to i386_create_target_description for 'segments' parameter. * lynx-i386-low.c (lynx_i386_arch_setup): Likewise. * nto-x86-low.c (nto_x86_arch_setup): Likewise. * win32-i386-low.c (i386_arch_setup): Likewise. --- gdb/ChangeLog | 31 ++++++++++++++++++++++++++ gdb/amd64-fbsd-nat.c | 4 ++-- gdb/amd64-tdep.c | 10 +-------- gdb/arch/i386.c | 6 ++++- gdb/arch/i386.h | 3 ++- gdb/features/i386/32bit-segments.c | 15 +++++++++++++ gdb/features/i386/32bit-segments.xml | 12 ++++++++++ gdb/gdbserver/ChangeLog | 8 +++++++ gdb/gdbserver/linux-x86-tdesc.c | 2 +- gdb/gdbserver/lynx-i386-low.c | 2 +- gdb/gdbserver/nto-x86-low.c | 2 +- gdb/gdbserver/win32-i386-low.c | 2 +- gdb/i386-fbsd-nat.c | 2 +- gdb/i386-fbsd-tdep.c | 2 +- gdb/i386-go32-tdep.c | 2 +- gdb/i386-linux-tdep.c | 2 +- gdb/i386-tdep.c | 33 +++++++++++++++++++++------- gdb/i386-tdep.h | 12 ++++++++-- 18 files changed, 119 insertions(+), 31 deletions(-) create mode 100644 gdb/features/i386/32bit-segments.c create mode 100644 gdb/features/i386/32bit-segments.xml diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8e03dbf883..4afd5b664e 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,34 @@ +2019-01-22 John Baldwin + + * amd64-fbsd-nat.c (amd64_fbsd_nat_target::read_description): + Update calls to i386_target_description to add 'segments' + parameter. + * amd64-tdep.c (amd64_init_abi): Set tdep->fsbase_regnum. Don't + add segment base registers. + * arch/i386.c (i386_create_target_description): Add 'segments' + parameter to enable segment base registers. + * arch/i386.h (i386_create_target_description): Likewise. + * features/i386/32bit-segments.xml: New file. + * features/i386/32bit-segments.c: Generate. + * i386-fbsd-nat.c (i386_fbsd_nat_target::read_description): Update + call to i386_target_description to add 'segments' parameter. + * i386-fbsd-tdep.c (i386fbsd_core_read_description): Likewise. + * i386-go32-tdep.c (i386_go32_init_abi): Likewise. + * i386-linux-tdep.c (i386_linux_read_description): Likewise. + * i386-tdep.c (i386_validate_tdesc_p): Add segment base registers + if feature is present. + (i386_gdbarch_init): Pass I386_NUM_REGS to set_gdbarch_num_regs. + Add 'segments' parameter to call to i386_target_description. + (i386_target_description): Add 'segments' parameter to enable + segment base registers. + (_initialize_i386_tdep) [GDB_SELF_TEST]: Add 'segments' parameter + to call to i386_target_description. + * i386-tdep.h (struct gdbarch_tdep): Add 'fsbase_regnum'. + (enum i386_regnum): Add I386_FSBASE_REGNUM and I386_GSBASE_REGNUM. + Define I386_NUM_REGS. + (i386_target_description): Add 'segments' parameter to enable + segment base registers. + 2019-01-22 Philippe Waroquiers * event-top.c (handle_line_of_input): use unique_xmalloc_ptr for diff --git a/gdb/amd64-fbsd-nat.c b/gdb/amd64-fbsd-nat.c index 6d8e12b033..39ba69d9bf 100644 --- a/gdb/amd64-fbsd-nat.c +++ b/gdb/amd64-fbsd-nat.c @@ -190,13 +190,13 @@ amd64_fbsd_nat_target::read_description () if (is64) return amd64_target_description (xcr0, true); else - return i386_target_description (xcr0); + return i386_target_description (xcr0, false); } #endif if (is64) return amd64_target_description (X86_XSTATE_SSE_MASK, true); else - return i386_target_description (X86_XSTATE_SSE_MASK); + return i386_target_description (X86_XSTATE_SSE_MASK, false); } #if defined(HAVE_PT_GETDBREGS) && defined(USE_SIGTRAP_SIGINFO) diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index d4143ae155..1eb0bcdf17 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -3107,15 +3107,7 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch, if (tdesc_find_feature (tdesc, "org.gnu.gdb.i386.segments") != NULL) { - const struct tdesc_feature *feature = - tdesc_find_feature (tdesc, "org.gnu.gdb.i386.segments"); - struct tdesc_arch_data *tdesc_data_segments = - (struct tdesc_arch_data *) info.tdep_info; - - tdesc_numbered_register (feature, tdesc_data_segments, - AMD64_FSBASE_REGNUM, "fs_base"); - tdesc_numbered_register (feature, tdesc_data_segments, - AMD64_GSBASE_REGNUM, "gs_base"); + tdep->fsbase_regnum = AMD64_FSBASE_REGNUM; } if (tdesc_find_feature (tdesc, "org.gnu.gdb.i386.pkeys") != NULL) diff --git a/gdb/arch/i386.c b/gdb/arch/i386.c index 73987da97b..311b5fd8c8 100644 --- a/gdb/arch/i386.c +++ b/gdb/arch/i386.c @@ -28,11 +28,12 @@ #include "../features/i386/32bit-avx512.c" #include "../features/i386/32bit-mpx.c" #include "../features/i386/32bit-pkeys.c" +#include "../features/i386/32bit-segments.c" /* Create i386 target descriptions according to XCR0. */ target_desc * -i386_create_target_description (uint64_t xcr0, bool is_linux) +i386_create_target_description (uint64_t xcr0, bool is_linux, bool segments) { target_desc *tdesc = allocate_target_description (); @@ -53,6 +54,9 @@ i386_create_target_description (uint64_t xcr0, bool is_linux) if (is_linux) regnum = create_feature_i386_32bit_linux (tdesc, regnum); + if (segments) + regnum = create_feature_i386_32bit_segments (tdesc, regnum); + if (xcr0 & X86_XSTATE_AVX) regnum = create_feature_i386_32bit_avx (tdesc, regnum); diff --git a/gdb/arch/i386.h b/gdb/arch/i386.h index a6a801b818..af8c6bd73f 100644 --- a/gdb/arch/i386.h +++ b/gdb/arch/i386.h @@ -18,4 +18,5 @@ #include "common/tdesc.h" #include -target_desc *i386_create_target_description (uint64_t xcr0, bool is_linux); +target_desc *i386_create_target_description (uint64_t xcr0, bool is_linux, + bool segments); diff --git a/gdb/features/i386/32bit-segments.c b/gdb/features/i386/32bit-segments.c new file mode 100644 index 0000000000..c22c3dfbc3 --- /dev/null +++ b/gdb/features/i386/32bit-segments.c @@ -0,0 +1,15 @@ +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: + Original: 32bit-segments.xml */ + +#include "common/tdesc.h" + +static int +create_feature_i386_32bit_segments (struct target_desc *result, long regnum) +{ + struct tdesc_feature *feature; + + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.segments"); + tdesc_create_reg (feature, "fs_base", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "gs_base", regnum++, 1, NULL, 32, "int"); + return regnum; +} diff --git a/gdb/features/i386/32bit-segments.xml b/gdb/features/i386/32bit-segments.xml new file mode 100644 index 0000000000..098948e5ec --- /dev/null +++ b/gdb/features/i386/32bit-segments.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 5312ca9919..fc8b37976a 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,11 @@ +2019-01-22 John Baldwin + + * linux-x86-tdesc.c (i386_linux_read_description): Update call to + i386_create_target_description for 'segments' parameter. + * lynx-i386-low.c (lynx_i386_arch_setup): Likewise. + * nto-x86-low.c (nto_x86_arch_setup): Likewise. + * win32-i386-low.c (i386_arch_setup): Likewise. + 2019-01-21 Tom Tromey * tracepoint.c: Fix includes. diff --git a/gdb/gdbserver/linux-x86-tdesc.c b/gdb/gdbserver/linux-x86-tdesc.c index 04bccc84ed..8f24a3d72d 100644 --- a/gdb/gdbserver/linux-x86-tdesc.c +++ b/gdb/gdbserver/linux-x86-tdesc.c @@ -87,7 +87,7 @@ i386_linux_read_description (uint64_t xcr0) if (*tdesc == NULL) { - *tdesc = i386_create_target_description (xcr0, true); + *tdesc = i386_create_target_description (xcr0, true, false); init_target_desc (*tdesc, i386_expedite_regs); } diff --git a/gdb/gdbserver/lynx-i386-low.c b/gdb/gdbserver/lynx-i386-low.c index 0731d2a73d..77ec8235e0 100644 --- a/gdb/gdbserver/lynx-i386-low.c +++ b/gdb/gdbserver/lynx-i386-low.c @@ -331,7 +331,7 @@ static void lynx_i386_arch_setup (void) { struct target_desc *tdesc - = i386_create_target_description (X86_XSTATE_SSE_MASK, false); + = i386_create_target_description (X86_XSTATE_SSE_MASK, false, false); init_target_desc (tdesc, i386_expedite_regs); diff --git a/gdb/gdbserver/nto-x86-low.c b/gdb/gdbserver/nto-x86-low.c index 19c9acf42b..6930664e00 100644 --- a/gdb/gdbserver/nto-x86-low.c +++ b/gdb/gdbserver/nto-x86-low.c @@ -89,7 +89,7 @@ nto_x86_arch_setup (void) { the_low_target.num_regs = 16; struct target_desc *tdesc - = i386_create_target_description (X86_XSTATE_SSE_MASK, false); + = i386_create_target_description (X86_XSTATE_SSE_MASK, false, false); init_target_desc (tdesc, i386_expedite_regs); diff --git a/gdb/gdbserver/win32-i386-low.c b/gdb/gdbserver/win32-i386-low.c index 30f7af7553..9b7bc40225 100644 --- a/gdb/gdbserver/win32-i386-low.c +++ b/gdb/gdbserver/win32-i386-low.c @@ -439,7 +439,7 @@ i386_arch_setup (void) false, false); const char **expedite_regs = amd64_expedite_regs; #else - tdesc = i386_create_target_description (X86_XSTATE_SSE_MASK, false); + tdesc = i386_create_target_description (X86_XSTATE_SSE_MASK, false, false); const char **expedite_regs = i386_expedite_regs; #endif diff --git a/gdb/i386-fbsd-nat.c b/gdb/i386-fbsd-nat.c index 855572143b..8ff104cf72 100644 --- a/gdb/i386-fbsd-nat.c +++ b/gdb/i386-fbsd-nat.c @@ -160,7 +160,7 @@ i386_fbsd_nat_target::read_description () if (x86bsd_xsave_len == 0) xcr0 = X86_XSTATE_SSE_MASK; - return i386_target_description (xcr0); + return i386_target_description (xcr0, false); } #endif diff --git a/gdb/i386-fbsd-tdep.c b/gdb/i386-fbsd-tdep.c index 82dfbd5c35..43b15167ae 100644 --- a/gdb/i386-fbsd-tdep.c +++ b/gdb/i386-fbsd-tdep.c @@ -267,7 +267,7 @@ i386fbsd_core_read_description (struct gdbarch *gdbarch, struct target_ops *target, bfd *abfd) { - return i386_target_description (i386fbsd_core_read_xcr0 (abfd)); + return i386_target_description (i386fbsd_core_read_xcr0 (abfd), false); } /* Similar to i386_supply_fpregset, but use XSAVE extended state. */ diff --git a/gdb/i386-go32-tdep.c b/gdb/i386-go32-tdep.c index 5a18f35f99..200de53cd8 100644 --- a/gdb/i386-go32-tdep.c +++ b/gdb/i386-go32-tdep.c @@ -35,7 +35,7 @@ i386_go32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* DJGPP does not support the SSE registers. */ if (!tdesc_has_registers (info.target_desc)) - tdep->tdesc = i386_target_description (X86_XSTATE_X87_MASK); + tdep->tdesc = i386_target_description (X86_XSTATE_X87_MASK, false); /* Native compiler is GCC, which uses the SVR4 register numbering even in COFF and STABS. See the comment in i386_gdbarch_init, diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c index 0f344b0710..b2461836ad 100644 --- a/gdb/i386-linux-tdep.c +++ b/gdb/i386-linux-tdep.c @@ -694,7 +694,7 @@ i386_linux_read_description (uint64_t xcr0) [(xcr0 & X86_XSTATE_PKRU) ? 1 : 0]; if (*tdesc == NULL) - *tdesc = i386_create_target_description (xcr0, true); + *tdesc = i386_create_target_description (xcr0, true, false); return *tdesc; } diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 8b2c72ac7b..65a5d6ab95 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -8175,7 +8175,7 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep, const struct tdesc_feature *feature_core; const struct tdesc_feature *feature_sse, *feature_avx, *feature_mpx, - *feature_avx512, *feature_pkeys; + *feature_avx512, *feature_pkeys, *feature_segments; int i, num_regs, valid_p; if (! tdesc_has_registers (tdesc)) @@ -8198,6 +8198,9 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep, /* Try AVX512 registers. */ feature_avx512 = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.avx512"); + /* Try segment base registers. */ + feature_segments = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.segments"); + /* Try PKEYS */ feature_pkeys = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.pkeys"); @@ -8307,6 +8310,16 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep, tdep->mpx_register_names[i]); } + if (feature_segments) + { + if (tdep->fsbase_regnum < 0) + tdep->fsbase_regnum = I386_FSBASE_REGNUM; + valid_p &= tdesc_numbered_register (feature_segments, tdesc_data, + tdep->fsbase_regnum, "fs_base"); + valid_p &= tdesc_numbered_register (feature_segments, tdesc_data, + tdep->fsbase_regnum + 1, "gs_base"); + } + if (feature_pkeys) { tdep->xcr0 |= X86_XSTATE_PKRU; @@ -8543,14 +8556,14 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Even though the default ABI only includes general-purpose registers, floating-point registers and the SSE registers, we have to leave a gap for the upper AVX, MPX and AVX512 registers. */ - set_gdbarch_num_regs (gdbarch, I386_PKEYS_NUM_REGS); + set_gdbarch_num_regs (gdbarch, I386_NUM_REGS); set_gdbarch_gnu_triplet_regexp (gdbarch, i386_gnu_triplet_regexp); /* Get the x86 target description from INFO. */ tdesc = info.target_desc; if (! tdesc_has_registers (tdesc)) - tdesc = i386_target_description (X86_XSTATE_SSE_MASK); + tdesc = i386_target_description (X86_XSTATE_SSE_MASK, false); tdep->tdesc = tdesc; tdep->num_core_regs = I386_NUM_GREGS + I387_NUM_REGS; @@ -8592,6 +8605,9 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->pkru_regnum = -1; tdep->num_pkeys_regs = 0; + /* No segment base registers. */ + tdep->fsbase_regnum = -1; + tdesc_data = tdesc_data_alloc (); set_gdbarch_relocate_instruction (gdbarch, i386_relocate_instruction); @@ -8717,20 +8733,21 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Return the target description for a specified XSAVE feature mask. */ const struct target_desc * -i386_target_description (uint64_t xcr0) +i386_target_description (uint64_t xcr0, bool segments) { static target_desc *i386_tdescs \ - [2/*SSE*/][2/*AVX*/][2/*MPX*/][2/*AVX512*/][2/*PKRU*/] = {}; + [2/*SSE*/][2/*AVX*/][2/*MPX*/][2/*AVX512*/][2/*PKRU*/][2/*segments*/] = {}; target_desc **tdesc; tdesc = &i386_tdescs[(xcr0 & X86_XSTATE_SSE) ? 1 : 0] [(xcr0 & X86_XSTATE_AVX) ? 1 : 0] [(xcr0 & X86_XSTATE_MPX) ? 1 : 0] [(xcr0 & X86_XSTATE_AVX512) ? 1 : 0] - [(xcr0 & X86_XSTATE_PKRU) ? 1 : 0]; + [(xcr0 & X86_XSTATE_PKRU) ? 1 : 0] + [segments ? 1 : 0]; if (*tdesc == NULL) - *tdesc = i386_create_target_description (xcr0, false); + *tdesc = i386_create_target_description (xcr0, false, segments); return *tdesc; } @@ -9072,7 +9089,7 @@ Show Intel Memory Protection Extensions specific variables."), for (auto &a : xml_masks) { - auto tdesc = i386_target_description (a.mask); + auto tdesc = i386_target_description (a.mask, false); selftests::record_xml_tdesc (a.xml, tdesc); } diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h index 2532306e5c..c0d494824c 100644 --- a/gdb/i386-tdep.h +++ b/gdb/i386-tdep.h @@ -200,6 +200,10 @@ struct gdbarch_tdep /* PKEYS register names. */ const char **pkeys_register_names; + /* Register number for %fsbase. Set this to -1 to indicate the + absence of segment base registers. */ + int fsbase_regnum; + /* Target description. */ const struct target_desc *tdesc; @@ -296,7 +300,9 @@ enum i386_regnum I386_K7_REGNUM = I386_K0_REGNUM + 7, I386_ZMM0H_REGNUM, /* %zmm0h */ I386_ZMM7H_REGNUM = I386_ZMM0H_REGNUM + 7, - I386_PKRU_REGNUM + I386_PKRU_REGNUM, + I386_FSBASE_REGNUM, + I386_GSBASE_REGNUM }; /* Register numbers of RECORD_REGMAP. */ @@ -337,6 +343,7 @@ enum record_i386_regnum #define I386_MPX_NUM_REGS (I386_BNDSTATUS_REGNUM + 1) #define I386_AVX512_NUM_REGS (I386_ZMM7H_REGNUM + 1) #define I386_PKEYS_NUM_REGS (I386_PKRU_REGNUM + 1) +#define I386_NUM_REGS (I386_GSBASE_REGNUM + 1) /* Size of the largest register. */ #define I386_MAX_REGISTER_SIZE 64 @@ -440,7 +447,8 @@ extern int i386_svr4_reg_to_regnum (struct gdbarch *gdbarch, int reg); extern int i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR addr); -extern const struct target_desc *i386_target_description (uint64_t xcr0); +extern const struct target_desc *i386_target_description (uint64_t xcr0, + bool segments); /* Return true iff the current target is MPX enabled. */ extern int i386_mpx_enabled (void);