GDB (API)
/home/stan/gdb/src/gdb/sparc64nbsd-tdep.c
Go to the documentation of this file.
00001 /* Target-dependent code for NetBSD/sparc64.
00002 
00003    Copyright (C) 2002-2013 Free Software Foundation, Inc.
00004    Based on code contributed by Wasabi Systems, Inc.
00005 
00006    This file is part of GDB.
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 3 of the License, or
00011    (at your option) any later version.
00012 
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00020 
00021 #include "defs.h"
00022 #include "frame.h"
00023 #include "frame-unwind.h"
00024 #include "gdbcore.h"
00025 #include "osabi.h"
00026 #include "regcache.h"
00027 #include "regset.h"
00028 #include "symtab.h"
00029 #include "objfiles.h"
00030 #include "solib-svr4.h"
00031 #include "trad-frame.h"
00032 
00033 #include "gdb_assert.h"
00034 #include "gdb_string.h"
00035 
00036 #include "sparc64-tdep.h"
00037 #include "nbsd-tdep.h"
00038 
00039 /* From <machine/reg.h>.  */
00040 const struct sparc_gregset sparc64nbsd_gregset =
00041 {
00042   0 * 8,                        /* "tstate" */
00043   1 * 8,                        /* %pc */
00044   2 * 8,                        /* %npc */
00045   3 * 8,                        /* %y */
00046   -1,                           /* %fprs */
00047   -1,
00048   5 * 8,                        /* %g1 */
00049   -1,                           /* %l0 */
00050   4                             /* sizeof (%y) */
00051 };
00052 
00053 
00054 static void
00055 sparc64nbsd_supply_gregset (const struct regset *regset,
00056                             struct regcache *regcache,
00057                             int regnum, const void *gregs, size_t len)
00058 {
00059   sparc64_supply_gregset (&sparc64nbsd_gregset, regcache, regnum, gregs);
00060 }
00061 
00062 static void
00063 sparc64nbsd_supply_fpregset (const struct regset *regset,
00064                              struct regcache *regcache,
00065                              int regnum, const void *fpregs, size_t len)
00066 {
00067   sparc64_supply_fpregset (&sparc64_bsd_fpregset, regcache, regnum, fpregs);
00068 }
00069 
00070 
00071 /* Signal trampolines.  */
00072 
00073 /* The following variables describe the location of an on-stack signal
00074    trampoline.  The current values correspond to the memory layout for
00075    NetBSD 1.3 and up.  These shouldn't be necessary for NetBSD 2.0 and
00076    up, since NetBSD uses signal trampolines provided by libc now.  */
00077 
00078 static const CORE_ADDR sparc64nbsd_sigtramp_start = 0xffffffffffffdee4ULL;
00079 static const CORE_ADDR sparc64nbsd_sigtramp_end = 0xffffffffffffe000ULL;
00080 
00081 static int
00082 sparc64nbsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
00083 {
00084   if (pc >= sparc64nbsd_sigtramp_start && pc < sparc64nbsd_sigtramp_end)
00085     return 1;
00086 
00087   return nbsd_pc_in_sigtramp (pc, name);
00088 }
00089 
00090 struct trad_frame_saved_reg *
00091 sparc64nbsd_sigcontext_saved_regs (CORE_ADDR sigcontext_addr,
00092                                    struct frame_info *this_frame)
00093 {
00094   struct gdbarch *gdbarch = get_frame_arch (this_frame);
00095   struct trad_frame_saved_reg *saved_regs;
00096   CORE_ADDR addr, sp;
00097   int regnum, delta;
00098 
00099   saved_regs = trad_frame_alloc_saved_regs (this_frame);
00100 
00101   /* The registers are saved in bits and pieces scattered all over the
00102      place.  The code below records their location on the assumption
00103      that the part of the signal trampoline that saves the state has
00104      been executed.  */
00105 
00106   saved_regs[SPARC_SP_REGNUM].addr = sigcontext_addr + 8;
00107   saved_regs[SPARC64_PC_REGNUM].addr = sigcontext_addr + 16;
00108   saved_regs[SPARC64_NPC_REGNUM].addr = sigcontext_addr + 24;
00109   saved_regs[SPARC64_STATE_REGNUM].addr = sigcontext_addr + 32;
00110   saved_regs[SPARC_G1_REGNUM].addr = sigcontext_addr + 40;
00111   saved_regs[SPARC_O0_REGNUM].addr = sigcontext_addr + 48;
00112 
00113   /* The remaining `global' registers and %y are saved in the `local'
00114      registers.  */
00115   delta = SPARC_L0_REGNUM - SPARC_G0_REGNUM;
00116   for (regnum = SPARC_G2_REGNUM; regnum <= SPARC_G7_REGNUM; regnum++)
00117     saved_regs[regnum].realreg = regnum + delta;
00118   saved_regs[SPARC64_Y_REGNUM].realreg = SPARC_L1_REGNUM;
00119 
00120   /* The remaining `out' registers can be found in the current frame's
00121      `in' registers.  */
00122   delta = SPARC_I0_REGNUM - SPARC_O0_REGNUM;
00123   for (regnum = SPARC_O1_REGNUM; regnum <= SPARC_O5_REGNUM; regnum++)
00124     saved_regs[regnum].realreg = regnum + delta;
00125   saved_regs[SPARC_O7_REGNUM].realreg = SPARC_I7_REGNUM;
00126 
00127   /* The `local' and `in' registers have been saved in the register
00128      save area.  */
00129   addr = saved_regs[SPARC_SP_REGNUM].addr;
00130   sp = get_frame_memory_unsigned (this_frame, addr, 8);
00131   for (regnum = SPARC_L0_REGNUM, addr = sp + BIAS;
00132        regnum <= SPARC_I7_REGNUM; regnum++, addr += 8)
00133     saved_regs[regnum].addr = addr;
00134 
00135   /* Handle StackGhost.  */
00136   {
00137     ULONGEST wcookie = sparc_fetch_wcookie (gdbarch);
00138 
00139     if (wcookie != 0)
00140       {
00141         ULONGEST i7;
00142 
00143         addr = saved_regs[SPARC_I7_REGNUM].addr;
00144         i7 = get_frame_memory_unsigned (this_frame, addr, 8);
00145         trad_frame_set_value (saved_regs, SPARC_I7_REGNUM, i7 ^ wcookie);
00146       }
00147   }
00148 
00149   /* TODO: Handle the floating-point registers.  */
00150 
00151   return saved_regs;
00152 }
00153 
00154 static struct sparc_frame_cache *
00155 sparc64nbsd_sigcontext_frame_cache (struct frame_info *this_frame,
00156                                     void **this_cache)
00157 {
00158   struct sparc_frame_cache *cache;
00159   CORE_ADDR addr;
00160 
00161   if (*this_cache)
00162     return *this_cache;
00163 
00164   cache = sparc_frame_cache (this_frame, this_cache);
00165   gdb_assert (cache == *this_cache);
00166 
00167   /* If we couldn't find the frame's function, we're probably dealing
00168      with an on-stack signal trampoline.  */
00169   if (cache->pc == 0)
00170     {
00171       cache->pc = sparc64nbsd_sigtramp_start;
00172 
00173       /* Since we couldn't find the frame's function, the cache was
00174          initialized under the assumption that we're frameless.  */
00175       sparc_record_save_insn (cache);
00176       addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
00177       if (addr & 1)
00178         addr += BIAS;
00179       cache->base = addr;
00180     }
00181 
00182   /* We find the appropriate instance of `struct sigcontext' at a
00183      fixed offset in the signal frame.  */
00184   addr = cache->base + 128 + 8;
00185   cache->saved_regs = sparc64nbsd_sigcontext_saved_regs (addr, this_frame);
00186 
00187   return cache;
00188 }
00189 
00190 static void
00191 sparc64nbsd_sigcontext_frame_this_id (struct frame_info *this_frame,
00192                                       void **this_cache,
00193                                       struct frame_id *this_id)
00194 {
00195   struct sparc_frame_cache *cache =
00196     sparc64nbsd_sigcontext_frame_cache (this_frame, this_cache);
00197 
00198   (*this_id) = frame_id_build (cache->base, cache->pc);
00199 }
00200 
00201 static struct value *
00202 sparc64nbsd_sigcontext_frame_prev_register (struct frame_info *this_frame,
00203                                             void **this_cache, int regnum)
00204 {
00205   struct sparc_frame_cache *cache =
00206     sparc64nbsd_sigcontext_frame_cache (this_frame, this_cache);
00207 
00208   return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
00209 }
00210 
00211 static int
00212 sparc64nbsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
00213                                     struct frame_info *this_frame,
00214                                     void **this_cache)
00215 {
00216   CORE_ADDR pc = get_frame_pc (this_frame);
00217   const char *name;
00218 
00219   find_pc_partial_function (pc, &name, NULL, NULL);
00220   if (sparc64nbsd_pc_in_sigtramp (pc, name))
00221     {
00222       if (name == NULL || strncmp (name, "__sigtramp_sigcontext", 21))
00223         return 1;
00224     }
00225 
00226   return 0;
00227 }
00228 
00229 static const struct frame_unwind sparc64nbsd_sigcontext_frame_unwind =
00230 {
00231   SIGTRAMP_FRAME,
00232   default_frame_unwind_stop_reason,
00233   sparc64nbsd_sigcontext_frame_this_id,
00234   sparc64nbsd_sigcontext_frame_prev_register,
00235   NULL,
00236   sparc64nbsd_sigtramp_frame_sniffer
00237 };
00238 
00239 
00240 static void
00241 sparc64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
00242 {
00243   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
00244 
00245   tdep->gregset = regset_alloc (gdbarch, sparc64nbsd_supply_gregset, NULL);
00246   tdep->sizeof_gregset = 160;
00247 
00248   tdep->fpregset = regset_alloc (gdbarch, sparc64nbsd_supply_fpregset, NULL);
00249   tdep->sizeof_fpregset = 272;
00250 
00251   /* Make sure we can single-step "new" syscalls.  */
00252   tdep->step_trap = sparcnbsd_step_trap;
00253 
00254   frame_unwind_append_unwinder (gdbarch, &sparc64nbsd_sigcontext_frame_unwind);
00255 
00256   sparc64_init_abi (info, gdbarch);
00257 
00258   /* NetBSD/sparc64 has SVR4-style shared libraries.  */
00259   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
00260   set_solib_svr4_fetch_link_map_offsets
00261     (gdbarch, svr4_lp64_fetch_link_map_offsets);
00262 }
00263 
00264 
00265 /* Provide a prototype to silence -Wmissing-prototypes.  */
00266 void _initialize_sparc64nbsd_tdep (void);
00267 
00268 void
00269 _initialize_sparc64nbsd_tdep (void)
00270 {
00271   gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
00272                           GDB_OSABI_NETBSD_ELF, sparc64nbsd_init_abi);
00273 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines