Import alloca explicitly
[deliverable/binutils-gdb.git] / gdb / amd64fbsd-tdep.c
CommitLineData
68cc0bfb 1/* Target-dependent code for FreeBSD/amd64.
477f40d1 2
ecd75fc8 3 Copyright (C) 2003-2014 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
10458914
DJ
34/* Assuming THIS_FRAME is for a BSD sigtramp routine, return the
35 address of the associated sigcontext structure. */
68cc0bfb
MK
36
37static CORE_ADDR
10458914 38amd64fbsd_sigcontext_addr (struct frame_info *this_frame)
68cc0bfb 39{
68cc0bfb
MK
40 CORE_ADDR sp;
41
212c460c
MK
42 /* The `struct sigcontext' (which really is an `ucontext_t' on
43 FreeBSD/amd64) lives at a fixed offset in the signal frame. See
44 <machine/sigframe.h>. */
10458914 45 sp = frame_unwind_register_unsigned (this_frame, AMD64_RSP_REGNUM);
212c460c 46 return sp + 16;
68cc0bfb
MK
47}
48\f
49/* FreeBSD 5.1-RELEASE or later. */
50
477f40d1
MK
51/* Mapping between the general-purpose registers in `struct reg'
52 format and GDB's register cache layout.
53
54 Note that some registers are 32-bit, but since we're little-endian
55 we get away with that. */
56
57/* From <machine/reg.h>. */
58static int amd64fbsd_r_reg_offset[] =
59{
af233647
MK
60 14 * 8, /* %rax */
61 11 * 8, /* %rbx */
62 13 * 8, /* %rcx */
63 12 * 8, /* %rdx */
64 9 * 8, /* %rsi */
65 8 * 8, /* %rdi */
66 10 * 8, /* %rbp */
67 20 * 8, /* %rsp */
0963b4bd 68 7 * 8, /* %r8 ... */
af233647
MK
69 6 * 8,
70 5 * 8,
71 4 * 8,
72 3 * 8,
73 2 * 8,
74 1 * 8,
75 0 * 8, /* ... %r15 */
76 17 * 8, /* %rip */
77 19 * 8, /* %eflags */
78 18 * 8, /* %cs */
79 21 * 8, /* %ss */
80 -1, /* %ds */
81 -1, /* %es */
82 -1, /* %fs */
83 -1 /* %gs */
477f40d1
MK
84};
85
68cc0bfb 86/* Location of the signal trampoline. */
ec20a626
UW
87CORE_ADDR amd64fbsd_sigtramp_start_addr = 0x7fffffffffc0ULL;
88CORE_ADDR amd64fbsd_sigtramp_end_addr = 0x7fffffffffe0ULL;
68cc0bfb
MK
89
90/* From <machine/signal.h>. */
af233647 91int amd64fbsd_sc_reg_offset[] =
68cc0bfb 92{
212c460c
MK
93 24 + 6 * 8, /* %rax */
94 24 + 7 * 8, /* %rbx */
95 24 + 3 * 8, /* %rcx */
96 24 + 2 * 8, /* %rdx */
97 24 + 1 * 8, /* %rsi */
98 24 + 0 * 8, /* %rdi */
99 24 + 8 * 8, /* %rbp */
dac94105 100 24 + 22 * 8, /* %rsp */
0963b4bd 101 24 + 4 * 8, /* %r8 ... */
af233647
MK
102 24 + 5 * 8,
103 24 + 9 * 8,
104 24 + 10 * 8,
105 24 + 11 * 8,
106 24 + 12 * 8,
107 24 + 13 * 8,
108 24 + 14 * 8, /* ... %r15 */
dac94105
MK
109 24 + 19 * 8, /* %rip */
110 24 + 21 * 8, /* %eflags */
af233647
MK
111 24 + 20 * 8, /* %cs */
112 24 + 23 * 8, /* %ss */
68cc0bfb
MK
113 -1, /* %ds */
114 -1, /* %es */
115 -1, /* %fs */
116 -1 /* %gs */
117};
118
1c02b2a5
MK
119/* From /usr/src/lib/libc/amd64/gen/_setjmp.S. */
120static int amd64fbsd_jmp_buf_reg_offset[] =
121{
122 -1, /* %rax */
123 1 * 8, /* %rbx */
124 -1, /* %rcx */
125 -1, /* %rdx */
126 -1, /* %rsi */
127 -1, /* %rdi */
128 3 * 8, /* %rbp */
129 2 * 8, /* %rsp */
0963b4bd 130 -1, /* %r8 ... */
1c02b2a5
MK
131 -1,
132 -1,
133 -1, /* ... %r11 */
0963b4bd 134 4 * 8, /* %r12 ... */
1c02b2a5
MK
135 5 * 8,
136 6 * 8,
137 7 * 8, /* ... %r15 */
138 0 * 8 /* %rip */
139};
140
141static void
142amd64fbsd_supply_uthread (struct regcache *regcache,
143 int regnum, CORE_ADDR addr)
144{
4252dc94 145 gdb_byte buf[8];
1c02b2a5
MK
146 int i;
147
148 gdb_assert (regnum >= -1);
149
150 for (i = 0; i < ARRAY_SIZE (amd64fbsd_jmp_buf_reg_offset); i++)
151 {
152 if (amd64fbsd_jmp_buf_reg_offset[i] != -1
153 && (regnum == -1 || regnum == i))
154 {
155 read_memory (addr + amd64fbsd_jmp_buf_reg_offset[i], buf, 8);
156 regcache_raw_supply (regcache, i, buf);
157 }
158 }
159}
160
161static void
162amd64fbsd_collect_uthread (const struct regcache *regcache,
163 int regnum, CORE_ADDR addr)
164{
4252dc94 165 gdb_byte buf[8];
1c02b2a5
MK
166 int i;
167
168 gdb_assert (regnum >= -1);
169
170 for (i = 0; i < ARRAY_SIZE (amd64fbsd_jmp_buf_reg_offset); i++)
171 {
172 if (amd64fbsd_jmp_buf_reg_offset[i] != -1
173 && (regnum == -1 || regnum == i))
174 {
175 regcache_raw_collect (regcache, i, buf);
176 write_memory (addr + amd64fbsd_jmp_buf_reg_offset[i], buf, 8);
177 }
178 }
179}
180
63807e1d 181static void
68cc0bfb
MK
182amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
183{
184 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
185
490496c3
AA
186 /* Generic FreeBSD support. */
187 fbsd_init_abi (info, gdbarch);
188
68cc0bfb
MK
189 /* Obviously FreeBSD is BSD-based. */
190 i386bsd_init_abi (info, gdbarch);
191
477f40d1
MK
192 tdep->gregset_reg_offset = amd64fbsd_r_reg_offset;
193 tdep->gregset_num_regs = ARRAY_SIZE (amd64fbsd_r_reg_offset);
194 tdep->sizeof_gregset = 22 * 8;
195
90f90721 196 amd64_init_abi (info, gdbarch);
68cc0bfb 197
10fc94a4
MK
198 tdep->sigtramp_start = amd64fbsd_sigtramp_start_addr;
199 tdep->sigtramp_end = amd64fbsd_sigtramp_end_addr;
68cc0bfb
MK
200 tdep->sigcontext_addr = amd64fbsd_sigcontext_addr;
201 tdep->sc_reg_offset = amd64fbsd_sc_reg_offset;
477f40d1 202 tdep->sc_num_regs = ARRAY_SIZE (amd64fbsd_sc_reg_offset);
7e654c37 203
1c02b2a5
MK
204 /* FreeBSD provides a user-level threads implementation. */
205 bsd_uthread_set_supply_uthread (gdbarch, amd64fbsd_supply_uthread);
206 bsd_uthread_set_collect_uthread (gdbarch, amd64fbsd_collect_uthread);
207
7e654c37
MK
208 /* FreeBSD uses SVR4-style shared libraries. */
209 set_solib_svr4_fetch_link_map_offsets
210 (gdbarch, svr4_lp64_fetch_link_map_offsets);
68cc0bfb
MK
211}
212\f
213
214/* Provide a prototype to silence -Wmissing-prototypes. */
215void _initialize_amd64fbsd_tdep (void);
216
217void
218_initialize_amd64fbsd_tdep (void)
219{
220 gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
221 GDB_OSABI_FREEBSD_ELF, amd64fbsd_init_abi);
222}
This page took 0.657225 seconds and 4 git commands to generate.