GDB (API)
|
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) ®s, 0) == -1) 00093 perror_with_name (_("Couldn't get registers")); 00094 00095 ppc_supply_gregset (&ppcnbsd_gregset, regcache, 00096 regnum, ®s, 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) ®s, 0) == -1) 00124 perror_with_name (_("Couldn't get registers")); 00125 00126 ppc_collect_gregset (&ppcnbsd_gregset, regcache, 00127 regnum, ®s, sizeof regs); 00128 00129 if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid), 00130 (PTRACE_TYPE_ARG3) ®s, 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 }