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