1 /* GNU/Linux/SH specific low level interface, for the remote server for GDB. 2 Copyright (C) 1995-2024 Free Software Foundation, Inc. 3 4 This file is part of GDB. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18 19 #include "linux-low.h" 20 21 /* Linux target op definitions for the SH architecture. */ 22 23 class sh_target : public linux_process_target 24 { 25 public: 26 27 const regs_info *get_regs_info () override; 28 29 const gdb_byte *sw_breakpoint_from_kind (int kind, int *size) override; 30 31 protected: 32 33 void low_arch_setup () override; 34 35 bool low_cannot_fetch_register (int regno) override; 36 37 bool low_cannot_store_register (int regno) override; 38 39 bool low_supports_breakpoints () override; 40 41 CORE_ADDR low_get_pc (regcache *regcache) override; 42 43 void low_set_pc (regcache *regcache, CORE_ADDR newpc) override; 44 45 bool low_breakpoint_at (CORE_ADDR pc) override; 46 }; 47 48 /* The singleton target ops object. */ 49 50 static sh_target the_sh_target; 51 52 bool 53 sh_target::low_supports_breakpoints () 54 { 55 return true; 56 } 57 58 CORE_ADDR 59 sh_target::low_get_pc (regcache *regcache) 60 { 61 return linux_get_pc_32bit (regcache); 62 } 63 64 void 65 sh_target::low_set_pc (regcache *regcache, CORE_ADDR pc) 66 { 67 linux_set_pc_32bit (regcache, pc); 68 } 69 70 /* Defined in auto-generated file reg-sh.c. */ 71 void init_registers_sh (void); 72 extern const struct target_desc *tdesc_sh; 73 74 #ifdef HAVE_SYS_REG_H 75 #include <sys/reg.h> 76 #endif 77 78 #include <asm/ptrace.h> 79 80 #define sh_num_regs 41 81 82 /* Currently, don't check/send MQ. */ 83 static int sh_regmap[] = { 84 0, 4, 8, 12, 16, 20, 24, 28, 85 32, 36, 40, 44, 48, 52, 56, 60, 86 87 REG_PC*4, REG_PR*4, REG_GBR*4, -1, 88 REG_MACH*4, REG_MACL*4, REG_SR*4, 89 REG_FPUL*4, REG_FPSCR*4, 90 91 REG_FPREG0*4+0, REG_FPREG0*4+4, REG_FPREG0*4+8, REG_FPREG0*4+12, 92 REG_FPREG0*4+16, REG_FPREG0*4+20, REG_FPREG0*4+24, REG_FPREG0*4+28, 93 REG_FPREG0*4+32, REG_FPREG0*4+36, REG_FPREG0*4+40, REG_FPREG0*4+44, 94 REG_FPREG0*4+48, REG_FPREG0*4+52, REG_FPREG0*4+56, REG_FPREG0*4+60, 95 }; 96 97 bool 98 sh_target::low_cannot_store_register (int regno) 99 { 100 return false; 101 } 102 103 bool 104 sh_target::low_cannot_fetch_register (int regno) 105 { 106 return false; 107 } 108 109 /* Correct in either endianness, obviously. */ 110 static const unsigned short sh_breakpoint = 0xc3c3; 111 #define sh_breakpoint_len 2 112 113 /* Implementation of target ops method "sw_breakpoint_from_kind". */ 114 115 const gdb_byte * 116 sh_target::sw_breakpoint_from_kind (int kind, int *size) 117 { 118 *size = sh_breakpoint_len; 119 return (const gdb_byte *) &sh_breakpoint; 120 } 121 122 bool 123 sh_target::low_breakpoint_at (CORE_ADDR where) 124 { 125 unsigned short insn; 126 127 read_memory (where, (unsigned char *) &insn, 2); 128 if (insn == sh_breakpoint) 129 return true; 130 131 /* If necessary, recognize more trap instructions here. GDB only uses the 132 one. */ 133 return false; 134 } 135 136 /* Provide only a fill function for the general register set. ps_lgetregs 137 will use this for NPTL support. */ 138 139 static void sh_fill_gregset (struct regcache *regcache, void *buf) 140 { 141 int i; 142 143 for (i = 0; i < 23; i++) 144 if (sh_regmap[i] != -1) 145 collect_register (regcache, i, (char *) buf + sh_regmap[i]); 146 } 147 148 static struct regset_info sh_regsets[] = { 149 { 0, 0, 0, 0, GENERAL_REGS, sh_fill_gregset, NULL }, 150 NULL_REGSET 151 }; 152 153 static struct regsets_info sh_regsets_info = 154 { 155 sh_regsets, /* regsets */ 156 0, /* num_regsets */ 157 NULL, /* disabled_regsets */ 158 }; 159 160 static struct usrregs_info sh_usrregs_info = 161 { 162 sh_num_regs, 163 sh_regmap, 164 }; 165 166 static struct regs_info myregs_info = 167 { 168 NULL, /* regset_bitmap */ 169 &sh_usrregs_info, 170 &sh_regsets_info 171 }; 172 173 const regs_info * 174 sh_target::get_regs_info () 175 { 176 return &myregs_info; 177 } 178 179 void 180 sh_target::low_arch_setup () 181 { 182 current_process ()->tdesc = tdesc_sh; 183 } 184 185 /* The linux target ops object. */ 186 187 linux_process_target *the_linux_target = &the_sh_target; 188 189 void 190 initialize_low_arch (void) 191 { 192 init_registers_sh (); 193 194 initialize_regsets_info (&sh_regsets_info); 195 } 196