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

Subversion Repositories or1k

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

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

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

powered by: WebSVN 2.1.0

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