1 /* Native-dependent code for Motorola 68000 BSD's. 2 3 Copyright 2004 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 59 Temple Place - Suite 330, 20 Boston, MA 02111-1307, USA. */ 21 22 #include "defs.h" 23 #include "gdbcore.h" 24 #include "inferior.h" 25 #include "regcache.h" 26 27 #include "gdb_assert.h" 28 #include <sys/types.h> 29 #include <sys/ptrace.h> 30 #include <machine/reg.h> 31 32 #include "m68k-tdep.h" 33 34 static int 35 m68kbsd_gregset_supplies_p (int regnum) 36 { 37 return (regnum >= M68K_D0_REGNUM && regnum <= M68K_PC_REGNUM); 38 } 39 40 static int 41 m68kbsd_fpregset_supplies_p (int regnum) 42 { 43 return (regnum >= M68K_FP0_REGNUM && regnum <= M68K_FPI_REGNUM); 44 } 45 46 /* Supply the general-purpose registers stored in GREGS to REGCACHE. */ 47 48 static void 49 m68kbsd_supply_gregset (struct regcache *regcache, const void *gregs) 50 { 51 const char *regs = gregs; 52 int regnum; 53 54 for (regnum = M68K_D0_REGNUM; regnum <= M68K_PC_REGNUM; regnum++) 55 regcache_raw_supply (regcache, regnum, regs + regnum * 4); 56 } 57 58 /* Supply the floating-point registers stored in FPREGS to REGCACHE. */ 59 60 static void 61 m68kbsd_supply_fpregset (struct regcache *regcache, const void *fpregs) 62 { 63 const char *regs = fpregs; 64 int regnum; 65 66 for (regnum = M68K_FP0_REGNUM; regnum <= M68K_FPI_REGNUM; regnum++) 67 regcache_raw_supply (regcache, regnum, 68 regs + m68kbsd_fpreg_offset (regnum)); 69 } 70 71 /* Collect the general-purpose registers from REGCACHE and store them 72 in GREGS. */ 73 74 static void 75 m68kbsd_collect_gregset (const struct regcache *regcache, 76 void *gregs, int regnum) 77 { 78 char *regs = gregs; 79 int i; 80 81 for (i = M68K_D0_REGNUM; i <= M68K_PC_REGNUM; i++) 82 { 83 if (regnum == -1 || regnum == i) 84 regcache_raw_collect (regcache, i, regs + i * 4); 85 } 86 } 87 88 /* Collect the floating-point registers from REGCACHE and store them 89 in FPREGS. */ 90 91 static void 92 m68kbsd_collect_fpregset (struct regcache *regcache, 93 void *fpregs, int regnum) 94 { 95 char *regs = fpregs; 96 int i; 97 98 for (i = M68K_FP0_REGNUM; i <= M68K_FPI_REGNUM; i++) 99 { 100 if (regnum == -1 || regnum == i) 101 regcache_raw_collect (regcache, i, regs + m68kbsd_fpreg_offset (i)); 102 } 103 } 104 105 106 /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this 107 for all registers (including the floating-point registers). */ 108 109 void 110 fetch_inferior_registers (int regnum) 111 { 112 if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum)) 113 { 114 struct reg regs; 115 116 if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), 117 (PTRACE_ARG3_TYPE) ®s, 0) == -1) 118 perror_with_name ("Couldn't get registers"); 119 120 m68kbsd_supply_gregset (current_regcache, ®s); 121 } 122 123 if (regnum == -1 || m68kbsd_fpregset_supplies_p (regnum)) 124 { 125 struct fpreg fpregs; 126 127 if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), 128 (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) 129 perror_with_name ("Couldn't get floating point status"); 130 131 m68kbsd_supply_fpregset (current_regcache, &fpregs); 132 } 133 } 134 135 /* Store register REGNUM back into the inferior. If REGNUM is -1, do 136 this for all registers (including the floating-point registers). */ 137 138 void 139 store_inferior_registers (int regnum) 140 { 141 if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum)) 142 { 143 struct reg regs; 144 145 if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), 146 (PTRACE_ARG3_TYPE) ®s, 0) == -1) 147 perror_with_name ("Couldn't get registers"); 148 149 m68kbsd_collect_gregset (current_regcache, ®s, regnum); 150 151 if (ptrace (PT_SETREGS, PIDGET (inferior_ptid), 152 (PTRACE_ARG3_TYPE) ®s, 0) == -1) 153 perror_with_name ("Couldn't write registers"); 154 } 155 156 if (regnum == -1 || m68kbsd_fpregset_supplies_p (regnum)) 157 { 158 struct fpreg fpregs; 159 160 if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), 161 (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) 162 perror_with_name ("Couldn't get floating point status"); 163 164 m68kbsd_collect_fpregset (current_regcache, &fpregs, regnum); 165 166 if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid), 167 (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) 168 perror_with_name ("Couldn't write floating point status"); 169 } 170 } 171 172 173 /* Support for debugging kernel virtual memory images. */ 174 175 #include <sys/types.h> 176 #include <machine/pcb.h> 177 178 #include "bsd-kvm.h" 179 180 /* OpenBSD doesn't have these. */ 181 #ifndef PCB_REGS_FP 182 #define PCB_REGS_FP 10 183 #endif 184 #ifndef PCB_REGS_SP 185 #define PCB_REGS_SP 11 186 #endif 187 188 static int 189 m68kbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) 190 { 191 int regnum, tmp; 192 int i = 0; 193 194 /* The following is true for NetBSD 1.6.2: 195 196 The pcb contains %d2...%d7, %a2...%a7 and %ps. This accounts for 197 all callee-saved registers. From this information we reconstruct 198 the register state as it would look when we just returned from 199 cpu_switch(). */ 200 201 /* The stack pointer shouldn't be zero. */ 202 if (pcb->pcb_regs[PCB_REGS_SP] == 0) 203 return 0; 204 205 for (regnum = M68K_D2_REGNUM; regnum <= M68K_D7_REGNUM; regnum++) 206 regcache_raw_supply (regcache, regnum, &pcb->pcb_regs[i++]); 207 for (regnum = M68K_A2_REGNUM; regnum <= M68K_SP_REGNUM; regnum++) 208 regcache_raw_supply (regcache, regnum, &pcb->pcb_regs[i++]); 209 210 tmp = pcb->pcb_ps & 0xffff; 211 regcache_raw_supply (regcache, M68K_PS_REGNUM, &tmp); 212 213 read_memory (pcb->pcb_regs[PCB_REGS_FP] + 4, (char *) &tmp, sizeof tmp); 214 regcache_raw_supply (regcache, M68K_PC_REGNUM, &tmp); 215 216 return 1; 217 } 218 219 220 /* Provide a prototype to silence -Wmissing-prototypes. */ 221 void _initialize_m68kbsd_nat (void); 222 223 void 224 _initialize_m68kbsd_nat (void) 225 { 226 /* Support debugging kernel virtual memory images. */ 227 bsd_kvm_add_target (m68kbsd_supply_pcb); 228 } 229