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

Subversion Repositories or1k

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

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

powered by: WebSVN 2.1.0

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