PR symtab/2161
[deliverable/binutils-gdb.git] / gdb / sparc-linux-tdep.c
CommitLineData
386c036b
MK
1/* Target-dependent code for GNU/Linux SPARC.
2
6aba47ca 3 Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
386c036b
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
9 the Free Software Foundation; either version 2 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, write to the Free Software
197e01b6
EZ
19 Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
386c036b
MK
21
22#include "defs.h"
faea95b1 23#include "dwarf2-frame.h"
386c036b
MK
24#include "frame.h"
25#include "frame-unwind.h"
e6bb342a 26#include "gdbtypes.h"
07c5f590 27#include "regset.h"
386c036b
MK
28#include "gdbarch.h"
29#include "gdbcore.h"
30#include "osabi.h"
31#include "regcache.h"
32#include "solib-svr4.h"
33#include "symtab.h"
34#include "trad-frame.h"
70f1dc74 35#include "tramp-frame.h"
386c036b 36
386c036b
MK
37#include "sparc-tdep.h"
38
81f726ab 39/* Signal trampoline support. */
386c036b 40
70f1dc74
MK
41static void sparc32_linux_sigframe_init (const struct tramp_frame *self,
42 struct frame_info *next_frame,
43 struct trad_frame_cache *this_cache,
44 CORE_ADDR func);
45
386c036b
MK
46/* GNU/Linux has two flavors of signals. Normal signal handlers, and
47 "realtime" (RT) signals. The RT signals can provide additional
48 information to the signal handler if the SA_SIGINFO flag is set
49 when establishing a signal handler using `sigaction'. It is not
50 unlikely that future versions of GNU/Linux will support SA_SIGINFO
51 for normal signals too. */
52
53/* When the sparc Linux kernel calls a signal handler and the
54 SA_RESTORER flag isn't set, the return address points to a bit of
70f1dc74
MK
55 code on the stack. This code checks whether the PC appears to be
56 within this bit of code.
386c036b 57
70f1dc74 58 The instruction sequence for normal signals is encoded below.
386c036b
MK
59 Checking for the code sequence should be somewhat reliable, because
60 the effect is to call the system call sigreturn. This is unlikely
70f1dc74 61 to occur anywhere other than a signal trampoline. */
386c036b 62
70f1dc74
MK
63static const struct tramp_frame sparc32_linux_sigframe =
64{
81f726ab
DM
65 SIGTRAMP_FRAME,
66 4,
67 {
70f1dc74
MK
68 { 0x821020d8, -1 }, /* mov __NR_sugreturn, %g1 */
69 { 0x91d02010, -1 }, /* ta 0x10 */
81f726ab
DM
70 { TRAMP_SENTINEL_INSN, -1 }
71 },
72 sparc32_linux_sigframe_init
73};
386c036b 74
70f1dc74
MK
75/* The instruction sequence for RT signals is slightly different. The
76 effect is to call the system call rt_sigreturn. */
77
78static const struct tramp_frame sparc32_linux_rt_sigframe =
79{
81f726ab
DM
80 SIGTRAMP_FRAME,
81 4,
82 {
70f1dc74
MK
83 { 0x82102065, -1 }, /* mov __NR_rt_sigreturn, %g1 */
84 { 0x91d02010, -1 }, /* ta 0x10 */
81f726ab
DM
85 { TRAMP_SENTINEL_INSN, -1 }
86 },
87 sparc32_linux_sigframe_init
88};
386c036b 89
81f726ab
DM
90static void
91sparc32_linux_sigframe_init (const struct tramp_frame *self,
92 struct frame_info *next_frame,
93 struct trad_frame_cache *this_cache,
94 CORE_ADDR func)
386c036b 95{
80f9e3aa 96 CORE_ADDR base, addr, sp_addr;
386c036b
MK
97 int regnum;
98
81f726ab
DM
99 base = frame_unwind_register_unsigned (next_frame, SPARC_O1_REGNUM);
100 if (self == &sparc32_linux_rt_sigframe)
101 base += 128;
386c036b 102
70f1dc74 103 /* Offsets from <bits/sigcontext.h>. */
78a0fd57 104
70f1dc74
MK
105 trad_frame_set_reg_addr (this_cache, SPARC32_PSR_REGNUM, base + 0);
106 trad_frame_set_reg_addr (this_cache, SPARC32_PC_REGNUM, base + 4);
107 trad_frame_set_reg_addr (this_cache, SPARC32_NPC_REGNUM, base + 8);
108 trad_frame_set_reg_addr (this_cache, SPARC32_Y_REGNUM, base + 12);
386c036b
MK
109
110 /* Since %g0 is always zero, keep the identity encoding. */
70f1dc74 111 addr = base + 20;
80f9e3aa 112 sp_addr = base + 16 + ((SPARC_SP_REGNUM - SPARC_G0_REGNUM) * 4);
81f726ab
DM
113 for (regnum = SPARC_G1_REGNUM; regnum <= SPARC_O7_REGNUM; regnum++)
114 {
115 trad_frame_set_reg_addr (this_cache, regnum, addr);
116 addr += 4;
117 }
386c036b 118
80f9e3aa
DM
119 base = frame_unwind_register_unsigned (next_frame, SPARC_SP_REGNUM);
120 addr = get_frame_memory_unsigned (next_frame, sp_addr, 4);
121
81f726ab
DM
122 for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++)
123 {
124 trad_frame_set_reg_addr (this_cache, regnum, addr);
125 addr += 4;
126 }
127 trad_frame_set_id (this_cache, frame_id_build (base, func));
386c036b 128}
386c036b 129\f
0b4294d3
DM
130/* Return the address of a system call's alternative return
131 address. */
132
133static CORE_ADDR
0b1b3e42 134sparc32_linux_step_trap (struct frame_info *frame, unsigned long insn)
0b4294d3
DM
135{
136 if (insn == 0x91d02010)
137 {
0b1b3e42 138 ULONGEST sc_num = get_frame_register_unsigned (frame, SPARC_G1_REGNUM);
0b4294d3
DM
139
140 /* __NR_rt_sigreturn is 101 and __NR_sigreturn is 216 */
141 if (sc_num == 101 || sc_num == 216)
142 {
143 ULONGEST sp, pc_offset;
144
0b1b3e42 145 sp = get_frame_register_unsigned (frame, SPARC_SP_REGNUM);
0b4294d3
DM
146
147 /* The kernel puts the sigreturn registers on the stack,
148 and this is where the signal unwinding state is take from
149 when returning from a signal.
150
151 For __NR_sigreturn, this register area sits 96 bytes from
152 the base of the stack. The saved PC sits 4 bytes into the
153 sigreturn register save area.
154
155 For __NR_rt_sigreturn a siginfo_t, which is 128 bytes, sits
156 right before the sigreturn register save area. */
157
158 pc_offset = 96 + 4;
159 if (sc_num == 101)
160 pc_offset += 128;
161
162 return read_memory_unsigned_integer (sp + pc_offset, 4);
163 }
164 }
165
166 return 0;
167}
168\f
386c036b 169
07c5f590
DM
170const struct sparc_gregset sparc32_linux_core_gregset =
171{
172 32 * 4, /* %psr */
173 33 * 4, /* %pc */
174 34 * 4, /* %npc */
175 35 * 4, /* %y */
176 -1, /* %wim */
177 -1, /* %tbr */
178 1 * 4, /* %g1 */
179 16 * 4, /* %l0 */
180 4, /* y size */
181};
182\f
183
184static void
185sparc32_linux_supply_core_gregset (const struct regset *regset,
186 struct regcache *regcache,
187 int regnum, const void *gregs, size_t len)
188{
189 sparc32_supply_gregset (&sparc32_linux_core_gregset, regcache, regnum, gregs);
190}
191
192static void
193sparc32_linux_collect_core_gregset (const struct regset *regset,
194 const struct regcache *regcache,
195 int regnum, void *gregs, size_t len)
196{
197 sparc32_collect_gregset (&sparc32_linux_core_gregset, regcache, regnum, gregs);
198}
199
200static void
201sparc32_linux_supply_core_fpregset (const struct regset *regset,
202 struct regcache *regcache,
203 int regnum, const void *fpregs, size_t len)
204{
205 sparc32_supply_fpregset (regcache, regnum, fpregs);
206}
207
208static void
209sparc32_linux_collect_core_fpregset (const struct regset *regset,
210 const struct regcache *regcache,
211 int regnum, void *fpregs, size_t len)
212{
213 sparc32_collect_fpregset (regcache, regnum, fpregs);
214}
215
216\f
217
386c036b
MK
218static void
219sparc32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
220{
a33e488c
MK
221 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
222
07c5f590
DM
223 tdep->gregset = regset_alloc (gdbarch, sparc32_linux_supply_core_gregset,
224 sparc32_linux_collect_core_gregset);
225 tdep->sizeof_gregset = 152;
226
227 tdep->fpregset = regset_alloc (gdbarch, sparc32_linux_supply_core_fpregset,
228 sparc32_linux_collect_core_fpregset);
229 tdep->sizeof_fpregset = 396;
230
81f726ab
DM
231 tramp_frame_prepend_unwinder (gdbarch, &sparc32_linux_sigframe);
232 tramp_frame_prepend_unwinder (gdbarch, &sparc32_linux_rt_sigframe);
233
a33e488c
MK
234 /* GNU/Linux has SVR4-style shared libraries... */
235 set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
236 set_solib_svr4_fetch_link_map_offsets
237 (gdbarch, svr4_ilp32_fetch_link_map_offsets);
386c036b 238
a33e488c
MK
239 /* ...which means that we need some special handling when doing
240 prologue analysis. */
241 tdep->plt_entry_size = 12;
386c036b
MK
242
243 /* GNU/Linux doesn't support the 128-bit `long double' from the psABI. */
244 set_gdbarch_long_double_bit (gdbarch, 64);
8da61cc4 245 set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
386c036b 246
b2756930
KB
247 /* Enable TLS support. */
248 set_gdbarch_fetch_tls_load_module_address (gdbarch,
249 svr4_fetch_objfile_link_map);
faea95b1 250
0b4294d3
DM
251 /* Make sure we can single-step over signal return system calls. */
252 tdep->step_trap = sparc32_linux_step_trap;
253
faea95b1
DM
254 /* Hook in the DWARF CFI frame unwinder. */
255 frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
386c036b
MK
256}
257
258/* Provide a prototype to silence -Wmissing-prototypes. */
259extern void _initialize_sparc_linux_tdep (void);
260
261void
262_initialize_sparc_linux_tdep (void)
263{
264 gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_LINUX,
265 sparc32_linux_init_abi);
266}
This page took 0.32374 seconds and 4 git commands to generate.