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