GDB (API)
|
00001 /* Native-dependent code for Alpha BSD's. 00002 00003 Copyright (C) 2000-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 "inferior.h" 00022 #include "regcache.h" 00023 00024 #include "alpha-tdep.h" 00025 #include "alphabsd-tdep.h" 00026 #include "inf-ptrace.h" 00027 00028 #include <sys/types.h> 00029 #include <sys/ptrace.h> 00030 #include <machine/reg.h> 00031 00032 #ifdef HAVE_SYS_PROCFS_H 00033 #include <sys/procfs.h> 00034 #endif 00035 00036 #ifndef HAVE_GREGSET_T 00037 typedef struct reg gregset_t; 00038 #endif 00039 00040 #ifndef HAVE_FPREGSET_T 00041 typedef struct fpreg fpregset_t; 00042 #endif 00043 00044 #include "gregset.h" 00045 00046 /* Provide *regset() wrappers around the generic Alpha BSD register 00047 supply/fill routines. */ 00048 00049 void 00050 supply_gregset (struct regcache *regcache, const gregset_t *gregsetp) 00051 { 00052 alphabsd_supply_reg (regcache, (const char *) gregsetp, -1); 00053 } 00054 00055 void 00056 fill_gregset (const struct regcache *regcache, gregset_t *gregsetp, int regno) 00057 { 00058 alphabsd_fill_reg (regcache, (char *) gregsetp, regno); 00059 } 00060 00061 void 00062 supply_fpregset (struct regcache *regcache, const fpregset_t *fpregsetp) 00063 { 00064 alphabsd_supply_fpreg (regcache, (const char *) fpregsetp, -1); 00065 } 00066 00067 void 00068 fill_fpregset (const struct regcache *regcache, 00069 fpregset_t *fpregsetp, int regno) 00070 { 00071 alphabsd_fill_fpreg (regcache, (char *) fpregsetp, regno); 00072 } 00073 00074 /* Determine if PT_GETREGS fetches this register. */ 00075 00076 static int 00077 getregs_supplies (int regno) 00078 { 00079 return ((regno >= ALPHA_V0_REGNUM && regno <= ALPHA_ZERO_REGNUM) 00080 || regno >= ALPHA_PC_REGNUM); 00081 } 00082 00083 /* Fetch register REGNO from the inferior. If REGNO is -1, do this 00084 for all registers (including the floating point registers). */ 00085 00086 static void 00087 alphabsd_fetch_inferior_registers (struct target_ops *ops, 00088 struct regcache *regcache, int regno) 00089 { 00090 if (regno == -1 || getregs_supplies (regno)) 00091 { 00092 struct reg gregs; 00093 00094 if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid), 00095 (PTRACE_TYPE_ARG3) &gregs, 0) == -1) 00096 perror_with_name (_("Couldn't get registers")); 00097 00098 alphabsd_supply_reg (regcache, (char *) &gregs, regno); 00099 if (regno != -1) 00100 return; 00101 } 00102 00103 if (regno == -1 00104 || regno >= gdbarch_fp0_regnum (get_regcache_arch (regcache))) 00105 { 00106 struct fpreg fpregs; 00107 00108 if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid), 00109 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) 00110 perror_with_name (_("Couldn't get floating point status")); 00111 00112 alphabsd_supply_fpreg (regcache, (char *) &fpregs, regno); 00113 } 00114 } 00115 00116 /* Store register REGNO back into the inferior. If REGNO is -1, do 00117 this for all registers (including the floating point registers). */ 00118 00119 static void 00120 alphabsd_store_inferior_registers (struct target_ops *ops, 00121 struct regcache *regcache, int regno) 00122 { 00123 if (regno == -1 || getregs_supplies (regno)) 00124 { 00125 struct reg gregs; 00126 if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid), 00127 (PTRACE_TYPE_ARG3) &gregs, 0) == -1) 00128 perror_with_name (_("Couldn't get registers")); 00129 00130 alphabsd_fill_reg (regcache, (char *) &gregs, regno); 00131 00132 if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid), 00133 (PTRACE_TYPE_ARG3) &gregs, 0) == -1) 00134 perror_with_name (_("Couldn't write registers")); 00135 00136 if (regno != -1) 00137 return; 00138 } 00139 00140 if (regno == -1 00141 || regno >= gdbarch_fp0_regnum (get_regcache_arch (regcache))) 00142 { 00143 struct fpreg fpregs; 00144 00145 if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid), 00146 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) 00147 perror_with_name (_("Couldn't get floating point status")); 00148 00149 alphabsd_fill_fpreg (regcache, (char *) &fpregs, regno); 00150 00151 if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid), 00152 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) 00153 perror_with_name (_("Couldn't write floating point status")); 00154 } 00155 } 00156 00157 00158 /* Support for debugging kernel virtual memory images. */ 00159 00160 #include <sys/types.h> 00161 #include <sys/signal.h> 00162 #include <machine/pcb.h> 00163 00164 #include "bsd-kvm.h" 00165 00166 static int 00167 alphabsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) 00168 { 00169 int regnum; 00170 00171 /* The following is true for OpenBSD 3.9: 00172 00173 The pcb contains the register state at the context switch inside 00174 cpu_switch(). */ 00175 00176 /* The stack pointer shouldn't be zero. */ 00177 if (pcb->pcb_hw.apcb_ksp == 0) 00178 return 0; 00179 00180 regcache_raw_supply (regcache, ALPHA_SP_REGNUM, &pcb->pcb_hw.apcb_ksp); 00181 00182 for (regnum = ALPHA_S0_REGNUM; regnum < ALPHA_A0_REGNUM; regnum++) 00183 regcache_raw_supply (regcache, regnum, 00184 &pcb->pcb_context[regnum - ALPHA_S0_REGNUM]); 00185 regcache_raw_supply (regcache, ALPHA_RA_REGNUM, &pcb->pcb_context[7]); 00186 00187 return 1; 00188 } 00189 00190 00191 /* Provide a prototype to silence -Wmissing-prototypes. */ 00192 void _initialize_alphabsd_nat (void); 00193 00194 void 00195 _initialize_alphabsd_nat (void) 00196 { 00197 struct target_ops *t; 00198 00199 t = inf_ptrace_target (); 00200 t->to_fetch_registers = alphabsd_fetch_inferior_registers; 00201 t->to_store_registers = alphabsd_store_inferior_registers; 00202 add_target (t); 00203 00204 /* Support debugging kernel virtual memory images. */ 00205 bsd_kvm_add_target (alphabsd_supply_pcb); 00206 }