From patchwork Sat Feb 9 00:40:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Baldwin X-Patchwork-Id: 31377 Received: (qmail 27589 invoked by alias); 9 Feb 2019 00:42:39 -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 27468 invoked by uid 89); 9 Feb 2019 00:42:39 -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=jhbFreeBSDorg, D*FreeBSD.org, jhb@FreeBSD.org, xsave 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; Sat, 09 Feb 2019 00:42:37 +0000 Received: from ralph.com (ralph.baldwin.cx [66.234.199.215]) by mail.baldwin.cx (Postfix) with ESMTPSA id 446F510AFD2 for ; Fri, 8 Feb 2019 19:42:35 -0500 (EST) From: John Baldwin To: gdb-patches@sourceware.org Subject: [PATCH v2 02/11] Support fs_base and gs_base on FreeBSD/i386. Date: Fri, 8 Feb 2019 16:40:05 -0800 Message-Id: <09f1d3796e59177459ac58c197192d17dc447134.1549672588.git.jhb@FreeBSD.org> In-Reply-To: References: MIME-Version: 1.0 X-IsSubscribed: yes The i386 BSD native target uses the same ptrace operations (PT_[GS]ET[FG]SBASE) as the amd64 BSD native target to fetch and store the registers. The amd64 BSD native now uses 'tdep->fsbase_regnum' instead of hardcoding AMD64_FSBASE_REGNUM and AMD64_GSBASE_REGNUM to support 32-bit targets. In addition, the store operations explicitly zero the new register value before fetching it from the register cache to ensure 32-bit values are zero-extended. gdb/ChangeLog: * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers): Use tdep->fsbase_regnum instead of constants for fs_base and gs_base. (amd64bsd_store_inferior_registers): Likewise. * amd64-fbsd-nat.c (amd64_fbsd_nat_target::read_description): Enable segment base registers. * i386-bsd-nat.c (i386bsd_fetch_inferior_registers): Use PT_GETFSBASE and PT_GETGSBASE. (i386bsd_store_inferior_registers): Use PT_SETFSBASE and PT_SETGSBASE. * i386-fbsd-nat.c (i386_fbsd_nat_target::read_description): Enable segment base registers. * i386-fbsd-tdep.c (i386fbsd_core_read_description): Likewise. --- gdb/ChangeLog | 14 ++++++++++++ gdb/amd64-bsd-nat.c | 26 ++++++++++++++------- gdb/amd64-fbsd-nat.c | 4 ++-- gdb/i386-bsd-nat.c | 54 ++++++++++++++++++++++++++++++++++++++++++++ gdb/i386-fbsd-nat.c | 2 +- gdb/i386-fbsd-tdep.c | 2 +- 6 files changed, 90 insertions(+), 12 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6a05ef594e..9751118c0e 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,17 @@ +2019-02-08 John Baldwin + + * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers): Use + tdep->fsbase_regnum instead of constants for fs_base and gs_base. + (amd64bsd_store_inferior_registers): Likewise. + * amd64-fbsd-nat.c (amd64_fbsd_nat_target::read_description): + Enable segment base registers. + * i386-bsd-nat.c (i386bsd_fetch_inferior_registers): Use + PT_GETFSBASE and PT_GETGSBASE. + (i386bsd_store_inferior_registers): Use PT_SETFSBASE and PT_SETGSBASE. + * i386-fbsd-nat.c (i386_fbsd_nat_target::read_description): Enable + segment base registers. + * i386-fbsd-tdep.c (i386fbsd_core_read_description): Likewise. + 2019-02-08 John Baldwin * amd64-fbsd-nat.c (amd64_fbsd_nat_target::read_description): diff --git a/gdb/amd64-bsd-nat.c b/gdb/amd64-bsd-nat.c index a2a91abb91..35763a5b95 100644 --- a/gdb/amd64-bsd-nat.c +++ b/gdb/amd64-bsd-nat.c @@ -43,6 +43,9 @@ amd64bsd_fetch_inferior_registers (struct regcache *regcache, int regnum) { struct gdbarch *gdbarch = regcache->arch (); pid_t pid = get_ptrace_pid (regcache->ptid ()); +#if defined(PT_GETFSBASE) || defined(PT_GETGSBASE) + const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); +#endif if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum)) { @@ -57,27 +60,27 @@ amd64bsd_fetch_inferior_registers (struct regcache *regcache, int regnum) } #ifdef PT_GETFSBASE - if (regnum == -1 || regnum == AMD64_FSBASE_REGNUM) + if (regnum == -1 || regnum == tdep->fsbase_regnum) { register_t base; if (ptrace (PT_GETFSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) perror_with_name (_("Couldn't get segment register fs_base")); - regcache->raw_supply (AMD64_FSBASE_REGNUM, &base); + regcache->raw_supply (tdep->fsbase_regnum, &base); if (regnum != -1) return; } #endif #ifdef PT_GETGSBASE - if (regnum == -1 || regnum == AMD64_GSBASE_REGNUM) + if (regnum == -1 || regnum == tdep->fsbase_regnum + 1) { register_t base; if (ptrace (PT_GETGSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) perror_with_name (_("Couldn't get segment register gs_base")); - regcache->raw_supply (AMD64_GSBASE_REGNUM, &base); + regcache->raw_supply (tdep->fsbase_regnum + 1, &base); if (regnum != -1) return; } @@ -116,6 +119,9 @@ amd64bsd_store_inferior_registers (struct regcache *regcache, int regnum) { struct gdbarch *gdbarch = regcache->arch (); pid_t pid = get_ptrace_pid (regcache->ptid ()); +#if defined(PT_SETFSBASE) || defined(PT_SETGSBASE) + const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); +#endif if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum)) { @@ -134,11 +140,13 @@ amd64bsd_store_inferior_registers (struct regcache *regcache, int regnum) } #ifdef PT_SETFSBASE - if (regnum == -1 || regnum == AMD64_FSBASE_REGNUM) + if (regnum == -1 || regnum == tdep->fsbase_regnum) { register_t base; - regcache->raw_collect (AMD64_FSBASE_REGNUM, &base); + /* Clear the full base value to support 32-bit targets. */ + base = 0; + regcache->raw_collect (tdep->fsbase_regnum, &base); if (ptrace (PT_SETFSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) perror_with_name (_("Couldn't write segment register fs_base")); @@ -147,11 +155,13 @@ amd64bsd_store_inferior_registers (struct regcache *regcache, int regnum) } #endif #ifdef PT_SETGSBASE - if (regnum == -1 || regnum == AMD64_GSBASE_REGNUM) + if (regnum == -1 || regnum == tdep->fsbase_regnum + 1) { register_t base; - regcache->raw_collect (AMD64_GSBASE_REGNUM, &base); + /* Clear the full base value to support 32-bit targets. */ + base = 0; + regcache->raw_collect (tdep->fsbase_regnum + 1, &base); if (ptrace (PT_SETGSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) perror_with_name (_("Couldn't write segment register gs_base")); diff --git a/gdb/amd64-fbsd-nat.c b/gdb/amd64-fbsd-nat.c index 9fff763dd3..cc676d3214 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, false); + return i386_target_description (xcr0, true); } #endif if (is64) return amd64_target_description (X86_XSTATE_SSE_MASK, true); else - return i386_target_description (X86_XSTATE_SSE_MASK, false); + return i386_target_description (X86_XSTATE_SSE_MASK, true); } #if defined(HAVE_PT_GETDBREGS) && defined(USE_SIGTRAP_SIGINFO) diff --git a/gdb/i386-bsd-nat.c b/gdb/i386-bsd-nat.c index 009a8dc1b2..a10b496096 100644 --- a/gdb/i386-bsd-nat.c +++ b/gdb/i386-bsd-nat.c @@ -144,6 +144,33 @@ i386bsd_fetch_inferior_registers (struct regcache *regcache, int regnum) return; } +#ifdef PT_GETFSBASE + if (regnum == -1 || regnum == I386_FSBASE_REGNUM) + { + register_t base; + + if (ptrace (PT_GETFSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) + perror_with_name (_("Couldn't get segment register fs_base")); + + regcache->raw_supply (I386_FSBASE_REGNUM, &base); + if (regnum != -1) + return; + } +#endif +#ifdef PT_GETGSBASE + if (regnum == -1 || regnum == I386_GSBASE_REGNUM) + { + register_t base; + + if (ptrace (PT_GETGSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) + perror_with_name (_("Couldn't get segment register gs_base")); + + regcache->raw_supply (I386_GSBASE_REGNUM, &base); + if (regnum != -1) + return; + } +#endif + if (regnum == -1 || regnum >= I386_ST0_REGNUM) { struct fpreg fpregs; @@ -211,6 +238,33 @@ i386bsd_store_inferior_registers (struct regcache *regcache, int regnum) return; } +#ifdef PT_SETFSBASE + if (regnum == -1 || regnum == I386_FSBASE_REGNUM) + { + register_t base; + + regcache->raw_collect (I386_FSBASE_REGNUM, &base); + + if (ptrace (PT_SETFSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) + perror_with_name (_("Couldn't write segment register fs_base")); + if (regnum != -1) + return; + } +#endif +#ifdef PT_SETGSBASE + if (regnum == -1 || regnum == I386_GSBASE_REGNUM) + { + register_t base; + + regcache->raw_collect (I386_GSBASE_REGNUM, &base); + + if (ptrace (PT_SETGSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) + perror_with_name (_("Couldn't write segment register gs_base")); + if (regnum != -1) + return; + } +#endif + if (regnum == -1 || regnum >= I386_ST0_REGNUM) { struct fpreg fpregs; diff --git a/gdb/i386-fbsd-nat.c b/gdb/i386-fbsd-nat.c index 7106e90801..be5d4c67be 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, false); + return i386_target_description (xcr0, true); } #endif diff --git a/gdb/i386-fbsd-tdep.c b/gdb/i386-fbsd-tdep.c index 2f28bad728..ac57e7383d 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), false); + return i386_target_description (i386fbsd_core_read_xcr0 (abfd), true); } /* Similar to i386_supply_fpregset, but use XSAVE extended state. */