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