xref: /dflybsd-src/contrib/gdb-7/gdb/amd64dfly-tdep.c (revision ffd49a44576ac6919c30847a4587ded460b0c99d)
1 /* Target-dependent code for DragonFly/amd64.
2 
3    Copyright (C) 2003-2013 Free Software Foundation, Inc.
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
9    the Free Software Foundation; either version 3 of the License, or
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
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
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 
27 #include "gdb_assert.h"
28 #include "gdb_string.h"
29 
30 #include "amd64-tdep.h"
31 #include "solib-svr4.h"
32 
33 /* Support for signal handlers.  */
34 
35 /* Assuming THIS_FRAME is for a BSD sigtramp routine, return the
36    address of the associated sigcontext structure.  */
37 
38 static CORE_ADDR
39 amd64dfly_sigcontext_addr(struct frame_info *this_frame)
40 {
41 	struct gdbarch *gdbarch = get_frame_arch(this_frame);
42 	enum bfd_endian byte_order = gdbarch_byte_order(gdbarch);
43 	CORE_ADDR sp;
44 	gdb_byte buf[8];
45 
46 	/* The `struct sigcontext' (which really is an `ucontext_t' on
47 	 * DragonFly/amd64) lives at a fixed offset in the signal frame.  See
48 	 * <machine/sigframe.h>.  */
49 	get_frame_register(this_frame, AMD64_RSP_REGNUM, buf);
50 	sp = extract_unsigned_integer(buf, 8, byte_order);
51 	return sp + 16;
52 }
53 
54 
55 /* Mapping between the general-purpose registers in `struct reg'
56    format and GDB's register cache layout.
57 
58    Note that some registers are 32-bit, but since we're little-endian
59    we get away with that.  */
60 
61 /* From <machine/reg.h>.  */
62 static int amd64dfly_r_reg_offset[] =
63 {
64 	6 * 8,			/* %rax */
65 	7 * 8,			/* %rbx */
66 	3 * 8,			/* %rcx */
67 	2 * 8,			/* %rdx */
68 	1 * 8,			/* %rsi */
69 	0 * 8,			/* %rdi */
70 	8 * 8,			/* %rbp */
71 	23 * 8,			/* %rsp */
72 	4 * 8,			/* %r8 ... */
73 	5 * 8,
74 	9 * 8,
75 	10 * 8,
76 	11 * 8,
77 	12 * 8,
78 	13 * 8,
79 	14 * 8,			/* ... %r15 */
80 	20 * 8,			/* %rip */
81 	22 * 8,			/* %eflags */
82 	21 * 8,			/* %cs */
83 	24 * 8,			/* %ss */
84 	-1,			/* %ds */
85 	-1,			/* %es */
86 	-1,			/* %fs */
87 	-1			/* %gs */
88 };
89 
90 /* Location of the signal trampoline.  */
91 CORE_ADDR amd64dfly_sigtramp_start_addr = 0x7fffffffffc0ULL;
92 CORE_ADDR amd64dfly_sigtramp_end_addr = 0x7fffffffffe0ULL;
93 
94 /* From <machine/signal.h>.  */
95 int amd64dfly_sc_reg_offset[] =
96 {
97 	24 + 6 * 8,		/* %rax */
98 	24 + 7 * 8,		/* %rbx */
99 	24 + 3 * 8,		/* %rcx */
100 	24 + 2 * 8,		/* %rdx */
101 	24 + 1 * 8,		/* %rsi */
102 	24 + 0 * 8,		/* %rdi */
103 	24 + 8 * 8,		/* %rbp */
104 	24 + 23 * 8,		/* %rsp */
105 	24 + 4 * 8,		/* %r8 ... */
106 	24 + 5 * 8,
107 	24 + 9 * 8,
108 	24 + 10 * 8,
109 	24 + 11 * 8,
110 	24 + 12 * 8,
111 	24 + 13 * 8,
112 	24 + 14 * 8,		/* ... %r15 */
113 	24 + 20 * 8,		/* %rip */
114 	24 + 22 * 8,		/* %eflags */
115 	24 + 21 * 8,		/* %cs */
116 	24 + 24 * 8,		/* %ss */
117 	-1,			/* %ds */
118 	-1,			/* %es */
119 	-1,			/* %fs */
120 	-1			/* %gs */
121 };
122 
123 /* From /usr/src/lib/libc/amd64/gen/_setjmp.S.  */
124 static int amd64dfly_jmp_buf_reg_offset[] =
125 {
126 	-1,			/* %rax */
127 	1 * 8,			/* %rbx */
128 	-1,			/* %rcx */
129 	-1,			/* %rdx */
130 	-1,			/* %rsi */
131 	-1,			/* %rdi */
132 	3 * 8,			/* %rbp */
133 	2 * 8,			/* %rsp */
134 	-1,			/* %r8 ... */
135 	-1,
136 	-1,
137 	-1,			/* ... %r11 */
138 	4 * 8,			/* %r12 ... */
139 	5 * 8,
140 	6 * 8,
141 	7 * 8,			/* ... %r15 */
142 	0 * 8			/* %rip */
143 };
144 
145 static void
146 amd64dfly_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
147 {
148 	struct gdbarch_tdep *tdep = gdbarch_tdep(gdbarch);
149 
150 	i386bsd_init_abi(info, gdbarch);
151 
152 	tdep->gregset_reg_offset = amd64dfly_r_reg_offset;
153 	tdep->gregset_num_regs = ARRAY_SIZE(amd64dfly_r_reg_offset);
154 	tdep->sizeof_gregset = 25 * 8;
155 
156 	amd64_init_abi(info, gdbarch);
157 
158 	tdep->sigtramp_start = amd64dfly_sigtramp_start_addr;
159 	tdep->sigtramp_end = amd64dfly_sigtramp_end_addr;
160 	tdep->sigcontext_addr = amd64dfly_sigcontext_addr;
161 	tdep->sc_reg_offset = amd64dfly_sc_reg_offset;
162 	tdep->sc_num_regs = ARRAY_SIZE(amd64dfly_sc_reg_offset);
163 
164 	set_solib_svr4_fetch_link_map_offsets
165 	    (gdbarch, svr4_lp64_fetch_link_map_offsets);
166 }
167 
168 
169 
170 /* Provide a prototype to silence -Wmissing-prototypes.  */
171 void _initialize_amd64dfly_tdep(void);
172 
173 void
174 _initialize_amd64dfly_tdep(void)
175 {
176 	gdbarch_register_osabi(bfd_arch_i386, bfd_mach_x86_64,
177 	    GDB_OSABI_DRAGONFLY, amd64dfly_init_abi);
178 }
179