[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