This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
PATCH: Use PTRACE_PEEKUSER to get fs_base and gs_base for x32
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: GDB <gdb-patches at sourceware dot org>
- Cc: Roland McGrath <roland at hack dot frob dot com>
- Date: Sat, 16 Jun 2012 10:41:48 -0700
- Subject: PATCH: Use PTRACE_PEEKUSER to get fs_base and gs_base for x32
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. It uses fs_base and gs_base
only if __ILP32__ is defined since they aren't available with the older
header files. 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 (ps_get_thread_area): Use PTRACE_PEEKUSER
to get fs_base and gs_base for x32.
diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
index 23eadbd..7a90065 100644
--- a/gdb/amd64-linux-nat.c
+++ b/gdb/amd64-linux-nat.c
@@ -479,12 +479,45 @@ ps_get_thread_area (const struct ps_prochandle *ph,
switch (idx)
{
case FS:
+#ifdef __ILP32__
+ {
+ /* 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 for x32. */
+ 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;
+ }
+ }
+#else
if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0)
return PS_OK;
+#endif
break;
case GS:
+#ifdef __ILP32__
+ {
+ 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;
+ }
+ }
+#else
if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0)
return PS_OK;
+#endif
break;
default: /* Should not happen. */
return PS_BADADDR;