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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [hppab-nat.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 104 markom
/* Machine-dependent hooks for the unix child process stratum.  This
2
   code is for the HP PA-RISC cpu.
3
 
4
   Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
5
 
6
   Contributed by the Center for Software Science at the
7
   University of Utah (pa-gdb-bugs@cs.utah.edu).
8
 
9
   This file is part of GDB.
10
 
11
   This program is free software; you can redistribute it and/or modify
12
   it under the terms of the GNU General Public License as published by
13
   the Free Software Foundation; either version 2 of the License, or
14
   (at your option) any later version.
15
 
16
   This program is distributed in the hope that it will be useful,
17
   but WITHOUT ANY WARRANTY; without even the implied warranty of
18
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
   GNU General Public License for more details.
20
 
21
   You should have received a copy of the GNU General Public License
22
   along with this program; if not, write to the Free Software
23
   Foundation, Inc., 59 Temple Place - Suite 330,
24
   Boston, MA 02111-1307, USA.  */
25
 
26
#include "defs.h"
27
#include "inferior.h"
28
#include "target.h"
29
#include <sys/ptrace.h>
30
 
31
/* Use an extra level of indirection for ptrace calls.
32
   This lets us breakpoint usefully on call_ptrace.   It also
33
   allows us to pass an extra argument to ptrace without
34
   using an ANSI-C specific macro.  */
35
 
36
#define ptrace call_ptrace
37
 
38
#if !defined (offsetof)
39
#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
40
#endif
41
 
42
/* U_REGS_OFFSET is the offset of the registers within the u area.  */
43
#if !defined (U_REGS_OFFSET)
44
#define U_REGS_OFFSET \
45
  ptrace (PT_READ_U, inferior_pid, \
46
          (PTRACE_ARG3_TYPE) (offsetof (struct user, u_ar0)), 0) \
47
    - KERNEL_U_ADDR
48
#endif
49
 
50
/* Fetch one register.  */
51
 
52
static void
53
fetch_register (regno)
54
     int regno;
55
{
56
  register unsigned int regaddr;
57
  char buf[MAX_REGISTER_RAW_SIZE];
58
  register int i;
59
 
60
  /* Offset of registers within the u area.  */
61
  unsigned int offset;
62
 
63
  offset = U_REGS_OFFSET;
64
 
65
  regaddr = register_addr (regno, offset);
66
  for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
67
    {
68
      errno = 0;
69
      *(int *) &buf[i] = ptrace (PT_RUREGS, inferior_pid,
70
                                 (PTRACE_ARG3_TYPE) regaddr, 0);
71
      regaddr += sizeof (int);
72
      if (errno != 0)
73
        {
74
          /* Warning, not error, in case we are attached; sometimes the
75
             kernel doesn't let us at the registers.  */
76
          char *err = safe_strerror (errno);
77
          char *msg = alloca (strlen (err) + 128);
78
          sprintf (msg, "reading register %s: %s", REGISTER_NAME (regno), err);
79
          warning (msg);
80
          goto error_exit;
81
        }
82
    }
83
  supply_register (regno, buf);
84
error_exit:;
85
}
86
 
87
/* Fetch all registers, or just one, from the child process.  */
88
 
89
void
90
fetch_inferior_registers (regno)
91
     int regno;
92
{
93
  if (regno == -1)
94
    for (regno = 0; regno < NUM_REGS; regno++)
95
      fetch_register (regno);
96
  else
97
    fetch_register (regno);
98
}
99
 
100
/* Store our register values back into the inferior.
101
   If REGNO is -1, do this for all registers.
102
   Otherwise, REGNO specifies which register (so we can save time).  */
103
 
104
void
105
store_inferior_registers (regno)
106
     int regno;
107
{
108
  register unsigned int regaddr;
109
  char buf[80];
110
  register int i;
111
  unsigned int offset = U_REGS_OFFSET;
112
  int scratch;
113
 
114
  if (regno >= 0)
115
    {
116
      if (CANNOT_STORE_REGISTER (regno))
117
        return;
118
      regaddr = register_addr (regno, offset);
119
      errno = 0;
120
      if (regno == PCOQ_HEAD_REGNUM || regno == PCOQ_TAIL_REGNUM)
121
        {
122
          scratch = *(int *) &registers[REGISTER_BYTE (regno)] | 0x3;
123
          ptrace (PT_WUREGS, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
124
                  scratch);
125
          if (errno != 0)
126
            {
127
              /* Error, even if attached.  Failing to write these two
128
                 registers is pretty serious.  */
129
              sprintf (buf, "writing register number %d", regno);
130
              perror_with_name (buf);
131
            }
132
        }
133
      else
134
        for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
135
          {
136
            errno = 0;
137
            ptrace (PT_WUREGS, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
138
                    *(int *) &registers[REGISTER_BYTE (regno) + i]);
139
            if (errno != 0)
140
              {
141
                /* Warning, not error, in case we are attached; sometimes the
142
                   kernel doesn't let us at the registers.  */
143
                char *err = safe_strerror (errno);
144
                char *msg = alloca (strlen (err) + 128);
145
                sprintf (msg, "writing register %s: %s",
146
                         REGISTER_NAME (regno), err);
147
                warning (msg);
148
                return;
149
              }
150
            regaddr += sizeof (int);
151
          }
152
    }
153
  else
154
    for (regno = 0; regno < NUM_REGS; regno++)
155
      store_inferior_registers (regno);
156
}
157
 
158
/* PT_PROT is specific to the PA BSD kernel and isn't documented
159
   anywhere (except here).
160
 
161
   PT_PROT allows one to enable/disable the data memory break bit
162
   for pages of memory in an inferior process.  This bit is used
163
   to cause "Data memory break traps" to occur when the appropriate
164
   page is written to.
165
 
166
   The arguments are as follows:
167
 
168
   PT_PROT -- The ptrace action to perform.
169
 
170
   INFERIOR_PID -- The pid of the process who's page table entries
171
   will be modified.
172
 
173
   PT_ARGS -- The *address* of a 3 word block of memory which has
174
   additional information:
175
 
176
   word 0 -- The start address to watch.  This should be a page-aligned
177
   address.
178
 
179
   word 1 -- The ending address to watch.  Again, this should be a
180
   page aligned address.
181
 
182
   word 2 -- Nonzero to enable the data memory break bit on the
183
   given address range or zero to disable the data memory break
184
   bit on the given address range.
185
 
186
   This call may fail if the given addresses are not valid in the inferior
187
   process.  This most often happens when restarting a program which
188
   as watchpoints inserted on heap or stack memory.  */
189
 
190
#define PT_PROT 21
191
 
192
int
193
hppa_set_watchpoint (addr, len, flag)
194
     int addr, len, flag;
195
{
196
  int pt_args[3];
197
  pt_args[0] = addr;
198
  pt_args[1] = addr + len;
199
  pt_args[2] = flag;
200
 
201
  /* Mask off the lower 12 bits since we want to work on a page basis.  */
202
  pt_args[0] >>= 12;
203
  pt_args[1] >>= 12;
204
 
205
  /* Rounding adjustments.  */
206
  pt_args[1] -= pt_args[0];
207
  pt_args[1]++;
208
 
209
  /* Put the lower 12 bits back as zero.  */
210
  pt_args[0] <<= 12;
211
  pt_args[1] <<= 12;
212
 
213
  /* Do it.  */
214
  return ptrace (PT_PROT, inferior_pid, (PTRACE_ARG3_TYPE) pt_args, 0);
215
}

powered by: WebSVN 2.1.0

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