Use PTRACE_PEEKUSER to get fs_base/gs_base
authorH.J. Lu <hjl.tools@gmail.com>
Tue, 26 Jun 2012 14:43:01 +0000 (14:43 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Tue, 26 Jun 2012 14:43:01 +0000 (14:43 +0000)
* amd64-linux-nat.c: Include <sys/user.h>.
(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.

gdb/ChangeLog
gdb/amd64-linux-nat.c
gdb/config.in
gdb/configure
gdb/configure.ac

index a36ce76e2bdc36cdee7a4ddc7446dadf31bffc51..d1e62544b02bd0c8f80f2f190f288143f19053ce 100644 (file)
@@ -1,3 +1,16 @@
+2012-06-26  Roland McGrath  <roland@hack.frob.com>
+           H.J. Lu  <hongjiu.lu@intel.com>
+
+       * amd64-linux-nat.c: Include <sys/user.h>.
+       (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.
+
 2012-06-25  Michael Eager  <eager@eagercon.com>
 
        PR python/14291
index 23eadbd79c64b3e9336377e21daa2d49dda6ea72..01982acf17c26fd840eeafcc281db0ec9a429c5c 100644 (file)
@@ -34,6 +34,7 @@
 #include <sys/debugreg.h>
 #include <sys/syscall.h>
 #include <sys/procfs.h>
+#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 +480,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;
index 5767773a6af22b8ec2d04f8d1b93c4b523d94782..74f5888282a8da5da06e88b314475869d7b7b96e 100644 (file)
 /* 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
 
index b6f4a064f89c0460a94c06c995f0b335fa7ed553..e8fa8c276de0c9ec8f7dcabc7abda78a912e86ac 100755 (executable)
@@ -10612,6 +10612,31 @@ _ACEOF
 fi
 
 
+# See if <sys/user.h> supports the %fs_base and %gs_bas amd64 segment registers.
+# Older amd64 Linux's don't have the fs_base and gs_base members of
+# `struct user_regs_struct'.
+ac_fn_c_check_member "$LINENO" "struct user_regs_struct" "fs_base" "ac_cv_member_struct_user_regs_struct_fs_base" "#include <sys/user.h>
+"
+if test "x$ac_cv_member_struct_user_regs_struct_fs_base" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_member "$LINENO" "struct user_regs_struct" "gs_base" "ac_cv_member_struct_user_regs_struct_gs_base" "#include <sys/user.h>
+"
+if test "x$ac_cv_member_struct_user_regs_struct_gs_base" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_USER_REGS_STRUCT_GS_BASE 1
+_ACEOF
+
+
+fi
+
+
 # See if <sys/ptrace.h> provides the PTRACE_GETREGS request.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTRACE_GETREGS" >&5
 $as_echo_n "checking for PTRACE_GETREGS... " >&6; }
index f77aa854111e028d513ed0e7e2f03a219bb44e2f..d52bd15d33d32f2d667270d85fd54c7b29c1dd95 100644 (file)
@@ -1274,6 +1274,12 @@ fi
 AC_CHECK_MEMBERS([struct reg.r_fs, struct reg.r_gs], [], [],
                  [#include <machine/reg.h>])
 
+# See if <sys/user.h> supports the %fs_base and %gs_bas amd64 segment registers.
+# Older amd64 Linux's don't have the fs_base and gs_base members of
+# `struct user_regs_struct'.
+AC_CHECK_MEMBERS([struct user_regs_struct.fs_base, struct user_regs_struct.gs_base],
+                [], [], [#include <sys/user.h>])
+
 # See if <sys/ptrace.h> provides the PTRACE_GETREGS request.
 AC_MSG_CHECKING(for PTRACE_GETREGS)
 AC_CACHE_VAL(gdb_cv_have_ptrace_getregs,