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