* infrun.c (handle_inferior_event): Check the current frame ID
[deliverable/binutils-gdb.git] / gdb / amd64-linux-tdep.c
CommitLineData
51433e4b 1/* Target-dependent code for GNU/Linux x86-64.
a4b6fc86 2
197e01b6 3 Copyright (C) 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
53e95fcf
JS
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
197e01b6
EZ
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
53e95fcf
JS
22
23#include "defs.h"
187e21d1 24#include "frame.h"
53e95fcf
JS
25#include "gdbcore.h"
26#include "regcache.h"
84dc46cb 27#include "osabi.h"
911bc6ee 28#include "symtab.h"
53e95fcf 29
c4f35dd8 30#include "gdb_string.h"
53e95fcf 31
9c1488cb 32#include "amd64-tdep.h"
187e21d1 33#include "solib-svr4.h"
eba29c8c
ML
34
35/* Mapping between the general-purpose registers in `struct user'
187e21d1 36 format and GDB's register cache layout. */
eba29c8c 37
187e21d1
MK
38/* From <sys/reg.h>. */
39static int amd64_linux_gregset_reg_offset[] =
eba29c8c 40{
187e21d1
MK
41 10 * 8, /* %rax */
42 5 * 8, /* %rbx */
43 11 * 8, /* %rcx */
44 12 * 8, /* %rdx */
45 13 * 8, /* %rsi */
46 14 * 8, /* %rdi */
47 4 * 8, /* %rbp */
48 19 * 8, /* %rsp */
49 9 * 8, /* %r8 ... */
50 8 * 8,
51 7 * 8,
52 6 * 8,
53 3 * 8,
54 2 * 8,
55 1 * 8,
56 0 * 8, /* ... %r15 */
57 16 * 8, /* %rip */
58 18 * 8, /* %eflags */
59 17 * 8, /* %cs */
60 20 * 8, /* %ss */
61 23 * 8, /* %ds */
62 24 * 8, /* %es */
63 25 * 8, /* %fs */
64 26 * 8 /* %gs */
eba29c8c 65};
187e21d1 66\f
eba29c8c 67
187e21d1 68/* Support for signal handlers. */
c4f35dd8
MK
69
70#define LINUX_SIGTRAMP_INSN0 0x48 /* mov $NNNNNNNN, %rax */
71#define LINUX_SIGTRAMP_OFFSET0 0
72#define LINUX_SIGTRAMP_INSN1 0x0f /* syscall */
73#define LINUX_SIGTRAMP_OFFSET1 7
74
4252dc94 75static const gdb_byte linux_sigtramp_code[] =
c4f35dd8
MK
76{
77 /* mov $__NR_rt_sigreturn, %rax */
baed091b
ML
78 LINUX_SIGTRAMP_INSN0, 0xc7, 0xc0, 0x0f, 0x00, 0x00, 0x00,
79 /* syscall */
80 LINUX_SIGTRAMP_INSN1, 0x05
53e95fcf
JS
81};
82
83#define LINUX_SIGTRAMP_LEN (sizeof linux_sigtramp_code)
84
85/* If PC is in a sigtramp routine, return the address of the start of
86 the routine. Otherwise, return 0. */
87
88static CORE_ADDR
387c058c 89amd64_linux_sigtramp_start (struct frame_info *next_frame)
53e95fcf 90{
387c058c 91 CORE_ADDR pc = frame_pc_unwind (next_frame);
4252dc94 92 gdb_byte buf[LINUX_SIGTRAMP_LEN];
c4f35dd8
MK
93
94 /* We only recognize a signal trampoline if PC is at the start of
95 one of the two instructions. We optimize for finding the PC at
96 the start, as will be the case when the trampoline is not the
97 first frame on the stack. We assume that in the case where the
98 PC is not at the start of the instruction sequence, there will be
99 a few trailing readable bytes on the stack. */
100
55e5a6d0 101 if (!safe_frame_unwind_memory (next_frame, pc, buf, sizeof buf))
53e95fcf
JS
102 return 0;
103
104 if (buf[0] != LINUX_SIGTRAMP_INSN0)
105 {
106 if (buf[0] != LINUX_SIGTRAMP_INSN1)
107 return 0;
108
109 pc -= LINUX_SIGTRAMP_OFFSET1;
55e5a6d0 110 if (!safe_frame_unwind_memory (next_frame, pc, buf, sizeof buf))
53e95fcf
JS
111 return 0;
112 }
113
114 if (memcmp (buf, linux_sigtramp_code, LINUX_SIGTRAMP_LEN) != 0)
115 return 0;
116
117 return pc;
118}
119
377d9ebd 120/* Return whether the frame preceding NEXT_FRAME corresponds to a
911bc6ee 121 GNU/Linux sigtramp routine. */
baed091b 122
c4f35dd8 123static int
911bc6ee 124amd64_linux_sigtramp_p (struct frame_info *next_frame)
baed091b 125{
911bc6ee
MK
126 CORE_ADDR pc = frame_pc_unwind (next_frame);
127 char *name;
128
129 find_pc_partial_function (pc, &name, NULL, NULL);
130
c4f35dd8
MK
131 /* If we have NAME, we can optimize the search. The trampoline is
132 named __restore_rt. However, it isn't dynamically exported from
133 the shared C library, so the trampoline may appear to be part of
134 the preceding function. This should always be sigaction,
135 __sigaction, or __libc_sigaction (all aliases to the same
136 function). */
137 if (name == NULL || strstr (name, "sigaction") != NULL)
387c058c 138 return (amd64_linux_sigtramp_start (next_frame) != 0);
c4f35dd8
MK
139
140 return (strcmp ("__restore_rt", name) == 0);
baed091b
ML
141}
142
c4f35dd8 143/* Offset to struct sigcontext in ucontext, from <asm/ucontext.h>. */
51433e4b 144#define AMD64_LINUX_UCONTEXT_SIGCONTEXT_OFFSET 40
b64bbf8c 145
c4f35dd8
MK
146/* Assuming NEXT_FRAME is a frame following a GNU/Linux sigtramp
147 routine, return the address of the associated sigcontext structure. */
baed091b 148
c4f35dd8 149static CORE_ADDR
51433e4b 150amd64_linux_sigcontext_addr (struct frame_info *next_frame)
baed091b 151{
c4f35dd8 152 CORE_ADDR sp;
4252dc94 153 gdb_byte buf[8];
c4f35dd8
MK
154
155 frame_unwind_register (next_frame, SP_REGNUM, buf);
156 sp = extract_unsigned_integer (buf, 8);
157
158 /* The sigcontext structure is part of the user context. A pointer
159 to the user context is passed as the third argument to the signal
160 handler, i.e. in %rdx. Unfortunately %rdx isn't preserved across
161 function calls so we can't use it. Fortunately the user context
162 is part of the signal frame and the unwound %rsp directly points
163 at it. */
51433e4b 164 return sp + AMD64_LINUX_UCONTEXT_SIGCONTEXT_OFFSET;
baed091b 165}
2213a65d
MK
166\f
167
2b5e0749 168/* From <asm/sigcontext.h>. */
51433e4b 169static int amd64_linux_sc_reg_offset[] =
2b5e0749
MK
170{
171 13 * 8, /* %rax */
172 11 * 8, /* %rbx */
173 14 * 8, /* %rcx */
174 12 * 8, /* %rdx */
175 9 * 8, /* %rsi */
176 8 * 8, /* %rdi */
177 10 * 8, /* %rbp */
178 15 * 8, /* %rsp */
179 0 * 8, /* %r8 */
180 1 * 8, /* %r9 */
181 2 * 8, /* %r10 */
182 3 * 8, /* %r11 */
183 4 * 8, /* %r12 */
184 5 * 8, /* %r13 */
185 6 * 8, /* %r14 */
186 7 * 8, /* %r15 */
187 16 * 8, /* %rip */
188 17 * 8, /* %eflags */
2b5e0749 189
af233647 190 /* FIXME: kettenis/2002030531: The registers %cs, %fs and %gs are
2b5e0749
MK
191 available in `struct sigcontext'. However, they only occupy two
192 bytes instead of four, which makes using them here rather
193 difficult. Leave them out for now. */
af233647
MK
194 -1, /* %cs */
195 -1, /* %ss */
196 -1, /* %ds */
197 -1, /* %es */
2b5e0749
MK
198 -1, /* %fs */
199 -1 /* %gs */
200};
201
2213a65d 202static void
51433e4b 203amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
2213a65d 204{
c4f35dd8 205 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
187e21d1
MK
206
207 tdep->gregset_reg_offset = amd64_linux_gregset_reg_offset;
208 tdep->gregset_num_regs = ARRAY_SIZE (amd64_linux_gregset_reg_offset);
209 tdep->sizeof_gregset = 27 * 8;
210
90f90721 211 amd64_init_abi (info, gdbarch);
c4f35dd8 212
911bc6ee 213 tdep->sigtramp_p = amd64_linux_sigtramp_p;
51433e4b
MK
214 tdep->sigcontext_addr = amd64_linux_sigcontext_addr;
215 tdep->sc_reg_offset = amd64_linux_sc_reg_offset;
216 tdep->sc_num_regs = ARRAY_SIZE (amd64_linux_sc_reg_offset);
187e21d1
MK
217
218 /* GNU/Linux uses SVR4-style shared libraries. */
219 set_solib_svr4_fetch_link_map_offsets
220 (gdbarch, svr4_lp64_fetch_link_map_offsets);
b2756930
KB
221
222 /* Enable TLS support. */
223 set_gdbarch_fetch_tls_load_module_address (gdbarch,
224 svr4_fetch_objfile_link_map);
2213a65d 225}
c4f35dd8 226\f
2213a65d
MK
227
228/* Provide a prototype to silence -Wmissing-prototypes. */
51433e4b 229extern void _initialize_amd64_linux_tdep (void);
2213a65d
MK
230
231void
51433e4b 232_initialize_amd64_linux_tdep (void)
2213a65d 233{
51433e4b
MK
234 gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
235 GDB_OSABI_LINUX, amd64_linux_init_abi);
2213a65d 236}
This page took 0.441642 seconds and 4 git commands to generate.