Home | History | Annotate | Line # | Download | only in gdb
mips64-obsd-tdep.c revision 1.1.1.4
      1      1.1  christos /* Target-dependent code for OpenBSD/mips64.
      2      1.1  christos 
      3  1.1.1.4  christos    Copyright (C) 2004-2023 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 "defs.h"
     21      1.1  christos #include "gdbtypes.h"
     22      1.1  christos #include "osabi.h"
     23      1.1  christos #include "regcache.h"
     24      1.1  christos #include "regset.h"
     25      1.1  christos #include "trad-frame.h"
     26      1.1  christos #include "tramp-frame.h"
     27      1.1  christos 
     28      1.1  christos #include "obsd-tdep.h"
     29      1.1  christos #include "mips-tdep.h"
     30      1.1  christos #include "solib-svr4.h"
     31      1.1  christos 
     32      1.1  christos #define MIPS64OBSD_NUM_REGS 73
     33      1.1  christos 
     34      1.1  christos /* Core file support.  */
     35      1.1  christos 
     36      1.1  christos /* Supply register REGNUM from the buffer specified by GREGS and LEN
     37      1.1  christos    in the general-purpose register set REGSET to register cache
     38      1.1  christos    REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */
     39      1.1  christos 
     40      1.1  christos static void
     41      1.1  christos mips64obsd_supply_gregset (const struct regset *regset,
     42      1.1  christos 			   struct regcache *regcache, int regnum,
     43      1.1  christos 			   const void *gregs, size_t len)
     44      1.1  christos {
     45      1.1  christos   const char *regs = (const char *) gregs;
     46      1.1  christos   int i;
     47      1.1  christos 
     48      1.1  christos   for (i = 0; i < MIPS64OBSD_NUM_REGS; i++)
     49      1.1  christos     {
     50      1.1  christos       if (regnum == i || regnum == -1)
     51  1.1.1.2  christos 	regcache->raw_supply (i, regs + i * 8);
     52      1.1  christos     }
     53      1.1  christos }
     54      1.1  christos 
     55      1.1  christos /* OpenBSD/mips64 register set.  */
     56      1.1  christos 
     57      1.1  christos static const struct regset mips64obsd_gregset =
     58      1.1  christos {
     59      1.1  christos   NULL,
     60      1.1  christos   mips64obsd_supply_gregset
     61      1.1  christos };
     62      1.1  christos 
     63      1.1  christos /* Iterate over core file register note sections.  */
     64      1.1  christos 
     65      1.1  christos static void
     66      1.1  christos mips64obsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
     67      1.1  christos 					 iterate_over_regset_sections_cb *cb,
     68      1.1  christos 					 void *cb_data,
     69      1.1  christos 					 const struct regcache *regcache)
     70      1.1  christos {
     71  1.1.1.2  christos   cb (".reg", MIPS64OBSD_NUM_REGS * 8, MIPS64OBSD_NUM_REGS * 8,
     72  1.1.1.2  christos       &mips64obsd_gregset, NULL, cb_data);
     73      1.1  christos }
     74      1.1  christos 
     75      1.1  christos 
     77      1.1  christos /* Signal trampolines.  */
     78      1.1  christos 
     79      1.1  christos static void
     80  1.1.1.4  christos mips64obsd_sigframe_init (const struct tramp_frame *self,
     81      1.1  christos 			  frame_info_ptr this_frame,
     82      1.1  christos 			  struct trad_frame_cache *cache,
     83      1.1  christos 			  CORE_ADDR func)
     84      1.1  christos {
     85      1.1  christos   struct gdbarch *gdbarch = get_frame_arch (this_frame);
     86      1.1  christos   CORE_ADDR sp, sigcontext_addr, addr;
     87      1.1  christos   int regnum;
     88      1.1  christos 
     89      1.1  christos   /* We find the appropriate instance of `struct sigcontext' at a
     90      1.1  christos      fixed offset in the signal frame.  */
     91      1.1  christos   sp = get_frame_register_signed (this_frame,
     92      1.1  christos 				  MIPS_SP_REGNUM + gdbarch_num_regs (gdbarch));
     93      1.1  christos   sigcontext_addr = sp + 32;
     94      1.1  christos 
     95      1.1  christos   /* PC.  */
     96      1.1  christos   regnum = mips_regnum (gdbarch)->pc;
     97      1.1  christos   trad_frame_set_reg_addr (cache,
     98      1.1  christos 			   regnum + gdbarch_num_regs (gdbarch),
     99      1.1  christos 			    sigcontext_addr + 16);
    100      1.1  christos 
    101      1.1  christos   /* GPRs.  */
    102      1.1  christos   for (regnum = MIPS_AT_REGNUM, addr = sigcontext_addr + 32;
    103      1.1  christos        regnum <= MIPS_RA_REGNUM; regnum++, addr += 8)
    104      1.1  christos     trad_frame_set_reg_addr (cache,
    105      1.1  christos 			     regnum + gdbarch_num_regs (gdbarch),
    106      1.1  christos 			     addr);
    107      1.1  christos 
    108      1.1  christos   /* HI and LO.  */
    109      1.1  christos   regnum = mips_regnum (gdbarch)->lo;
    110      1.1  christos   trad_frame_set_reg_addr (cache,
    111      1.1  christos 			   regnum + gdbarch_num_regs (gdbarch),
    112      1.1  christos 			   sigcontext_addr + 280);
    113      1.1  christos   regnum = mips_regnum (gdbarch)->hi;
    114      1.1  christos   trad_frame_set_reg_addr (cache,
    115      1.1  christos 			   regnum + gdbarch_num_regs (gdbarch),
    116      1.1  christos 			   sigcontext_addr + 288);
    117      1.1  christos 
    118      1.1  christos   /* TODO: Handle the floating-point registers.  */
    119      1.1  christos 
    120      1.1  christos   trad_frame_set_id (cache, frame_id_build (sp, func));
    121      1.1  christos }
    122      1.1  christos 
    123      1.1  christos static const struct tramp_frame mips64obsd_sigframe =
    124      1.1  christos {
    125      1.1  christos   SIGTRAMP_FRAME,
    126      1.1  christos   MIPS_INSN32_SIZE,
    127  1.1.1.2  christos   {
    128  1.1.1.2  christos     { 0x67a40020, ULONGEST_MAX },		/* daddiu  a0,sp,32 */
    129  1.1.1.2  christos     { 0x24020067, ULONGEST_MAX },		/* li      v0,103 */
    130  1.1.1.2  christos     { 0x0000000c, ULONGEST_MAX },		/* syscall */
    131  1.1.1.2  christos     { 0x0000000d, ULONGEST_MAX },		/* break */
    132      1.1  christos     { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
    133      1.1  christos   },
    134      1.1  christos   mips64obsd_sigframe_init
    135      1.1  christos };
    136      1.1  christos 
    137      1.1  christos 
    138      1.1  christos static void
    140      1.1  christos mips64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
    141      1.1  christos {
    142      1.1  christos   /* OpenBSD/mips64 only supports the n64 ABI, but the braindamaged
    143      1.1  christos      way GDB works, forces us to pretend we can handle them all.  */
    144      1.1  christos 
    145      1.1  christos   set_gdbarch_iterate_over_regset_sections
    146      1.1  christos     (gdbarch, mips64obsd_iterate_over_regset_sections);
    147      1.1  christos 
    148      1.1  christos   tramp_frame_prepend_unwinder (gdbarch, &mips64obsd_sigframe);
    149  1.1.1.4  christos 
    150      1.1  christos   set_gdbarch_long_double_bit (gdbarch, 128);
    151      1.1  christos   set_gdbarch_long_double_format (gdbarch, floatformats_ieee_quad);
    152      1.1  christos 
    153      1.1  christos   obsd_init_abi(info, gdbarch);
    154      1.1  christos 
    155      1.1  christos   /* OpenBSD/mips64 has SVR4-style shared libraries.  */
    156      1.1  christos   set_solib_svr4_fetch_link_map_offsets
    157      1.1  christos     (gdbarch, svr4_lp64_fetch_link_map_offsets);
    158  1.1.1.3  christos }
    159      1.1  christos 
    160  1.1.1.3  christos void _initialize_mips64obsd_tdep ();
    161      1.1  christos void
    162      1.1  christos _initialize_mips64obsd_tdep ()
    163      1.1  christos {
    164      1.1  christos   gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_OPENBSD,
    165                    			  mips64obsd_init_abi);
    166                    }
    167