From 6fea9e186c3da74c8f0ba9d007522a7575d24a73 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Tue, 26 Jun 2012 14:43:01 +0000 Subject: [PATCH] Use PTRACE_PEEKUSER to get fs_base/gs_base * amd64-linux-nat.c: Include . (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 | 13 +++++++++++++ gdb/amd64-linux-nat.c | 30 ++++++++++++++++++++++++++++++ gdb/config.in | 6 ++++++ gdb/configure | 25 +++++++++++++++++++++++++ gdb/configure.ac | 6 ++++++ 5 files changed, 80 insertions(+) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a36ce76e2bd..d1e62544b02 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,16 @@ +2012-06-26 Roland McGrath + H.J. Lu + + * amd64-linux-nat.c: Include . + (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 PR python/14291 diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c index 23eadbd79c6..01982acf17c 100644 --- a/gdb/amd64-linux-nat.c +++ b/gdb/amd64-linux-nat.c @@ -34,6 +34,7 @@ #include #include #include +#include #include /* FIXME ezannoni-2003-07-09: we need to be included after 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; diff --git a/gdb/config.in b/gdb/config.in index 5767773a6af..74f5888282a 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 diff --git a/gdb/configure b/gdb/configure index b6f4a064f89..e8fa8c276de 100755 --- a/gdb/configure +++ b/gdb/configure @@ -10612,6 +10612,31 @@ _ACEOF fi +# See if 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 +" +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 +" +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 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; } diff --git a/gdb/configure.ac b/gdb/configure.ac index f77aa854111..d52bd15d33d 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -1274,6 +1274,12 @@ fi AC_CHECK_MEMBERS([struct reg.r_fs, struct reg.r_gs], [], [], [#include ]) +# See if 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 ]) + # See if provides the PTRACE_GETREGS request. AC_MSG_CHECKING(for PTRACE_GETREGS) AC_CACHE_VAL(gdb_cv_have_ptrace_getregs, -- 2.30.2