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 66 67 #define REGSx16(base) \ 68 {(base), 0}, \ 69 {(base) + 1, 4}, \ 70 {(base) + 2, 8}, \ 71 {(base) + 3, 12}, \ 72 {(base) + 4, 16}, \ 73 {(base) + 5, 20}, \ 74 {(base) + 6, 24}, \ 75 {(base) + 7, 28}, \ 76 {(base) + 8, 32}, \ 77 {(base) + 9, 36}, \ 78 {(base) + 10, 40}, \ 79 {(base) + 11, 44}, \ 80 {(base) + 12, 48}, \ 81 {(base) + 13, 52}, \ 82 {(base) + 14, 56}, \ 83 {(base) + 15, 60} 84 85 /* Convert an FPU register number into an offset into a ptrace 86 register structure. */ 87 static const struct sh_corefile_regmap fpregmap[] = 88 { 89 REGSx16 (FR0_REGNUM), 90 /* XXX: REGSx16(XF0_REGNUM) omitted. */ 91 {FPSCR_REGNUM, 128}, 92 {FPUL_REGNUM, 132}, 93 {-1 /* Terminator. */, 0} 94 }; 95 96 97 /* From <machine/mcontext.h>. */ 98 static const int shnbsd_mc_reg_offset[] = 99 { 100 (20 * 4), /* r0 */ 101 (19 * 4), /* r1 */ 102 (18 * 4), /* r2 */ 103 (17 * 4), /* r3 */ 104 (16 * 4), /* r4 */ 105 (15 * 4), /* r5 */ 106 (14 * 4), /* r6 */ 107 (13 * 4), /* r7 */ 108 (12 * 4), /* r8 */ 109 (11 * 4), /* r9 */ 110 (10 * 4), /* r10 */ 111 ( 9 * 4), /* r11 */ 112 ( 8 * 4), /* r12 */ 113 ( 7 * 4), /* r13 */ 114 ( 6 * 4), /* r14 */ 115 (21 * 4), /* r15/sp */ 116 ( 1 * 4), /* pc */ 117 ( 5 * 4), /* pr */ 118 ( 0 * 4), /* gbr */ 119 -1, 120 ( 4 * 4), /* mach */ 121 ( 3 * 4), /* macl */ 122 ( 2 * 4), /* sr */ 123 }; 124 125 /* SH register sets. */ 126 127 128 static void 129 shnbsd_sigtramp_cache_init (const struct tramp_frame *, 130 frame_info_ptr, 131 struct trad_frame_cache *, 132 CORE_ADDR); 133 134 /* The siginfo signal trampoline for NetBSD/sh3 versions 2.0 and later */ 135 static const struct tramp_frame shnbsd_sigtramp_si2 = 136 { 137 SIGTRAMP_FRAME, 138 2, 139 { 140 { 0x64f3, ULONGEST_MAX }, /* mov r15,r4 */ 141 { 0xd002, ULONGEST_MAX }, /* mov.l .LSYS_setcontext */ 142 { 0xc380, ULONGEST_MAX }, /* trapa #-128 */ 143 { 0xa003, ULONGEST_MAX }, /* bra .Lskip1 */ 144 { 0x0009, ULONGEST_MAX }, /* nop */ 145 { 0x0009, ULONGEST_MAX }, /* nop */ 146 /* .LSYS_setcontext */ 147 { 0x0134, ULONGEST_MAX }, { 0x0000, ULONGEST_MAX }, /* 0x134 */ 148 /* .Lskip1 */ 149 { 0x6403, ULONGEST_MAX }, /* mov r0,r4 */ 150 { 0xd002, ULONGEST_MAX }, /* mov.l .LSYS_exit */ 151 { 0xc380, ULONGEST_MAX }, /* trapa #-128 */ 152 { 0xa003, ULONGEST_MAX }, /* bra .Lskip2 */ 153 { 0x0009, ULONGEST_MAX }, /* nop */ 154 { 0x0009, ULONGEST_MAX }, /* nop */ 155 /* .LSYS_exit */ 156 { 0x0001, ULONGEST_MAX }, { 0x0000, ULONGEST_MAX }, /* 0x1 */ 157 /* .Lskip2 */ 158 { TRAMP_SENTINEL_INSN, ULONGEST_MAX } 159 }, 160 shnbsd_sigtramp_cache_init 161 }; 162 163 static void 164 shnbsd_sigtramp_cache_init (const struct tramp_frame *self, 165 frame_info_ptr next_frame, 166 struct trad_frame_cache *this_cache, 167 CORE_ADDR func) 168 { 169 struct gdbarch *gdbarch = get_frame_arch (next_frame); 170 // struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 171 int sp_regnum = gdbarch_sp_regnum (gdbarch); 172 CORE_ADDR sp = get_frame_register_unsigned (next_frame, sp_regnum); 173 CORE_ADDR base; 174 const int *reg_offset; 175 int num_regs; 176 int i; 177 178 reg_offset = shnbsd_mc_reg_offset; 179 num_regs = ARRAY_SIZE (shnbsd_mc_reg_offset); 180 /* SP already points at the ucontext. */ 181 base = sp; 182 /* offsetof(ucontext_t, uc_mcontext) == 36 */ 183 base += 36; 184 185 for (i = 0; i < num_regs; i++) 186 if (reg_offset[i] != -1) 187 trad_frame_set_reg_addr (this_cache, i, base + reg_offset[i]); 188 189 /* Construct the frame ID using the function start. */ 190 trad_frame_set_id (this_cache, frame_id_build (sp, func)); 191 } 192 193 static void 194 shnbsd_init_abi (struct gdbarch_info info, 195 struct gdbarch *gdbarch) 196 { 197 sh_gdbarch_tdep *tdep = gdbarch_tdep<sh_gdbarch_tdep> (gdbarch); 198 nbsd_init_abi (info, gdbarch); 199 200 tdep->core_gregmap = (struct sh_corefile_regmap *)regmap; 201 tdep->sizeof_gregset = 88; 202 203 tdep->core_fpregmap = (struct sh_corefile_regmap *)fpregmap; 204 tdep->sizeof_fpregset = 0; /* XXX */ 205 206 set_solib_svr4_fetch_link_map_offsets 207 (gdbarch, svr4_ilp32_fetch_link_map_offsets); 208 tramp_frame_prepend_unwinder (gdbarch, &shnbsd_sigtramp_si2); 209 } 210 211 void _initialize_shnbsd_tdep (); 212 void 213 _initialize_shnbsd_tdep () 214 { 215 gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_NETBSD, 216 shnbsd_init_abi); 217 } 218