1b725ae77Skettenis /* Target-dependent code for GNU/Linux SPARC.
2b725ae77Skettenis
3*11efff7fSkettenis Copyright 2003, 2004 Free Software Foundation, Inc.
4b725ae77Skettenis
5b725ae77Skettenis This file is part of GDB.
6b725ae77Skettenis
7b725ae77Skettenis This program is free software; you can redistribute it and/or modify
8b725ae77Skettenis it under the terms of the GNU General Public License as published by
9b725ae77Skettenis the Free Software Foundation; either version 2 of the License, or
10b725ae77Skettenis (at your option) any later version.
11b725ae77Skettenis
12b725ae77Skettenis This program is distributed in the hope that it will be useful,
13b725ae77Skettenis but WITHOUT ANY WARRANTY; without even the implied warranty of
14b725ae77Skettenis MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15b725ae77Skettenis GNU General Public License for more details.
16b725ae77Skettenis
17b725ae77Skettenis You should have received a copy of the GNU General Public License
18b725ae77Skettenis along with this program; if not, write to the Free Software
19b725ae77Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
20b725ae77Skettenis Boston, MA 02111-1307, USA. */
21b725ae77Skettenis
22b725ae77Skettenis #include "defs.h"
23b725ae77Skettenis #include "floatformat.h"
24b725ae77Skettenis #include "frame.h"
25b725ae77Skettenis #include "frame-unwind.h"
26b725ae77Skettenis #include "gdbarch.h"
27b725ae77Skettenis #include "gdbcore.h"
28b725ae77Skettenis #include "osabi.h"
29b725ae77Skettenis #include "regcache.h"
30b725ae77Skettenis #include "solib-svr4.h"
31b725ae77Skettenis #include "symtab.h"
32b725ae77Skettenis #include "trad-frame.h"
33b725ae77Skettenis
34b725ae77Skettenis #include "gdb_assert.h"
35b725ae77Skettenis #include "gdb_string.h"
36b725ae77Skettenis
37b725ae77Skettenis #include "sparc-tdep.h"
38b725ae77Skettenis
39b725ae77Skettenis /* Recognizing signal handler frames. */
40b725ae77Skettenis
41b725ae77Skettenis /* GNU/Linux has two flavors of signals. Normal signal handlers, and
42b725ae77Skettenis "realtime" (RT) signals. The RT signals can provide additional
43b725ae77Skettenis information to the signal handler if the SA_SIGINFO flag is set
44b725ae77Skettenis when establishing a signal handler using `sigaction'. It is not
45b725ae77Skettenis unlikely that future versions of GNU/Linux will support SA_SIGINFO
46b725ae77Skettenis for normal signals too. */
47b725ae77Skettenis
48b725ae77Skettenis /* When the sparc Linux kernel calls a signal handler and the
49b725ae77Skettenis SA_RESTORER flag isn't set, the return address points to a bit of
50b725ae77Skettenis code on the stack. This function returns whether the PC appears to
51b725ae77Skettenis be within this bit of code.
52b725ae77Skettenis
53b725ae77Skettenis The instruction sequence for normal signals is
54b725ae77Skettenis mov __NR_sigreturn, %g1 ! hex: 0x821020d8
55b725ae77Skettenis ta 0x10 ! hex: 0x91d02010
56b725ae77Skettenis
57b725ae77Skettenis Checking for the code sequence should be somewhat reliable, because
58b725ae77Skettenis the effect is to call the system call sigreturn. This is unlikely
59b725ae77Skettenis to occur anywhere other than a signal trampoline.
60b725ae77Skettenis
61b725ae77Skettenis It kind of sucks that we have to read memory from the process in
62b725ae77Skettenis order to identify a signal trampoline, but there doesn't seem to be
63b725ae77Skettenis any other way. However, sparc32_linux_pc_in_sigtramp arranges to
64b725ae77Skettenis only call us if no function name could be identified, which should
65b725ae77Skettenis be the case since the code is on the stack. */
66b725ae77Skettenis
67b725ae77Skettenis #define LINUX32_SIGTRAMP_INSN0 0x821020d8 /* mov __NR_sigreturn, %g1 */
68b725ae77Skettenis #define LINUX32_SIGTRAMP_INSN1 0x91d02010 /* ta 0x10 */
69b725ae77Skettenis
70b725ae77Skettenis /* The instruction sequence for RT signals is
71b725ae77Skettenis mov __NR_rt_sigreturn, %g1 ! hex: 0x82102065
72b725ae77Skettenis ta {0x10,0x6d} ! hex: 0x91d02010 or 0x91d0206d
73b725ae77Skettenis
74b725ae77Skettenis The effect is to call the system call rt_sigreturn. The trap number
75b725ae77Skettenis is variable based upon whether this is a 32-bit or 64-bit sparc binary.
76b725ae77Skettenis Note that 64-bit binaries only use this RT signal return method. */
77b725ae77Skettenis
78b725ae77Skettenis #define LINUX32_RT_SIGTRAMP_INSN0 0x82102065
79b725ae77Skettenis #define LINUX32_RT_SIGTRAMP_INSN1 0x91d02010
80b725ae77Skettenis
81b725ae77Skettenis /* If PC is in a sigtramp routine consisting of the instructions INSN0
82b725ae77Skettenis and INSN1, return the address of the start of the routine.
83b725ae77Skettenis Otherwise, return 0. */
84b725ae77Skettenis
85b725ae77Skettenis CORE_ADDR
sparc_linux_sigtramp_start(struct frame_info * next_frame,ULONGEST insn0,ULONGEST insn1)86*11efff7fSkettenis sparc_linux_sigtramp_start (struct frame_info *next_frame,
87*11efff7fSkettenis ULONGEST insn0, ULONGEST insn1)
88b725ae77Skettenis {
89*11efff7fSkettenis CORE_ADDR pc = frame_pc_unwind (next_frame);
90b725ae77Skettenis ULONGEST word0, word1;
91*11efff7fSkettenis unsigned char buf[8]; /* Two instructions. */
92b725ae77Skettenis
93b725ae77Skettenis /* We only recognize a signal trampoline if PC is at the start of
94b725ae77Skettenis one of the instructions. We optimize for finding the PC at the
95b725ae77Skettenis start of the instruction sequence, as will be the case when the
96b725ae77Skettenis trampoline is not the first frame on the stack. We assume that
97b725ae77Skettenis in the case where the PC is not at the start of the instruction
98b725ae77Skettenis sequence, there will be a few trailing readable bytes on the
99b725ae77Skettenis stack. */
100b725ae77Skettenis
101*11efff7fSkettenis if (!safe_frame_unwind_memory (next_frame, pc, buf, sizeof buf))
102b725ae77Skettenis return 0;
103b725ae77Skettenis
104b725ae77Skettenis word0 = extract_unsigned_integer (buf, 4);
105b725ae77Skettenis if (word0 != insn0)
106b725ae77Skettenis {
107b725ae77Skettenis if (word0 != insn1)
108b725ae77Skettenis return 0;
109b725ae77Skettenis
110b725ae77Skettenis pc -= 4;
111*11efff7fSkettenis if (!safe_frame_unwind_memory (next_frame, pc, buf, sizeof buf))
112b725ae77Skettenis return 0;
113b725ae77Skettenis
114b725ae77Skettenis word0 = extract_unsigned_integer (buf, 4);
115b725ae77Skettenis }
116b725ae77Skettenis
117b725ae77Skettenis word1 = extract_unsigned_integer (buf + 4, 4);
118b725ae77Skettenis if (word0 != insn0 || word1 != insn1)
119b725ae77Skettenis return 0;
120b725ae77Skettenis
121b725ae77Skettenis return pc;
122b725ae77Skettenis }
123b725ae77Skettenis
124b725ae77Skettenis static CORE_ADDR
sparc32_linux_sigtramp_start(struct frame_info * next_frame)125*11efff7fSkettenis sparc32_linux_sigtramp_start (struct frame_info *next_frame)
126b725ae77Skettenis {
127*11efff7fSkettenis return sparc_linux_sigtramp_start (next_frame, LINUX32_SIGTRAMP_INSN0,
128b725ae77Skettenis LINUX32_SIGTRAMP_INSN1);
129b725ae77Skettenis }
130b725ae77Skettenis
131b725ae77Skettenis static CORE_ADDR
sparc32_linux_rt_sigtramp_start(struct frame_info * next_frame)132*11efff7fSkettenis sparc32_linux_rt_sigtramp_start (struct frame_info *next_frame)
133b725ae77Skettenis {
134*11efff7fSkettenis return sparc_linux_sigtramp_start (next_frame, LINUX32_RT_SIGTRAMP_INSN0,
135b725ae77Skettenis LINUX32_RT_SIGTRAMP_INSN1);
136b725ae77Skettenis }
137b725ae77Skettenis
138b725ae77Skettenis static int
sparc32_linux_sigtramp_p(struct frame_info * next_frame)139*11efff7fSkettenis sparc32_linux_sigtramp_p (struct frame_info *next_frame)
140b725ae77Skettenis {
141*11efff7fSkettenis CORE_ADDR pc = frame_pc_unwind (next_frame);
142*11efff7fSkettenis char *name;
143*11efff7fSkettenis
144*11efff7fSkettenis find_pc_partial_function (pc, &name, NULL, NULL);
145*11efff7fSkettenis
146b725ae77Skettenis /* If we have NAME, we can optimize the search. The trampolines are
147b725ae77Skettenis named __restore and __restore_rt. However, they aren't dynamically
148b725ae77Skettenis exported from the shared C library, so the trampoline may appear to
149b725ae77Skettenis be part of the preceding function. This should always be sigaction,
150b725ae77Skettenis __sigaction, or __libc_sigaction (all aliases to the same function). */
151b725ae77Skettenis if (name == NULL || strstr (name, "sigaction") != NULL)
152*11efff7fSkettenis return (sparc32_linux_sigtramp_start (next_frame) != 0
153*11efff7fSkettenis || sparc32_linux_rt_sigtramp_start (next_frame) != 0);
154b725ae77Skettenis
155b725ae77Skettenis return (strcmp ("__restore", name) == 0
156b725ae77Skettenis || strcmp ("__restore_rt", name) == 0);
157b725ae77Skettenis }
158b725ae77Skettenis
159b725ae77Skettenis static struct sparc_frame_cache *
sparc32_linux_sigtramp_frame_cache(struct frame_info * next_frame,void ** this_cache)160b725ae77Skettenis sparc32_linux_sigtramp_frame_cache (struct frame_info *next_frame,
161b725ae77Skettenis void **this_cache)
162b725ae77Skettenis {
163b725ae77Skettenis struct sparc_frame_cache *cache;
164b725ae77Skettenis CORE_ADDR sigcontext_addr, addr;
165b725ae77Skettenis int regnum;
166b725ae77Skettenis
167b725ae77Skettenis if (*this_cache)
168b725ae77Skettenis return *this_cache;
169b725ae77Skettenis
170b725ae77Skettenis cache = sparc32_frame_cache (next_frame, this_cache);
171b725ae77Skettenis gdb_assert (cache == *this_cache);
172b725ae77Skettenis
173b725ae77Skettenis /* ??? What about signal trampolines that aren't frameless? */
174b725ae77Skettenis regnum = SPARC_SP_REGNUM;
175b725ae77Skettenis cache->base = frame_unwind_register_unsigned (next_frame, regnum);
176b725ae77Skettenis
177b725ae77Skettenis regnum = SPARC_O1_REGNUM;
178b725ae77Skettenis sigcontext_addr = frame_unwind_register_unsigned (next_frame, regnum);
179b725ae77Skettenis
180*11efff7fSkettenis addr = sparc32_linux_sigtramp_start (next_frame);
181b725ae77Skettenis if (addr == 0)
182b725ae77Skettenis {
183b725ae77Skettenis /* If this is a RT signal trampoline, adjust SIGCONTEXT_ADDR
184b725ae77Skettenis accordingly. */
185*11efff7fSkettenis addr = sparc32_linux_rt_sigtramp_start (next_frame);
186b725ae77Skettenis if (addr)
187b725ae77Skettenis sigcontext_addr += 128;
188b725ae77Skettenis else
189b725ae77Skettenis addr = frame_func_unwind (next_frame);
190b725ae77Skettenis }
191b725ae77Skettenis cache->pc = addr;
192b725ae77Skettenis
193b725ae77Skettenis cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
194b725ae77Skettenis
195b725ae77Skettenis cache->saved_regs[SPARC32_PSR_REGNUM].addr = sigcontext_addr + 0;
196b725ae77Skettenis cache->saved_regs[SPARC32_PC_REGNUM].addr = sigcontext_addr + 4;
197b725ae77Skettenis cache->saved_regs[SPARC32_NPC_REGNUM].addr = sigcontext_addr + 8;
198b725ae77Skettenis cache->saved_regs[SPARC32_Y_REGNUM].addr = sigcontext_addr + 12;
199b725ae77Skettenis
200b725ae77Skettenis /* Since %g0 is always zero, keep the identity encoding. */
201b725ae77Skettenis for (regnum = SPARC_G1_REGNUM, addr = sigcontext_addr + 20;
202b725ae77Skettenis regnum <= SPARC_O7_REGNUM; regnum++, addr += 4)
203b725ae77Skettenis cache->saved_regs[regnum].addr = addr;
204b725ae77Skettenis
205b725ae77Skettenis for (regnum = SPARC_L0_REGNUM, addr = cache->base;
206b725ae77Skettenis regnum <= SPARC_I7_REGNUM; regnum++, addr += 4)
207b725ae77Skettenis cache->saved_regs[regnum].addr = addr;
208b725ae77Skettenis
209b725ae77Skettenis return cache;
210b725ae77Skettenis }
211b725ae77Skettenis
212b725ae77Skettenis static void
sparc32_linux_sigtramp_frame_this_id(struct frame_info * next_frame,void ** this_cache,struct frame_id * this_id)213b725ae77Skettenis sparc32_linux_sigtramp_frame_this_id (struct frame_info *next_frame,
214b725ae77Skettenis void **this_cache,
215b725ae77Skettenis struct frame_id *this_id)
216b725ae77Skettenis {
217b725ae77Skettenis struct sparc_frame_cache *cache =
218b725ae77Skettenis sparc32_linux_sigtramp_frame_cache (next_frame, this_cache);
219b725ae77Skettenis
220b725ae77Skettenis (*this_id) = frame_id_build (cache->base, cache->pc);
221b725ae77Skettenis }
222b725ae77Skettenis
223b725ae77Skettenis static void
sparc32_linux_sigtramp_frame_prev_register(struct frame_info * next_frame,void ** this_cache,int regnum,int * optimizedp,enum lval_type * lvalp,CORE_ADDR * addrp,int * realnump,void * valuep)224b725ae77Skettenis sparc32_linux_sigtramp_frame_prev_register (struct frame_info *next_frame,
225b725ae77Skettenis void **this_cache,
226b725ae77Skettenis int regnum, int *optimizedp,
227b725ae77Skettenis enum lval_type *lvalp,
228b725ae77Skettenis CORE_ADDR *addrp,
229b725ae77Skettenis int *realnump, void *valuep)
230b725ae77Skettenis {
231b725ae77Skettenis struct sparc_frame_cache *cache =
232b725ae77Skettenis sparc32_linux_sigtramp_frame_cache (next_frame, this_cache);
233b725ae77Skettenis
234*11efff7fSkettenis trad_frame_get_prev_register (next_frame, cache->saved_regs, regnum,
235b725ae77Skettenis optimizedp, lvalp, addrp, realnump, valuep);
236b725ae77Skettenis }
237b725ae77Skettenis
238b725ae77Skettenis static const struct frame_unwind sparc32_linux_sigtramp_frame_unwind =
239b725ae77Skettenis {
240b725ae77Skettenis SIGTRAMP_FRAME,
241b725ae77Skettenis sparc32_linux_sigtramp_frame_this_id,
242b725ae77Skettenis sparc32_linux_sigtramp_frame_prev_register
243b725ae77Skettenis };
244b725ae77Skettenis
245b725ae77Skettenis static const struct frame_unwind *
sparc32_linux_sigtramp_frame_sniffer(struct frame_info * next_frame)246b725ae77Skettenis sparc32_linux_sigtramp_frame_sniffer (struct frame_info *next_frame)
247b725ae77Skettenis {
248*11efff7fSkettenis if (sparc32_linux_sigtramp_p (next_frame))
249b725ae77Skettenis return &sparc32_linux_sigtramp_frame_unwind;
250b725ae77Skettenis
251b725ae77Skettenis return NULL;
252b725ae77Skettenis }
253b725ae77Skettenis
254b725ae77Skettenis
255b725ae77Skettenis static void
sparc32_linux_init_abi(struct gdbarch_info info,struct gdbarch * gdbarch)256b725ae77Skettenis sparc32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
257b725ae77Skettenis {
258b725ae77Skettenis /* GNU/Linux is very similar to Solaris ... */
259b725ae77Skettenis sparc32_sol2_init_abi (info, gdbarch);
260b725ae77Skettenis
261b725ae77Skettenis /* ... but doesn't have kernel-assisted single-stepping support. */
262b725ae77Skettenis set_gdbarch_software_single_step (gdbarch, sparc_software_single_step);
263b725ae77Skettenis
264b725ae77Skettenis /* GNU/Linux doesn't support the 128-bit `long double' from the psABI. */
265b725ae77Skettenis set_gdbarch_long_double_bit (gdbarch, 64);
266b725ae77Skettenis set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big);
267b725ae77Skettenis
268b725ae77Skettenis frame_unwind_append_sniffer (gdbarch, sparc32_linux_sigtramp_frame_sniffer);
269b725ae77Skettenis }
270b725ae77Skettenis
271b725ae77Skettenis /* Provide a prototype to silence -Wmissing-prototypes. */
272b725ae77Skettenis extern void _initialize_sparc_linux_tdep (void);
273b725ae77Skettenis
274b725ae77Skettenis void
_initialize_sparc_linux_tdep(void)275b725ae77Skettenis _initialize_sparc_linux_tdep (void)
276b725ae77Skettenis {
277b725ae77Skettenis gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_LINUX,
278b725ae77Skettenis sparc32_linux_init_abi);
279b725ae77Skettenis }
280