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