btrace: Fix memory leak in btrace_clear.
[deliverable/binutils-gdb.git] / gdb / amd64-linux-nat.c
index 4a2036b0f9256d2b21c26fc05b82fce2b14b77c7..d24c028d215581339bf856701f49c74f6d49bcaf 100644 (file)
 #include "nat/linux-ptrace.h"
 #include "nat/amd64-linux-siginfo.h"
 
+/* This definition comes from prctl.h.  Kernels older than 2.5.64
+   do not have it.  */
+#ifndef PTRACE_ARCH_PRCTL
+#define PTRACE_ARCH_PRCTL      30
+#endif
+
 /* Mapping between the general-purpose registers in GNU/Linux x86-64
    `struct user' format and GDB's register cache layout for GNU/Linux
    i386.
@@ -67,6 +73,7 @@ static int amd64_linux_gregset32_reg_offset[] =
   -1, -1,                        /* MPX registers BNDCFGU, BNDSTATUS.  */
   -1, -1, -1, -1, -1, -1, -1, -1, /* k0 ... k7 (AVX512)  */
   -1, -1, -1, -1, -1, -1, -1, -1, /* zmm0 ... zmm7 (AVX512)  */
+  -1,                            /* PKEYS register PKRU  */
   ORIG_RAX * 8                   /* "orig_eax"  */
 };
 \f
@@ -131,9 +138,9 @@ amd64_linux_fetch_inferior_registers (struct target_ops *ops,
   int tid;
 
   /* GNU/Linux LWP ID's are process ID's.  */
-  tid = ptid_get_lwp (inferior_ptid);
+  tid = ptid_get_lwp (regcache_get_ptid (regcache));
   if (tid == 0)
-    tid = ptid_get_pid (inferior_ptid); /* Not a threaded program.  */
+    tid = ptid_get_pid (regcache_get_ptid (regcache)); /* Not a threaded program.  */
 
   if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
     {
@@ -171,6 +178,30 @@ amd64_linux_fetch_inferior_registers (struct target_ops *ops,
 
          amd64_supply_fxsave (regcache, -1, &fpregs);
        }
+#ifndef 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 base;
+
+       if (regnum == -1 || regnum == AMD64_FSBASE_REGNUM)
+         {
+           if (ptrace (PTRACE_ARCH_PRCTL, tid, &base, ARCH_GET_FS) < 0)
+             perror_with_name (_("Couldn't get segment register fs_base"));
+
+           regcache_raw_supply (regcache, AMD64_FSBASE_REGNUM, &base);
+         }
+
+       if (regnum == -1 || regnum == AMD64_GSBASE_REGNUM)
+         {
+           if (ptrace (PTRACE_ARCH_PRCTL, tid, &base, ARCH_GET_GS) < 0)
+             perror_with_name (_("Couldn't get segment register gs_base"));
+
+           regcache_raw_supply (regcache, AMD64_GSBASE_REGNUM, &base);
+         }
+      }
+#endif
     }
 }
 
@@ -186,9 +217,9 @@ amd64_linux_store_inferior_registers (struct target_ops *ops,
   int tid;
 
   /* GNU/Linux LWP ID's are process ID's.  */
-  tid = ptid_get_lwp (inferior_ptid);
+  tid = ptid_get_lwp (regcache_get_ptid (regcache));
   if (tid == 0)
-    tid = ptid_get_pid (inferior_ptid); /* Not a threaded program.  */
+    tid = ptid_get_pid (regcache_get_ptid (regcache)); /* Not a threaded program.  */
 
   if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
     {
@@ -237,6 +268,30 @@ amd64_linux_store_inferior_registers (struct target_ops *ops,
          if (ptrace (PTRACE_SETFPREGS, tid, 0, (long) &fpregs) < 0)
            perror_with_name (_("Couldn't write floating point status"));
        }
+
+#ifndef 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.  */
+       void *base;
+
+       if (regnum == -1 || regnum == AMD64_FSBASE_REGNUM)
+         {
+           regcache_raw_collect (regcache, AMD64_FSBASE_REGNUM, &base);
+
+           if (ptrace (PTRACE_ARCH_PRCTL, tid, base, ARCH_SET_FS) < 0)
+             perror_with_name (_("Couldn't write segment register fs_base"));
+         }
+       if (regnum == -1 || regnum == AMD64_GSBASE_REGNUM)
+         {
+
+           regcache_raw_collect (regcache, AMD64_GSBASE_REGNUM, &base);
+           if (ptrace (PTRACE_ARCH_PRCTL, tid, base, ARCH_SET_GS) < 0)
+             perror_with_name (_("Couldn't write segment register gs_base"));
+         }
+      }
+#endif
     }
 }
 \f
@@ -265,11 +320,7 @@ ps_get_thread_area (struct ps_prochandle *ph,
     }
   else
     {
-      /* This definition comes from prctl.h, but some kernels may not
-         have it.  */
-#ifndef PTRACE_ARCH_PRCTL
-#define PTRACE_ARCH_PRCTL      30
-#endif
+
       /* FIXME: ezannoni-2003-07-09 see comment above about include
         file order.  We could be getting bogus values for these two.  */
       gdb_assert (FS < ELF_NGREG);
This page took 0.025473 seconds and 4 git commands to generate.