GDB (API)
/home/stan/gdb/src/gdb/sparcnbsd-tdep.c
Go to the documentation of this file.
00001 /* Target-dependent code for NetBSD/sparc.
00002 
00003    Copyright (C) 2002-2013 Free Software Foundation, Inc.
00004    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 "gdbtypes.h"
00026 #include "osabi.h"
00027 #include "regcache.h"
00028 #include "regset.h"
00029 #include "solib-svr4.h"
00030 #include "symtab.h"
00031 #include "trad-frame.h"
00032 
00033 #include "gdb_assert.h"
00034 #include "gdb_string.h"
00035 
00036 #include "sparc-tdep.h"
00037 #include "nbsd-tdep.h"
00038 
00039 /* Macros to extract fields from SPARC instructions.  */
00040 #define X_RS1(i) (((i) >> 14) & 0x1f)
00041 #define X_RS2(i) ((i) & 0x1f)
00042 #define X_I(i) (((i) >> 13) & 1)
00043 
00044 const struct sparc_gregset sparc32nbsd_gregset =
00045 {
00046   0 * 4,                        /* %psr */
00047   1 * 4,                        /* %pc */
00048   2 * 4,                        /* %npc */
00049   3 * 4,                        /* %y */
00050   -1,                           /* %wim */
00051   -1,                           /* %tbr */
00052   5 * 4,                        /* %g1 */
00053   -1                            /* %l0 */
00054 };
00055 
00056 static void
00057 sparc32nbsd_supply_gregset (const struct regset *regset,
00058                             struct regcache *regcache,
00059                             int regnum, const void *gregs, size_t len)
00060 {
00061   sparc32_supply_gregset (&sparc32nbsd_gregset, regcache, regnum, gregs);
00062 
00063   /* Traditional NetBSD core files don't use multiple register sets.
00064      Instead, the general-purpose and floating-point registers are
00065      lumped together in a single section.  */
00066   if (len >= 212)
00067     sparc32_supply_fpregset (&sparc32_bsd_fpregset, regcache, regnum,
00068                              (const char *) gregs + 80);
00069 }
00070 
00071 static void
00072 sparc32nbsd_supply_fpregset (const struct regset *regset,
00073                              struct regcache *regcache,
00074                              int regnum, const void *fpregs, size_t len)
00075 {
00076   sparc32_supply_fpregset (&sparc32_bsd_fpregset, regcache, regnum, fpregs);
00077 }
00078 
00079 
00080 /* Signal trampolines.  */
00081 
00082 /* The following variables describe the location of an on-stack signal
00083    trampoline.  The current values correspond to the memory layout for
00084    NetBSD 1.3 and up.  These shouldn't be necessary for NetBSD 2.0 and
00085    up, since NetBSD uses signal trampolines provided by libc now.  */
00086 
00087 static const CORE_ADDR sparc32nbsd_sigtramp_start = 0xeffffef0;
00088 static const CORE_ADDR sparc32nbsd_sigtramp_end = 0xeffffff0;
00089 
00090 static int
00091 sparc32nbsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
00092 {
00093   if (pc >= sparc32nbsd_sigtramp_start && pc < sparc32nbsd_sigtramp_end)
00094     return 1;
00095 
00096   return nbsd_pc_in_sigtramp (pc, name);
00097 }
00098 
00099 struct trad_frame_saved_reg *
00100 sparc32nbsd_sigcontext_saved_regs (struct frame_info *this_frame)
00101 {
00102   struct gdbarch *gdbarch = get_frame_arch (this_frame);
00103   struct trad_frame_saved_reg *saved_regs;
00104   CORE_ADDR addr, sigcontext_addr;
00105   int regnum, delta;
00106   ULONGEST psr;
00107 
00108   saved_regs = trad_frame_alloc_saved_regs (this_frame);
00109 
00110   /* We find the appropriate instance of `struct sigcontext' at a
00111      fixed offset in the signal frame.  */
00112   addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
00113   sigcontext_addr = addr + 64 + 16;
00114 
00115   /* The registers are saved in bits and pieces scattered all over the
00116      place.  The code below records their location on the assumption
00117      that the part of the signal trampoline that saves the state has
00118      been executed.  */
00119 
00120   saved_regs[SPARC_SP_REGNUM].addr = sigcontext_addr + 8;
00121   saved_regs[SPARC32_PC_REGNUM].addr = sigcontext_addr + 12;
00122   saved_regs[SPARC32_NPC_REGNUM].addr = sigcontext_addr + 16;
00123   saved_regs[SPARC32_PSR_REGNUM].addr = sigcontext_addr + 20;
00124   saved_regs[SPARC_G1_REGNUM].addr = sigcontext_addr + 24;
00125   saved_regs[SPARC_O0_REGNUM].addr = sigcontext_addr + 28;
00126 
00127   /* The remaining `global' registers and %y are saved in the `local'
00128      registers.  */
00129   delta = SPARC_L0_REGNUM - SPARC_G0_REGNUM;
00130   for (regnum = SPARC_G2_REGNUM; regnum <= SPARC_G7_REGNUM; regnum++)
00131     saved_regs[regnum].realreg = regnum + delta;
00132   saved_regs[SPARC32_Y_REGNUM].realreg = SPARC_L1_REGNUM;
00133 
00134   /* The remaining `out' registers can be found in the current frame's
00135      `in' registers.  */
00136   delta = SPARC_I0_REGNUM - SPARC_O0_REGNUM;
00137   for (regnum = SPARC_O1_REGNUM; regnum <= SPARC_O5_REGNUM; regnum++)
00138     saved_regs[regnum].realreg = regnum + delta;
00139   saved_regs[SPARC_O7_REGNUM].realreg = SPARC_I7_REGNUM;
00140 
00141   /* The `local' and `in' registers have been saved in the register
00142      save area.  */
00143   addr = saved_regs[SPARC_SP_REGNUM].addr;
00144   addr = get_frame_memory_unsigned (this_frame, addr, 4);
00145   for (regnum = SPARC_L0_REGNUM;
00146        regnum <= SPARC_I7_REGNUM; regnum++, addr += 4)
00147     saved_regs[regnum].addr = addr;
00148 
00149   /* Handle StackGhost.  */
00150   {
00151     ULONGEST wcookie = sparc_fetch_wcookie (gdbarch);
00152 
00153     if (wcookie != 0)
00154       {
00155         ULONGEST i7;
00156 
00157         addr = saved_regs[SPARC_I7_REGNUM].addr;
00158         i7 = get_frame_memory_unsigned (this_frame, addr, 4);
00159         trad_frame_set_value (saved_regs, SPARC_I7_REGNUM, i7 ^ wcookie);
00160       }
00161   }
00162 
00163   /* The floating-point registers are only saved if the EF bit in %prs
00164      has been set.  */
00165 
00166 #define PSR_EF  0x00001000
00167 
00168   addr = saved_regs[SPARC32_PSR_REGNUM].addr;
00169   psr = get_frame_memory_unsigned (this_frame, addr, 4);
00170   if (psr & PSR_EF)
00171     {
00172       CORE_ADDR sp;
00173 
00174       sp = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
00175       saved_regs[SPARC32_FSR_REGNUM].addr = sp + 96;
00176       for (regnum = SPARC_F0_REGNUM, addr = sp + 96 + 8;
00177            regnum <= SPARC_F31_REGNUM; regnum++, addr += 4)
00178         saved_regs[regnum].addr = addr;
00179     }
00180 
00181   return saved_regs;
00182 }
00183 
00184 static struct sparc_frame_cache *
00185 sparc32nbsd_sigcontext_frame_cache (struct frame_info *this_frame,
00186                                     void **this_cache)
00187 {
00188   struct sparc_frame_cache *cache;
00189   CORE_ADDR addr;
00190 
00191   if (*this_cache)
00192     return *this_cache;
00193 
00194   cache = sparc_frame_cache (this_frame, this_cache);
00195   gdb_assert (cache == *this_cache);
00196 
00197   /* If we couldn't find the frame's function, we're probably dealing
00198      with an on-stack signal trampoline.  */
00199   if (cache->pc == 0)
00200     {
00201       cache->pc = sparc32nbsd_sigtramp_start;
00202 
00203       /* Since we couldn't find the frame's function, the cache was
00204          initialized under the assumption that we're frameless.  */
00205       sparc_record_save_insn (cache);
00206       addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
00207       cache->base = addr;
00208     }
00209 
00210   cache->saved_regs = sparc32nbsd_sigcontext_saved_regs (this_frame);
00211 
00212   return cache;
00213 }
00214 
00215 static void
00216 sparc32nbsd_sigcontext_frame_this_id (struct frame_info *this_frame,
00217                                       void **this_cache,
00218                                       struct frame_id *this_id)
00219 {
00220   struct sparc_frame_cache *cache =
00221     sparc32nbsd_sigcontext_frame_cache (this_frame, this_cache);
00222 
00223   (*this_id) = frame_id_build (cache->base, cache->pc);
00224 }
00225 
00226 static struct value *
00227 sparc32nbsd_sigcontext_frame_prev_register (struct frame_info *this_frame,
00228                                             void **this_cache, int regnum)
00229 {
00230   struct sparc_frame_cache *cache =
00231     sparc32nbsd_sigcontext_frame_cache (this_frame, this_cache);
00232 
00233   return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
00234 }
00235 
00236 static int
00237 sparc32nbsd_sigcontext_frame_sniffer (const struct frame_unwind *self,
00238                                       struct frame_info *this_frame,
00239                                       void **this_cache)
00240 {
00241   CORE_ADDR pc = get_frame_pc (this_frame);
00242   const char *name;
00243 
00244   find_pc_partial_function (pc, &name, NULL, NULL);
00245   if (sparc32nbsd_pc_in_sigtramp (pc, name))
00246     {
00247       if (name == NULL || strncmp (name, "__sigtramp_sigcontext", 21))
00248         return 1;
00249     }
00250 
00251   return 0;
00252 }
00253 
00254 static const struct frame_unwind sparc32nbsd_sigcontext_frame_unwind =
00255 {
00256   SIGTRAMP_FRAME,
00257   default_frame_unwind_stop_reason,
00258   sparc32nbsd_sigcontext_frame_this_id,
00259   sparc32nbsd_sigcontext_frame_prev_register,
00260   NULL,
00261   sparc32nbsd_sigcontext_frame_sniffer
00262 };
00263 
00264 /* Return the address of a system call's alternative return
00265    address.  */
00266 
00267 CORE_ADDR
00268 sparcnbsd_step_trap (struct frame_info *frame, unsigned long insn)
00269 {
00270   if ((X_I (insn) == 0 && X_RS1 (insn) == 0 && X_RS2 (insn) == 0)
00271       || (X_I (insn) == 1 && X_RS1 (insn) == 0 && (insn & 0x7f) == 0))
00272     {
00273       /* "New" system call.  */
00274       ULONGEST number = get_frame_register_unsigned (frame, SPARC_G1_REGNUM);
00275 
00276       if (number & 0x400)
00277         return get_frame_register_unsigned (frame, SPARC_G2_REGNUM);
00278       if (number & 0x800)
00279         return get_frame_register_unsigned (frame, SPARC_G7_REGNUM);
00280     }
00281 
00282   return 0;
00283 }
00284 
00285 
00286 static void
00287 sparc32nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
00288 {
00289   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
00290 
00291   /* NetBSD doesn't support the 128-bit `long double' from the psABI.  */
00292   set_gdbarch_long_double_bit (gdbarch, 64);
00293   set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
00294 
00295   tdep->gregset = regset_alloc (gdbarch, sparc32nbsd_supply_gregset, NULL);
00296   tdep->sizeof_gregset = 20 * 4;
00297 
00298   tdep->fpregset = regset_alloc (gdbarch, sparc32nbsd_supply_fpregset, NULL);
00299   tdep->sizeof_fpregset = 33 * 4;
00300 
00301   /* Make sure we can single-step "new" syscalls.  */
00302   tdep->step_trap = sparcnbsd_step_trap;
00303 
00304   frame_unwind_append_unwinder (gdbarch, &sparc32nbsd_sigcontext_frame_unwind);
00305 }
00306 
00307 static void
00308 sparc32nbsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
00309 {
00310   sparc32nbsd_init_abi (info, gdbarch);
00311 }
00312 
00313 void
00314 sparc32nbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
00315 {
00316   sparc32nbsd_init_abi (info, gdbarch);
00317 
00318   set_solib_svr4_fetch_link_map_offsets
00319     (gdbarch, svr4_ilp32_fetch_link_map_offsets);
00320 }
00321 
00322 static enum gdb_osabi
00323 sparcnbsd_aout_osabi_sniffer (bfd *abfd)
00324 {
00325   if (strcmp (bfd_get_target (abfd), "a.out-sparc-netbsd") == 0)
00326     return GDB_OSABI_NETBSD_AOUT;
00327 
00328   return GDB_OSABI_UNKNOWN;
00329 }
00330 
00331 /* OpenBSD uses the traditional NetBSD core file format, even for
00332    ports that use ELF.  Therefore, if the default OS ABI is OpenBSD
00333    ELF, we return that instead of NetBSD a.out.  This is mainly for
00334    the benfit of OpenBSD/sparc64, which inherits the sniffer below
00335    since we include this file for an OpenBSD/sparc64 target.  For
00336    OpenBSD/sparc, the NetBSD a.out OS ABI is probably similar enough
00337    to both the OpenBSD a.out and the OpenBSD ELF OS ABI.  */
00338 #if defined (GDB_OSABI_DEFAULT) && (GDB_OSABI_DEFAULT == GDB_OSABI_OPENBSD_ELF)
00339 #define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF
00340 #else
00341 #define GDB_OSABI_NETBSD_CORE GDB_OSABI_NETBSD_AOUT
00342 #endif
00343 
00344 static enum gdb_osabi
00345 sparcnbsd_core_osabi_sniffer (bfd *abfd)
00346 {
00347   if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
00348     return GDB_OSABI_NETBSD_CORE;
00349 
00350   return GDB_OSABI_UNKNOWN;
00351 }
00352 
00353 
00354 /* Provide a prototype to silence -Wmissing-prototypes.  */
00355 void _initialize_sparcnbsd_tdep (void);
00356 
00357 void
00358 _initialize_sparcnbsd_tdep (void)
00359 {
00360   gdbarch_register_osabi_sniffer (bfd_arch_sparc, bfd_target_aout_flavour,
00361                                   sparcnbsd_aout_osabi_sniffer);
00362 
00363   /* BFD doesn't set a flavour for NetBSD style a.out core files.  */
00364   gdbarch_register_osabi_sniffer (bfd_arch_sparc, bfd_target_unknown_flavour,
00365                                   sparcnbsd_core_osabi_sniffer);
00366 
00367   gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_NETBSD_AOUT,
00368                           sparc32nbsd_aout_init_abi);
00369   gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_NETBSD_ELF,
00370                           sparc32nbsd_elf_init_abi);
00371 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines