]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/remote-vxsparc.c
Update FSF address.
[thirdparty/binutils-gdb.git] / gdb / remote-vxsparc.c
1 /* sparc-dependent portions of the RPC protocol
2 used with a VxWorks target
3
4 Contributed by Wind River Systems.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
22 #include <stdio.h>
23 #include "defs.h"
24
25 #include "vx-share/regPacket.h"
26 #include "frame.h"
27 #include "inferior.h"
28 #include "wait.h"
29 #include "target.h"
30 #include "gdbcore.h"
31 #include "command.h"
32 #include "symtab.h"
33 #include "symfile.h" /* for struct complaint */
34
35 #include "gdb_string.h"
36 #include <errno.h>
37 #include <signal.h>
38 #include <fcntl.h>
39 #include <sys/types.h>
40 #include <sys/time.h>
41 #include <sys/socket.h>
42
43 #ifdef _AIX /* IBM claims "void *malloc()" not char * */
44 #define malloc bogon_malloc
45 #endif
46
47 #include <rpc/rpc.h>
48 #include <sys/time.h> /* UTek's <rpc/rpc.h> doesn't #incl this */
49 #include <netdb.h>
50 #include "vx-share/ptrace.h"
51 #include "vx-share/xdr_ptrace.h"
52 #include "vx-share/xdr_ld.h"
53 #include "vx-share/xdr_rdb.h"
54 #include "vx-share/dbgRpcLib.h"
55
56 /* get rid of value.h if possible */
57 #include <value.h>
58 #include <symtab.h>
59
60 /* Flag set if target has fpu */
61
62 extern int target_has_fp;
63
64 /* sparc floating point format descriptor, from "sparc-tdep.c." */
65
66 extern struct ext_format ext_format_sparc;
67
68 /* Generic register read/write routines in remote-vx.c. */
69
70 extern void net_read_registers ();
71 extern void net_write_registers ();
72
73 /* Read a register or registers from the VxWorks target.
74 REGNO is the register to read, or -1 for all; currently,
75 it is ignored. FIXME look at regno to improve efficiency. */
76
77 void
78 vx_read_register (regno)
79 int regno;
80 {
81 char sparc_greg_packet[SPARC_GREG_PLEN];
82 char sparc_fpreg_packet[SPARC_FPREG_PLEN];
83 CORE_ADDR sp;
84
85 /* Get general-purpose registers. When copying values into
86 registers [], don't assume that a location in registers []
87 is properly aligned for the target data type. */
88
89 net_read_registers (sparc_greg_packet, SPARC_GREG_PLEN, PTRACE_GETREGS);
90
91 /* Now copy the register values into registers[].
92 Note that this code depends on the ordering of the REGNUMs
93 as defined in "tm-sparc.h". */
94
95 bcopy (&sparc_greg_packet[SPARC_R_G0],
96 &registers[REGISTER_BYTE (G0_REGNUM)], 32 * SPARC_GREG_SIZE);
97 bcopy (&sparc_greg_packet[SPARC_R_Y],
98 &registers[REGISTER_BYTE (Y_REGNUM)], 6 * SPARC_GREG_SIZE);
99
100 /* Now write the local and in registers to the register window
101 spill area in the frame. VxWorks does not do this for the
102 active frame automatically; it greatly simplifies debugging
103 (FRAME_FIND_SAVED_REGS, in particular, depends on this). */
104
105 sp = extract_address (&registers[REGISTER_BYTE (SP_REGNUM)],
106 REGISTER_RAW_SIZE (CORE_ADDR));
107 write_memory (sp, &registers[REGISTER_BYTE (L0_REGNUM)],
108 16 * REGISTER_RAW_SIZE (L0_REGNUM));
109
110 /* If the target has floating point registers, fetch them.
111 Otherwise, zero the floating point register values in
112 registers[] for good measure, even though we might not
113 need to. */
114
115 if (target_has_fp)
116 {
117 net_read_registers (sparc_fpreg_packet, SPARC_FPREG_PLEN,
118 PTRACE_GETFPREGS);
119 bcopy (&sparc_fpreg_packet[SPARC_R_FP0],
120 &registers[REGISTER_BYTE (FP0_REGNUM)], 32 * SPARC_FPREG_SIZE);
121 bcopy (&sparc_fpreg_packet[SPARC_R_FSR],
122 &registers[REGISTER_BYTE (FPS_REGNUM)], 1 * SPARC_FPREG_SIZE);
123 }
124 else
125 {
126 bzero (&registers[REGISTER_BYTE (FP0_REGNUM)], 32 * SPARC_FPREG_SIZE);
127 bzero (&registers[REGISTER_BYTE (FPS_REGNUM)], 1 * SPARC_FPREG_SIZE);
128 }
129
130 /* Mark the register cache valid. */
131
132 registers_fetched ();
133 }
134
135 /* Store a register or registers into the VxWorks target.
136 REGNO is the register to store, or -1 for all; currently,
137 it is ignored. FIXME look at regno to improve efficiency. */
138
139 void
140 vx_write_register (regno)
141 int regno;
142 {
143 char sparc_greg_packet[SPARC_GREG_PLEN];
144 char sparc_fpreg_packet[SPARC_FPREG_PLEN];
145 int in_gp_regs;
146 int in_fp_regs;
147 CORE_ADDR sp;
148
149 /* Store general purpose registers. When copying values from
150 registers [], don't assume that a location in registers []
151 is properly aligned for the target data type. */
152
153 in_gp_regs = 1;
154 in_fp_regs = 1;
155 if (regno >= 0)
156 {
157 if ((G0_REGNUM <= regno && regno <= I7_REGNUM)
158 || (Y_REGNUM <= regno && regno <= NPC_REGNUM))
159 in_fp_regs = 0;
160 else
161 in_gp_regs = 0;
162 }
163 if (in_gp_regs)
164 {
165 bcopy (&registers[REGISTER_BYTE (G0_REGNUM)],
166 &sparc_greg_packet[SPARC_R_G0], 32 * SPARC_GREG_SIZE);
167 bcopy (&registers[REGISTER_BYTE (Y_REGNUM)],
168 &sparc_greg_packet[SPARC_R_Y], 6 * SPARC_GREG_SIZE);
169
170 net_write_registers (sparc_greg_packet, SPARC_GREG_PLEN, PTRACE_SETREGS);
171
172 /* If this is a local or in register, or we're storing all
173 registers, update the register window spill area. */
174
175 if (regno < 0 || (L0_REGNUM <= regno && regno <= I7_REGNUM))
176 {
177 sp = extract_address (&registers[REGISTER_BYTE (SP_REGNUM)],
178 REGISTER_RAW_SIZE (CORE_ADDR));
179 write_memory (sp, &registers[REGISTER_BYTE (L0_REGNUM)],
180 16 * REGISTER_RAW_SIZE (L0_REGNUM));
181 }
182 }
183
184 /* Store floating point registers if the target has them. */
185
186 if (in_fp_regs && target_has_fp)
187 {
188 bcopy (&registers[REGISTER_BYTE (FP0_REGNUM)],
189 &sparc_fpreg_packet[SPARC_R_FP0], 32 * SPARC_FPREG_SIZE);
190 bcopy (&registers[REGISTER_BYTE (FPS_REGNUM)],
191 &sparc_fpreg_packet[SPARC_R_FSR], 1 * SPARC_FPREG_SIZE);
192
193 net_write_registers (sparc_fpreg_packet, SPARC_FPREG_PLEN,
194 PTRACE_SETFPREGS);
195 }
196 }
197
198 /* Convert from an extended float to a double.
199 The extended float is stored as raw data pointed to by FROM.
200 Return the converted value as raw data in the double pointed to by TO. */
201
202 void
203 vx_convert_to_virtual (regno, from, to)
204 int regno;
205 char *from;
206 char *to;
207 {
208 if (REGISTER_CONVERTIBLE (regno))
209 {
210 if (target_has_fp)
211 ieee_extended_to_double (&ext_format_sparc, from, to);
212 else
213 bzero (to, sizeof (double));
214 }
215 else
216 bcopy (from, to, REGISTER_VIRTUAL_SIZE (regno));
217 }
218
219 /* The converse: convert from a double to an extended float.
220 The double is stored as raw data pointed to by FROM.
221 Return the converted value as raw data in the extended
222 float pointed to by TO. */
223
224 void
225 vx_convert_from_virtual (regno, from, to)
226 int regno;
227 char *from;
228 char *to;
229 {
230 if (REGISTER_CONVERTIBLE (regno))
231 {
232 if (target_has_fp)
233 double_to_ieee_extended (&ext_format_sparc, from, to);
234 else
235 bzero (to, REGISTER_RAW_SIZE (FP0_REGNUM));
236 }
237 else
238 bcopy (from, to, REGISTER_VIRTUAL_SIZE (regno));
239 }