xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/sparc64-netbsd-tdep.c (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
1*6881a400Schristos /* Target-dependent code for NetBSD/sparc64.
2*6881a400Schristos 
3*6881a400Schristos    Copyright (C) 2002-2023 Free Software Foundation, Inc.
4*6881a400Schristos    Based on code contributed by Wasabi Systems, Inc.
5*6881a400Schristos 
6*6881a400Schristos    This file is part of GDB.
7*6881a400Schristos 
8*6881a400Schristos    This program is free software; you can redistribute it and/or modify
9*6881a400Schristos    it under the terms of the GNU General Public License as published by
10*6881a400Schristos    the Free Software Foundation; either version 3 of the License, or
11*6881a400Schristos    (at your option) any later version.
12*6881a400Schristos 
13*6881a400Schristos    This program is distributed in the hope that it will be useful,
14*6881a400Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
15*6881a400Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*6881a400Schristos    GNU General Public License for more details.
17*6881a400Schristos 
18*6881a400Schristos    You should have received a copy of the GNU General Public License
19*6881a400Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20*6881a400Schristos 
21*6881a400Schristos #include "defs.h"
22*6881a400Schristos #include "frame.h"
23*6881a400Schristos #include "frame-unwind.h"
24*6881a400Schristos #include "gdbcore.h"
25*6881a400Schristos #include "osabi.h"
26*6881a400Schristos #include "regcache.h"
27*6881a400Schristos #include "regset.h"
28*6881a400Schristos #include "symtab.h"
29*6881a400Schristos #include "objfiles.h"
30*6881a400Schristos #include "solib-svr4.h"
31*6881a400Schristos #include "trad-frame.h"
32*6881a400Schristos 
33*6881a400Schristos #include "sparc64-tdep.h"
34*6881a400Schristos #include "netbsd-tdep.h"
35*6881a400Schristos 
36*6881a400Schristos /* From <machine/reg.h>.  */
37*6881a400Schristos const struct sparc_gregmap sparc64nbsd_gregmap =
38*6881a400Schristos {
39*6881a400Schristos   0 * 8,			/* "tstate" */
40*6881a400Schristos   1 * 8,			/* %pc */
41*6881a400Schristos   2 * 8,			/* %npc */
42*6881a400Schristos   3 * 8,			/* %y */
43*6881a400Schristos   -1,				/* %fprs */
44*6881a400Schristos   -1,
45*6881a400Schristos   5 * 8,			/* %g1 */
46*6881a400Schristos   -1,				/* %l0 */
47*6881a400Schristos   4				/* sizeof (%y) */
48*6881a400Schristos };
49*6881a400Schristos 
50*6881a400Schristos 
51*6881a400Schristos static void
52*6881a400Schristos sparc64nbsd_supply_gregset (const struct regset *regset,
53*6881a400Schristos 			    struct regcache *regcache,
54*6881a400Schristos 			    int regnum, const void *gregs, size_t len)
55*6881a400Schristos {
56*6881a400Schristos   sparc64_supply_gregset (&sparc64nbsd_gregmap, regcache, regnum, gregs);
57*6881a400Schristos }
58*6881a400Schristos 
59*6881a400Schristos static void
60*6881a400Schristos sparc64nbsd_supply_fpregset (const struct regset *regset,
61*6881a400Schristos 			     struct regcache *regcache,
62*6881a400Schristos 			     int regnum, const void *fpregs, size_t len)
63*6881a400Schristos {
64*6881a400Schristos   sparc64_supply_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
65*6881a400Schristos }
66*6881a400Schristos 
67*6881a400Schristos 
68*6881a400Schristos /* Signal trampolines.  */
69*6881a400Schristos 
70*6881a400Schristos /* The following variables describe the location of an on-stack signal
71*6881a400Schristos    trampoline.  The current values correspond to the memory layout for
72*6881a400Schristos    NetBSD 1.3 and up.  These shouldn't be necessary for NetBSD 2.0 and
73*6881a400Schristos    up, since NetBSD uses signal trampolines provided by libc now.  */
74*6881a400Schristos 
75*6881a400Schristos static const CORE_ADDR sparc64nbsd_sigtramp_start = 0xffffffffffffdee4ULL;
76*6881a400Schristos static const CORE_ADDR sparc64nbsd_sigtramp_end = 0xffffffffffffe000ULL;
77*6881a400Schristos 
78*6881a400Schristos static int
79*6881a400Schristos sparc64nbsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
80*6881a400Schristos {
81*6881a400Schristos   if (pc >= sparc64nbsd_sigtramp_start && pc < sparc64nbsd_sigtramp_end)
82*6881a400Schristos     return 1;
83*6881a400Schristos 
84*6881a400Schristos   return nbsd_pc_in_sigtramp (pc, name);
85*6881a400Schristos }
86*6881a400Schristos 
87*6881a400Schristos trad_frame_saved_reg *
88*6881a400Schristos sparc64nbsd_sigcontext_saved_regs (CORE_ADDR sigcontext_addr,
89*6881a400Schristos 				   frame_info_ptr this_frame)
90*6881a400Schristos {
91*6881a400Schristos   struct gdbarch *gdbarch = get_frame_arch (this_frame);
92*6881a400Schristos   trad_frame_saved_reg *saved_regs;
93*6881a400Schristos   CORE_ADDR addr, sp;
94*6881a400Schristos   int regnum, delta;
95*6881a400Schristos 
96*6881a400Schristos   saved_regs = trad_frame_alloc_saved_regs (this_frame);
97*6881a400Schristos 
98*6881a400Schristos   /* The registers are saved in bits and pieces scattered all over the
99*6881a400Schristos      place.  The code below records their location on the assumption
100*6881a400Schristos      that the part of the signal trampoline that saves the state has
101*6881a400Schristos      been executed.  */
102*6881a400Schristos 
103*6881a400Schristos   saved_regs[SPARC_SP_REGNUM].set_addr (sigcontext_addr + 8);
104*6881a400Schristos   saved_regs[SPARC64_PC_REGNUM].set_addr (sigcontext_addr + 16);
105*6881a400Schristos   saved_regs[SPARC64_NPC_REGNUM].set_addr (sigcontext_addr + 24);
106*6881a400Schristos   saved_regs[SPARC64_STATE_REGNUM].set_addr (sigcontext_addr + 32);
107*6881a400Schristos   saved_regs[SPARC_G1_REGNUM].set_addr (sigcontext_addr + 40);
108*6881a400Schristos   saved_regs[SPARC_O0_REGNUM].set_addr (sigcontext_addr + 48);
109*6881a400Schristos 
110*6881a400Schristos   /* The remaining `global' registers and %y are saved in the `local'
111*6881a400Schristos      registers.  */
112*6881a400Schristos   delta = SPARC_L0_REGNUM - SPARC_G0_REGNUM;
113*6881a400Schristos   for (regnum = SPARC_G2_REGNUM; regnum <= SPARC_G7_REGNUM; regnum++)
114*6881a400Schristos     saved_regs[regnum].set_realreg (regnum + delta);
115*6881a400Schristos   saved_regs[SPARC64_Y_REGNUM].set_realreg (SPARC_L1_REGNUM);
116*6881a400Schristos 
117*6881a400Schristos   /* The remaining `out' registers can be found in the current frame's
118*6881a400Schristos      `in' registers.  */
119*6881a400Schristos   delta = SPARC_I0_REGNUM - SPARC_O0_REGNUM;
120*6881a400Schristos   for (regnum = SPARC_O1_REGNUM; regnum <= SPARC_O5_REGNUM; regnum++)
121*6881a400Schristos     saved_regs[regnum].set_realreg (regnum + delta);
122*6881a400Schristos   saved_regs[SPARC_O7_REGNUM].set_realreg (SPARC_I7_REGNUM);
123*6881a400Schristos 
124*6881a400Schristos   /* The `local' and `in' registers have been saved in the register
125*6881a400Schristos      save area.  */
126*6881a400Schristos   addr = saved_regs[SPARC_SP_REGNUM].addr ();
127*6881a400Schristos   sp = get_frame_memory_unsigned (this_frame, addr, 8);
128*6881a400Schristos   for (regnum = SPARC_L0_REGNUM, addr = sp + BIAS;
129*6881a400Schristos        regnum <= SPARC_I7_REGNUM; regnum++, addr += 8)
130*6881a400Schristos     saved_regs[regnum].set_addr (addr);
131*6881a400Schristos 
132*6881a400Schristos   /* Handle StackGhost.  */
133*6881a400Schristos   {
134*6881a400Schristos     ULONGEST wcookie = sparc_fetch_wcookie (gdbarch);
135*6881a400Schristos 
136*6881a400Schristos     if (wcookie != 0)
137*6881a400Schristos       {
138*6881a400Schristos 	ULONGEST i7;
139*6881a400Schristos 
140*6881a400Schristos 	addr = saved_regs[SPARC_I7_REGNUM].addr ();
141*6881a400Schristos 	i7 = get_frame_memory_unsigned (this_frame, addr, 8);
142*6881a400Schristos 	saved_regs[SPARC_I7_REGNUM].set_value (i7 ^ wcookie);
143*6881a400Schristos       }
144*6881a400Schristos   }
145*6881a400Schristos 
146*6881a400Schristos   /* TODO: Handle the floating-point registers.  */
147*6881a400Schristos 
148*6881a400Schristos   return saved_regs;
149*6881a400Schristos }
150*6881a400Schristos 
151*6881a400Schristos static struct sparc_frame_cache *
152*6881a400Schristos sparc64nbsd_sigcontext_frame_cache (frame_info_ptr this_frame,
153*6881a400Schristos 				    void **this_cache)
154*6881a400Schristos {
155*6881a400Schristos   struct sparc_frame_cache *cache;
156*6881a400Schristos   CORE_ADDR addr;
157*6881a400Schristos 
158*6881a400Schristos   if (*this_cache)
159*6881a400Schristos     return (struct sparc_frame_cache *) *this_cache;
160*6881a400Schristos 
161*6881a400Schristos   cache = sparc_frame_cache (this_frame, this_cache);
162*6881a400Schristos   gdb_assert (cache == *this_cache);
163*6881a400Schristos 
164*6881a400Schristos   /* If we couldn't find the frame's function, we're probably dealing
165*6881a400Schristos      with an on-stack signal trampoline.  */
166*6881a400Schristos   if (cache->pc == 0)
167*6881a400Schristos     {
168*6881a400Schristos       cache->pc = sparc64nbsd_sigtramp_start;
169*6881a400Schristos 
170*6881a400Schristos       /* Since we couldn't find the frame's function, the cache was
171*6881a400Schristos 	 initialized under the assumption that we're frameless.  */
172*6881a400Schristos       sparc_record_save_insn (cache);
173*6881a400Schristos       addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
174*6881a400Schristos       if (addr & 1)
175*6881a400Schristos 	addr += BIAS;
176*6881a400Schristos       cache->base = addr;
177*6881a400Schristos     }
178*6881a400Schristos 
179*6881a400Schristos   /* We find the appropriate instance of `struct sigcontext' at a
180*6881a400Schristos      fixed offset in the signal frame.  */
181*6881a400Schristos   addr = cache->base + 128 + 8;
182*6881a400Schristos   cache->saved_regs = sparc64nbsd_sigcontext_saved_regs (addr, this_frame);
183*6881a400Schristos 
184*6881a400Schristos   return cache;
185*6881a400Schristos }
186*6881a400Schristos 
187*6881a400Schristos static void
188*6881a400Schristos sparc64nbsd_sigcontext_frame_this_id (frame_info_ptr this_frame,
189*6881a400Schristos 				      void **this_cache,
190*6881a400Schristos 				      struct frame_id *this_id)
191*6881a400Schristos {
192*6881a400Schristos   struct sparc_frame_cache *cache =
193*6881a400Schristos     sparc64nbsd_sigcontext_frame_cache (this_frame, this_cache);
194*6881a400Schristos 
195*6881a400Schristos   (*this_id) = frame_id_build (cache->base, cache->pc);
196*6881a400Schristos }
197*6881a400Schristos 
198*6881a400Schristos static struct value *
199*6881a400Schristos sparc64nbsd_sigcontext_frame_prev_register (frame_info_ptr this_frame,
200*6881a400Schristos 					    void **this_cache, int regnum)
201*6881a400Schristos {
202*6881a400Schristos   struct sparc_frame_cache *cache =
203*6881a400Schristos     sparc64nbsd_sigcontext_frame_cache (this_frame, this_cache);
204*6881a400Schristos 
205*6881a400Schristos   return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
206*6881a400Schristos }
207*6881a400Schristos 
208*6881a400Schristos static int
209*6881a400Schristos sparc64nbsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
210*6881a400Schristos 				    frame_info_ptr this_frame,
211*6881a400Schristos 				    void **this_cache)
212*6881a400Schristos {
213*6881a400Schristos   CORE_ADDR pc = get_frame_pc (this_frame);
214*6881a400Schristos   const char *name;
215*6881a400Schristos 
216*6881a400Schristos   find_pc_partial_function (pc, &name, NULL, NULL);
217*6881a400Schristos   if (sparc64nbsd_pc_in_sigtramp (pc, name))
218*6881a400Schristos     {
219*6881a400Schristos       if (name == NULL || !startswith (name, "__sigtramp_sigcontext"))
220*6881a400Schristos 	return 1;
221*6881a400Schristos     }
222*6881a400Schristos 
223*6881a400Schristos   return 0;
224*6881a400Schristos }
225*6881a400Schristos 
226*6881a400Schristos static const struct frame_unwind sparc64nbsd_sigcontext_frame_unwind =
227*6881a400Schristos {
228*6881a400Schristos   "sparc64 netbsd sigcontext",
229*6881a400Schristos   SIGTRAMP_FRAME,
230*6881a400Schristos   default_frame_unwind_stop_reason,
231*6881a400Schristos   sparc64nbsd_sigcontext_frame_this_id,
232*6881a400Schristos   sparc64nbsd_sigcontext_frame_prev_register,
233*6881a400Schristos   NULL,
234*6881a400Schristos   sparc64nbsd_sigtramp_frame_sniffer
235*6881a400Schristos };
236*6881a400Schristos 
237*6881a400Schristos 
238*6881a400Schristos static const struct regset sparc64nbsd_gregset =
239*6881a400Schristos   {
240*6881a400Schristos     NULL, sparc64nbsd_supply_gregset, NULL
241*6881a400Schristos   };
242*6881a400Schristos 
243*6881a400Schristos static const struct regset sparc64nbsd_fpregset =
244*6881a400Schristos   {
245*6881a400Schristos     NULL, sparc64nbsd_supply_fpregset, NULL
246*6881a400Schristos   };
247*6881a400Schristos 
248*6881a400Schristos static void
249*6881a400Schristos sparc64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
250*6881a400Schristos {
251*6881a400Schristos   sparc_gdbarch_tdep *tdep = gdbarch_tdep<sparc_gdbarch_tdep> (gdbarch);
252*6881a400Schristos 
253*6881a400Schristos   nbsd_init_abi (info, gdbarch);
254*6881a400Schristos 
255*6881a400Schristos   tdep->gregset = &sparc64nbsd_gregset;
256*6881a400Schristos   tdep->sizeof_gregset = 160;
257*6881a400Schristos 
258*6881a400Schristos   tdep->fpregset =  &sparc64nbsd_fpregset;
259*6881a400Schristos   tdep->sizeof_fpregset = 272;
260*6881a400Schristos 
261*6881a400Schristos   /* Make sure we can single-step "new" syscalls.  */
262*6881a400Schristos   tdep->step_trap = sparcnbsd_step_trap;
263*6881a400Schristos 
264*6881a400Schristos   frame_unwind_append_unwinder (gdbarch, &sparc64nbsd_sigcontext_frame_unwind);
265*6881a400Schristos 
266*6881a400Schristos   sparc64_init_abi (info, gdbarch);
267*6881a400Schristos 
268*6881a400Schristos   /* NetBSD/sparc64 has SVR4-style shared libraries.  */
269*6881a400Schristos   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
270*6881a400Schristos   set_solib_svr4_fetch_link_map_offsets
271*6881a400Schristos     (gdbarch, svr4_lp64_fetch_link_map_offsets);
272*6881a400Schristos }
273*6881a400Schristos 
274*6881a400Schristos void _initialize_sparc64nbsd_tdep ();
275*6881a400Schristos void
276*6881a400Schristos _initialize_sparc64nbsd_tdep ()
277*6881a400Schristos {
278*6881a400Schristos   gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
279*6881a400Schristos 			  GDB_OSABI_NETBSD, sparc64nbsd_init_abi);
280*6881a400Schristos }
281