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

Subversion Repositories or1k

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

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, 2000 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, Boston, MA 02111-1307, USA.  */
19
 
20
#include "defs.h"
21
#include <sys/types.h>
22
#include <sys/wait.h>
23
#include "frame.h"
24
#include "inferior.h"
25
 
26
#include <stdio.h>
27
#include <errno.h>
28
 
29
/***************Begin MY defs*********************/
30
int quit_flag = 0;
31
static char my_registers[REGISTER_BYTES];
32
char *registers = my_registers;
33
 
34
/* Index within `registers' of the first byte of the space for
35
   register N.  */
36
 
37
char buf2[MAX_REGISTER_RAW_SIZE];
38
/***************End MY defs*********************/
39
 
40
#include <sys/ptrace.h>
41
#include <machine/reg.h>
42
 
43
extern int sys_nerr;
44
// extern char **sys_errlist;
45
extern char **environ;
46
extern int inferior_pid;
47
void quit (), perror_with_name ();
48
 
49
#ifdef TM_I386_H
50
/* i386_register_raw_size[i] is the number of bytes of storage in the
51
   actual machine representation for register i.  */
52
int i386_register_raw_size[MAX_NUM_REGS] = {
53
   4,  4,  4,  4,
54
   4,  4,  4,  4,
55
   4,  4,  4,  4,
56
   4,  4,  4,  4,
57
  10, 10, 10, 10,
58
  10, 10, 10, 10,
59
   4,  4,  4,  4,
60
   4,  4,  4,  4,
61
  16, 16, 16, 16,
62
  16, 16, 16, 16,
63
  4
64
};
65
 
66
int i386_register_byte[MAX_NUM_REGS];
67
 
68
static void
69
initialize_arch()
70
{
71
  /* Initialize the table saying where each register starts in the
72
     register file.  */
73
  {
74
    int i, offset;
75
 
76
    offset = 0;
77
    for (i = 0; i < MAX_NUM_REGS; i++)
78
      {
79
        i386_register_byte[i] = offset;
80
        offset += i386_register_raw_size[i];
81
      }
82
  }
83
}
84
 
85
#endif
86
 
87
 
88
/* Start an inferior process and returns its pid.
89
   ALLARGS is a vector of program-name and args.
90
   ENV is the environment vector to pass.  */
91
 
92
int
93
create_inferior (program, allargs)
94
     char *program;
95
     char **allargs;
96
{
97
  int pid;
98
 
99
  pid = fork ();
100
  if (pid < 0)
101
    perror_with_name ("fork");
102
 
103
  if (pid == 0)
104
    {
105
      ptrace (PT_TRACE_ME, 0, 0, 0);
106
 
107
      execv (program, allargs);
108
 
109
      fprintf (stderr, "Cannot exec %s: %s.\n", program,
110
               errno < sys_nerr ? sys_errlist[errno] : "unknown error");
111
      fflush (stderr);
112
      _exit (0177);
113
    }
114
 
115
  return pid;
116
}
117
 
118
/* Kill the inferior process.  Make us have no inferior.  */
119
 
120
void
121
kill_inferior ()
122
{
123
  if (inferior_pid == 0)
124
    return;
125
  ptrace (PT_KILL, inferior_pid, 0, 0);
126
  wait (0);
127
  /*************inferior_died ();****VK**************/
128
}
129
 
130
/* Return nonzero if the given thread is still alive.  */
131
int
132
mythread_alive (pid)
133
     int pid;
134
{
135
  return 1;
136
}
137
 
138
/* Wait for process, returns status */
139
 
140
unsigned char
141
mywait (status)
142
     char *status;
143
{
144
  int pid;
145
  int w;
146
 
147
  pid = wait (&w);
148
  if (pid != inferior_pid)
149
    perror_with_name ("wait");
150
 
151
  if (WIFEXITED (w))
152
    {
153
      fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
154
      *status = 'W';
155
      return ((unsigned char) WEXITSTATUS (w));
156
    }
157
  else if (!WIFSTOPPED (w))
158
    {
159
      fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
160
      *status = 'X';
161
      return ((unsigned char) WTERMSIG (w));
162
    }
163
 
164
  fetch_inferior_registers (0);
165
 
166
  *status = 'T';
167
  return ((unsigned char) WSTOPSIG (w));
168
}
169
 
170
/* Resume execution of the inferior process.
171
   If STEP is nonzero, single-step it.
172
   If SIGNAL is nonzero, give it that signal.  */
173
 
174
void
175
myresume (step, signal)
176
     int step;
177
     int signal;
178
{
179
  errno = 0;
180
  ptrace (step ? PT_STEP : PT_CONTINUE, inferior_pid,
181
          (PTRACE_ARG3_TYPE) 1, signal);
182
  if (errno)
183
    perror_with_name ("ptrace");
184
}
185
 
186
/* Fetch one or more registers from the inferior.  REGNO == -1 to get
187
   them all.  We actually fetch more than requested, when convenient,
188
   marking them as valid so we won't fetch them again.  */
189
 
190
void
191
fetch_inferior_registers (ignored)
192
     int ignored;
193
{
194
  struct reg inferior_registers;
195
  struct fpreg inferior_fp_registers;
196
 
197
  ptrace (PT_GETREGS, inferior_pid,
198
          (PTRACE_ARG3_TYPE) &inferior_registers, 0);
199
  memcpy (&registers[REGISTER_BYTE(0)], &inferior_registers,
200
          sizeof(inferior_registers));
201
 
202
#if 0 /* def FP0_REGNUM */
203
  ptrace (PT_GETFPREGS, inferior_pid,
204
          (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
205
  memcpy (&registers[REGISTER_BYTE(FP0_REGNUM)], &inferior_fp_registers,
206
          sizeof(inferior_fp_registers));
207
#endif
208
}
209
 
210
/* Store our register values back into the inferior.
211
   If REGNO is -1, do this for all registers.
212
   Otherwise, REGNO specifies which register (so we can save time).  */
213
 
214
void
215
store_inferior_registers (ignored)
216
     int ignored;
217
{
218
  struct reg inferior_registers;
219
  struct fpreg inferior_fp_registers;
220
 
221
  memcpy (&inferior_registers, &registers[REGISTER_BYTE(0)],
222
          sizeof(inferior_registers));
223
  ptrace (PT_SETREGS, inferior_pid,
224
          (PTRACE_ARG3_TYPE) &inferior_registers, 0);
225
 
226
#if 0 /* def FP0_REGNUM */
227
  memcpy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
228
          sizeof (inferior_fp_registers));
229
  ptrace (PT_SETFPREGS, inferior_pid,
230
          (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
231
#endif
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
read_inferior_memory (memaddr, myaddr, len)
244
     CORE_ADDR memaddr;
245
     char *myaddr;
246
     int len;
247
{
248
  register int i;
249
  /* Round starting address down to longword boundary.  */
250
  register CORE_ADDR addr = memaddr & -sizeof (int);
251
  /* Round ending address up; get number of longwords that makes.  */
252
  register int count
253
  = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
254
  /* Allocate buffer of that many longwords.  */
255
  register int *buffer = (int *) alloca (count * sizeof (int));
256
 
257
  /* Read all the longwords */
258
  for (i = 0; i < count; i++, addr += sizeof (int))
259
    {
260
      buffer[i] = ptrace (PT_READ_D, inferior_pid, (PTRACE_ARG3_TYPE) addr, 0);
261
    }
262
 
263
  /* Copy appropriate bytes out of the buffer.  */
264
  memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
265
}
266
 
267
/* Copy LEN bytes of data from debugger memory at MYADDR
268
   to inferior's memory at MEMADDR.
269
   On failure (cannot write the inferior)
270
   returns the value of errno.  */
271
 
272
int
273
write_inferior_memory (memaddr, myaddr, len)
274
     CORE_ADDR memaddr;
275
     char *myaddr;
276
     int len;
277
{
278
  register int i;
279
  /* Round starting address down to longword boundary.  */
280
  register CORE_ADDR addr = memaddr & -sizeof (int);
281
  /* Round ending address up; get number of longwords that makes.  */
282
  register int count
283
  = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
284
  /* Allocate buffer of that many longwords.  */
285
  register int *buffer = (int *) alloca (count * sizeof (int));
286
  extern int errno;
287
 
288
  /* Fill start and end extra bytes of buffer with existing memory data.  */
289
 
290
  buffer[0] = ptrace (PT_READ_D, inferior_pid, (PTRACE_ARG3_TYPE) addr, 0);
291
 
292
  if (count > 1)
293
    {
294
      buffer[count - 1]
295
        = ptrace (PT_READ_D, inferior_pid,
296
                  (PTRACE_ARG3_TYPE) addr + (count - 1) * sizeof (int), 0);
297
    }
298
 
299
  /* Copy data to be written over corresponding part of buffer */
300
 
301
  memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
302
 
303
  /* Write the entire buffer.  */
304
 
305
  for (i = 0; i < count; i++, addr += sizeof (int))
306
    {
307
      errno = 0;
308
      ptrace (PT_WRITE_D, inferior_pid, (PTRACE_ARG3_TYPE) addr, buffer[i]);
309
      if (errno)
310
        return errno;
311
    }
312
 
313
  return 0;
314
}
315
 
316
void
317
initialize_low ()
318
{
319
  initialize_arch ();
320
}

powered by: WebSVN 2.1.0

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