1b725ae77Skettenis /* Target-dependent code for OpenBSD/sparc.
2b725ae77Skettenis
3*369311e4Skettenis Copyright 2004, 2005 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 "osabi.h"
27b725ae77Skettenis #include "solib-svr4.h"
28b725ae77Skettenis #include "symtab.h"
29b725ae77Skettenis #include "trad-frame.h"
30b725ae77Skettenis
31b725ae77Skettenis #include "gdb_assert.h"
32b725ae77Skettenis
33*369311e4Skettenis #include "obsd-tdep.h"
34b725ae77Skettenis #include "sparc-tdep.h"
35b725ae77Skettenis
36b725ae77Skettenis /* Signal trampolines. */
37b725ae77Skettenis
38b725ae77Skettenis /* The OpenBSD kernel maps the signal trampoline at some random
39b725ae77Skettenis location in user space, which means that the traditional BSD way of
40b725ae77Skettenis detecting it won't work.
41b725ae77Skettenis
42b725ae77Skettenis The signal trampoline will be mapped at an address that is page
43b725ae77Skettenis aligned. We recognize the signal trampoline by the looking for the
44b725ae77Skettenis sigreturn system call. */
45b725ae77Skettenis
46b725ae77Skettenis static const int sparc32obsd_page_size = 4096;
47b725ae77Skettenis
48b725ae77Skettenis static int
sparc32obsd_pc_in_sigtramp(CORE_ADDR pc,char * name)49b725ae77Skettenis sparc32obsd_pc_in_sigtramp (CORE_ADDR pc, char *name)
50b725ae77Skettenis {
51b725ae77Skettenis CORE_ADDR start_pc = (pc & ~(sparc32obsd_page_size - 1));
52b725ae77Skettenis unsigned long insn;
53b725ae77Skettenis
54b725ae77Skettenis if (name)
55b725ae77Skettenis return 0;
56b725ae77Skettenis
57b725ae77Skettenis /* Check for "restore %g0, SYS_sigreturn, %g1". */
58b725ae77Skettenis insn = sparc_fetch_instruction (start_pc + 0xec);
59b725ae77Skettenis if (insn != 0x83e82067)
60b725ae77Skettenis return 0;
61b725ae77Skettenis
62b725ae77Skettenis /* Check for "t ST_SYSCALL". */
63b725ae77Skettenis insn = sparc_fetch_instruction (start_pc + 0xf4);
64b725ae77Skettenis if (insn != 0x91d02000)
65b725ae77Skettenis return 0;
66b725ae77Skettenis
67b725ae77Skettenis return 1;
68b725ae77Skettenis }
69b725ae77Skettenis
70b725ae77Skettenis static struct sparc_frame_cache *
sparc32obsd_frame_cache(struct frame_info * next_frame,void ** this_cache)71b725ae77Skettenis sparc32obsd_frame_cache (struct frame_info *next_frame, void **this_cache)
72b725ae77Skettenis {
73b725ae77Skettenis struct sparc_frame_cache *cache;
74b725ae77Skettenis CORE_ADDR addr;
75b725ae77Skettenis
76b725ae77Skettenis if (*this_cache)
77b725ae77Skettenis return *this_cache;
78b725ae77Skettenis
79b725ae77Skettenis cache = sparc_frame_cache (next_frame, this_cache);
80b725ae77Skettenis gdb_assert (cache == *this_cache);
81b725ae77Skettenis
82b725ae77Skettenis /* If we couldn't find the frame's function, we're probably dealing
83b725ae77Skettenis with an on-stack signal trampoline. */
84b725ae77Skettenis if (cache->pc == 0)
85b725ae77Skettenis {
86b725ae77Skettenis cache->pc = frame_pc_unwind (next_frame);
87b725ae77Skettenis cache->pc &= ~(sparc32obsd_page_size - 1);
88b725ae77Skettenis
89b725ae77Skettenis /* Since we couldn't find the frame's function, the cache was
90b725ae77Skettenis initialized under the assumption that we're frameless. */
91b725ae77Skettenis cache->frameless_p = 0;
92b725ae77Skettenis addr = frame_unwind_register_unsigned (next_frame, SPARC_FP_REGNUM);
93b725ae77Skettenis cache->base = addr;
94b725ae77Skettenis }
95b725ae77Skettenis
96b725ae77Skettenis cache->saved_regs = sparc32nbsd_sigcontext_saved_regs (next_frame);
97b725ae77Skettenis
98b725ae77Skettenis return cache;
99b725ae77Skettenis }
100b725ae77Skettenis
101b725ae77Skettenis static void
sparc32obsd_frame_this_id(struct frame_info * next_frame,void ** this_cache,struct frame_id * this_id)102b725ae77Skettenis sparc32obsd_frame_this_id (struct frame_info *next_frame, void **this_cache,
103b725ae77Skettenis struct frame_id *this_id)
104b725ae77Skettenis {
105b725ae77Skettenis struct sparc_frame_cache *cache =
106b725ae77Skettenis sparc32obsd_frame_cache (next_frame, this_cache);
107b725ae77Skettenis
108b725ae77Skettenis (*this_id) = frame_id_build (cache->base, cache->pc);
109b725ae77Skettenis }
110b725ae77Skettenis
111b725ae77Skettenis static void
sparc32obsd_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)112b725ae77Skettenis sparc32obsd_frame_prev_register (struct frame_info *next_frame,
113b725ae77Skettenis void **this_cache,
114b725ae77Skettenis int regnum, int *optimizedp,
115b725ae77Skettenis enum lval_type *lvalp, CORE_ADDR *addrp,
116b725ae77Skettenis int *realnump, void *valuep)
117b725ae77Skettenis {
118b725ae77Skettenis struct sparc_frame_cache *cache =
119b725ae77Skettenis sparc32obsd_frame_cache (next_frame, this_cache);
120b725ae77Skettenis
12111efff7fSkettenis trad_frame_get_prev_register (next_frame, cache->saved_regs, regnum,
122b725ae77Skettenis optimizedp, lvalp, addrp, realnump, valuep);
123b725ae77Skettenis }
124b725ae77Skettenis
125b725ae77Skettenis static const struct frame_unwind sparc32obsd_frame_unwind =
126b725ae77Skettenis {
127b725ae77Skettenis SIGTRAMP_FRAME,
128b725ae77Skettenis sparc32obsd_frame_this_id,
129b725ae77Skettenis sparc32obsd_frame_prev_register
130b725ae77Skettenis };
131b725ae77Skettenis
132b725ae77Skettenis static const struct frame_unwind *
sparc32obsd_sigtramp_frame_sniffer(struct frame_info * next_frame)133b725ae77Skettenis sparc32obsd_sigtramp_frame_sniffer (struct frame_info *next_frame)
134b725ae77Skettenis {
135b725ae77Skettenis CORE_ADDR pc = frame_pc_unwind (next_frame);
136b725ae77Skettenis char *name;
137b725ae77Skettenis
138b725ae77Skettenis find_pc_partial_function (pc, &name, NULL, NULL);
139b725ae77Skettenis if (sparc32obsd_pc_in_sigtramp (pc, name))
140b725ae77Skettenis return &sparc32obsd_frame_unwind;
141b725ae77Skettenis
142b725ae77Skettenis return NULL;
143b725ae77Skettenis }
144b725ae77Skettenis
145b725ae77Skettenis
146b725ae77Skettenis static void
sparc32obsd_init_abi(struct gdbarch_info info,struct gdbarch * gdbarch)147b725ae77Skettenis sparc32obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
148b725ae77Skettenis {
149b725ae77Skettenis struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
150b725ae77Skettenis
1516c910867Skettenis /* OpenBSD/sparc is very similar to NetBSD/sparc ELF. */
1526c910867Skettenis sparc32nbsd_elf_init_abi (info, gdbarch);
153b725ae77Skettenis
154*369311e4Skettenis set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
155*369311e4Skettenis
156b725ae77Skettenis frame_unwind_append_sniffer (gdbarch, sparc32obsd_sigtramp_frame_sniffer);
157b725ae77Skettenis }
158b725ae77Skettenis
159b725ae77Skettenis
160b725ae77Skettenis /* Provide a prototype to silence -Wmissing-prototypes. */
161b725ae77Skettenis void _initialize_sparc32obsd_tdep (void);
162b725ae77Skettenis
163b725ae77Skettenis void
_initialize_sparc32obsd_tdep(void)164b725ae77Skettenis _initialize_sparc32obsd_tdep (void)
165b725ae77Skettenis {
166b725ae77Skettenis gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_OPENBSD_ELF,
167b725ae77Skettenis sparc32obsd_init_abi);
168b725ae77Skettenis }
169