[PATCH 2/3] Use PTRACE_PEEKUSER to get fs_base/gs_base for x32
Mark Kettenis
mark.kettenis@xs4all.nl
Tue Jun 26 11:32:00 GMT 2012
> Date: Thu, 21 Jun 2012 11:59:36 -0700
> From: "H.J. Lu" <hongjiu.lu@intel.com>
>
> On Thu, Jun 21, 2012 at 11:15:29AM -0700, H.J. Lu wrote:
> > PTRACE_ARCH_PRCTL is obsolete since 2.6.25, where the fs_base and gs_base
> > fields of user_regs_struct can be used directly. Since x32 support was
> > added to kernel 3.4.0 and PTRACE_ARCH_PRCTL support was removed for x32,
> > we should always use fs_base/gs_base for x32. OK to install? We
> >
> > Thanks.
>
> Here is a better patch to use the fs_base and gs_base fields of
> struct user_regs_struct to get fs/gs base. OK to install?
>
> Thanks.
>
>
> H.J.
> ---
> 2012-06-16 Roland McGrath <roland@hack.frob.com>
> H.J. Lu <hongjiu.lu@intel.com>
>
> * amd64-linux-nat.c: Include <sys/user.h> if
> HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE or
> HAVE_STRUCT_USER_REGS_STRUCT_GS_BASE is defined.
> (ps_get_thread_area): Use PTRACE_PEEKUSER to get fs_base/gs_base
> if HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE or
> HAVE_STRUCT_USER_REGS_STRUCT_GS_BASE is defined.
>
> * configure.ac: Check if the fs_base and gs_base members of
> `struct user_regs_struct' exist.
> * config.in: Regenerated.
> * configure: Likewise.
>
> diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
> index 23eadbd..781456f 100644
> --- a/gdb/amd64-linux-nat.c
> +++ b/gdb/amd64-linux-nat.c
> @@ -34,6 +34,10 @@
> #include <sys/debugreg.h>
> #include <sys/syscall.h>
> #include <sys/procfs.h>
> +#if defined HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE \
> + || defined HAVE_STRUCT_USER_REGS_STRUCT_GS_BASE
> +#include <sys/user.h>
> +#endif
Any reason to not just unconditionally include <sys/user.h>?
> #include <asm/prctl.h>
> /* FIXME ezannoni-2003-07-09: we need <sys/reg.h> to be included after
> <asm/ptrace.h> because the latter redefines FS and GS for no apparent
> @@ -479,10 +483,39 @@ ps_get_thread_area (const struct ps_prochandle *ph,
> switch (idx)
> {
> case FS:
> +#ifdef HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE
> + {
> + /* PTRACE_ARCH_PRCTL is obsolete since 2.6.25, where the
> + fs_base and gs_base fields of user_regs_struct can be
> + used directly. */
> + unsigned long fs;
> + errno = 0;
> + fs = ptrace (PTRACE_PEEKUSER, lwpid,
> + offsetof (struct user_regs_struct, fs_base), 0);
> + if (errno == 0)
> + {
> + *base = (void *) fs;
> + return PS_OK;
> + }
> + }
> +#endif
> if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0)
> return PS_OK;
> break;
> case GS:
> +#ifdef HAVE_STRUCT_USER_REGS_STRUCT_GS_BASE
> + {
> + unsigned long gs;
> + errno = 0;
> + gs = ptrace (PTRACE_PEEKUSER, lwpid,
> + offsetof (struct user_regs_struct, gs_base), 0);
> + if (errno == 0)
> + {
> + *base = (void *) gs;
> + return PS_OK;
> + }
> + }
> +#endif
> if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0)
> return PS_OK;
> break;
> diff --git a/gdb/config.in b/gdb/config.in
> index 5767773..74f5888 100644
> --- a/gdb/config.in
> +++ b/gdb/config.in
> @@ -447,6 +447,12 @@
> /* Define to 1 if `struct thread' is a member of `td_pcb'. */
> #undef HAVE_STRUCT_THREAD_TD_PCB
>
> +/* Define to 1 if `struct user_regs_struct' is a member of `fs_base'. */
> +#undef HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE
> +
> +/* Define to 1 if `struct user_regs_struct' is a member of `gs_base'. */
> +#undef HAVE_STRUCT_USER_REGS_STRUCT_GS_BASE
> +
> /* Define to 1 if you have the `syscall' function. */
> #undef HAVE_SYSCALL
>
More information about the Gdb-patches
mailing list