2002-02-19 Daniel Jacobowitz <drow@mvista.com>
[deliverable/binutils-gdb.git] / gdb / hppab-nat.c
CommitLineData
c906108c
SS
1/* Machine-dependent hooks for the unix child process stratum. This
2 code is for the HP PA-RISC cpu.
3
b6ba6518
KB
4 Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1998,
5 1999, 2000, 2001 Free Software Foundation, Inc.
c906108c
SS
6
7 Contributed by the Center for Software Science at the
8 University of Utah (pa-gdb-bugs@cs.utah.edu).
9
c5aa993b 10 This file is part of GDB.
c906108c 11
c5aa993b
JM
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
c906108c 16
c5aa993b
JM
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
c906108c 21
c5aa993b
JM
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place - Suite 330,
25 Boston, MA 02111-1307, USA. */
c906108c
SS
26
27#include "defs.h"
28#include "inferior.h"
29#include "target.h"
4e052eda 30#include "regcache.h"
c906108c
SS
31#include <sys/ptrace.h>
32
33/* Use an extra level of indirection for ptrace calls.
34 This lets us breakpoint usefully on call_ptrace. It also
35 allows us to pass an extra argument to ptrace without
36 using an ANSI-C specific macro. */
37
38#define ptrace call_ptrace
39
40#if !defined (offsetof)
41#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
42#endif
43
44/* U_REGS_OFFSET is the offset of the registers within the u area. */
45#if !defined (U_REGS_OFFSET)
46#define U_REGS_OFFSET \
39f77062 47 ptrace (PT_READ_U, PIDGET (inferior_ptid), \
c906108c
SS
48 (PTRACE_ARG3_TYPE) (offsetof (struct user, u_ar0)), 0) \
49 - KERNEL_U_ADDR
50#endif
51
52/* Fetch one register. */
53
54static void
fba45db2 55fetch_register (int regno)
c906108c
SS
56{
57 register unsigned int regaddr;
58 char buf[MAX_REGISTER_RAW_SIZE];
59 register int i;
60
61 /* Offset of registers within the u area. */
62 unsigned int offset;
63
64 offset = U_REGS_OFFSET;
65
66 regaddr = register_addr (regno, offset);
67 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
68 {
69 errno = 0;
39f77062 70 *(int *) &buf[i] = ptrace (PT_RUREGS, PIDGET (inferior_ptid),
c906108c
SS
71 (PTRACE_ARG3_TYPE) regaddr, 0);
72 regaddr += sizeof (int);
73 if (errno != 0)
74 {
75 /* Warning, not error, in case we are attached; sometimes the
76 kernel doesn't let us at the registers. */
77 char *err = safe_strerror (errno);
78 char *msg = alloca (strlen (err) + 128);
79 sprintf (msg, "reading register %s: %s", REGISTER_NAME (regno), err);
80 warning (msg);
81 goto error_exit;
82 }
83 }
84 supply_register (regno, buf);
c5aa993b 85error_exit:;
c906108c
SS
86}
87
88/* Fetch all registers, or just one, from the child process. */
89
90void
fba45db2 91fetch_inferior_registers (int regno)
c906108c
SS
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
104void
fba45db2 105store_inferior_registers (int regno)
c906108c
SS
106{
107 register unsigned int regaddr;
108 char buf[80];
c906108c
SS
109 register int i;
110 unsigned int offset = U_REGS_OFFSET;
111 int scratch;
112
113 if (regno >= 0)
114 {
115 if (CANNOT_STORE_REGISTER (regno))
116 return;
117 regaddr = register_addr (regno, offset);
118 errno = 0;
119 if (regno == PCOQ_HEAD_REGNUM || regno == PCOQ_TAIL_REGNUM)
c5aa993b
JM
120 {
121 scratch = *(int *) &registers[REGISTER_BYTE (regno)] | 0x3;
39f77062 122 ptrace (PT_WUREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr,
c5aa993b
JM
123 scratch);
124 if (errno != 0)
125 {
c906108c 126 /* Error, even if attached. Failing to write these two
c5aa993b
JM
127 registers is pretty serious. */
128 sprintf (buf, "writing register number %d", regno);
129 perror_with_name (buf);
130 }
131 }
c906108c 132 else
c5aa993b 133 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
c906108c
SS
134 {
135 errno = 0;
39f77062
KB
136 ptrace (PT_WUREGS, PIDGET (inferior_ptid),
137 (PTRACE_ARG3_TYPE) regaddr,
c906108c
SS
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 }
c5aa993b 150 regaddr += sizeof (int);
c906108c
SS
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
c5aa993b
JM
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.
c906108c 172
c5aa993b
JM
173 PT_ARGS -- The *address* of a 3 word block of memory which has
174 additional information:
c906108c 175
c5aa993b
JM
176 word 0 -- The start address to watch. This should be a page-aligned
177 address.
c906108c 178
c5aa993b
JM
179 word 1 -- The ending address to watch. Again, this should be a
180 page aligned address.
c906108c 181
c5aa993b
JM
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.
c906108c 185
c5aa993b
JM
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
7e73cedf 188 has watchpoints inserted on heap or stack memory. */
c906108c 189
c906108c
SS
190#define PT_PROT 21
191
192int
fba45db2 193hppa_set_watchpoint (int addr, int len, int flag)
c906108c
SS
194{
195 int pt_args[3];
196 pt_args[0] = addr;
197 pt_args[1] = addr + len;
198 pt_args[2] = flag;
199
200 /* Mask off the lower 12 bits since we want to work on a page basis. */
c5aa993b
JM
201 pt_args[0] >>= 12;
202 pt_args[1] >>= 12;
c906108c
SS
203
204 /* Rounding adjustments. */
c5aa993b
JM
205 pt_args[1] -= pt_args[0];
206 pt_args[1]++;
c906108c
SS
207
208 /* Put the lower 12 bits back as zero. */
c5aa993b
JM
209 pt_args[0] <<= 12;
210 pt_args[1] <<= 12;
c906108c
SS
211
212 /* Do it. */
39f77062 213 return ptrace (PT_PROT, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) pt_args, 0);
c906108c 214}
This page took 0.174468 seconds and 4 git commands to generate.