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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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