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