xref: /openbsd-src/gnu/usr.bin/binutils/gdb/mipsnbsd-nat.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
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 (&registers[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 (&registers[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, &registers[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, &registers[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(&registers[REGISTER_BYTE (0)],
136 	   &core_reg->intreg, sizeof(struct reg));
137   }
138 
139   else if (which == 2) {
140     /* Floating point registers */
141     memcpy(&registers[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