GDB (API)
/home/stan/gdb/src/gdb/ppcnbsd-nat.c
Go to the documentation of this file.
00001 /* Native-dependent code for NetBSD/powerpc.
00002 
00003    Copyright (C) 2002-2013 Free Software Foundation, Inc.
00004 
00005    Contributed by Wasabi Systems, Inc.
00006 
00007    This file is part of GDB.
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 3 of the License, or
00012    (at your option) any later version.
00013 
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018 
00019    You should have received a copy of the GNU General Public License
00020    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00021 
00022 #include "defs.h"
00023 
00024 #include <sys/types.h>
00025 #include <sys/ptrace.h>
00026 #include <machine/reg.h>
00027 #include <machine/frame.h>
00028 #include <machine/pcb.h>
00029 
00030 #include "gdbcore.h"
00031 #include "inferior.h"
00032 #include "regcache.h"
00033 
00034 #include "gdb_assert.h"
00035 
00036 #include "ppc-tdep.h"
00037 #include "ppcnbsd-tdep.h"
00038 #include "bsd-kvm.h"
00039 #include "inf-ptrace.h"
00040 
00041 /* Returns true if PT_GETREGS fetches this register.  */
00042 
00043 static int
00044 getregs_supplies (struct gdbarch *gdbarch, int regnum)
00045 {
00046   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
00047 
00048   return ((regnum >= tdep->ppc_gp0_regnum
00049            && regnum < tdep->ppc_gp0_regnum + ppc_num_gprs)
00050           || regnum == tdep->ppc_lr_regnum
00051           || regnum == tdep->ppc_cr_regnum
00052           || regnum == tdep->ppc_xer_regnum
00053           || regnum == tdep->ppc_ctr_regnum
00054           || regnum == gdbarch_pc_regnum (gdbarch));
00055 }
00056 
00057 /* Like above, but for PT_GETFPREGS.  */
00058 
00059 static int
00060 getfpregs_supplies (struct gdbarch *gdbarch, int regnum)
00061 {
00062   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
00063 
00064   /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
00065      point registers.  Traditionally, GDB's register set has still
00066      listed the floating point registers for such machines, so this
00067      code is harmless.  However, the new E500 port actually omits the
00068      floating point registers entirely from the register set --- they
00069      don't even have register numbers assigned to them.
00070 
00071      It's not clear to me how best to update this code, so this assert
00072      will alert the first person to encounter the NetBSD/E500
00073      combination to the problem.  */
00074   gdb_assert (ppc_floating_point_unit_p (gdbarch));
00075 
00076   return ((regnum >= tdep->ppc_fp0_regnum
00077            && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs)
00078           || regnum == tdep->ppc_fpscr_regnum);
00079 }
00080 
00081 static void
00082 ppcnbsd_fetch_inferior_registers (struct target_ops *ops,
00083                                   struct regcache *regcache, int regnum)
00084 {
00085   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00086 
00087   if (regnum == -1 || getregs_supplies (gdbarch, regnum))
00088     {
00089       struct reg regs;
00090 
00091       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
00092                   (PTRACE_TYPE_ARG3) &regs, 0) == -1)
00093         perror_with_name (_("Couldn't get registers"));
00094 
00095       ppc_supply_gregset (&ppcnbsd_gregset, regcache,
00096                           regnum, &regs, sizeof regs);
00097     }
00098 
00099   if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
00100     {
00101       struct fpreg fpregs;
00102 
00103       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
00104                   (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
00105         perror_with_name (_("Couldn't get FP registers"));
00106 
00107       ppc_supply_fpregset (&ppcnbsd_fpregset, regcache,
00108                            regnum, &fpregs, sizeof fpregs);
00109     }
00110 }
00111 
00112 static void
00113 ppcnbsd_store_inferior_registers (struct target_ops *ops,
00114                                   struct regcache *regcache, int regnum)
00115 {
00116   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00117 
00118   if (regnum == -1 || getregs_supplies (gdbarch, regnum))
00119     {
00120       struct reg regs;
00121 
00122       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
00123                   (PTRACE_TYPE_ARG3) &regs, 0) == -1)
00124         perror_with_name (_("Couldn't get registers"));
00125 
00126       ppc_collect_gregset (&ppcnbsd_gregset, regcache,
00127                            regnum, &regs, sizeof regs);
00128 
00129       if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
00130                   (PTRACE_TYPE_ARG3) &regs, 0) == -1)
00131         perror_with_name (_("Couldn't write registers"));
00132     }
00133 
00134   if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
00135     {
00136       struct fpreg fpregs;
00137 
00138       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
00139                   (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
00140         perror_with_name (_("Couldn't get FP registers"));
00141 
00142       ppc_collect_fpregset (&ppcnbsd_fpregset, regcache,
00143                             regnum, &fpregs, sizeof fpregs);
00144 
00145       if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
00146                   (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
00147         perror_with_name (_("Couldn't set FP registers"));
00148     }
00149 }
00150 
00151 static int
00152 ppcnbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
00153 {
00154   struct switchframe sf;
00155   struct callframe cf;
00156   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00157   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
00158   int i;
00159 
00160   /* The stack pointer shouldn't be zero.  */
00161   if (pcb->pcb_sp == 0)
00162     return 0;
00163 
00164   read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf);
00165   regcache_raw_supply (regcache, tdep->ppc_cr_regnum, &sf.cr);
00166   regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 2, &sf.fixreg2);
00167   for (i = 0 ; i < 19 ; i++)
00168     regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 13 + i,
00169                          &sf.fixreg[i]);
00170 
00171   read_memory(sf.sp, (gdb_byte *)&cf, sizeof(cf));
00172   regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 30, &cf.r30);
00173   regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 31, &cf.r31);
00174   regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 1, &cf.sp);
00175 
00176   read_memory(cf.sp, (gdb_byte *)&cf, sizeof(cf));
00177   regcache_raw_supply (regcache, tdep->ppc_lr_regnum, &cf.lr);
00178   regcache_raw_supply (regcache, gdbarch_pc_regnum (gdbarch), &cf.lr);
00179 
00180   return 1;
00181 }
00182 
00183 /* Provide a prototype to silence -Wmissing-prototypes.  */
00184 void _initialize_ppcnbsd_nat (void);
00185 
00186 void
00187 _initialize_ppcnbsd_nat (void)
00188 {
00189   struct target_ops *t;
00190 
00191   /* Support debugging kernel virtual memory images.  */
00192   bsd_kvm_add_target (ppcnbsd_supply_pcb);
00193 
00194   /* Add in local overrides.  */
00195   t = inf_ptrace_target ();
00196   t->to_fetch_registers = ppcnbsd_fetch_inferior_registers;
00197   t->to_store_registers = ppcnbsd_store_inferior_registers;
00198   add_target (t);
00199 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines