summaryrefslogtreecommitdiff
path: root/devel/gdb/files/commit-0aa37b654c
blob: ee6db77f7d1c447ebce7202796e2d438c9b9d187 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
commit 0aa37b654c0f31e446ab47826f0bcbec15d0112f
Author: John Baldwin <jhb@FreeBSD.org>
Date:   Mon Jun 26 18:18:19 2017 -0700

    Support the fs_base and gs_base registers on FreeBSD/amd64 native processes.
    
    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.

diff --git gdb/amd64-bsd-nat.c gdb/amd64-bsd-nat.c
index ca61a3551b..41dee84269 100644
--- gdb/amd64-bsd-nat.c
+++ gdb/amd64-bsd-nat.c
@@ -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;