GDB (API)
/home/stan/gdb/src/gdb/mips64obsd-tdep.c
Go to the documentation of this file.
00001 /* Target-dependent code for OpenBSD/mips64.
00002 
00003    Copyright (C) 2004-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #include "defs.h"
00021 #include "gdbtypes.h"
00022 #include "osabi.h"
00023 #include "regcache.h"
00024 #include "regset.h"
00025 #include "trad-frame.h"
00026 #include "tramp-frame.h"
00027 
00028 #include "gdb_assert.h"
00029 #include "gdb_string.h"
00030 
00031 #include "mips-tdep.h"
00032 #include "solib-svr4.h"
00033 
00034 /* The MIPS64 Floating-Point Quad-Precision format is similar to
00035    big-endian IA-64 Quad-Precision format.  */
00036 #define floatformats_mips64_quad floatformats_ia64_quad
00037 
00038 #define MIPS64OBSD_NUM_REGS 73
00039 
00040 /* Core file support.  */
00041 
00042 /* Supply register REGNUM from the buffer specified by GREGS and LEN
00043    in the general-purpose register set REGSET to register cache
00044    REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */
00045 
00046 static void
00047 mips64obsd_supply_gregset (const struct regset *regset,
00048                            struct regcache *regcache, int regnum,
00049                            const void *gregs, size_t len)
00050 {
00051   const char *regs = gregs;
00052   int i;
00053 
00054   for (i = 0; i < MIPS64OBSD_NUM_REGS; i++)
00055     {
00056       if (regnum == i || regnum == -1)
00057         regcache_raw_supply (regcache, i, regs + i * 8);
00058     }
00059 }
00060 
00061 /* OpenBSD/mips64 register set.  */
00062 
00063 static struct regset mips64obsd_gregset =
00064 {
00065   NULL,
00066   mips64obsd_supply_gregset
00067 };
00068 
00069 /* Return the appropriate register set for the core section identified
00070    by SECT_NAME and SECT_SIZE.  */
00071 
00072 static const struct regset *
00073 mips64obsd_regset_from_core_section (struct gdbarch *gdbarch,
00074                                      const char *sect_name, size_t sect_size)
00075 {
00076   if (strcmp (sect_name, ".reg") == 0 && sect_size >= MIPS64OBSD_NUM_REGS * 8)
00077     return &mips64obsd_gregset;
00078 
00079   return NULL;
00080 }
00081 
00082 
00083 /* Signal trampolines.  */
00084 
00085 static void
00086 mips64obsd_sigframe_init (const struct tramp_frame *self,
00087                           struct frame_info *this_frame,
00088                           struct trad_frame_cache *cache,
00089                           CORE_ADDR func)
00090 {
00091   struct gdbarch *gdbarch = get_frame_arch (this_frame);
00092   CORE_ADDR sp, sigcontext_addr, addr;
00093   int regnum;
00094 
00095   /* We find the appropriate instance of `struct sigcontext' at a
00096      fixed offset in the signal frame.  */
00097   sp = get_frame_register_signed (this_frame,
00098                                   MIPS_SP_REGNUM + gdbarch_num_regs (gdbarch));
00099   sigcontext_addr = sp + 32;
00100 
00101   /* PC.  */
00102   regnum = mips_regnum (gdbarch)->pc;
00103   trad_frame_set_reg_addr (cache,
00104                            regnum + gdbarch_num_regs (gdbarch),
00105                             sigcontext_addr + 16);
00106 
00107   /* GPRs.  */
00108   for (regnum = MIPS_AT_REGNUM, addr = sigcontext_addr + 32;
00109        regnum <= MIPS_RA_REGNUM; regnum++, addr += 8)
00110     trad_frame_set_reg_addr (cache,
00111                              regnum + gdbarch_num_regs (gdbarch),
00112                              addr);
00113 
00114   /* HI and LO.  */
00115   regnum = mips_regnum (gdbarch)->lo;
00116   trad_frame_set_reg_addr (cache,
00117                            regnum + gdbarch_num_regs (gdbarch),
00118                            sigcontext_addr + 280);
00119   regnum = mips_regnum (gdbarch)->hi;
00120   trad_frame_set_reg_addr (cache,
00121                            regnum + gdbarch_num_regs (gdbarch),
00122                            sigcontext_addr + 288);
00123 
00124   /* TODO: Handle the floating-point registers.  */
00125 
00126   trad_frame_set_id (cache, frame_id_build (sp, func));
00127 }
00128 
00129 static const struct tramp_frame mips64obsd_sigframe =
00130 {
00131   SIGTRAMP_FRAME,
00132   MIPS_INSN32_SIZE,
00133   {
00134     { 0x67a40020, -1 },         /* daddiu  a0,sp,32 */
00135     { 0x24020067, -1 },         /* li      v0,103 */
00136     { 0x0000000c, -1 },         /* syscall */
00137     { 0x0000000d, -1 },         /* break */
00138     { TRAMP_SENTINEL_INSN, -1 }
00139   },
00140   mips64obsd_sigframe_init
00141 };
00142 
00143 
00144 static void
00145 mips64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
00146 {
00147   /* OpenBSD/mips64 only supports the n64 ABI, but the braindamaged
00148      way GDB works, forces us to pretend we can handle them all.  */
00149 
00150   set_gdbarch_regset_from_core_section
00151     (gdbarch, mips64obsd_regset_from_core_section);
00152 
00153   tramp_frame_prepend_unwinder (gdbarch, &mips64obsd_sigframe);
00154 
00155   set_gdbarch_long_double_bit (gdbarch, 128);
00156   set_gdbarch_long_double_format (gdbarch, floatformats_mips64_quad);
00157 
00158   /* OpenBSD/mips64 has SVR4-style shared libraries.  */
00159   set_solib_svr4_fetch_link_map_offsets
00160     (gdbarch, svr4_lp64_fetch_link_map_offsets);
00161 }
00162 
00163 
00164 /* Provide a prototype to silence -Wmissing-prototypes.  */
00165 void _initialize_mips64obsd_tdep (void);
00166 
00167 void
00168 _initialize_mips64obsd_tdep (void)
00169 {
00170   gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_OPENBSD_ELF,
00171                           mips64obsd_init_abi);
00172 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines