OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [gdbserver/] [low-sparc.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 106 markom
/* 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 (program, allargs)
67
     char *program;
68
     char **allargs;
69
{
70
  int pid;
71
 
72
  pid = fork ();
73
  if (pid < 0)
74
    perror_with_name ("fork");
75
 
76
  if (pid == 0)
77
    {
78
      ptrace (PTRACE_TRACEME);
79
 
80
      execv (program, allargs);
81
 
82
      fprintf (stderr, "Cannot exec %s: %s.\n", program,
83
               errno < sys_nerr ? sys_errlist[errno] : "unknown error");
84
      fflush (stderr);
85
      _exit (0177);
86
    }
87
 
88
  return pid;
89
}
90
 
91
/* Kill the inferior process.  Make us have no inferior.  */
92
 
93
void
94
kill_inferior ()
95
{
96
  if (inferior_pid == 0)
97
    return;
98
  ptrace (8, inferior_pid, 0, 0);
99
  wait (0);
100
/*************inferior_died ();****VK**************/
101
}
102
 
103
/* Return nonzero if the given thread is still alive.  */
104
int
105
mythread_alive (pid)
106
     int pid;
107
{
108
  return 1;
109
}
110
 
111
/* Wait for process, returns status */
112
 
113
unsigned char
114
mywait (status)
115
     char *status;
116
{
117
  int pid;
118
  union wait w;
119
 
120
  pid = wait (&w);
121
  if (pid != inferior_pid)
122
    perror_with_name ("wait");
123
 
124
  if (WIFEXITED (w))
125
    {
126
      fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
127
      *status = 'W';
128
      return ((unsigned char) WEXITSTATUS (w));
129
    }
130
  else if (!WIFSTOPPED (w))
131
    {
132
      fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
133
      *status = 'X';
134
      return ((unsigned char) WTERMSIG (w));
135
    }
136
 
137
  fetch_inferior_registers (0);
138
 
139
  *status = 'T';
140
  return ((unsigned char) WSTOPSIG (w));
141
}
142
 
143
/* Resume execution of the inferior process.
144
   If STEP is nonzero, single-step it.
145
   If SIGNAL is nonzero, give it that signal.  */
146
 
147
void
148
myresume (step, signal)
149
     int step;
150
     int signal;
151
{
152
  errno = 0;
153
  ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, inferior_pid, 1, signal);
154
  if (errno)
155
    perror_with_name ("ptrace");
156
}
157
 
158
/* Fetch one or more registers from the inferior.  REGNO == -1 to get
159
   them all.  We actually fetch more than requested, when convenient,
160
   marking them as valid so we won't fetch them again.  */
161
 
162
void
163
fetch_inferior_registers (ignored)
164
     int ignored;
165
{
166
  struct regs inferior_registers;
167
  struct fp_status inferior_fp_registers;
168
  int i;
169
 
170
  /* Global and Out regs are fetched directly, as well as the control
171
     registers.  If we're getting one of the in or local regs,
172
     and the stack pointer has not yet been fetched,
173
     we have to do that first, since they're found in memory relative
174
     to the stack pointer.  */
175
 
176
  if (ptrace (PTRACE_GETREGS, inferior_pid,
177
              (PTRACE_ARG3_TYPE) & inferior_registers, 0))
178
    perror ("ptrace_getregs");
179
 
180
  registers[REGISTER_BYTE (0)] = 0;
181
  memcpy (&registers[REGISTER_BYTE (1)], &inferior_registers.r_g1,
182
          15 * REGISTER_RAW_SIZE (G0_REGNUM));
183
  *(int *) &registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
184
  *(int *) &registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
185
  *(int *) &registers[REGISTER_BYTE (NPC_REGNUM)] = inferior_registers.r_npc;
186
  *(int *) &registers[REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y;
187
 
188
  /* Floating point registers */
189
 
190
  if (ptrace (PTRACE_GETFPREGS, inferior_pid,
191
              (PTRACE_ARG3_TYPE) & inferior_fp_registers,
192
              0))
193
    perror ("ptrace_getfpregs");
194
  memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
195
          sizeof inferior_fp_registers.fpu_fr);
196
 
197
  /* These regs are saved on the stack by the kernel.  Only read them
198
     all (16 ptrace calls!) if we really need them.  */
199
 
200
  read_inferior_memory (*(CORE_ADDR *) & registers[REGISTER_BYTE (SP_REGNUM)],
201
                        &registers[REGISTER_BYTE (L0_REGNUM)],
202
                        16 * REGISTER_RAW_SIZE (L0_REGNUM));
203
}
204
 
205
/* Store our register values back into the inferior.
206
   If REGNO is -1, do this for all registers.
207
   Otherwise, REGNO specifies which register (so we can save time).  */
208
 
209
void
210
store_inferior_registers (ignored)
211
     int ignored;
212
{
213
  struct regs inferior_registers;
214
  struct fp_status inferior_fp_registers;
215
  CORE_ADDR sp = *(CORE_ADDR *) & registers[REGISTER_BYTE (SP_REGNUM)];
216
 
217
  write_inferior_memory (sp, &registers[REGISTER_BYTE (L0_REGNUM)],
218
                         16 * REGISTER_RAW_SIZE (L0_REGNUM));
219
 
220
  memcpy (&inferior_registers.r_g1, &registers[REGISTER_BYTE (G1_REGNUM)],
221
          15 * REGISTER_RAW_SIZE (G1_REGNUM));
222
 
223
  inferior_registers.r_ps =
224
    *(int *) &registers[REGISTER_BYTE (PS_REGNUM)];
225
  inferior_registers.r_pc =
226
    *(int *) &registers[REGISTER_BYTE (PC_REGNUM)];
227
  inferior_registers.r_npc =
228
    *(int *) &registers[REGISTER_BYTE (NPC_REGNUM)];
229
  inferior_registers.r_y =
230
    *(int *) &registers[REGISTER_BYTE (Y_REGNUM)];
231
 
232
  if (ptrace (PTRACE_SETREGS, inferior_pid,
233
              (PTRACE_ARG3_TYPE) & inferior_registers, 0))
234
    perror ("ptrace_setregs");
235
 
236
  memcpy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
237
          sizeof inferior_fp_registers.fpu_fr);
238
 
239
  if (ptrace (PTRACE_SETFPREGS, inferior_pid,
240
              (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0))
241
    perror ("ptrace_setfpregs");
242
}
243
 
244
/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
245
   in the NEW_SUN_PTRACE case.
246
   It ought to be straightforward.  But it appears that writing did
247
   not write the data that I specified.  I cannot understand where
248
   it got the data that it actually did write.  */
249
 
250
/* Copy LEN bytes from inferior's memory starting at MEMADDR
251
   to debugger memory starting at MYADDR.  */
252
 
253
read_inferior_memory (memaddr, myaddr, len)
254
     CORE_ADDR memaddr;
255
     char *myaddr;
256
     int len;
257
{
258
  register int i;
259
  /* Round starting address down to longword boundary.  */
260
  register CORE_ADDR addr = memaddr & -sizeof (int);
261
  /* Round ending address up; get number of longwords that makes.  */
262
  register int count
263
  = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
264
  /* Allocate buffer of that many longwords.  */
265
  register int *buffer = (int *) alloca (count * sizeof (int));
266
 
267
  /* Read all the longwords */
268
  for (i = 0; i < count; i++, addr += sizeof (int))
269
    {
270
      buffer[i] = ptrace (1, inferior_pid, addr, 0);
271
    }
272
 
273
  /* Copy appropriate bytes out of the buffer.  */
274
  memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
275
}
276
 
277
/* Copy LEN bytes of data from debugger memory at MYADDR
278
   to inferior's memory at MEMADDR.
279
   On failure (cannot write the inferior)
280
   returns the value of errno.  */
281
 
282
int
283
write_inferior_memory (memaddr, myaddr, len)
284
     CORE_ADDR memaddr;
285
     char *myaddr;
286
     int len;
287
{
288
  register int i;
289
  /* Round starting address down to longword boundary.  */
290
  register CORE_ADDR addr = memaddr & -sizeof (int);
291
  /* Round ending address up; get number of longwords that makes.  */
292
  register int count
293
  = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
294
  /* Allocate buffer of that many longwords.  */
295
  register int *buffer = (int *) alloca (count * sizeof (int));
296
  extern int errno;
297
 
298
  /* Fill start and end extra bytes of buffer with existing memory data.  */
299
 
300
  buffer[0] = ptrace (1, inferior_pid, addr, 0);
301
 
302
  if (count > 1)
303
    {
304
      buffer[count - 1]
305
        = ptrace (1, inferior_pid,
306
                  addr + (count - 1) * sizeof (int), 0);
307
    }
308
 
309
  /* Copy data to be written over corresponding part of buffer */
310
 
311
  bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
312
 
313
  /* Write the entire buffer.  */
314
 
315
  for (i = 0; i < count; i++, addr += sizeof (int))
316
    {
317
      errno = 0;
318
      ptrace (4, inferior_pid, addr, buffer[i]);
319
      if (errno)
320
        return errno;
321
    }
322
 
323
  return 0;
324
}
325
 
326
void
327
initialize_low ()
328
{
329
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.