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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [gdbserver/] [low-hppabsd.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) 1995 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 <stdio.h>
27
#include <sys/param.h>
28
#include <sys/dir.h>
29
#include <sys/user.h>
30
#include <signal.h>
31
#include <sys/ioctl.h>
32
#include <sgtty.h>
33
#include <fcntl.h>
34
 
35
/***************Begin MY defs*********************/
36
int quit_flag = 0;
37
static char my_registers[REGISTER_BYTES];
38
char *registers = my_registers;
39
 
40
/* Index within `registers' of the first byte of the space for
41
   register N.  */
42
 
43
 
44
char buf2[MAX_REGISTER_RAW_SIZE];
45
/***************End MY defs*********************/
46
 
47
#include <sys/ptrace.h>
48
#include <machine/reg.h>
49
 
50
extern char **environ;
51
extern int errno;
52
extern int inferior_pid;
53
void quit (), perror_with_name ();
54
int query ();
55
 
56
/* Start an inferior process and returns its pid.
57
   ALLARGS is a vector of program-name and args.
58
   ENV is the environment vector to pass.  */
59
 
60
int
61
create_inferior (program, allargs)
62
     char *program;
63
     char **allargs;
64
{
65
  int pid;
66
 
67
  pid = fork ();
68
  if (pid < 0)
69
    perror_with_name ("fork");
70
 
71
  if (pid == 0)
72
    {
73
      ptrace (PT_TRACE_ME, 0, 0, 0, 0);
74
 
75
      execv (program, allargs);
76
 
77
      fprintf (stderr, "Cannot exec %s: %s.\n", program,
78
               errno < sys_nerr ? sys_errlist[errno] : "unknown error");
79
      fflush (stderr);
80
      _exit (0177);
81
    }
82
 
83
  return pid;
84
}
85
 
86
/* Kill the inferior process.  Make us have no inferior.  */
87
 
88
void
89
kill_inferior ()
90
{
91
  if (inferior_pid == 0)
92
    return;
93
  ptrace (8, inferior_pid, 0, 0, 0);
94
  wait (0);
95
/*************inferior_died ();****VK**************/
96
}
97
 
98
/* Return nonzero if the given thread is still alive.  */
99
int
100
mythread_alive (pid)
101
     int pid;
102
{
103
  return 1;
104
}
105
 
106
/* Wait for process, returns status */
107
 
108
unsigned char
109
mywait (status)
110
     char *status;
111
{
112
  int pid;
113
  union wait w;
114
 
115
  pid = wait (&w);
116
  if (pid != inferior_pid)
117
    perror_with_name ("wait");
118
 
119
  if (WIFEXITED (w))
120
    {
121
      fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
122
      *status = 'W';
123
      return ((unsigned char) WEXITSTATUS (w));
124
    }
125
  else if (!WIFSTOPPED (w))
126
    {
127
      fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
128
      *status = 'X';
129
      return ((unsigned char) WTERMSIG (w));
130
    }
131
 
132
  fetch_inferior_registers (0);
133
 
134
  *status = 'T';
135
  return ((unsigned char) WSTOPSIG (w));
136
}
137
 
138
/* Resume execution of the inferior process.
139
   If STEP is nonzero, single-step it.
140
   If SIGNAL is nonzero, give it that signal.  */
141
 
142
void
143
myresume (step, signal)
144
     int step;
145
     int signal;
146
{
147
  errno = 0;
148
  ptrace (step ? PT_STEP : PT_CONTINUE, inferior_pid, 1, signal, 0);
149
  if (errno)
150
    perror_with_name ("ptrace");
151
}
152
 
153
 
154
#if !defined (offsetof)
155
#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
156
#endif
157
 
158
/* U_REGS_OFFSET is the offset of the registers within the u area.  */
159
#if !defined (U_REGS_OFFSET)
160
#define U_REGS_OFFSET \
161
  ptrace (PT_READ_U, inferior_pid, \
162
          (PTRACE_ARG3_TYPE) (offsetof (struct user, u_ar0)), 0) \
163
    - KERNEL_U_ADDR
164
#endif
165
 
166
CORE_ADDR
167
register_addr (regno, blockend)
168
     int regno;
169
     CORE_ADDR blockend;
170
{
171
  CORE_ADDR addr;
172
 
173
  if (regno < 0 || regno >= ARCH_NUM_REGS)
174
    error ("Invalid register number %d.", regno);
175
 
176
  REGISTER_U_ADDR (addr, blockend, regno);
177
 
178
  return addr;
179
}
180
 
181
/* Fetch one register.  */
182
 
183
static void
184
fetch_register (regno)
185
     int regno;
186
{
187
  register unsigned int regaddr;
188
  char buf[MAX_REGISTER_RAW_SIZE];
189
  register int i;
190
 
191
  /* Offset of registers within the u area.  */
192
  unsigned int offset;
193
 
194
  offset = U_REGS_OFFSET;
195
 
196
  regaddr = register_addr (regno, offset);
197
  for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
198
    {
199
      errno = 0;
200
      *(int *) &registers[regno * 4 + i] = ptrace (PT_RUREGS, inferior_pid,
201
                                          (PTRACE_ARG3_TYPE) regaddr, 0, 0);
202
      regaddr += sizeof (int);
203
      if (errno != 0)
204
        {
205
          /* Warning, not error, in case we are attached; sometimes the
206
             kernel doesn't let us at the registers.  */
207
          char *err = strerror (errno);
208
          char *msg = alloca (strlen (err) + 128);
209
          sprintf (msg, "reading register %d: %s", regno, err);
210
          error (msg);
211
          goto error_exit;
212
        }
213
    }
214
error_exit:;
215
}
216
 
217
/* Fetch all registers, or just one, from the child process.  */
218
 
219
void
220
fetch_inferior_registers (regno)
221
     int regno;
222
{
223
  if (regno == -1 || regno == 0)
224
    for (regno = 0; regno < NUM_REGS; regno++)
225
      fetch_register (regno);
226
  else
227
    fetch_register (regno);
228
}
229
 
230
/* Store our register values back into the inferior.
231
   If REGNO is -1, do this for all registers.
232
   Otherwise, REGNO specifies which register (so we can save time).  */
233
 
234
void
235
store_inferior_registers (regno)
236
     int regno;
237
{
238
  register unsigned int regaddr;
239
  char buf[80];
240
  extern char registers[];
241
  register int i;
242
  unsigned int offset = U_REGS_OFFSET;
243
  int scratch;
244
 
245
  if (regno >= 0)
246
    {
247
      if (CANNOT_STORE_REGISTER (regno))
248
        return;
249
      regaddr = register_addr (regno, offset);
250
      errno = 0;
251
      if (regno == PCOQ_HEAD_REGNUM || regno == PCOQ_TAIL_REGNUM)
252
        {
253
          scratch = *(int *) &registers[REGISTER_BYTE (regno)] | 0x3;
254
          ptrace (PT_WUREGS, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
255
                  scratch, 0);
256
          if (errno != 0)
257
            {
258
              /* Error, even if attached.  Failing to write these two
259
                 registers is pretty serious.  */
260
              sprintf (buf, "writing register number %d", regno);
261
              perror_with_name (buf);
262
            }
263
        }
264
      else
265
        for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
266
          {
267
            errno = 0;
268
            ptrace (PT_WUREGS, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
269
                    *(int *) &registers[REGISTER_BYTE (regno) + i], 0);
270
            if (errno != 0)
271
              {
272
                /* Warning, not error, in case we are attached; sometimes the
273
                   kernel doesn't let us at the registers.  */
274
                char *err = strerror (errno);
275
                char *msg = alloca (strlen (err) + 128);
276
                sprintf (msg, "writing register %d: %s",
277
                         regno, err);
278
                error (msg);
279
                return;
280
              }
281
            regaddr += sizeof (int);
282
          }
283
    }
284
  else
285
    for (regno = 0; regno < NUM_REGS; regno++)
286
      store_inferior_registers (regno);
287
}
288
 
289
/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
290
   in the NEW_SUN_PTRACE case.
291
   It ought to be straightforward.  But it appears that writing did
292
   not write the data that I specified.  I cannot understand where
293
   it got the data that it actually did write.  */
294
 
295
/* Copy LEN bytes from inferior's memory starting at MEMADDR
296
   to debugger memory starting at MYADDR.  */
297
 
298
read_inferior_memory (memaddr, myaddr, len)
299
     CORE_ADDR memaddr;
300
     char *myaddr;
301
     int len;
302
{
303
  register int i;
304
  /* Round starting address down to longword boundary.  */
305
  register CORE_ADDR addr = memaddr & -sizeof (int);
306
  /* Round ending address up; get number of longwords that makes.  */
307
  register int count
308
  = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
309
  /* Allocate buffer of that many longwords.  */
310
  register int *buffer = (int *) alloca (count * sizeof (int));
311
 
312
  /* Read all the longwords */
313
  for (i = 0; i < count; i++, addr += sizeof (int))
314
    {
315
      buffer[i] = ptrace (1, inferior_pid, addr, 0, 0);
316
    }
317
 
318
  /* Copy appropriate bytes out of the buffer.  */
319
  memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
320
}
321
 
322
/* Copy LEN bytes of data from debugger memory at MYADDR
323
   to inferior's memory at MEMADDR.
324
   On failure (cannot write the inferior)
325
   returns the value of errno.  */
326
 
327
int
328
write_inferior_memory (memaddr, myaddr, len)
329
     CORE_ADDR memaddr;
330
     char *myaddr;
331
     int len;
332
{
333
  register int i;
334
  /* Round starting address down to longword boundary.  */
335
  register CORE_ADDR addr = memaddr & -sizeof (int);
336
  /* Round ending address up; get number of longwords that makes.  */
337
  register int count
338
  = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
339
  /* Allocate buffer of that many longwords.  */
340
  register int *buffer = (int *) alloca (count * sizeof (int));
341
  extern int errno;
342
 
343
  /* Fill start and end extra bytes of buffer with existing memory data.  */
344
 
345
  buffer[0] = ptrace (1, inferior_pid, addr, 0, 0);
346
 
347
  if (count > 1)
348
    {
349
      buffer[count - 1]
350
        = ptrace (1, inferior_pid,
351
                  addr + (count - 1) * sizeof (int), 0, 0);
352
    }
353
 
354
  /* Copy data to be written over corresponding part of buffer */
355
 
356
  memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
357
 
358
  /* Write the entire buffer.  */
359
 
360
  for (i = 0; i < count; i++, addr += sizeof (int))
361
    {
362
      errno = 0;
363
      ptrace (4, inferior_pid, addr, buffer[i], 0);
364
      if (errno)
365
        return errno;
366
    }
367
 
368
  return 0;
369
}
370
 
371
void
372
initialize_low ()
373
{
374
}

powered by: WebSVN 2.1.0

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