Home | History | Annotate | Line # | Download | only in gdb
      1      1.1  christos /* Target-dependent code for OpenBSD/mips64.
      2      1.1  christos 
      3  1.1.1.5  christos    Copyright (C) 2004-2024 Free Software Foundation, Inc.
      4      1.1  christos 
      5      1.1  christos    This file is part of GDB.
      6      1.1  christos 
      7      1.1  christos    This program is free software; you can redistribute it and/or modify
      8      1.1  christos    it under the terms of the GNU General Public License as published by
      9      1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10      1.1  christos    (at your option) any later version.
     11      1.1  christos 
     12      1.1  christos    This program is distributed in the hope that it will be useful,
     13      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15      1.1  christos    GNU General Public License for more details.
     16      1.1  christos 
     17      1.1  christos    You should have received a copy of the GNU General Public License
     18      1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19      1.1  christos 
     20      1.1  christos #include "gdbtypes.h"
     21      1.1  christos #include "osabi.h"
     22      1.1  christos #include "regcache.h"
     23      1.1  christos #include "regset.h"
     24      1.1  christos #include "trad-frame.h"
     25      1.1  christos #include "tramp-frame.h"
     26      1.1  christos 
     27      1.1  christos #include "obsd-tdep.h"
     28      1.1  christos #include "mips-tdep.h"
     29      1.1  christos #include "solib-svr4.h"
     30      1.1  christos 
     31      1.1  christos #define MIPS64OBSD_NUM_REGS 73
     32      1.1  christos 
     33      1.1  christos /* Core file support.  */
     34      1.1  christos 
     35      1.1  christos /* Supply register REGNUM from the buffer specified by GREGS and LEN
     36      1.1  christos    in the general-purpose register set REGSET to register cache
     37      1.1  christos    REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */
     38      1.1  christos 
     39      1.1  christos static void
     40      1.1  christos mips64obsd_supply_gregset (const struct regset *regset,
     41      1.1  christos 			   struct regcache *regcache, int regnum,
     42      1.1  christos 			   const void *gregs, size_t len)
     43      1.1  christos {
     44      1.1  christos   const char *regs = (const char *) gregs;
     45      1.1  christos   int i;
     46      1.1  christos 
     47      1.1  christos   for (i = 0; i < MIPS64OBSD_NUM_REGS; i++)
     48      1.1  christos     {
     49      1.1  christos       if (regnum == i || regnum == -1)
     50  1.1.1.2  christos 	regcache->raw_supply (i, regs + i * 8);
     51      1.1  christos     }
     52      1.1  christos }
     53      1.1  christos 
     54      1.1  christos /* OpenBSD/mips64 register set.  */
     55      1.1  christos 
     56      1.1  christos static const struct regset mips64obsd_gregset =
     57      1.1  christos {
     58      1.1  christos   NULL,
     59      1.1  christos   mips64obsd_supply_gregset
     60      1.1  christos };
     61      1.1  christos 
     62      1.1  christos /* Iterate over core file register note sections.  */
     63      1.1  christos 
     64      1.1  christos static void
     65      1.1  christos mips64obsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
     66      1.1  christos 					 iterate_over_regset_sections_cb *cb,
     67      1.1  christos 					 void *cb_data,
     68      1.1  christos 					 const struct regcache *regcache)
     69      1.1  christos {
     70  1.1.1.2  christos   cb (".reg", MIPS64OBSD_NUM_REGS * 8, MIPS64OBSD_NUM_REGS * 8,
     71  1.1.1.2  christos       &mips64obsd_gregset, NULL, cb_data);
     72      1.1  christos }
     73      1.1  christos 
     74      1.1  christos 
     76      1.1  christos /* Signal trampolines.  */
     77      1.1  christos 
     78      1.1  christos static void
     79  1.1.1.5  christos mips64obsd_sigframe_init (const struct tramp_frame *self,
     80      1.1  christos 			  const frame_info_ptr &this_frame,
     81      1.1  christos 			  struct trad_frame_cache *cache,
     82      1.1  christos 			  CORE_ADDR func)
     83      1.1  christos {
     84      1.1  christos   struct gdbarch *gdbarch = get_frame_arch (this_frame);
     85      1.1  christos   CORE_ADDR sp, sigcontext_addr, addr;
     86      1.1  christos   int regnum;
     87      1.1  christos 
     88      1.1  christos   /* We find the appropriate instance of `struct sigcontext' at a
     89      1.1  christos      fixed offset in the signal frame.  */
     90      1.1  christos   sp = get_frame_register_signed (this_frame,
     91      1.1  christos 				  MIPS_SP_REGNUM + gdbarch_num_regs (gdbarch));
     92      1.1  christos   sigcontext_addr = sp + 32;
     93      1.1  christos 
     94      1.1  christos   /* PC.  */
     95      1.1  christos   regnum = mips_regnum (gdbarch)->pc;
     96      1.1  christos   trad_frame_set_reg_addr (cache,
     97      1.1  christos 			   regnum + gdbarch_num_regs (gdbarch),
     98      1.1  christos 			    sigcontext_addr + 16);
     99      1.1  christos 
    100      1.1  christos   /* GPRs.  */
    101      1.1  christos   for (regnum = MIPS_AT_REGNUM, addr = sigcontext_addr + 32;
    102      1.1  christos        regnum <= MIPS_RA_REGNUM; regnum++, addr += 8)
    103      1.1  christos     trad_frame_set_reg_addr (cache,
    104      1.1  christos 			     regnum + gdbarch_num_regs (gdbarch),
    105      1.1  christos 			     addr);
    106      1.1  christos 
    107      1.1  christos   /* HI and LO.  */
    108      1.1  christos   regnum = mips_regnum (gdbarch)->lo;
    109      1.1  christos   trad_frame_set_reg_addr (cache,
    110      1.1  christos 			   regnum + gdbarch_num_regs (gdbarch),
    111      1.1  christos 			   sigcontext_addr + 280);
    112      1.1  christos   regnum = mips_regnum (gdbarch)->hi;
    113      1.1  christos   trad_frame_set_reg_addr (cache,
    114      1.1  christos 			   regnum + gdbarch_num_regs (gdbarch),
    115      1.1  christos 			   sigcontext_addr + 288);
    116      1.1  christos 
    117      1.1  christos   /* TODO: Handle the floating-point registers.  */
    118      1.1  christos 
    119      1.1  christos   trad_frame_set_id (cache, frame_id_build (sp, func));
    120      1.1  christos }
    121      1.1  christos 
    122      1.1  christos static const struct tramp_frame mips64obsd_sigframe =
    123      1.1  christos {
    124      1.1  christos   SIGTRAMP_FRAME,
    125      1.1  christos   MIPS_INSN32_SIZE,
    126  1.1.1.2  christos   {
    127  1.1.1.2  christos     { 0x67a40020, ULONGEST_MAX },		/* daddiu  a0,sp,32 */
    128  1.1.1.2  christos     { 0x24020067, ULONGEST_MAX },		/* li      v0,103 */
    129  1.1.1.2  christos     { 0x0000000c, ULONGEST_MAX },		/* syscall */
    130  1.1.1.2  christos     { 0x0000000d, ULONGEST_MAX },		/* break */
    131      1.1  christos     { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
    132      1.1  christos   },
    133      1.1  christos   mips64obsd_sigframe_init
    134      1.1  christos };
    135      1.1  christos 
    136      1.1  christos 
    137      1.1  christos static void
    139      1.1  christos mips64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
    140      1.1  christos {
    141      1.1  christos   /* OpenBSD/mips64 only supports the n64 ABI, but the braindamaged
    142      1.1  christos      way GDB works, forces us to pretend we can handle them all.  */
    143      1.1  christos 
    144      1.1  christos   set_gdbarch_iterate_over_regset_sections
    145      1.1  christos     (gdbarch, mips64obsd_iterate_over_regset_sections);
    146      1.1  christos 
    147      1.1  christos   tramp_frame_prepend_unwinder (gdbarch, &mips64obsd_sigframe);
    148  1.1.1.4  christos 
    149      1.1  christos   set_gdbarch_long_double_bit (gdbarch, 128);
    150      1.1  christos   set_gdbarch_long_double_format (gdbarch, floatformats_ieee_quad);
    151      1.1  christos 
    152      1.1  christos   obsd_init_abi(info, gdbarch);
    153      1.1  christos 
    154      1.1  christos   /* OpenBSD/mips64 has SVR4-style shared libraries.  */
    155      1.1  christos   set_solib_svr4_fetch_link_map_offsets
    156      1.1  christos     (gdbarch, svr4_lp64_fetch_link_map_offsets);
    157  1.1.1.3  christos }
    158      1.1  christos 
    159  1.1.1.3  christos void _initialize_mips64obsd_tdep ();
    160      1.1  christos void
    161      1.1  christos _initialize_mips64obsd_tdep ()
    162      1.1  christos {
    163      1.1  christos   gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_OPENBSD,
    164                    			  mips64obsd_init_abi);
    165                    }
    166