* c-valprint.c (print_function_pointer_address): New function
[deliverable/binutils-gdb.git] / gdb / gdbserver / low-sparc.c
1 /* Low level interface to ptrace, for the remote server for GDB.
2 Copyright (C) 1986, 1987, 1993 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21 #include "defs.h"
22 #include <sys/wait.h>
23 #include "frame.h"
24 #include "inferior.h"
25 /***************************
26 #include "initialize.h"
27 ****************************/
28
29 #include <stdio.h>
30 #include <sys/param.h>
31 #include <sys/dir.h>
32 #include <sys/user.h>
33 #include <signal.h>
34 #include <sys/ioctl.h>
35 #include <sgtty.h>
36 #include <fcntl.h>
37
38 /***************Begin MY defs*********************/
39 int quit_flag = 0;
40 static char my_registers[REGISTER_BYTES];
41 char *registers = my_registers;
42
43 /* Index within `registers' of the first byte of the space for
44 register N. */
45
46
47 char buf2[MAX_REGISTER_RAW_SIZE];
48 /***************End MY defs*********************/
49
50 #include <sys/ptrace.h>
51 #include <sys/reg.h>
52
53 extern int sys_nerr;
54 extern char **sys_errlist;
55 extern char **environ;
56 extern int errno;
57 extern int inferior_pid;
58 void quit (), perror_with_name ();
59 int query ();
60
61 /* Start an inferior process and returns its pid.
62 ALLARGS is a vector of program-name and args.
63 ENV is the environment vector to pass. */
64
65 int
66 create_inferior (char *program, char **allargs)
67 {
68 int pid;
69
70 pid = fork ();
71 if (pid < 0)
72 perror_with_name ("fork");
73
74 if (pid == 0)
75 {
76 ptrace (PTRACE_TRACEME);
77
78 execv (program, allargs);
79
80 fprintf (stderr, "Cannot exec %s: %s.\n", program,
81 errno < sys_nerr ? sys_errlist[errno] : "unknown error");
82 fflush (stderr);
83 _exit (0177);
84 }
85
86 return pid;
87 }
88
89 /* Kill the inferior process. Make us have no inferior. */
90
91 void
92 kill_inferior (void)
93 {
94 if (inferior_pid == 0)
95 return;
96 ptrace (8, inferior_pid, 0, 0);
97 wait (0);
98 /*************inferior_died ();****VK**************/
99 }
100
101 /* Return nonzero if the given thread is still alive. */
102 int
103 mythread_alive (int pid)
104 {
105 return 1;
106 }
107
108 /* Wait for process, returns status */
109
110 unsigned char
111 mywait (char *status)
112 {
113 int pid;
114 union wait w;
115
116 pid = wait (&w);
117 if (pid != inferior_pid)
118 perror_with_name ("wait");
119
120 if (WIFEXITED (w))
121 {
122 fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
123 *status = 'W';
124 return ((unsigned char) WEXITSTATUS (w));
125 }
126 else if (!WIFSTOPPED (w))
127 {
128 fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
129 *status = 'X';
130 return ((unsigned char) WTERMSIG (w));
131 }
132
133 fetch_inferior_registers (0);
134
135 *status = 'T';
136 return ((unsigned char) WSTOPSIG (w));
137 }
138
139 /* Resume execution of the inferior process.
140 If STEP is nonzero, single-step it.
141 If SIGNAL is nonzero, give it that signal. */
142
143 void
144 myresume (int step, int signal)
145 {
146 errno = 0;
147 ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, inferior_pid, 1, signal);
148 if (errno)
149 perror_with_name ("ptrace");
150 }
151
152 /* Fetch one or more registers from the inferior. REGNO == -1 to get
153 them all. We actually fetch more than requested, when convenient,
154 marking them as valid so we won't fetch them again. */
155
156 void
157 fetch_inferior_registers (int ignored)
158 {
159 struct regs inferior_registers;
160 struct fp_status inferior_fp_registers;
161 int i;
162
163 /* Global and Out regs are fetched directly, as well as the control
164 registers. If we're getting one of the in or local regs,
165 and the stack pointer has not yet been fetched,
166 we have to do that first, since they're found in memory relative
167 to the stack pointer. */
168
169 if (ptrace (PTRACE_GETREGS, inferior_pid,
170 (PTRACE_ARG3_TYPE) & inferior_registers, 0))
171 perror ("ptrace_getregs");
172
173 registers[REGISTER_BYTE (0)] = 0;
174 memcpy (&registers[REGISTER_BYTE (1)], &inferior_registers.r_g1,
175 15 * REGISTER_RAW_SIZE (G0_REGNUM));
176 *(int *) &registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
177 *(int *) &registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
178 *(int *) &registers[REGISTER_BYTE (NPC_REGNUM)] = inferior_registers.r_npc;
179 *(int *) &registers[REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y;
180
181 /* Floating point registers */
182
183 if (ptrace (PTRACE_GETFPREGS, inferior_pid,
184 (PTRACE_ARG3_TYPE) & inferior_fp_registers,
185 0))
186 perror ("ptrace_getfpregs");
187 memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
188 sizeof inferior_fp_registers.fpu_fr);
189
190 /* These regs are saved on the stack by the kernel. Only read them
191 all (16 ptrace calls!) if we really need them. */
192
193 read_inferior_memory (*(CORE_ADDR *) & registers[REGISTER_BYTE (SP_REGNUM)],
194 &registers[REGISTER_BYTE (L0_REGNUM)],
195 16 * REGISTER_RAW_SIZE (L0_REGNUM));
196 }
197
198 /* Store our register values back into the inferior.
199 If REGNO is -1, do this for all registers.
200 Otherwise, REGNO specifies which register (so we can save time). */
201
202 void
203 store_inferior_registers (int ignored)
204 {
205 struct regs inferior_registers;
206 struct fp_status inferior_fp_registers;
207 CORE_ADDR sp = *(CORE_ADDR *) & registers[REGISTER_BYTE (SP_REGNUM)];
208
209 write_inferior_memory (sp, &registers[REGISTER_BYTE (L0_REGNUM)],
210 16 * REGISTER_RAW_SIZE (L0_REGNUM));
211
212 memcpy (&inferior_registers.r_g1, &registers[REGISTER_BYTE (G1_REGNUM)],
213 15 * REGISTER_RAW_SIZE (G1_REGNUM));
214
215 inferior_registers.r_ps =
216 *(int *) &registers[REGISTER_BYTE (PS_REGNUM)];
217 inferior_registers.r_pc =
218 *(int *) &registers[REGISTER_BYTE (PC_REGNUM)];
219 inferior_registers.r_npc =
220 *(int *) &registers[REGISTER_BYTE (NPC_REGNUM)];
221 inferior_registers.r_y =
222 *(int *) &registers[REGISTER_BYTE (Y_REGNUM)];
223
224 if (ptrace (PTRACE_SETREGS, inferior_pid,
225 (PTRACE_ARG3_TYPE) & inferior_registers, 0))
226 perror ("ptrace_setregs");
227
228 memcpy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
229 sizeof inferior_fp_registers.fpu_fr);
230
231 if (ptrace (PTRACE_SETFPREGS, inferior_pid,
232 (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0))
233 perror ("ptrace_setfpregs");
234 }
235
236 /* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
237 in the NEW_SUN_PTRACE case.
238 It ought to be straightforward. But it appears that writing did
239 not write the data that I specified. I cannot understand where
240 it got the data that it actually did write. */
241
242 /* Copy LEN bytes from inferior's memory starting at MEMADDR
243 to debugger memory starting at MYADDR. */
244
245 read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
246 {
247 register int i;
248 /* Round starting address down to longword boundary. */
249 register CORE_ADDR addr = memaddr & -sizeof (int);
250 /* Round ending address up; get number of longwords that makes. */
251 register int count
252 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
253 /* Allocate buffer of that many longwords. */
254 register int *buffer = (int *) alloca (count * sizeof (int));
255
256 /* Read all the longwords */
257 for (i = 0; i < count; i++, addr += sizeof (int))
258 {
259 buffer[i] = ptrace (1, inferior_pid, addr, 0);
260 }
261
262 /* Copy appropriate bytes out of the buffer. */
263 memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
264 }
265
266 /* Copy LEN bytes of data from debugger memory at MYADDR
267 to inferior's memory at MEMADDR.
268 On failure (cannot write the inferior)
269 returns the value of errno. */
270
271 int
272 write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
273 {
274 register int i;
275 /* Round starting address down to longword boundary. */
276 register CORE_ADDR addr = memaddr & -sizeof (int);
277 /* Round ending address up; get number of longwords that makes. */
278 register int count
279 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
280 /* Allocate buffer of that many longwords. */
281 register int *buffer = (int *) alloca (count * sizeof (int));
282 extern int errno;
283
284 /* Fill start and end extra bytes of buffer with existing memory data. */
285
286 buffer[0] = ptrace (1, inferior_pid, addr, 0);
287
288 if (count > 1)
289 {
290 buffer[count - 1]
291 = ptrace (1, inferior_pid,
292 addr + (count - 1) * sizeof (int), 0);
293 }
294
295 /* Copy data to be written over corresponding part of buffer */
296
297 bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
298
299 /* Write the entire buffer. */
300
301 for (i = 0; i < count; i++, addr += sizeof (int))
302 {
303 errno = 0;
304 ptrace (4, inferior_pid, addr, buffer[i]);
305 if (errno)
306 return errno;
307 }
308
309 return 0;
310 }
311 \f
312 void
313 initialize_low (void)
314 {
315 }
This page took 0.049072 seconds and 4 git commands to generate.