sh-netbsd-tdep.c revision 1.1 1 /* Target-dependent code for NetBSD/sh.
2
3 Copyright (C) 2002-2023 Free Software Foundation, Inc.
4
5 Contributed by Wasabi Systems, Inc.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21
22 #include "defs.h"
23 #include "gdbcore.h"
24 #include "regset.h"
25 #include "value.h"
26 #include "osabi.h"
27 #include "trad-frame.h"
28 #include "tramp-frame.h"
29 #include "frame-unwind.h"
30
31 #include "sh-tdep.h"
32 #include "netbsd-tdep.h"
33 #include "solib-svr4.h"
34 #include "gdbarch.h"
35
36 /* Convert a register number into an offset into a ptrace
37 register structure. */
38 static const struct sh_corefile_regmap regmap[] =
39 {
40 {R0_REGNUM, 20 * 4},
41 {R0_REGNUM + 1, 19 * 4},
42 {R0_REGNUM + 2, 18 * 4},
43 {R0_REGNUM + 3, 17 * 4},
44 {R0_REGNUM + 4, 16 * 4},
45 {R0_REGNUM + 5, 15 * 4},
46 {R0_REGNUM + 6, 14 * 4},
47 {R0_REGNUM + 7, 13 * 4},
48 {R0_REGNUM + 8, 12 * 4},
49 {R0_REGNUM + 9, 11 * 4},
50 {R0_REGNUM + 10, 10 * 4},
51 {R0_REGNUM + 11, 9 * 4},
52 {R0_REGNUM + 12, 8 * 4},
53 {R0_REGNUM + 13, 7 * 4},
54 {R0_REGNUM + 14, 6 * 4},
55 {R0_REGNUM + 15, 5 * 4},
56 {PC_REGNUM, 0 * 4},
57 {SR_REGNUM, 1 * 4},
58 {PR_REGNUM, 2 * 4},
59 {MACH_REGNUM, 3 * 4},
60 {MACL_REGNUM, 4 * 4},
61 {GBR_REGNUM, 21 * 4},
62 {-1 /* Terminator. */, 0}
63 };
64
65
67
68 #define REGSx16(base) \
69 {(base), 0}, \
70 {(base) + 1, 4}, \
71 {(base) + 2, 8}, \
72 {(base) + 3, 12}, \
73 {(base) + 4, 16}, \
74 {(base) + 5, 20}, \
75 {(base) + 6, 24}, \
76 {(base) + 7, 28}, \
77 {(base) + 8, 32}, \
78 {(base) + 9, 36}, \
79 {(base) + 10, 40}, \
80 {(base) + 11, 44}, \
81 {(base) + 12, 48}, \
82 {(base) + 13, 52}, \
83 {(base) + 14, 56}, \
84 {(base) + 15, 60}
85
86 /* Convert an FPU register number into an offset into a ptrace
87 register structure. */
88 static const struct sh_corefile_regmap fpregmap[] =
89 {
90 REGSx16 (FR0_REGNUM),
91 /* XXX: REGSx16(XF0_REGNUM) omitted. */
92 {FPSCR_REGNUM, 128},
93 {FPUL_REGNUM, 132},
94 {-1 /* Terminator. */, 0}
95 };
96
97
98 /* From <machine/mcontext.h>. */
99 static const int shnbsd_mc_reg_offset[] =
100 {
101 (20 * 4), /* r0 */
102 (19 * 4), /* r1 */
103 (18 * 4), /* r2 */
104 (17 * 4), /* r3 */
105 (16 * 4), /* r4 */
106 (15 * 4), /* r5 */
107 (14 * 4), /* r6 */
108 (13 * 4), /* r7 */
109 (12 * 4), /* r8 */
110 (11 * 4), /* r9 */
111 (10 * 4), /* r10 */
112 ( 9 * 4), /* r11 */
113 ( 8 * 4), /* r12 */
114 ( 7 * 4), /* r13 */
115 ( 6 * 4), /* r14 */
116 (21 * 4), /* r15/sp */
117 ( 1 * 4), /* pc */
118 ( 5 * 4), /* pr */
119 ( 0 * 4), /* gbr */
120 -1,
121 ( 4 * 4), /* mach */
122 ( 3 * 4), /* macl */
123 ( 2 * 4), /* sr */
124 };
125
126 /* SH register sets. */
127
128
129 static void
131 shnbsd_sigtramp_cache_init (const struct tramp_frame *,
132 frame_info_ptr,
133 struct trad_frame_cache *,
134 CORE_ADDR);
135
136 /* The siginfo signal trampoline for NetBSD/sh3 versions 2.0 and later */
137 static const struct tramp_frame shnbsd_sigtramp_si2 =
138 {
139 SIGTRAMP_FRAME,
140 2,
141 {
142 { 0x64f3, ULONGEST_MAX }, /* mov r15,r4 */
143 { 0xd002, ULONGEST_MAX }, /* mov.l .LSYS_setcontext */
144 { 0xc380, ULONGEST_MAX }, /* trapa #-128 */
145 { 0xa003, ULONGEST_MAX }, /* bra .Lskip1 */
146 { 0x0009, ULONGEST_MAX }, /* nop */
147 { 0x0009, ULONGEST_MAX }, /* nop */
148 /* .LSYS_setcontext */
149 { 0x0134, ULONGEST_MAX }, { 0x0000, ULONGEST_MAX }, /* 0x134 */
150 /* .Lskip1 */
151 { 0x6403, ULONGEST_MAX }, /* mov r0,r4 */
152 { 0xd002, ULONGEST_MAX }, /* mov.l .LSYS_exit */
153 { 0xc380, ULONGEST_MAX }, /* trapa #-128 */
154 { 0xa003, ULONGEST_MAX }, /* bra .Lskip2 */
155 { 0x0009, ULONGEST_MAX }, /* nop */
156 { 0x0009, ULONGEST_MAX }, /* nop */
157 /* .LSYS_exit */
158 { 0x0001, ULONGEST_MAX }, { 0x0000, ULONGEST_MAX }, /* 0x1 */
159 /* .Lskip2 */
160 { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
161 },
162 shnbsd_sigtramp_cache_init
163 };
164
165 static void
166 shnbsd_sigtramp_cache_init (const struct tramp_frame *self,
167 frame_info_ptr next_frame,
168 struct trad_frame_cache *this_cache,
169 CORE_ADDR func)
170 {
171 struct gdbarch *gdbarch = get_frame_arch (next_frame);
172 // struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
173 int sp_regnum = gdbarch_sp_regnum (gdbarch);
174 CORE_ADDR sp = get_frame_register_unsigned (next_frame, sp_regnum);
175 CORE_ADDR base;
176 const int *reg_offset;
177 int num_regs;
178 int i;
179
180 reg_offset = shnbsd_mc_reg_offset;
181 num_regs = ARRAY_SIZE (shnbsd_mc_reg_offset);
182 /* SP already points at the ucontext. */
183 base = sp;
184 /* offsetof(ucontext_t, uc_mcontext) == 36 */
185 base += 36;
186
187 for (i = 0; i < num_regs; i++)
188 if (reg_offset[i] != -1)
189 trad_frame_set_reg_addr (this_cache, i, base + reg_offset[i]);
190
191 /* Construct the frame ID using the function start. */
192 trad_frame_set_id (this_cache, frame_id_build (sp, func));
193 }
194
195 static void
196 shnbsd_init_abi (struct gdbarch_info info,
197 struct gdbarch *gdbarch)
198 {
199 sh_gdbarch_tdep *tdep = gdbarch_tdep<sh_gdbarch_tdep> (gdbarch);
200 nbsd_init_abi (info, gdbarch);
201
202 tdep->core_gregmap = (struct sh_corefile_regmap *)regmap;
203 tdep->sizeof_gregset = 88;
204
205 tdep->core_fpregmap = (struct sh_corefile_regmap *)fpregmap;
206 tdep->sizeof_fpregset = 0; /* XXX */
207
208 set_solib_svr4_fetch_link_map_offsets
209 (gdbarch, svr4_ilp32_fetch_link_map_offsets);
210 tramp_frame_prepend_unwinder (gdbarch, &shnbsd_sigtramp_si2);
211 }
212
213 void _initialize_shnbsd_tdep ();
214 void
215 _initialize_shnbsd_tdep ()
216 {
217 gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_NETBSD,
218 shnbsd_init_abi);
219 }
220