btrace: Store btrace_insn in an std::vector
[deliverable/binutils-gdb.git] / gdb / amd64-fbsd-tdep.c
CommitLineData
68cc0bfb 1/* Target-dependent code for FreeBSD/amd64.
477f40d1 2
61baf725 3 Copyright (C) 2003-2017 Free Software Foundation, Inc.
68cc0bfb
MK
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
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
68cc0bfb
MK
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
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
68cc0bfb
MK
19
20#include "defs.h"
21#include "arch-utils.h"
22#include "frame.h"
23#include "gdbcore.h"
24#include "regcache.h"
25#include "osabi.h"
97de3545 26#include "regset.h"
03b62bbb 27#include "i386-fbsd-tdep.h"
97de3545 28#include "x86-xstate.h"
68cc0bfb 29
85be1ca6 30#include "amd64-tdep.h"
490496c3 31#include "fbsd-tdep.h"
7e654c37 32#include "solib-svr4.h"
68cc0bfb
MK
33
34/* Support for signal handlers. */
35
cf424aef
JB
36/* Return whether THIS_FRAME corresponds to a FreeBSD sigtramp
37 routine. */
38
39static const gdb_byte amd64fbsd_sigtramp_code[] =
40{
41 0x48, 0x8d, 0x7c, 0x24, 0x10, /* lea SIGF_UC(%rsp),%rdi */
42 0x6a, 0x00, /* pushq $0 */
43 0x48, 0xc7, 0xc0, 0xa1, 0x01, 0x00, 0x00,
44 /* movq $SYS_sigreturn,%rax */
45 0x0f, 0x05 /* syscall */
46};
47
48static int
49amd64fbsd_sigtramp_p (struct frame_info *this_frame)
50{
51 CORE_ADDR pc = get_frame_pc (this_frame);
52 gdb_byte buf[sizeof amd64fbsd_sigtramp_code];
53
54 if (!safe_frame_unwind_memory (this_frame, pc, buf, sizeof buf))
55 return 0;
773eacf5
JB
56 if (memcmp (buf, amd64fbsd_sigtramp_code, sizeof amd64fbsd_sigtramp_code)
57 != 0)
cf424aef
JB
58 return 0;
59
60 return 1;
61}
62
10458914
DJ
63/* Assuming THIS_FRAME is for a BSD sigtramp routine, return the
64 address of the associated sigcontext structure. */
68cc0bfb
MK
65
66static CORE_ADDR
10458914 67amd64fbsd_sigcontext_addr (struct frame_info *this_frame)
68cc0bfb 68{
c5cb74ee
JB
69 struct gdbarch *gdbarch = get_frame_arch (this_frame);
70 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
68cc0bfb 71 CORE_ADDR sp;
c5cb74ee 72 gdb_byte buf[8];
68cc0bfb 73
212c460c
MK
74 /* The `struct sigcontext' (which really is an `ucontext_t' on
75 FreeBSD/amd64) lives at a fixed offset in the signal frame. See
76 <machine/sigframe.h>. */
c5cb74ee
JB
77 get_frame_register (this_frame, AMD64_RSP_REGNUM, buf);
78 sp = extract_unsigned_integer (buf, 8, byte_order);
212c460c 79 return sp + 16;
68cc0bfb
MK
80}
81\f
82/* FreeBSD 5.1-RELEASE or later. */
83
477f40d1
MK
84/* Mapping between the general-purpose registers in `struct reg'
85 format and GDB's register cache layout.
86
87 Note that some registers are 32-bit, but since we're little-endian
88 we get away with that. */
89
90/* From <machine/reg.h>. */
91static int amd64fbsd_r_reg_offset[] =
92{
af233647
MK
93 14 * 8, /* %rax */
94 11 * 8, /* %rbx */
95 13 * 8, /* %rcx */
96 12 * 8, /* %rdx */
97 9 * 8, /* %rsi */
98 8 * 8, /* %rdi */
99 10 * 8, /* %rbp */
100 20 * 8, /* %rsp */
0963b4bd 101 7 * 8, /* %r8 ... */
af233647
MK
102 6 * 8,
103 5 * 8,
104 4 * 8,
105 3 * 8,
106 2 * 8,
107 1 * 8,
108 0 * 8, /* ... %r15 */
109 17 * 8, /* %rip */
110 19 * 8, /* %eflags */
111 18 * 8, /* %cs */
112 21 * 8, /* %ss */
113 -1, /* %ds */
114 -1, /* %es */
115 -1, /* %fs */
116 -1 /* %gs */
477f40d1
MK
117};
118
68cc0bfb 119/* Location of the signal trampoline. */
cf424aef
JB
120CORE_ADDR amd64fbsd_sigtramp_start_addr;
121CORE_ADDR amd64fbsd_sigtramp_end_addr;
68cc0bfb
MK
122
123/* From <machine/signal.h>. */
af233647 124int amd64fbsd_sc_reg_offset[] =
68cc0bfb 125{
212c460c
MK
126 24 + 6 * 8, /* %rax */
127 24 + 7 * 8, /* %rbx */
128 24 + 3 * 8, /* %rcx */
129 24 + 2 * 8, /* %rdx */
130 24 + 1 * 8, /* %rsi */
131 24 + 0 * 8, /* %rdi */
132 24 + 8 * 8, /* %rbp */
dac94105 133 24 + 22 * 8, /* %rsp */
0963b4bd 134 24 + 4 * 8, /* %r8 ... */
af233647
MK
135 24 + 5 * 8,
136 24 + 9 * 8,
137 24 + 10 * 8,
138 24 + 11 * 8,
139 24 + 12 * 8,
140 24 + 13 * 8,
141 24 + 14 * 8, /* ... %r15 */
dac94105
MK
142 24 + 19 * 8, /* %rip */
143 24 + 21 * 8, /* %eflags */
af233647
MK
144 24 + 20 * 8, /* %cs */
145 24 + 23 * 8, /* %ss */
68cc0bfb
MK
146 -1, /* %ds */
147 -1, /* %es */
148 -1, /* %fs */
149 -1 /* %gs */
150};
151
97de3545
JB
152/* Implement the core_read_description gdbarch method. */
153
154static const struct target_desc *
155amd64fbsd_core_read_description (struct gdbarch *gdbarch,
156 struct target_ops *target,
157 bfd *abfd)
158{
159 return amd64_target_description (i386fbsd_core_read_xcr0 (abfd));
160}
161
162/* Similar to amd64_supply_fpregset, but use XSAVE extended state. */
163
164static void
165amd64fbsd_supply_xstateregset (const struct regset *regset,
166 struct regcache *regcache, int regnum,
167 const void *xstateregs, size_t len)
168{
169 amd64_supply_xsave (regcache, regnum, xstateregs);
170}
171
172/* Similar to amd64_collect_fpregset, but use XSAVE extended state. */
173
174static void
175amd64fbsd_collect_xstateregset (const struct regset *regset,
176 const struct regcache *regcache,
177 int regnum, void *xstateregs, size_t len)
178{
179 amd64_collect_xsave (regcache, regnum, xstateregs, 1);
180}
181
182static const struct regset amd64fbsd_xstateregset =
183 {
184 NULL,
185 amd64fbsd_supply_xstateregset,
186 amd64fbsd_collect_xstateregset
187 };
188
189/* Iterate over core file register note sections. */
190
191static void
192amd64fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
193 iterate_over_regset_sections_cb *cb,
194 void *cb_data,
195 const struct regcache *regcache)
196{
197 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
198
199 cb (".reg", tdep->sizeof_gregset, &i386_gregset, NULL, cb_data);
200 cb (".reg2", tdep->sizeof_fpregset, &amd64_fpregset, NULL, cb_data);
201 cb (".reg-xstate", X86_XSTATE_SIZE(tdep->xcr0),
202 &amd64fbsd_xstateregset, "XSAVE extended state", cb_data);
203}
204
63807e1d 205static void
68cc0bfb
MK
206amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
207{
208 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
209
490496c3
AA
210 /* Generic FreeBSD support. */
211 fbsd_init_abi (info, gdbarch);
212
68cc0bfb
MK
213 /* Obviously FreeBSD is BSD-based. */
214 i386bsd_init_abi (info, gdbarch);
215
477f40d1
MK
216 tdep->gregset_reg_offset = amd64fbsd_r_reg_offset;
217 tdep->gregset_num_regs = ARRAY_SIZE (amd64fbsd_r_reg_offset);
218 tdep->sizeof_gregset = 22 * 8;
219
c55a47e7 220 amd64_init_abi (info, gdbarch, tdesc_amd64);
68cc0bfb 221
cf424aef 222 tdep->sigtramp_p = amd64fbsd_sigtramp_p;
10fc94a4
MK
223 tdep->sigtramp_start = amd64fbsd_sigtramp_start_addr;
224 tdep->sigtramp_end = amd64fbsd_sigtramp_end_addr;
68cc0bfb
MK
225 tdep->sigcontext_addr = amd64fbsd_sigcontext_addr;
226 tdep->sc_reg_offset = amd64fbsd_sc_reg_offset;
477f40d1 227 tdep->sc_num_regs = ARRAY_SIZE (amd64fbsd_sc_reg_offset);
7e654c37 228
97de3545
JB
229 tdep->xsave_xcr0_offset = I386_FBSD_XSAVE_XCR0_OFFSET;
230
231 /* Iterate over core file register note sections. */
232 set_gdbarch_iterate_over_regset_sections
233 (gdbarch, amd64fbsd_iterate_over_regset_sections);
234
235 set_gdbarch_core_read_description (gdbarch,
236 amd64fbsd_core_read_description);
237
7e654c37
MK
238 /* FreeBSD uses SVR4-style shared libraries. */
239 set_solib_svr4_fetch_link_map_offsets
240 (gdbarch, svr4_lp64_fetch_link_map_offsets);
68cc0bfb
MK
241}
242\f
243
244/* Provide a prototype to silence -Wmissing-prototypes. */
245void _initialize_amd64fbsd_tdep (void);
246
247void
248_initialize_amd64fbsd_tdep (void)
249{
250 gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
1736a7bd 251 GDB_OSABI_FREEBSD, amd64fbsd_init_abi);
68cc0bfb 252}
This page took 0.812543 seconds and 4 git commands to generate.