Support the fs_base and gs_base registers on FreeBSD/amd64 native processes.
authorJohn Baldwin <jhb@FreeBSD.org>
Tue, 27 Jun 2017 01:18:19 +0000 (18:18 -0700)
committerJohn Baldwin <jhb@FreeBSD.org>
Tue, 11 Jul 2017 16:47:14 +0000 (09:47 -0700)
Use ptrace operations to fetch and store the fs_base and gs_base registers
for FreeBSD/amd64 processes.  Note that FreeBSD does not currently store the
value of these registers in core dumps, so these registers are only
available when inspecting a running process.

gdb/ChangeLog:

* amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers): Use
PT_GETFSBASE and PT_GETGSBASE.
(amd64bsd_store_inferior_registers): Use PT_SETFSBASE and
PT_SETGSBASE.

gdb/ChangeLog
gdb/amd64-bsd-nat.c

index 39d3680..012b3e4 100644 (file)
@@ -1,5 +1,12 @@
 2017-07-11  John Baldwin  <jhb@FreeBSD.org>
 
+       * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers): Use
+       PT_GETFSBASE and PT_GETGSBASE.
+       (amd64bsd_store_inferior_registers): Use PT_SETFSBASE and
+       PT_SETGSBASE.
+
+2017-07-11  John Baldwin  <jhb@FreeBSD.org>
+
        * features/Makefile (amd64.dat, amd64-avx.dat, amd64-mpx.dat)
        (amd64-avx-mpx.dat, amd64-avx-avx512.dat)
        (amd64-avx-mpx-avx512-pku.dat): Add i386/64bit-segments.xml in
index ca61a35..41dee84 100644 (file)
@@ -57,6 +57,33 @@ amd64bsd_fetch_inferior_registers (struct target_ops *ops,
        return;
     }
 
+#ifdef PT_GETFSBASE
+  if (regnum == -1 || regnum == AMD64_FSBASE_REGNUM)
+    {
+      register_t base;
+
+      if (ptrace (PT_GETFSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1)
+       perror_with_name (_("Couldn't get segment register fs_base"));
+
+      regcache_raw_supply (regcache, AMD64_FSBASE_REGNUM, &base);
+      if (regnum != -1)
+       return;
+    }
+#endif
+#ifdef PT_GETGSBASE
+  if (regnum == -1 || regnum == AMD64_GSBASE_REGNUM)
+    {
+      register_t base;
+
+      if (ptrace (PT_GETGSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1)
+       perror_with_name (_("Couldn't get segment register gs_base"));
+
+      regcache_raw_supply (regcache, AMD64_GSBASE_REGNUM, &base);
+      if (regnum != -1)
+       return;
+    }
+#endif
+
   if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
     {
       struct fpreg fpregs;
@@ -108,6 +135,33 @@ amd64bsd_store_inferior_registers (struct target_ops *ops,
        return;
     }
 
+#ifdef PT_SETFSBASE
+  if (regnum == -1 || regnum == AMD64_FSBASE_REGNUM)
+    {
+      register_t base;
+
+      regcache_raw_collect (regcache, AMD64_FSBASE_REGNUM, &base);
+
+      if (ptrace (PT_SETFSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1)
+       perror_with_name (_("Couldn't write segment register fs_base"));
+      if (regnum != -1)
+       return;
+    }
+#endif
+#ifdef PT_SETGSBASE
+  if (regnum == -1 || regnum == AMD64_GSBASE_REGNUM)
+    {
+      register_t base;
+
+      regcache_raw_collect (regcache, AMD64_GSBASE_REGNUM, &base);
+
+      if (ptrace (PT_SETGSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1)
+       perror_with_name (_("Couldn't write segment register gs_base"));
+      if (regnum != -1)
+       return;
+    }
+#endif
+
   if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
     {
       struct fpreg fpregs;