[AArch64] Don't warn on XZR/SP overlapping when it's in load/store
[deliverable/binutils-gdb.git] / gdb / amd64fbsd-tdep.c
CommitLineData
68cc0bfb 1/* Target-dependent code for FreeBSD/amd64.
477f40d1 2
32d0add0 3 Copyright (C) 2003-2015 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"
26
85be1ca6 27#include "amd64-tdep.h"
1c02b2a5 28#include "bsd-uthread.h"
490496c3 29#include "fbsd-tdep.h"
7e654c37 30#include "solib-svr4.h"
68cc0bfb
MK
31
32/* Support for signal handlers. */
33
cf424aef
JB
34/* Return whether THIS_FRAME corresponds to a FreeBSD sigtramp
35 routine. */
36
37static const gdb_byte amd64fbsd_sigtramp_code[] =
38{
39 0x48, 0x8d, 0x7c, 0x24, 0x10, /* lea SIGF_UC(%rsp),%rdi */
40 0x6a, 0x00, /* pushq $0 */
41 0x48, 0xc7, 0xc0, 0xa1, 0x01, 0x00, 0x00,
42 /* movq $SYS_sigreturn,%rax */
43 0x0f, 0x05 /* syscall */
44};
45
46static int
47amd64fbsd_sigtramp_p (struct frame_info *this_frame)
48{
49 CORE_ADDR pc = get_frame_pc (this_frame);
50 gdb_byte buf[sizeof amd64fbsd_sigtramp_code];
51
52 if (!safe_frame_unwind_memory (this_frame, pc, buf, sizeof buf))
53 return 0;
54 if (memcmp (buf, amd64fbsd_sigtramp_code, sizeof amd64fbsd_sigtramp_code) !=
55 0)
56 return 0;
57
58 return 1;
59}
60
10458914
DJ
61/* Assuming THIS_FRAME is for a BSD sigtramp routine, return the
62 address of the associated sigcontext structure. */
68cc0bfb
MK
63
64static CORE_ADDR
10458914 65amd64fbsd_sigcontext_addr (struct frame_info *this_frame)
68cc0bfb 66{
c5cb74ee
JB
67 struct gdbarch *gdbarch = get_frame_arch (this_frame);
68 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
68cc0bfb 69 CORE_ADDR sp;
c5cb74ee 70 gdb_byte buf[8];
68cc0bfb 71
212c460c
MK
72 /* The `struct sigcontext' (which really is an `ucontext_t' on
73 FreeBSD/amd64) lives at a fixed offset in the signal frame. See
74 <machine/sigframe.h>. */
c5cb74ee
JB
75 get_frame_register (this_frame, AMD64_RSP_REGNUM, buf);
76 sp = extract_unsigned_integer (buf, 8, byte_order);
212c460c 77 return sp + 16;
68cc0bfb
MK
78}
79\f
80/* FreeBSD 5.1-RELEASE or later. */
81
477f40d1
MK
82/* Mapping between the general-purpose registers in `struct reg'
83 format and GDB's register cache layout.
84
85 Note that some registers are 32-bit, but since we're little-endian
86 we get away with that. */
87
88/* From <machine/reg.h>. */
89static int amd64fbsd_r_reg_offset[] =
90{
af233647
MK
91 14 * 8, /* %rax */
92 11 * 8, /* %rbx */
93 13 * 8, /* %rcx */
94 12 * 8, /* %rdx */
95 9 * 8, /* %rsi */
96 8 * 8, /* %rdi */
97 10 * 8, /* %rbp */
98 20 * 8, /* %rsp */
0963b4bd 99 7 * 8, /* %r8 ... */
af233647
MK
100 6 * 8,
101 5 * 8,
102 4 * 8,
103 3 * 8,
104 2 * 8,
105 1 * 8,
106 0 * 8, /* ... %r15 */
107 17 * 8, /* %rip */
108 19 * 8, /* %eflags */
109 18 * 8, /* %cs */
110 21 * 8, /* %ss */
111 -1, /* %ds */
112 -1, /* %es */
113 -1, /* %fs */
114 -1 /* %gs */
477f40d1
MK
115};
116
68cc0bfb 117/* Location of the signal trampoline. */
cf424aef
JB
118CORE_ADDR amd64fbsd_sigtramp_start_addr;
119CORE_ADDR amd64fbsd_sigtramp_end_addr;
68cc0bfb
MK
120
121/* From <machine/signal.h>. */
af233647 122int amd64fbsd_sc_reg_offset[] =
68cc0bfb 123{
212c460c
MK
124 24 + 6 * 8, /* %rax */
125 24 + 7 * 8, /* %rbx */
126 24 + 3 * 8, /* %rcx */
127 24 + 2 * 8, /* %rdx */
128 24 + 1 * 8, /* %rsi */
129 24 + 0 * 8, /* %rdi */
130 24 + 8 * 8, /* %rbp */
dac94105 131 24 + 22 * 8, /* %rsp */
0963b4bd 132 24 + 4 * 8, /* %r8 ... */
af233647
MK
133 24 + 5 * 8,
134 24 + 9 * 8,
135 24 + 10 * 8,
136 24 + 11 * 8,
137 24 + 12 * 8,
138 24 + 13 * 8,
139 24 + 14 * 8, /* ... %r15 */
dac94105
MK
140 24 + 19 * 8, /* %rip */
141 24 + 21 * 8, /* %eflags */
af233647
MK
142 24 + 20 * 8, /* %cs */
143 24 + 23 * 8, /* %ss */
68cc0bfb
MK
144 -1, /* %ds */
145 -1, /* %es */
146 -1, /* %fs */
147 -1 /* %gs */
148};
149
1c02b2a5
MK
150/* From /usr/src/lib/libc/amd64/gen/_setjmp.S. */
151static int amd64fbsd_jmp_buf_reg_offset[] =
152{
153 -1, /* %rax */
154 1 * 8, /* %rbx */
155 -1, /* %rcx */
156 -1, /* %rdx */
157 -1, /* %rsi */
158 -1, /* %rdi */
159 3 * 8, /* %rbp */
160 2 * 8, /* %rsp */
0963b4bd 161 -1, /* %r8 ... */
1c02b2a5
MK
162 -1,
163 -1,
164 -1, /* ... %r11 */
0963b4bd 165 4 * 8, /* %r12 ... */
1c02b2a5
MK
166 5 * 8,
167 6 * 8,
168 7 * 8, /* ... %r15 */
169 0 * 8 /* %rip */
170};
171
172static void
173amd64fbsd_supply_uthread (struct regcache *regcache,
174 int regnum, CORE_ADDR addr)
175{
4252dc94 176 gdb_byte buf[8];
1c02b2a5
MK
177 int i;
178
179 gdb_assert (regnum >= -1);
180
181 for (i = 0; i < ARRAY_SIZE (amd64fbsd_jmp_buf_reg_offset); i++)
182 {
183 if (amd64fbsd_jmp_buf_reg_offset[i] != -1
184 && (regnum == -1 || regnum == i))
185 {
186 read_memory (addr + amd64fbsd_jmp_buf_reg_offset[i], buf, 8);
187 regcache_raw_supply (regcache, i, buf);
188 }
189 }
190}
191
192static void
193amd64fbsd_collect_uthread (const struct regcache *regcache,
194 int regnum, CORE_ADDR addr)
195{
4252dc94 196 gdb_byte buf[8];
1c02b2a5
MK
197 int i;
198
199 gdb_assert (regnum >= -1);
200
201 for (i = 0; i < ARRAY_SIZE (amd64fbsd_jmp_buf_reg_offset); i++)
202 {
203 if (amd64fbsd_jmp_buf_reg_offset[i] != -1
204 && (regnum == -1 || regnum == i))
205 {
206 regcache_raw_collect (regcache, i, buf);
207 write_memory (addr + amd64fbsd_jmp_buf_reg_offset[i], buf, 8);
208 }
209 }
210}
211
63807e1d 212static void
68cc0bfb
MK
213amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
214{
215 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
216
490496c3
AA
217 /* Generic FreeBSD support. */
218 fbsd_init_abi (info, gdbarch);
219
68cc0bfb
MK
220 /* Obviously FreeBSD is BSD-based. */
221 i386bsd_init_abi (info, gdbarch);
222
477f40d1
MK
223 tdep->gregset_reg_offset = amd64fbsd_r_reg_offset;
224 tdep->gregset_num_regs = ARRAY_SIZE (amd64fbsd_r_reg_offset);
225 tdep->sizeof_gregset = 22 * 8;
226
90f90721 227 amd64_init_abi (info, gdbarch);
68cc0bfb 228
cf424aef 229 tdep->sigtramp_p = amd64fbsd_sigtramp_p;
10fc94a4
MK
230 tdep->sigtramp_start = amd64fbsd_sigtramp_start_addr;
231 tdep->sigtramp_end = amd64fbsd_sigtramp_end_addr;
68cc0bfb
MK
232 tdep->sigcontext_addr = amd64fbsd_sigcontext_addr;
233 tdep->sc_reg_offset = amd64fbsd_sc_reg_offset;
477f40d1 234 tdep->sc_num_regs = ARRAY_SIZE (amd64fbsd_sc_reg_offset);
7e654c37 235
1c02b2a5
MK
236 /* FreeBSD provides a user-level threads implementation. */
237 bsd_uthread_set_supply_uthread (gdbarch, amd64fbsd_supply_uthread);
238 bsd_uthread_set_collect_uthread (gdbarch, amd64fbsd_collect_uthread);
239
7e654c37
MK
240 /* FreeBSD uses SVR4-style shared libraries. */
241 set_solib_svr4_fetch_link_map_offsets
242 (gdbarch, svr4_lp64_fetch_link_map_offsets);
68cc0bfb
MK
243}
244\f
245
246/* Provide a prototype to silence -Wmissing-prototypes. */
247void _initialize_amd64fbsd_tdep (void);
248
249void
250_initialize_amd64fbsd_tdep (void)
251{
252 gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
253 GDB_OSABI_FREEBSD_ELF, amd64fbsd_init_abi);
254}
This page took 0.660556 seconds and 4 git commands to generate.