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