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

Subversion Repositories or1k

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

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

powered by: WebSVN 2.1.0

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