i386nbsd-nat.c revision 1.1
1/* Functions specific to running gdb native on an i386 running NetBSD 2 Copyright 1989, 1992, 1993, 1994, 1996 Free Software Foundation, Inc. 3 4This file is part of GDB. 5 6This program is free software; you can redistribute it and/or modify 7it under the terms of the GNU General Public License as published by 8the Free Software Foundation; either version 2 of the License, or 9(at your option) any later version. 10 11This program is distributed in the hope that it will be useful, 12but WITHOUT ANY WARRANTY; without even the implied warranty of 13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14GNU General Public License for more details. 15 16You should have received a copy of the GNU General Public License 17along with this program; if not, write to the Free Software 18Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 19 20#include <sys/types.h> 21#include <sys/ptrace.h> 22#include <machine/reg.h> 23#include <machine/frame.h> 24#include <machine/pcb.h> 25 26#include "defs.h" 27#include "inferior.h" 28#include "target.h" 29#include "gdbcore.h" 30 31void 32fetch_inferior_registers (regno) 33 int regno; 34{ 35 struct reg inferior_registers; 36 37 ptrace (PT_GETREGS, inferior_pid, 38 (PTRACE_ARG3_TYPE) &inferior_registers, 0); 39 memcpy (®isters[REGISTER_BYTE (0)], &inferior_registers, 40 sizeof(inferior_registers)); 41 42 /* FIXME: FP regs? */ 43 registers_fetched (); 44} 45 46void 47store_inferior_registers (regno) 48 int regno; 49{ 50 struct reg inferior_registers; 51 52 memcpy (&inferior_registers, ®isters[REGISTER_BYTE (0)], 53 sizeof(inferior_registers)); 54 ptrace (PT_SETREGS, inferior_pid, 55 (PTRACE_ARG3_TYPE) &inferior_registers, 0); 56 57 /* FIXME: FP regs? */ 58} 59 60 61/* XXX - Add this to machine/regs.h instead? */ 62struct md_core { 63 struct reg intreg; 64 struct fpreg freg; 65}; 66 67static struct fpreg i386_fp_registers; 68static int i386_fp_read = 0; 69 70static void 71fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr) 72 char *core_reg_sect; 73 unsigned core_reg_size; 74 int which; 75 unsigned int reg_addr; /* Unused in this version */ 76{ 77 struct md_core *core_reg; 78 79 core_reg = (struct md_core *)core_reg_sect; 80 81 /* We get everything from the .reg section. */ 82 if (which != 0) 83 return; 84 85 if (core_reg_size < sizeof(struct reg)) { 86 fprintf_unfiltered (gdb_stderr, "Couldn't read regs from core file\n"); 87 return; 88 } 89 90 /* Integer registers */ 91 memcpy(®isters[REGISTER_BYTE (0)], 92 &core_reg->intreg, sizeof(struct reg)); 93 94 /* Floating point registers */ 95 i386_fp_registers = core_reg->freg; 96 i386_fp_read = 1; 97 98 registers_fetched (); 99} 100 101/* Register that we are able to handle i386nbsd core file formats. 102 FIXME: is this really bfd_target_unknown_flavour? */ 103 104static struct core_fns nat_core_fns = 105{ 106 bfd_target_unknown_flavour, 107 fetch_core_registers, 108 NULL 109}; 110 111void 112_initialize_i386nbsd_nat () 113{ 114 add_core_fns (&nat_core_fns); 115} 116 117 118/* 119 * kernel_u_size() is not helpful on NetBSD because 120 * the "u" struct is NOT in the core dump file. 121 */ 122 123#ifdef FETCH_KCORE_REGISTERS 124/* 125 * Get registers from a kernel crash dump or live kernel. 126 * Called by kcore-nbsd.c:get_kcore_registers(). 127 */ 128void 129fetch_kcore_registers (pcb) 130 struct pcb *pcb; 131{ 132 int i, regno, regs[4]; 133 134 /* 135 * get the register values out of the sys pcb and 136 * store them where `read_register' will find them. 137 */ 138 if (target_read_memory(pcb->pcb_tss.tss_esp+4, 139 (char *)regs, sizeof(regs))) 140 error("Cannot read ebx, esi, and edi."); 141 for (i = 0, regno = 0; regno < 3; regno++) 142 supply_register(regno, (char *)&i); 143 supply_register(3, (char *)®s[2]); 144 supply_register(4, (char *)&pcb->pcb_tss.tss_esp); 145 supply_register(5, (char *)&pcb->pcb_tss.tss_ebp); 146 supply_register(6, (char *)®s[1]); 147 supply_register(7, (char *)®s[0]); 148 supply_register(8, (char *)®s[3]); 149 for (i = 0, regno = 9; regno < 10; regno++) 150 supply_register(regno, (char *)&i); 151#if 0 152 i = 0x08; 153 supply_register(10, (char *)&i); 154 i = 0x10; 155 supply_register(11, (char *)&i); 156#endif 157 158 /* The kernel does not use the FPU, so ignore it. */ 159 registers_fetched (); 160} 161#endif /* FETCH_KCORE_REGISTERS */ 162 163#ifdef FLOAT_INFO 164#include "language.h" /* for local_hex_string */ 165#include "floatformat.h" 166 167#include <sys/param.h> 168#include <sys/dir.h> 169#include <signal.h> 170#include <sys/ioctl.h> 171#include <fcntl.h> 172 173#include <a.out.h> 174 175#include <sys/time.h> 176#include <sys/resource.h> 177#include <sys/uio.h> 178#define curpcb Xcurpcb /* XXX avoid leaking declaration from pcb.h */ 179#include <sys/user.h> 180#undef curpcb 181#include <sys/file.h> 182#include "gdb_stat.h" 183#include <sys/ptrace.h> 184 185extern void print_387_control_word (); /* i387-tdep.h */ 186extern void print_387_status_word (); 187 188struct env387 189{ 190 unsigned short control; 191 unsigned short r0; 192 unsigned short status; 193 unsigned short r1; 194 unsigned short tag; 195 unsigned short r2; 196 unsigned long eip; 197 unsigned short code_seg; 198 unsigned short opcode; 199 unsigned long operand; 200 unsigned short operand_seg; 201 unsigned short r3; 202 unsigned char regs[8][10]; 203}; 204 205static void 206print_387_status (status, ep) 207 unsigned short status; 208 struct env387 *ep; 209{ 210 int i; 211 int bothstatus; 212 int top; 213 int fpreg; 214 215 bothstatus = ((status != 0) && (ep->status != 0)); 216 if (status != 0) 217 { 218 if (bothstatus) 219 printf_unfiltered ("u: "); 220 print_387_status_word ((unsigned int)status); 221 } 222 223 if (ep->status != 0) 224 { 225 if (bothstatus) 226 printf_unfiltered ("e: "); 227 print_387_status_word ((unsigned int)ep->status); 228 } 229 230 print_387_control_word ((unsigned int)ep->control); 231 printf_unfiltered ("last exception: "); 232 printf_unfiltered ("opcode %s; ", local_hex_string(ep->opcode)); 233 printf_unfiltered ("pc %s:", local_hex_string(ep->code_seg)); 234 printf_unfiltered ("%s; ", local_hex_string(ep->eip)); 235 printf_unfiltered ("operand %s", local_hex_string(ep->operand_seg)); 236 printf_unfiltered (":%s\n", local_hex_string(ep->operand)); 237 238 top = (ep->status >> 11) & 7; 239 240 printf_unfiltered ("regno tag msb lsb value\n"); 241 for (fpreg = 7; fpreg >= 0; fpreg--) 242 { 243 double val; 244 245 printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : " ", fpreg); 246 247 switch ((ep->tag >> (fpreg * 2)) & 3) 248 { 249 case 0: printf_unfiltered ("valid "); break; 250 case 1: printf_unfiltered ("zero "); break; 251 case 2: printf_unfiltered ("trap "); break; 252 case 3: printf_unfiltered ("empty "); break; 253 } 254 for (i = 9; i >= 0; i--) 255 printf_unfiltered ("%02x", ep->regs[fpreg][i]); 256 257 floatformat_to_double(&floatformat_i387_ext, (char *) ep->regs[fpreg], 258 &val); 259 printf_unfiltered (" %g\n", val); 260 } 261} 262 263i386_float_info () 264{ 265 extern int inferior_pid; 266 267 if (inferior_pid) 268 { 269 ptrace (PT_GETFPREGS, inferior_pid, (PTRACE_ARG3_TYPE) &i386_fp_registers, 270 0); 271 } 272 else if (!i386_fp_read) 273 { 274 error ("The program has no floating point registers now."); 275 } 276 277 print_387_status (0, (struct env387 *) &i386_fp_registers); 278} 279#endif 280