1 /* Machine-dependent hooks for the unix child process stratum. This
2 code is for the HP PA-RISC cpu.
4 Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
6 Contributed by the Center for Software Science at the
9 This file is part of GDB.
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.
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.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
28 #include <sys/ptrace.h>
30 /* Use an extra level of indirection for ptrace calls.
31 This lets us breakpoint usefully on call_ptrace. It also
32 allows us to pass an extra argument to ptrace without
33 using an ANSI-C specific macro. */
35 #define ptrace call_ptrace
37 #if !defined (offsetof)
38 #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
41 /* U_REGS_OFFSET is the offset of the registers within the u area. */
42 #if !defined (U_REGS_OFFSET)
43 #define U_REGS_OFFSET \
44 ptrace (PT_READ_U, inferior_pid, \
45 (PTRACE_ARG3_TYPE) (offsetof (struct user, u_ar0)), 0) \
49 /* Fetch one register. */
52 fetch_register (regno)
55 register unsigned int regaddr;
56 char buf[MAX_REGISTER_RAW_SIZE];
59 /* Offset of registers within the u area. */
62 offset = U_REGS_OFFSET;
64 regaddr = register_addr (regno, offset);
65 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
68 *(int *) &buf[i] = ptrace (PT_RUREGS, inferior_pid,
69 (PTRACE_ARG3_TYPE) regaddr, 0);
70 regaddr += sizeof (int);
73 /* Warning, not error, in case we are attached; sometimes the
74 kernel doesn't let us at the registers. */
75 char *err = safe_strerror (errno);
76 char *msg = alloca (strlen (err) + 128);
77 sprintf (msg, "reading register %s: %s", reg_names[regno], err);
82 supply_register (regno, buf);
86 /* Fetch all registers, or just one, from the child process. */
89 fetch_inferior_registers (regno)
93 for (regno = 0; regno < NUM_REGS; regno++)
94 fetch_register (regno);
96 fetch_register (regno);
99 /* Store our register values back into the inferior.
100 If REGNO is -1, do this for all registers.
101 Otherwise, REGNO specifies which register (so we can save time). */
104 store_inferior_registers (regno)
107 register unsigned int regaddr;
108 extern char registers[];
111 unsigned int offset = U_REGS_OFFSET;
115 regaddr = register_addr (regno, offset);
116 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(int))
119 ptrace (PT_WUREGS, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
120 *(int *) ®isters[REGISTER_BYTE (regno) + i]);
123 char *err = safe_strerror (errno);
124 char *msg = alloca (strlen (err) + 128);
125 sprintf (msg, "writing register %s: %s", reg_names[regno], err);
128 regaddr += sizeof(int);
133 for (regno = 0; regno < NUM_REGS; regno++)
135 if (CANNOT_STORE_REGISTER (regno))
137 store_inferior_registers (regno);
144 /* PT_PROT is specific to the PA BSD kernel and isn't documented
145 anywhere (except here).
147 PT_PROT allows one to enable/disable the data memory break bit
148 for pages of memory in an inferior process. This bit is used
149 to cause "Data memory break traps" to occur when the appropriate
152 The arguments are as follows:
154 PT_PROT -- The ptrace action to perform.
156 INFERIOR_PID -- The pid of the process who's page table entries
159 PT_ARGS -- The *address* of a 3 word block of memory which has
160 additional information:
162 word 0 -- The start address to watch. This should be a page-aligned
165 word 1 -- The ending address to watch. Again, this should be a
166 page aligned address.
168 word 2 -- Nonzero to enable the data memory break bit on the
169 given address range or zero to disable the data memory break
170 bit on the given address range.
172 This call may fail if the given addresses are not valid in the inferior
173 process. This most often happens when restarting a program which
174 as watchpoints inserted on heap or stack memory. */
179 hppa_set_watchpoint (addr, len, flag)
184 pt_args[1] = addr + len;
187 /* Mask off the lower 12 bits since we want to work on a page basis. */
191 /* Rounding adjustments. */
192 pt_args[1] -= pt_args[0];
195 /* Put the lower 12 bits back as zero. */
200 return ptrace (PT_PROT, inferior_pid, (PTRACE_ARG3_TYPE) pt_args, 0);