xref: /netbsd-src/external/gpl3/gdb/dist/gdbserver/linux-sh-low.cc (revision 13ed34fa5696ce1ff8e9519eeb5619eee4331db8)
18dffb485Schristos /* GNU/Linux/SH specific low level interface, for the remote server for GDB.
2*13ed34faSchristos    Copyright (C) 1995-2024 Free Software Foundation, Inc.
38dffb485Schristos 
48dffb485Schristos    This file is part of GDB.
58dffb485Schristos 
68dffb485Schristos    This program is free software; you can redistribute it and/or modify
78dffb485Schristos    it under the terms of the GNU General Public License as published by
88dffb485Schristos    the Free Software Foundation; either version 3 of the License, or
98dffb485Schristos    (at your option) any later version.
108dffb485Schristos 
118dffb485Schristos    This program is distributed in the hope that it will be useful,
128dffb485Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
138dffb485Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
148dffb485Schristos    GNU General Public License for more details.
158dffb485Schristos 
168dffb485Schristos    You should have received a copy of the GNU General Public License
178dffb485Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
188dffb485Schristos 
198dffb485Schristos #include "linux-low.h"
208dffb485Schristos 
218dffb485Schristos /* Linux target op definitions for the SH architecture.  */
228dffb485Schristos 
238dffb485Schristos class sh_target : public linux_process_target
248dffb485Schristos {
258dffb485Schristos public:
268dffb485Schristos 
278dffb485Schristos   const regs_info *get_regs_info () override;
288dffb485Schristos 
298dffb485Schristos   const gdb_byte *sw_breakpoint_from_kind (int kind, int *size) override;
308dffb485Schristos 
318dffb485Schristos protected:
328dffb485Schristos 
338dffb485Schristos   void low_arch_setup () override;
348dffb485Schristos 
358dffb485Schristos   bool low_cannot_fetch_register (int regno) override;
368dffb485Schristos 
378dffb485Schristos   bool low_cannot_store_register (int regno) override;
388dffb485Schristos 
398dffb485Schristos   bool low_supports_breakpoints () override;
408dffb485Schristos 
418dffb485Schristos   CORE_ADDR low_get_pc (regcache *regcache) override;
428dffb485Schristos 
438dffb485Schristos   void low_set_pc (regcache *regcache, CORE_ADDR newpc) override;
448dffb485Schristos 
458dffb485Schristos   bool low_breakpoint_at (CORE_ADDR pc) override;
468dffb485Schristos };
478dffb485Schristos 
488dffb485Schristos /* The singleton target ops object.  */
498dffb485Schristos 
508dffb485Schristos static sh_target the_sh_target;
518dffb485Schristos 
528dffb485Schristos bool
538dffb485Schristos sh_target::low_supports_breakpoints ()
548dffb485Schristos {
558dffb485Schristos   return true;
568dffb485Schristos }
578dffb485Schristos 
588dffb485Schristos CORE_ADDR
598dffb485Schristos sh_target::low_get_pc (regcache *regcache)
608dffb485Schristos {
618dffb485Schristos   return linux_get_pc_32bit (regcache);
628dffb485Schristos }
638dffb485Schristos 
648dffb485Schristos void
658dffb485Schristos sh_target::low_set_pc (regcache *regcache, CORE_ADDR pc)
668dffb485Schristos {
678dffb485Schristos   linux_set_pc_32bit (regcache, pc);
688dffb485Schristos }
698dffb485Schristos 
708dffb485Schristos /* Defined in auto-generated file reg-sh.c.  */
718dffb485Schristos void init_registers_sh (void);
728dffb485Schristos extern const struct target_desc *tdesc_sh;
738dffb485Schristos 
748dffb485Schristos #ifdef HAVE_SYS_REG_H
758dffb485Schristos #include <sys/reg.h>
768dffb485Schristos #endif
778dffb485Schristos 
788dffb485Schristos #include <asm/ptrace.h>
798dffb485Schristos 
808dffb485Schristos #define sh_num_regs 41
818dffb485Schristos 
828dffb485Schristos /* Currently, don't check/send MQ.  */
838dffb485Schristos static int sh_regmap[] = {
848dffb485Schristos  0,	4,	8,	12,	16,	20,	24,	28,
858dffb485Schristos  32,	36,	40,	44,	48,	52,	56,	60,
868dffb485Schristos 
878dffb485Schristos  REG_PC*4,   REG_PR*4,   REG_GBR*4,  -1,
888dffb485Schristos  REG_MACH*4, REG_MACL*4, REG_SR*4,
898dffb485Schristos  REG_FPUL*4, REG_FPSCR*4,
908dffb485Schristos 
918dffb485Schristos  REG_FPREG0*4+0,   REG_FPREG0*4+4,   REG_FPREG0*4+8,   REG_FPREG0*4+12,
928dffb485Schristos  REG_FPREG0*4+16,  REG_FPREG0*4+20,  REG_FPREG0*4+24,  REG_FPREG0*4+28,
938dffb485Schristos  REG_FPREG0*4+32,  REG_FPREG0*4+36,  REG_FPREG0*4+40,  REG_FPREG0*4+44,
948dffb485Schristos  REG_FPREG0*4+48,  REG_FPREG0*4+52,  REG_FPREG0*4+56,  REG_FPREG0*4+60,
958dffb485Schristos };
968dffb485Schristos 
978dffb485Schristos bool
988dffb485Schristos sh_target::low_cannot_store_register (int regno)
998dffb485Schristos {
1008dffb485Schristos   return false;
1018dffb485Schristos }
1028dffb485Schristos 
1038dffb485Schristos bool
1048dffb485Schristos sh_target::low_cannot_fetch_register (int regno)
1058dffb485Schristos {
1068dffb485Schristos   return false;
1078dffb485Schristos }
1088dffb485Schristos 
1098dffb485Schristos /* Correct in either endianness, obviously.  */
1108dffb485Schristos static const unsigned short sh_breakpoint = 0xc3c3;
1118dffb485Schristos #define sh_breakpoint_len 2
1128dffb485Schristos 
1138dffb485Schristos /* Implementation of target ops method "sw_breakpoint_from_kind".  */
1148dffb485Schristos 
1158dffb485Schristos const gdb_byte *
1168dffb485Schristos sh_target::sw_breakpoint_from_kind (int kind, int *size)
1178dffb485Schristos {
1188dffb485Schristos   *size = sh_breakpoint_len;
1198dffb485Schristos   return (const gdb_byte *) &sh_breakpoint;
1208dffb485Schristos }
1218dffb485Schristos 
1228dffb485Schristos bool
1238dffb485Schristos sh_target::low_breakpoint_at (CORE_ADDR where)
1248dffb485Schristos {
1258dffb485Schristos   unsigned short insn;
1268dffb485Schristos 
1278dffb485Schristos   read_memory (where, (unsigned char *) &insn, 2);
1288dffb485Schristos   if (insn == sh_breakpoint)
1298dffb485Schristos     return true;
1308dffb485Schristos 
1318dffb485Schristos   /* If necessary, recognize more trap instructions here.  GDB only uses the
1328dffb485Schristos      one.  */
1338dffb485Schristos   return false;
1348dffb485Schristos }
1358dffb485Schristos 
1368dffb485Schristos /* Provide only a fill function for the general register set.  ps_lgetregs
1378dffb485Schristos    will use this for NPTL support.  */
1388dffb485Schristos 
1398dffb485Schristos static void sh_fill_gregset (struct regcache *regcache, void *buf)
1408dffb485Schristos {
1418dffb485Schristos   int i;
1428dffb485Schristos 
1438dffb485Schristos   for (i = 0; i < 23; i++)
1448dffb485Schristos     if (sh_regmap[i] != -1)
1458dffb485Schristos       collect_register (regcache, i, (char *) buf + sh_regmap[i]);
1468dffb485Schristos }
1478dffb485Schristos 
1488dffb485Schristos static struct regset_info sh_regsets[] = {
1498dffb485Schristos   { 0, 0, 0, 0, GENERAL_REGS, sh_fill_gregset, NULL },
1508dffb485Schristos   NULL_REGSET
1518dffb485Schristos };
1528dffb485Schristos 
1538dffb485Schristos static struct regsets_info sh_regsets_info =
1548dffb485Schristos   {
1558dffb485Schristos     sh_regsets, /* regsets */
1568dffb485Schristos     0, /* num_regsets */
1578dffb485Schristos     NULL, /* disabled_regsets */
1588dffb485Schristos   };
1598dffb485Schristos 
1608dffb485Schristos static struct usrregs_info sh_usrregs_info =
1618dffb485Schristos   {
1628dffb485Schristos     sh_num_regs,
1638dffb485Schristos     sh_regmap,
1648dffb485Schristos   };
1658dffb485Schristos 
1668dffb485Schristos static struct regs_info myregs_info =
1678dffb485Schristos   {
1688dffb485Schristos     NULL, /* regset_bitmap */
1698dffb485Schristos     &sh_usrregs_info,
1708dffb485Schristos     &sh_regsets_info
1718dffb485Schristos   };
1728dffb485Schristos 
1738dffb485Schristos const regs_info *
1748dffb485Schristos sh_target::get_regs_info ()
1758dffb485Schristos {
1768dffb485Schristos   return &myregs_info;
1778dffb485Schristos }
1788dffb485Schristos 
1798dffb485Schristos void
1808dffb485Schristos sh_target::low_arch_setup ()
1818dffb485Schristos {
1828dffb485Schristos   current_process ()->tdesc = tdesc_sh;
1838dffb485Schristos }
1848dffb485Schristos 
1858dffb485Schristos /* The linux target ops object.  */
1868dffb485Schristos 
1878dffb485Schristos linux_process_target *the_linux_target = &the_sh_target;
1888dffb485Schristos 
1898dffb485Schristos void
1908dffb485Schristos initialize_low_arch (void)
1918dffb485Schristos {
1928dffb485Schristos   init_registers_sh ();
1938dffb485Schristos 
1948dffb485Schristos   initialize_regsets_info (&sh_regsets_info);
1958dffb485Schristos }
196