1 /* Functions specific to running gdb native on a mips running NetBSD 2 Copyright 1997 Free Software Foundation, Inc. 3 Contributed by Jonathan Stone(jonathan@dsg.stanford.edu) at Stanford 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, Boston, MA 02111-1307, USA. */ 20 21 #include <sys/types.h> 22 #include <sys/ptrace.h> 23 #include <machine/reg.h> 24 #include <machine/pcb.h> 25 #include <setjmp.h> 26 27 #include "defs.h" 28 #include "inferior.h" 29 #include "target.h" 30 #include "gdbcore.h" 31 32 #define JB_ELEMENT_SIZE 4 33 34 void 35 fetch_inferior_registers (regno) 36 int regno; 37 { 38 struct reg inferior_registers; 39 struct fpreg inferior_fp_registers; 40 41 bzero(&inferior_registers, sizeof(inferior_registers)); 42 ptrace (PT_GETREGS, inferior_pid, 43 (PTRACE_ARG3_TYPE) &inferior_registers, 0); 44 45 memcpy (®isters[REGISTER_BYTE (0)], 46 &inferior_registers, sizeof(inferior_registers)); 47 48 bzero(&inferior_fp_registers, sizeof(inferior_fp_registers)); 49 ptrace (PT_GETFPREGS, inferior_pid, 50 (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0); 51 52 memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], 53 &inferior_fp_registers, sizeof(struct fpreg)); 54 55 registers_fetched (); 56 } 57 58 void 59 store_inferior_registers (regno) 60 int regno; 61 { 62 struct reg inferior_registers; 63 struct fpreg inferior_fp_registers; 64 65 memcpy (&inferior_registers, ®isters[REGISTER_BYTE (0)], 66 sizeof(inferior_registers)); 67 68 ptrace (PT_SETREGS, inferior_pid, 69 (PTRACE_ARG3_TYPE) &inferior_registers, 0); 70 71 memcpy (&inferior_fp_registers, ®isters[REGISTER_BYTE (FP0_REGNUM)], 72 sizeof(inferior_fp_registers)); 73 74 ptrace (PT_SETFPREGS, inferior_pid, 75 (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0); 76 } 77 78 79 /* Figure out where the longjmp will land. 80 We expect the first arg to be a pointer to the jmp_buf structure from which 81 we extract the pc (JB_PC) that we will land at. The pc is copied into PC. 82 This routine returns true on success. */ 83 84 int 85 get_longjmp_target(pc) 86 CORE_ADDR *pc; 87 { 88 CORE_ADDR jb_addr; 89 char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT]; 90 91 jb_addr = read_register (A0_REGNUM); 92 93 if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf, 94 TARGET_PTR_BIT / TARGET_CHAR_BIT)) 95 return 0; 96 97 *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT); 98 99 return 1; 100 } 101 102 103 /* XXX - Add this to machine/regs.h instead? */ 104 struct md_core { 105 struct reg intreg; 106 struct fpreg freg; 107 }; 108 109 110 /* Extract the register values out of the core file and store 111 them where `read_register' will find them. 112 113 CORE_REG_SECT points to the register values themselves, read into memory. 114 CORE_REG_SIZE is the size of that area. 115 WHICH says which set of registers we are handling (0 = int, 2 = float 116 on machines where they are discontiguous). 117 REG_ADDR is the offset from u.u_ar0 to the register values relative to 118 core_reg_sect. This is used with old-fashioned core files to 119 locate the registers in a large upage-plus-stack ".reg" section. 120 Original upage address X is at location core_reg_sect+x+reg_addr. 121 */ 122 void 123 fetch_core_registers (core_reg_sect, core_reg_size, which, ignore) 124 char *core_reg_sect; 125 unsigned core_reg_size; 126 int which; 127 unsigned int ignore; /* reg addr, unused in this version */ 128 { 129 struct md_core *core_reg; 130 131 core_reg = (struct md_core *)core_reg_sect; 132 133 if (which == 0) { 134 /* Integer registers */ 135 memcpy(®isters[REGISTER_BYTE (0)], 136 &core_reg->intreg, sizeof(struct reg)); 137 } 138 139 else if (which == 2) { 140 /* Floating point registers */ 141 memcpy(®isters[REGISTER_BYTE (FP0_REGNUM)], 142 &core_reg->freg, sizeof(struct fpreg)); 143 } 144 } 145 146 #ifdef FETCH_KCORE_REGISTERS 147 /* Get registers from a kernel crash dump. 148 FIXME: NetBSD 1.3 does not produce kernel crashdumps. */ 149 void 150 fetch_kcore_registers(pcb) 151 struct pcb *pcb; 152 { 153 int i, *ip, tmp=0; 154 u_long sp; 155 156 #if 0 157 supply_register(SP_REGNUM, (char *)&pcb->pcb_sp); 158 supply_register(PC_REGNUM, (char *)&pcb->pcb_pc); 159 #endif 160 161 /* The kernel does not use the FPU, so ignore it. */ 162 registers_fetched (); 163 } 164 #endif /* FETCH_KCORE_REGISTERS */ 165 166 167 /* Register that we are able to handle core file formats. 168 FIXME: is this really bfd_target_unknown_flavour? */ 169 170 static struct core_fns netbsd_core_fns = 171 { 172 bfd_target_unknown_flavour, 173 fetch_core_registers, 174 NULL 175 }; 176 177 void 178 _initialize_mipsbsd_nat () 179 { 180 add_core_fns (&netbsd_core_fns); 181 } 182