GDB (API)
/home/stan/gdb/src/gdb/sparc64nbsd-nat.c
Go to the documentation of this file.
00001 /* Native-dependent code for NetBSD/sparc64.
00002 
00003    Copyright (C) 2003-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 "gdbcore.h"
00022 #include "regcache.h"
00023 #include "target.h"
00024 
00025 #include "sparc64-tdep.h"
00026 #include "sparc-nat.h"
00027 
00028 /* NetBSD is different from the other OSes that support both SPARC and
00029    UltraSPARC in that the result of ptrace(2) depends on whether the
00030    traced process is 32-bit or 64-bit.  */
00031 
00032 static void
00033 sparc64nbsd_supply_gregset (const struct sparc_gregset *gregset,
00034                             struct regcache *regcache,
00035                             int regnum, const void *gregs)
00036 {
00037   int sparc32 = (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32);
00038 
00039   if (sparc32)
00040     sparc32_supply_gregset (&sparc32nbsd_gregset, regcache, regnum, gregs);
00041   else
00042     sparc64_supply_gregset (&sparc64nbsd_gregset, regcache, regnum, gregs);
00043 }
00044 
00045 static void
00046 sparc64nbsd_collect_gregset (const struct sparc_gregset *gregset,
00047                              const struct regcache *regcache,
00048                              int regnum, void *gregs)
00049 {
00050   int sparc32 = (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32);
00051 
00052   if (sparc32)
00053     sparc32_collect_gregset (&sparc32nbsd_gregset, regcache, regnum, gregs);
00054   else
00055     sparc64_collect_gregset (&sparc64nbsd_gregset, regcache, regnum, gregs);
00056 }
00057 
00058 static void
00059 sparc64nbsd_supply_fpregset (const struct sparc_fpregset *fpregset,
00060                              struct regcache *regcache,
00061                              int regnum, const void *fpregs)
00062 {
00063   int sparc32 = (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32);
00064 
00065   if (sparc32)
00066     sparc32_supply_fpregset (&sparc32_bsd_fpregset, regcache, regnum, fpregs);
00067   else
00068     sparc64_supply_fpregset (&sparc64_bsd_fpregset, regcache, regnum, fpregs);
00069 }
00070 
00071 static void
00072 sparc64nbsd_collect_fpregset (const struct regcache *regcache,
00073                               int regnum, void *fpregs)
00074 {
00075   int sparc32 = (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32);
00076 
00077   if (sparc32)
00078     sparc32_collect_fpregset (&sparc32_bsd_fpregset, regcache, regnum, fpregs);
00079   else
00080     sparc64_collect_fpregset (&sparc64_bsd_fpregset, regcache, regnum, fpregs);
00081 }
00082 
00083 /* Determine whether `gregset_t' contains register REGNUM.  */
00084 
00085 static int
00086 sparc64nbsd_gregset_supplies_p (struct gdbarch *gdbarch, int regnum)
00087 {
00088   if (gdbarch_ptr_bit (gdbarch) == 32)
00089     return sparc32_gregset_supplies_p (gdbarch, regnum);
00090 
00091   /* Integer registers.  */
00092   if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_G7_REGNUM)
00093       || (regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM)
00094       || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_L7_REGNUM)
00095       || (regnum >= SPARC_I0_REGNUM && regnum <= SPARC_I7_REGNUM))
00096     return 1;
00097 
00098   /* Control registers.  */
00099   if (regnum == SPARC64_PC_REGNUM
00100       || regnum == SPARC64_NPC_REGNUM
00101       || regnum == SPARC64_STATE_REGNUM
00102       || regnum == SPARC64_Y_REGNUM)
00103     return 1;
00104 
00105   return 0;
00106 }
00107 
00108 /* Determine whether `fpregset_t' contains register REGNUM.  */
00109 
00110 static int
00111 sparc64nbsd_fpregset_supplies_p (struct gdbarch *gdbarch, int regnum)
00112 {
00113   if (gdbarch_ptr_bit (gdbarch) == 32)
00114     return sparc32_fpregset_supplies_p (gdbarch, regnum);
00115 
00116   /* Floating-point registers.  */
00117   if ((regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM)
00118       || (regnum >= SPARC64_F32_REGNUM && regnum <= SPARC64_F62_REGNUM))
00119     return 1;
00120 
00121   /* Control registers.  */
00122   if (regnum == SPARC64_FSR_REGNUM)
00123     return 1;
00124 
00125   return 0;
00126 }
00127 
00128 
00129 /* Support for debugging kernel virtual memory images.  */
00130 
00131 #include <sys/types.h>
00132 #include <machine/pcb.h>
00133 
00134 #include "bsd-kvm.h"
00135 
00136 static int
00137 sparc64nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
00138 {
00139   u_int64_t state;
00140   int regnum;
00141 
00142   /* The following is true for NetBSD 1.6.2:
00143 
00144      The pcb contains %sp and %pc, %pstate and %cwp.  From this
00145      information we reconstruct the register state as it would look
00146      when we just returned from cpu_switch().  */
00147 
00148   /* The stack pointer shouldn't be zero.  */
00149   if (pcb->pcb_sp == 0)
00150     return 0;
00151 
00152   /* If the program counter is zero, this is probably a core dump, and
00153      we can get %pc from the stack.  */
00154   if (pcb->pcb_pc == 0)
00155       read_memory(pcb->pcb_sp + BIAS - 176 + (11 * 8), 
00156                   (gdb_byte *)&pcb->pcb_pc, sizeof pcb->pcb_pc);
00157 
00158   regcache_raw_supply (regcache, SPARC_SP_REGNUM, &pcb->pcb_sp);
00159   regcache_raw_supply (regcache, SPARC64_PC_REGNUM, &pcb->pcb_pc);
00160 
00161   state = pcb->pcb_pstate << 8 | pcb->pcb_cwp;
00162   regcache_raw_supply (regcache, SPARC64_STATE_REGNUM, &state);
00163 
00164   sparc_supply_rwindow (regcache, pcb->pcb_sp, -1);
00165 
00166   return 1;
00167 }
00168 
00169 
00170 /* Provide a prototype to silence -Wmissing-prototypes.  */
00171 void _initialize_sparc64nbsd_nat (void);
00172 
00173 void
00174 _initialize_sparc64nbsd_nat (void)
00175 {
00176   sparc_supply_gregset = sparc64nbsd_supply_gregset;
00177   sparc_collect_gregset = sparc64nbsd_collect_gregset;
00178   sparc_supply_fpregset = sparc64nbsd_supply_fpregset;
00179   sparc_collect_fpregset = sparc64nbsd_collect_fpregset;
00180   sparc_gregset_supplies_p = sparc64nbsd_gregset_supplies_p;
00181   sparc_fpregset_supplies_p = sparc64nbsd_fpregset_supplies_p;
00182 
00183   /* We've got nothing to add to the generic SPARC target.  */
00184   add_target (sparc_target ());
00185 
00186   /* Support debugging kernel virtual memory images.  */
00187   bsd_kvm_add_target (sparc64nbsd_supply_pcb);
00188 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines