Support fs_base and gs_base on FreeBSD/i386.
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.
This commit is contained in:
parent
1163a4b7a3
commit
dd6876c91c
@ -1,3 +1,18 @@
|
||||
2019-03-12 John Baldwin <jhb@FreeBSD.org>
|
||||
|
||||
* 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-03-12 John Baldwin <jhb@FreeBSD.org>
|
||||
|
||||
* amd64-fbsd-nat.c (amd64_fbsd_nat_target::read_description):
|
||||
|
@ -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"));
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user