]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/sparc-sol2-tdep.c
trad-frame cleanups
[thirdparty/binutils-gdb.git] / gdb / sparc-sol2-tdep.c
CommitLineData
386c036b
MK
1/* Target-dependent code for Solaris SPARC.
2
3666a048 3 Copyright (C) 2003-2021 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
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
386c036b
MK
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
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
386c036b
MK
19
20#include "defs.h"
21#include "frame.h"
22#include "frame-unwind.h"
23#include "gdbcore.h"
24#include "symtab.h"
25#include "objfiles.h"
26#include "osabi.h"
27#include "regcache.h"
ff1eb2b5 28#include "regset.h"
386c036b
MK
29#include "target.h"
30#include "trad-frame.h"
31
081bf9da 32#include "sol2-tdep.h"
386c036b 33#include "sparc-tdep.h"
70b216c8 34#include "solib-svr4.h"
386c036b
MK
35
36/* From <sys/regset.h>. */
b4fd25c9 37const struct sparc_gregmap sparc32_sol2_gregmap =
386c036b
MK
38{
39 32 * 4, /* %psr */
40 33 * 4, /* %pc */
41 34 * 4, /* %npc */
42 35 * 4, /* %y */
43 36 * 4, /* %wim */
44 37 * 4, /* %tbr */
45 1 * 4, /* %g1 */
46 16 * 4, /* %l0 */
47};
db75c717 48
b4fd25c9 49const struct sparc_fpregmap sparc32_sol2_fpregmap =
db75c717
DM
50{
51 0 * 4, /* %f0 */
52 33 * 4, /* %fsr */
53};
ff1eb2b5
UW
54
55static void
56sparc32_sol2_supply_core_gregset (const struct regset *regset,
57 struct regcache *regcache,
58 int regnum, const void *gregs, size_t len)
59{
60 sparc32_supply_gregset (&sparc32_sol2_gregmap, regcache, regnum, gregs);
61}
62
63static void
64sparc32_sol2_collect_core_gregset (const struct regset *regset,
65 const struct regcache *regcache,
66 int regnum, void *gregs, size_t len)
67{
68 sparc32_collect_gregset (&sparc32_sol2_gregmap, regcache, regnum, gregs);
69}
70
71static void
72sparc32_sol2_supply_core_fpregset (const struct regset *regset,
73 struct regcache *regcache,
74 int regnum, const void *fpregs, size_t len)
75{
76 sparc32_supply_fpregset (&sparc32_sol2_fpregmap, regcache, regnum, fpregs);
77}
78
79static void
80sparc32_sol2_collect_core_fpregset (const struct regset *regset,
81 const struct regcache *regcache,
82 int regnum, void *fpregs, size_t len)
83{
84 sparc32_collect_fpregset (&sparc32_sol2_fpregmap, regcache, regnum, fpregs);
85}
86
87static const struct regset sparc32_sol2_gregset =
88 {
89 NULL,
90 sparc32_sol2_supply_core_gregset,
91 sparc32_sol2_collect_core_gregset
92 };
93
94static const struct regset sparc32_sol2_fpregset =
95 {
96 NULL,
97 sparc32_sol2_supply_core_fpregset,
98 sparc32_sol2_collect_core_fpregset
99 };
386c036b
MK
100\f
101
386c036b 102static struct sparc_frame_cache *
236369e7 103sparc32_sol2_sigtramp_frame_cache (struct frame_info *this_frame,
386c036b
MK
104 void **this_cache)
105{
106 struct sparc_frame_cache *cache;
107 CORE_ADDR mcontext_addr, addr;
108 int regnum;
109
110 if (*this_cache)
19ba03f4 111 return (struct sparc_frame_cache *) *this_cache;
386c036b 112
236369e7 113 cache = sparc_frame_cache (this_frame, this_cache);
386c036b
MK
114 gdb_assert (cache == *this_cache);
115
236369e7 116 cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
386c036b
MK
117
118 /* The third argument is a pointer to an instance of `ucontext_t',
119 which has a member `uc_mcontext' that contains the saved
120 registers. */
369c397b
JB
121 regnum =
122 (cache->copied_regs_mask & 0x04) ? SPARC_I2_REGNUM : SPARC_O2_REGNUM;
236369e7 123 mcontext_addr = get_frame_register_unsigned (this_frame, regnum) + 40;
386c036b 124
098caef4
LM
125 cache->saved_regs[SPARC32_PSR_REGNUM].set_addr (mcontext_addr + 0 * 4);
126 cache->saved_regs[SPARC32_PC_REGNUM].set_addr (mcontext_addr + 1 * 4);
127 cache->saved_regs[SPARC32_NPC_REGNUM].set_addr (mcontext_addr + 2 * 4);
128 cache->saved_regs[SPARC32_Y_REGNUM].set_addr (mcontext_addr + 3 * 4);
386c036b
MK
129
130 /* Since %g0 is always zero, keep the identity encoding. */
131 for (regnum = SPARC_G1_REGNUM, addr = mcontext_addr + 4 * 4;
132 regnum <= SPARC_O7_REGNUM; regnum++, addr += 4)
098caef4 133 cache->saved_regs[regnum].set_addr (addr);
386c036b 134
236369e7 135 if (get_frame_memory_unsigned (this_frame, mcontext_addr + 19 * 4, 4))
386c036b
MK
136 {
137 /* The register windows haven't been flushed. */
138 for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++)
a9a87d35 139 cache->saved_regs[regnum].set_unknown ();
386c036b
MK
140 }
141 else
142 {
098caef4 143 addr = cache->saved_regs[SPARC_SP_REGNUM].addr ();
236369e7 144 addr = get_frame_memory_unsigned (this_frame, addr, 4);
386c036b
MK
145 for (regnum = SPARC_L0_REGNUM;
146 regnum <= SPARC_I7_REGNUM; regnum++, addr += 4)
098caef4 147 cache->saved_regs[regnum].set_addr (addr);
386c036b
MK
148 }
149
150 return cache;
151}
152
153static void
236369e7 154sparc32_sol2_sigtramp_frame_this_id (struct frame_info *this_frame,
386c036b
MK
155 void **this_cache,
156 struct frame_id *this_id)
157{
158 struct sparc_frame_cache *cache =
236369e7 159 sparc32_sol2_sigtramp_frame_cache (this_frame, this_cache);
386c036b
MK
160
161 (*this_id) = frame_id_build (cache->base, cache->pc);
162}
163
236369e7
JB
164static struct value *
165sparc32_sol2_sigtramp_frame_prev_register (struct frame_info *this_frame,
386c036b 166 void **this_cache,
236369e7 167 int regnum)
386c036b
MK
168{
169 struct sparc_frame_cache *cache =
236369e7 170 sparc32_sol2_sigtramp_frame_cache (this_frame, this_cache);
386c036b 171
236369e7 172 return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
386c036b
MK
173}
174
236369e7
JB
175static int
176sparc32_sol2_sigtramp_frame_sniffer (const struct frame_unwind *self,
177 struct frame_info *this_frame,
178 void **this_cache)
386c036b 179{
d412e696 180 return sol2_sigtramp_p (this_frame);
386c036b 181}
149ad273 182
236369e7
JB
183static const struct frame_unwind sparc32_sol2_sigtramp_frame_unwind =
184{
185 SIGTRAMP_FRAME,
8fbca658 186 default_frame_unwind_stop_reason,
236369e7
JB
187 sparc32_sol2_sigtramp_frame_this_id,
188 sparc32_sol2_sigtramp_frame_prev_register,
189 NULL,
190 sparc32_sol2_sigtramp_frame_sniffer
191};
192
386c036b
MK
193\f
194
a7e6196b 195static void
386c036b
MK
196sparc32_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
197{
198 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
199
ff1eb2b5
UW
200 tdep->gregset = &sparc32_sol2_gregset;
201 tdep->sizeof_gregset = 152;
202
203 tdep->fpregset = &sparc32_sol2_fpregset;
204 tdep->sizeof_fpregset = 400;
205
d412e696 206 sol2_init_abi (info, gdbarch);
149ad273 207
386c036b 208 /* Solaris has SVR4-style shared libraries... */
386c036b 209 set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
70b216c8
MK
210 set_solib_svr4_fetch_link_map_offsets
211 (gdbarch, svr4_ilp32_fetch_link_map_offsets);
386c036b
MK
212
213 /* ...which means that we need some special handling when doing
214 prologue analysis. */
215 tdep->plt_entry_size = 12;
216
217 /* Solaris has kernel-assisted single-stepping support. */
218 set_gdbarch_software_single_step (gdbarch, NULL);
219
236369e7 220 frame_unwind_append_unwinder (gdbarch, &sparc32_sol2_sigtramp_frame_unwind);
386c036b 221}
386c036b 222
6c265988 223void _initialize_sparc_sol2_tdep ();
386c036b 224void
6c265988 225_initialize_sparc_sol2_tdep ()
386c036b
MK
226{
227 gdbarch_register_osabi (bfd_arch_sparc, 0,
228 GDB_OSABI_SOLARIS, sparc32_sol2_init_abi);
229}