GDB (xrefs)
/tmp/gdb-7.10/gdb/amd64fbsd-nat.c
Go to the documentation of this file.
1 /* Native-dependent code for FreeBSD/amd64.
2 
3  Copyright (C) 2003-2015 Free Software Foundation, Inc.
4 
5  This file is part of GDB.
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 
20 #include "defs.h"
21 #include "inferior.h"
22 #include "regcache.h"
23 #include "target.h"
24 
25 #include <signal.h>
26 #include <sys/types.h>
27 #include <sys/ptrace.h>
28 #include <sys/sysctl.h>
29 #include <sys/user.h>
30 #include <machine/reg.h>
31 
32 #include "fbsd-nat.h"
33 #include "amd64-tdep.h"
34 #include "amd64-nat.h"
35 #include "amd64bsd-nat.h"
36 #include "x86-nat.h"
37 
38 
39 /* Offset in `struct reg' where MEMBER is stored. */
40 #define REG_OFFSET(member) offsetof (struct reg, member)
41 
42 /* At amd64fbsd64_r_reg_offset[REGNUM] you'll find the offset in
43  `struct reg' location where the GDB register REGNUM is stored.
44  Unsupported registers are marked with `-1'. */
46 {
47  REG_OFFSET (r_rax),
48  REG_OFFSET (r_rbx),
49  REG_OFFSET (r_rcx),
50  REG_OFFSET (r_rdx),
51  REG_OFFSET (r_rsi),
52  REG_OFFSET (r_rdi),
53  REG_OFFSET (r_rbp),
54  REG_OFFSET (r_rsp),
55  REG_OFFSET (r_r8),
56  REG_OFFSET (r_r9),
57  REG_OFFSET (r_r10),
58  REG_OFFSET (r_r11),
59  REG_OFFSET (r_r12),
60  REG_OFFSET (r_r13),
61  REG_OFFSET (r_r14),
62  REG_OFFSET (r_r15),
63  REG_OFFSET (r_rip),
64  REG_OFFSET (r_rflags),
65  REG_OFFSET (r_cs),
66  REG_OFFSET (r_ss),
67  -1,
68  -1,
69  -1,
70  -1
71 };
72 
73 
74 /* Mapping between the general-purpose registers in FreeBSD/amd64
75  `struct reg' format and GDB's register cache layout for
76  FreeBSD/i386.
77 
78  Note that most FreeBSD/amd64 registers are 64-bit, while the
79  FreeBSD/i386 registers are all 32-bit, but since we're
80  little-endian we get away with that. */
81 
82 /* From <machine/reg.h>. */
84 {
85  14 * 8, 13 * 8, /* %eax, %ecx */
86  12 * 8, 11 * 8, /* %edx, %ebx */
87  20 * 8, 10 * 8, /* %esp, %ebp */
88  9 * 8, 8 * 8, /* %esi, %edi */
89  17 * 8, 19 * 8, /* %eip, %eflags */
90  18 * 8, 21 * 8, /* %cs, %ss */
91  -1, -1, -1, -1 /* %ds, %es, %fs, %gs */
92 };
93 
94 
95 /* Support for debugging kernel virtual memory images. */
96 
97 #include <machine/pcb.h>
98 #include <osreldate.h>
99 
100 #include "bsd-kvm.h"
101 
102 static int
103 amd64fbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
104 {
105  /* The following is true for FreeBSD 5.2:
106 
107  The pcb contains %rip, %rbx, %rsp, %rbp, %r12, %r13, %r14, %r15,
108  %ds, %es, %fs and %gs. This accounts for all callee-saved
109  registers specified by the psABI and then some. Here %esp
110  contains the stack pointer at the point just after the call to
111  cpu_switch(). From this information we reconstruct the register
112  state as it would like when we just returned from cpu_switch(). */
113 
114  /* The stack pointer shouldn't be zero. */
115  if (pcb->pcb_rsp == 0)
116  return 0;
117 
118  pcb->pcb_rsp += 8;
119  regcache_raw_supply (regcache, AMD64_RIP_REGNUM, &pcb->pcb_rip);
120  regcache_raw_supply (regcache, AMD64_RBX_REGNUM, &pcb->pcb_rbx);
121  regcache_raw_supply (regcache, AMD64_RSP_REGNUM, &pcb->pcb_rsp);
122  regcache_raw_supply (regcache, AMD64_RBP_REGNUM, &pcb->pcb_rbp);
123  regcache_raw_supply (regcache, 12, &pcb->pcb_r12);
124  regcache_raw_supply (regcache, 13, &pcb->pcb_r13);
125  regcache_raw_supply (regcache, 14, &pcb->pcb_r14);
126  regcache_raw_supply (regcache, 15, &pcb->pcb_r15);
127 #if (__FreeBSD_version < 800075) && (__FreeBSD_kernel_version < 800075)
128  /* struct pcb provides the pcb_ds/pcb_es/pcb_fs/pcb_gs fields only
129  up until __FreeBSD_version 800074: The removal of these fields
130  occurred on 2009-04-01 while the __FreeBSD_version number was
131  bumped to 800075 on 2009-04-06. So 800075 is the closest version
132  number where we should not try to access these fields. */
133  regcache_raw_supply (regcache, AMD64_DS_REGNUM, &pcb->pcb_ds);
134  regcache_raw_supply (regcache, AMD64_ES_REGNUM, &pcb->pcb_es);
135  regcache_raw_supply (regcache, AMD64_FS_REGNUM, &pcb->pcb_fs);
136  regcache_raw_supply (regcache, AMD64_GS_REGNUM, &pcb->pcb_gs);
137 #endif
138 
139  return 1;
140 }
141 
142 
143 static void (*super_mourn_inferior) (struct target_ops *ops);
144 
145 static void
147 {
148 #ifdef HAVE_PT_GETDBREGS
150 #endif
151  super_mourn_inferior (ops);
152 }
153 
154 /* Implement the to_read_description method. */
155 
156 static const struct target_desc *
158 {
159 #ifdef PT_GETXSTATE_INFO
160  static int xsave_probed;
161  static uint64_t xcr0;
162 #endif
163  struct reg regs;
164  int is64;
165 
166  if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
167  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
168  perror_with_name (_("Couldn't get registers"));
169  is64 = (regs.r_cs == GSEL (GUCODE_SEL, SEL_UPL));
170 #ifdef PT_GETXSTATE_INFO
171  if (!xsave_probed)
172  {
173  struct ptrace_xstate_info info;
174 
175  if (ptrace (PT_GETXSTATE_INFO, ptid_get_pid (inferior_ptid),
176  (PTRACE_TYPE_ARG3) &info, sizeof (info)) == 0)
177  {
178  amd64bsd_xsave_len = info.xsave_len;
179  xcr0 = info.xsave_mask;
180  }
181  xsave_probed = 1;
182  }
183 
184  if (amd64bsd_xsave_len != 0)
185  {
186  if (is64)
187  return amd64_target_description (xcr0);
188  else
189  return i386_target_description (xcr0);
190  }
191 #endif
192  if (is64)
193  return tdesc_amd64;
194  else
195  return tdesc_i386;
196 }
197 
198 /* Provide a prototype to silence -Wmissing-prototypes. */
199 void _initialize_amd64fbsd_nat (void);
200 
201 void
203 {
204  struct target_ops *t;
205  int offset;
206 
209 
210  /* Add some extra features to the common *BSD/i386 target. */
211  t = amd64bsd_target ();
212 
213 #ifdef HAVE_PT_GETDBREGS
214 
216 
223 
224 #endif /* HAVE_PT_GETDBREGS */
225 
229 
231 
232  /* Support debugging kernel virtual memory images. */
234 
235  /* To support the recognition of signal handlers, i386bsd-tdep.c
236  hardcodes some constants. Inclusion of this file means that we
237  are compiling a native debugger, which means that we can use the
238  system header files and sysctl(3) to get at the relevant
239  information. */
240 
241 #define SC_REG_OFFSET amd64fbsd_sc_reg_offset
242 
243  /* We only check the program counter, stack pointer and frame
244  pointer since these members of `struct sigcontext' are essential
245  for providing backtraces. */
246 
247 #define SC_RIP_OFFSET SC_REG_OFFSET[AMD64_RIP_REGNUM]
248 #define SC_RSP_OFFSET SC_REG_OFFSET[AMD64_RSP_REGNUM]
249 #define SC_RBP_OFFSET SC_REG_OFFSET[AMD64_RBP_REGNUM]
250 
251  /* Override the default value for the offset of the program counter
252  in the sigcontext structure. */
253  offset = offsetof (struct sigcontext, sc_rip);
254 
255  if (SC_RIP_OFFSET != offset)
256  {
257  warning (_("\
258 offsetof (struct sigcontext, sc_rip) yields %d instead of %d.\n\
259 Please report this to <bug-gdb@gnu.org>."),
260  offset, SC_RIP_OFFSET);
261  }
262 
264 
265  /* Likewise for the stack pointer. */
266  offset = offsetof (struct sigcontext, sc_rsp);
267 
268  if (SC_RSP_OFFSET != offset)
269  {
270  warning (_("\
271 offsetof (struct sigcontext, sc_rsp) yields %d instead of %d.\n\
272 Please report this to <bug-gdb@gnu.org>."),
273  offset, SC_RSP_OFFSET);
274  }
275 
277 
278  /* And the frame pointer. */
279  offset = offsetof (struct sigcontext, sc_rbp);
280 
281  if (SC_RBP_OFFSET != offset)
282  {
283  warning (_("\
284 offsetof (struct sigcontext, sc_rbp) yields %d instead of %d.\n\
285 Please report this to <bug-gdb@gnu.org>."),
286  offset, SC_RBP_OFFSET);
287  }
288 
290 
291 #ifdef KERN_PROC_SIGTRAMP
292  /* Normally signal frames are detected via amd64fbsd_sigtramp_p.
293  However, FreeBSD 9.2 through 10.1 do not include the page holding
294  the signal code in core dumps. These releases do provide a
295  kern.proc.sigtramp.<pid> sysctl that returns the location of the
296  signal trampoline for a running process. We fetch the location
297  of the current (gdb) process and use this to identify signal
298  frames in core dumps from these releases. Note that this only
299  works for core dumps of 64-bit (FreeBSD/amd64) processes and does
300  not handle core dumps of 32-bit (FreeBSD/i386) processes. */
301  {
302  int mib[4];
303  struct kinfo_sigtramp kst;
304  size_t len;
305 
306  mib[0] = CTL_KERN;
307  mib[1] = KERN_PROC;
308  mib[2] = KERN_PROC_SIGTRAMP;
309  mib[3] = getpid ();
310  len = sizeof (kst);
311  if (sysctl (mib, 4, &kst, &len, NULL, 0) == 0)
312  {
313  amd64fbsd_sigtramp_start_addr = (uintptr_t) kst.ksigtramp_start;
314  amd64fbsd_sigtramp_end_addr = (uintptr_t) kst.ksigtramp_end;
315  }
316  }
317 #endif
318 }
#define I386_NUM_GREGS
Definition: i386-tdep.h:320
#define SC_RBP_OFFSET
const struct target_desc *(* to_read_description)(struct target_ops *ops) TARGET_DEFAULT_RETURN(NULL)
Definition: target.h:769
#define REG_OFFSET(member)
Definition: amd64fbsd-nat.c:40
static int amd64fbsd32_r_reg_offset[I386_NUM_GREGS]
Definition: amd64fbsd-nat.c:83
void fbsd_nat_add_target(struct target_ops *t)
Definition: fbsd-nat.c:491
void warning(const char *fmt,...)
Definition: errors.c:26
static int amd64fbsd_supply_pcb(struct regcache *regcache, struct pcb *pcb)
struct target_desc * tdesc_amd64
Definition: amd64.c:8
void amd64bsd_dr_set_addr(int regnum, CORE_ADDR addr)
static int amd64fbsd64_r_reg_offset[]
Definition: amd64fbsd-nat.c:45
#define _(String)
Definition: gdb_locale.h:40
void(* set_control)(unsigned long)
Definition: x86-dregs.h:44
struct x86_dr_low_type x86_dr_low
Definition: x86-nat.c:37
CORE_ADDR amd64fbsd_sigtramp_start_addr
CORE_ADDR(* get_addr)(int)
Definition: x86-dregs.h:52
PTRACE_TYPE_RET ptrace()
#define SC_RIP_OFFSET
#define SC_RSP_OFFSET
size_t amd64bsd_xsave_len
int * amd64_native_gregset32_reg_offset
Definition: amd64-nat.c:41
void(* set_addr)(int, CORE_ADDR)
Definition: x86-dregs.h:48
static const struct target_desc * amd64fbsd_read_description(struct target_ops *ops)
unsigned long(* get_status)(void)
Definition: x86-dregs.h:56
int * amd64_native_gregset64_reg_offset
Definition: amd64-nat.c:45
struct target_ops * amd64bsd_target(void)
Definition: amd64bsd-nat.c:155
struct target_desc * tdesc_i386
Definition: i386.c:8
void amd64bsd_dr_set_control(unsigned long control)
unsigned long amd64bsd_dr_get_status(void)
unsigned long amd64bsd_dr_get_control(void)
void _initialize_amd64fbsd_nat(void)
unsigned long(* get_control)(void)
Definition: x86-dregs.h:60
Definition: regdef.h:22
int ptid_get_pid(ptid_t ptid)
Definition: ptid.c:52
void(* to_mourn_inferior)(struct target_ops *) TARGET_DEFAULT_FUNC(default_mourn_inferior)
Definition: target.h:607
void void void void void void void void void perror_with_name(const char *string) ATTRIBUTE_NORETURN
Definition: utils.c:979
static void amd64fbsd_mourn_inferior(struct target_ops *ops)
ptid_t inferior_ptid
Definition: infcmd.c:124
int offset
Definition: agent.c:65
CORE_ADDR amd64bsd_dr_get_addr(int regnum)
void regcache_raw_supply(struct regcache *regcache, int regnum, const void *buf)
Definition: regcache.c:1041
void x86_set_debug_register_length(int len)
Definition: x86-nat.c:307
CORE_ADDR amd64fbsd_sigtramp_end_addr
#define PTRACE_TYPE_ARG3
Definition: config.h:658
void x86_use_watchpoints(struct target_ops *t)
Definition: x86-nat.c:289
void bsd_kvm_add_target(int(*supply_pcb)(struct regcache *, struct pcb *))
Definition: bsd-kvm.c:351
void x86_cleanup_dregs(void)
Definition: x86-nat.c:141
static void(* super_mourn_inferior)(struct target_ops *ops)
const struct target_desc * amd64_target_description(uint64_t xcr0)
Definition: amd64-tdep.c:3127
const struct target_desc * i386_target_description(uint64_t xcr0)
Definition: i386-tdep.c:8604
const ULONGEST const LONGEST len
Definition: target.h:309