ubsan: aarch64: left shift of negative value
[deliverable/binutils-gdb.git] / gdb / amd64-fbsd-tdep.c
CommitLineData
68cc0bfb 1/* Target-dependent code for FreeBSD/amd64.
477f40d1 2
42a4f53d 3 Copyright (C) 2003-2019 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"
d55e5aa6 24#include "regcache.h"
4de283e4 25#include "osabi.h"
97de3545 26#include "regset.h"
4de283e4 27#include "i386-fbsd-tdep.h"
268a13a5 28#include "gdbsupport/x86-xstate.h"
4de283e4
TT
29
30#include "amd64-tdep.h"
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{
41206e32 159 return amd64_target_description (i386fbsd_core_read_xcr0 (abfd), true);
97de3545
JB
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
a616bb94
AH
199 cb (".reg", tdep->sizeof_gregset, tdep->sizeof_gregset, &i386_gregset, NULL,
200 cb_data);
201 cb (".reg2", tdep->sizeof_fpregset, tdep->sizeof_fpregset, &amd64_fpregset,
202 NULL, cb_data);
203 cb (".reg-xstate", X86_XSTATE_SIZE (tdep->xcr0), X86_XSTATE_SIZE (tdep->xcr0),
97de3545
JB
204 &amd64fbsd_xstateregset, "XSAVE extended state", cb_data);
205}
206
f5424cfa
JB
207/* Implement the get_thread_local_address gdbarch method. */
208
209static CORE_ADDR
210amd64fbsd_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid,
211 CORE_ADDR lm_addr, CORE_ADDR offset)
212{
213 struct regcache *regcache;
214
215 regcache = get_thread_arch_regcache (ptid, gdbarch);
216
217 target_fetch_registers (regcache, AMD64_FSBASE_REGNUM);
218
219 ULONGEST fsbase;
220 if (regcache->cooked_read (AMD64_FSBASE_REGNUM, &fsbase) != REG_VALID)
221 error (_("Unable to fetch %%fsbase"));
222
223 CORE_ADDR dtv_addr = fsbase + gdbarch_ptr_bit (gdbarch) / 8;
224 return fbsd_get_thread_local_address (gdbarch, dtv_addr, lm_addr, offset);
225}
226
63807e1d 227static void
68cc0bfb
MK
228amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
229{
230 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
231
490496c3
AA
232 /* Generic FreeBSD support. */
233 fbsd_init_abi (info, gdbarch);
234
68cc0bfb
MK
235 /* Obviously FreeBSD is BSD-based. */
236 i386bsd_init_abi (info, gdbarch);
237
477f40d1
MK
238 tdep->gregset_reg_offset = amd64fbsd_r_reg_offset;
239 tdep->gregset_num_regs = ARRAY_SIZE (amd64fbsd_r_reg_offset);
240 tdep->sizeof_gregset = 22 * 8;
241
2434b019 242 amd64_init_abi (info, gdbarch,
41206e32 243 amd64_target_description (X86_XSTATE_SSE_MASK, true));
68cc0bfb 244
cf424aef 245 tdep->sigtramp_p = amd64fbsd_sigtramp_p;
10fc94a4
MK
246 tdep->sigtramp_start = amd64fbsd_sigtramp_start_addr;
247 tdep->sigtramp_end = amd64fbsd_sigtramp_end_addr;
68cc0bfb
MK
248 tdep->sigcontext_addr = amd64fbsd_sigcontext_addr;
249 tdep->sc_reg_offset = amd64fbsd_sc_reg_offset;
477f40d1 250 tdep->sc_num_regs = ARRAY_SIZE (amd64fbsd_sc_reg_offset);
7e654c37 251
97de3545
JB
252 tdep->xsave_xcr0_offset = I386_FBSD_XSAVE_XCR0_OFFSET;
253
254 /* Iterate over core file register note sections. */
255 set_gdbarch_iterate_over_regset_sections
256 (gdbarch, amd64fbsd_iterate_over_regset_sections);
257
258 set_gdbarch_core_read_description (gdbarch,
259 amd64fbsd_core_read_description);
260
7e654c37
MK
261 /* FreeBSD uses SVR4-style shared libraries. */
262 set_solib_svr4_fetch_link_map_offsets
263 (gdbarch, svr4_lp64_fetch_link_map_offsets);
f5424cfa
JB
264
265 set_gdbarch_fetch_tls_load_module_address (gdbarch,
266 svr4_fetch_objfile_link_map);
267 set_gdbarch_get_thread_local_address (gdbarch,
268 amd64fbsd_get_thread_local_address);
68cc0bfb 269}
68cc0bfb
MK
270
271void
272_initialize_amd64fbsd_tdep (void)
273{
274 gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
1736a7bd 275 GDB_OSABI_FREEBSD, amd64fbsd_init_abi);
68cc0bfb 276}
This page took 1.002515 seconds and 4 git commands to generate.