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