* x86-64-tdep.c (amd64_register_info): Add %cs and %ss. Adjust
[deliverable/binutils-gdb.git] / gdb / x86-64-linux-tdep.c
1 /* Target-dependent code for GNU/Linux running on x86-64, for GDB.
2
3 Copyright 2001, 2003, 2004 Free Software Foundation, Inc.
4 Contributed by Jiri Smid, SuSE Labs.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
22
23 #include "defs.h"
24 #include "inferior.h"
25 #include "gdbcore.h"
26 #include "regcache.h"
27 #include "osabi.h"
28
29 #include "gdb_string.h"
30
31 #include "x86-64-tdep.h"
32 #include "x86-64-linux-tdep.h"
33
34 /* Register indexes to 'struct user' come from <sys/reg.h>. */
35
36 #define USER_R15 0
37 #define USER_R14 1
38 #define USER_R13 2
39 #define USER_R12 3
40 #define USER_RBP 4
41 #define USER_RBX 5
42 #define USER_R11 6
43 #define USER_R10 7
44 #define USER_R9 8
45 #define USER_R8 9
46 #define USER_RAX 10
47 #define USER_RCX 11
48 #define USER_RDX 12
49 #define USER_RSI 13
50 #define USER_RDI 14
51 #define USER_RIP 16
52 #define USER_CS 17
53 #define USER_EFLAGS 18
54 #define USER_RSP 19
55 #define USER_SS 20
56 #define USER_DS 23
57 #define USER_ES 24
58 #define USER_FS 25
59 #define USER_GS 26
60
61 /* Mapping between the general-purpose registers in `struct user'
62 format and GDB's register array layout. */
63
64 static int user_to_gdb_regmap[] =
65 {
66 USER_RAX, USER_RBX, USER_RCX, USER_RDX,
67 USER_RSI, USER_RDI, USER_RBP, USER_RSP,
68 USER_R8, USER_R9, USER_R10, USER_R11,
69 USER_R12, USER_R13, USER_R14, USER_R15,
70 USER_RIP, USER_EFLAGS,
71 USER_CS, USER_SS,
72 USER_DS, USER_ES, USER_FS, USER_GS
73 };
74
75 /* Fill GDB's register array with the general-purpose register values
76 in *GREGSETP. */
77
78 void
79 x86_64_linux_supply_gregset (char *regp)
80 {
81 int i;
82
83 for (i = 0; i < X86_64_NUM_GREGS; i++)
84 supply_register (i, regp + (user_to_gdb_regmap[i] * 8));
85 }
86
87 /* Fill register REGNO (if it is a general-purpose register) in
88 *GREGSETPS with the value in GDB's register array. If REGNO is -1,
89 do this for all registers. */
90
91 void
92 x86_64_linux_fill_gregset (char *regp, int regno)
93 {
94 int i;
95
96 for (i = 0; i < X86_64_NUM_GREGS; i++)
97 if (regno == -1 || regno == i)
98 regcache_collect (i, regp + (user_to_gdb_regmap[i] * 8));
99 }
100
101 /* The register sets used in GNU/Linux ELF core-dumps are identical to
102 the register sets used by `ptrace'. The corresponding types are
103 `elf_gregset_t' for the general-purpose registers (with
104 `elf_greg_t' the type of a single GP register) and `elf_fpregset_t'
105 for the floating-point registers. */
106
107 static void
108 fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
109 int which, CORE_ADDR ignore)
110 {
111 switch (which)
112 {
113 case 0: /* Integer registers. */
114 if (core_reg_size != 216)
115 warning ("Wrong size register set in core file.");
116 else
117 x86_64_linux_supply_gregset (core_reg_sect);
118 break;
119
120 case 2: /* Floating point registers. */
121 case 3: /* "Extended" floating point registers. This is gdb-speak
122 for SSE/SSE2. */
123 if (core_reg_size != 512)
124 warning ("Wrong size XMM register set in core file.");
125 else
126 x86_64_supply_fxsave (current_regcache, -1, core_reg_sect);
127 break;
128
129 default:
130 /* Don't know what kind of register request this is; just ignore it. */
131 break;
132 }
133 }
134
135 static struct core_fns x86_64_core_fns =
136 {
137 bfd_target_elf_flavour, /* core_flavour */
138 default_check_format, /* check_format */
139 default_core_sniffer, /* core_sniffer */
140 fetch_core_registers, /* core_read_registers */
141 NULL /* next */
142 };
143
144 #define LINUX_SIGTRAMP_INSN0 0x48 /* mov $NNNNNNNN, %rax */
145 #define LINUX_SIGTRAMP_OFFSET0 0
146 #define LINUX_SIGTRAMP_INSN1 0x0f /* syscall */
147 #define LINUX_SIGTRAMP_OFFSET1 7
148
149 static const unsigned char linux_sigtramp_code[] =
150 {
151 /* mov $__NR_rt_sigreturn, %rax */
152 LINUX_SIGTRAMP_INSN0, 0xc7, 0xc0, 0x0f, 0x00, 0x00, 0x00,
153 /* syscall */
154 LINUX_SIGTRAMP_INSN1, 0x05
155 };
156
157 #define LINUX_SIGTRAMP_LEN (sizeof linux_sigtramp_code)
158
159 /* If PC is in a sigtramp routine, return the address of the start of
160 the routine. Otherwise, return 0. */
161
162 static CORE_ADDR
163 x86_64_linux_sigtramp_start (CORE_ADDR pc)
164 {
165 unsigned char buf[LINUX_SIGTRAMP_LEN];
166
167 /* We only recognize a signal trampoline if PC is at the start of
168 one of the two instructions. We optimize for finding the PC at
169 the start, as will be the case when the trampoline is not the
170 first frame on the stack. We assume that in the case where the
171 PC is not at the start of the instruction sequence, there will be
172 a few trailing readable bytes on the stack. */
173
174 if (read_memory_nobpt (pc, (char *) buf, LINUX_SIGTRAMP_LEN) != 0)
175 return 0;
176
177 if (buf[0] != LINUX_SIGTRAMP_INSN0)
178 {
179 if (buf[0] != LINUX_SIGTRAMP_INSN1)
180 return 0;
181
182 pc -= LINUX_SIGTRAMP_OFFSET1;
183
184 if (read_memory_nobpt (pc, (char *) buf, LINUX_SIGTRAMP_LEN) != 0)
185 return 0;
186 }
187
188 if (memcmp (buf, linux_sigtramp_code, LINUX_SIGTRAMP_LEN) != 0)
189 return 0;
190
191 return pc;
192 }
193
194 /* Return whether PC is in a GNU/Linux sigtramp routine. */
195
196 static int
197 x86_64_linux_pc_in_sigtramp (CORE_ADDR pc, char *name)
198 {
199 /* If we have NAME, we can optimize the search. The trampoline is
200 named __restore_rt. However, it isn't dynamically exported from
201 the shared C library, so the trampoline may appear to be part of
202 the preceding function. This should always be sigaction,
203 __sigaction, or __libc_sigaction (all aliases to the same
204 function). */
205 if (name == NULL || strstr (name, "sigaction") != NULL)
206 return (x86_64_linux_sigtramp_start (pc) != 0);
207
208 return (strcmp ("__restore_rt", name) == 0);
209 }
210
211 /* Offset to struct sigcontext in ucontext, from <asm/ucontext.h>. */
212 #define X86_64_LINUX_UCONTEXT_SIGCONTEXT_OFFSET 40
213
214 /* Assuming NEXT_FRAME is a frame following a GNU/Linux sigtramp
215 routine, return the address of the associated sigcontext structure. */
216
217 static CORE_ADDR
218 x86_64_linux_sigcontext_addr (struct frame_info *next_frame)
219 {
220 CORE_ADDR sp;
221 char buf[8];
222
223 frame_unwind_register (next_frame, SP_REGNUM, buf);
224 sp = extract_unsigned_integer (buf, 8);
225
226 /* The sigcontext structure is part of the user context. A pointer
227 to the user context is passed as the third argument to the signal
228 handler, i.e. in %rdx. Unfortunately %rdx isn't preserved across
229 function calls so we can't use it. Fortunately the user context
230 is part of the signal frame and the unwound %rsp directly points
231 at it. */
232 return sp + X86_64_LINUX_UCONTEXT_SIGCONTEXT_OFFSET;
233 }
234 \f
235
236 /* From <asm/sigcontext.h>. */
237 static int x86_64_linux_sc_reg_offset[] =
238 {
239 13 * 8, /* %rax */
240 11 * 8, /* %rbx */
241 14 * 8, /* %rcx */
242 12 * 8, /* %rdx */
243 9 * 8, /* %rsi */
244 8 * 8, /* %rdi */
245 10 * 8, /* %rbp */
246 15 * 8, /* %rsp */
247 0 * 8, /* %r8 */
248 1 * 8, /* %r9 */
249 2 * 8, /* %r10 */
250 3 * 8, /* %r11 */
251 4 * 8, /* %r12 */
252 5 * 8, /* %r13 */
253 6 * 8, /* %r14 */
254 7 * 8, /* %r15 */
255 16 * 8, /* %rip */
256 17 * 8, /* %eflags */
257
258 /* FIXME: kettenis/2002030531: The registers %cs, %fs and %gs are
259 available in `struct sigcontext'. However, they only occupy two
260 bytes instead of four, which makes using them here rather
261 difficult. Leave them out for now. */
262 -1, /* %cs */
263 -1, /* %ss */
264 -1, /* %ds */
265 -1, /* %es */
266 -1, /* %fs */
267 -1 /* %gs */
268 };
269
270 static void
271 x86_64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
272 {
273 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
274 x86_64_init_abi (info, gdbarch);
275
276 set_gdbarch_pc_in_sigtramp (gdbarch, x86_64_linux_pc_in_sigtramp);
277
278 tdep->sigcontext_addr = x86_64_linux_sigcontext_addr;
279 tdep->sc_reg_offset = x86_64_linux_sc_reg_offset;
280 tdep->sc_num_regs = ARRAY_SIZE (x86_64_linux_sc_reg_offset);
281 }
282 \f
283
284 /* Provide a prototype to silence -Wmissing-prototypes. */
285 extern void _initialize_x86_64_linux_tdep (void);
286
287 void
288 _initialize_x86_64_linux_tdep (void)
289 {
290 add_core_fns (&x86_64_core_fns);
291
292 gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, GDB_OSABI_LINUX,
293 x86_64_linux_init_abi);
294 }
This page took 0.035904 seconds and 4 git commands to generate.