Commit | Line | Data |
---|---|---|
5076de82 FF |
1 | /* Native support for HPPA-RISC machine running HPUX, for GDB. |
2 | Copyright 1991, 1992 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 | |
6c9638b4 | 18 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
5076de82 FF |
19 | |
20 | #define U_REGS_OFFSET 0 | |
21 | ||
fe15373a JL |
22 | #define KERNEL_U_ADDR 0 |
23 | ||
5076de82 FF |
24 | /* What a coincidence! */ |
25 | #define REGISTER_U_ADDR(addr, blockend, regno) \ | |
26 | { addr = (int)(blockend) + REGISTER_BYTE (regno);} | |
22b4b223 | 27 | |
fe15373a JL |
28 | /* HPUX 8.0, in its infinite wisdom, has chosen to prototype ptrace |
29 | with five arguments, so programs written for normal ptrace lose. */ | |
30 | #define FIVE_ARG_PTRACE | |
31 | ||
32 | /* We need to figure out where the text region is so that we use the | |
33 | appropriate ptrace operator to manipulate text. Simply reading/writing | |
34 | user space will crap out HPUX. */ | |
a6a070be | 35 | #define NEED_TEXT_START_END 1 |
fe15373a JL |
36 | |
37 | /* This macro defines the register numbers (from REGISTER_NAMES) that | |
38 | are effectively unavailable to the user through ptrace(). It allows | |
39 | us to include the whole register set in REGISTER_NAMES (inorder to | |
40 | better support remote debugging). If it is used in | |
41 | fetch/store_inferior_registers() gdb will not complain about I/O errors | |
42 | on fetching these registers. If all registers in REGISTER_NAMES | |
43 | are available, then return false (0). */ | |
44 | ||
45 | #define CANNOT_STORE_REGISTER(regno) \ | |
46 | ((regno) == 0) || \ | |
47 | ((regno) == PCSQ_HEAD_REGNUM) || \ | |
48 | ((regno) >= PCSQ_TAIL_REGNUM && (regno) < IPSW_REGNUM) || \ | |
49 | ((regno) > IPSW_REGNUM && (regno) < FP4_REGNUM) | |
50 | ||
61ada545 | 51 | /* In hppah-nat.c: */ |
40df7e27 | 52 | #define FETCH_INFERIOR_REGISTERS |
40df7e27 | 53 | #define CHILD_XFER_MEMORY |
61ada545 DT |
54 | #define CHILD_POST_FOLLOW_INFERIOR_BY_CLONE |
55 | #define CHILD_POST_FOLLOW_VFORK | |
56 | ||
57 | /* While this is for use by threaded programs, it doesn't appear | |
58 | * to hurt non-threaded ones. This is used in infrun.c: */ | |
59 | #define PREPARE_TO_PROCEED() hppa_prepare_to_proceed() | |
60 | extern int hppa_prepare_to_proceed PARAMS(( void )); | |
61 | ||
62 | /* In infptrace.c or infttrace.c: */ | |
63 | #define CHILD_PID_TO_EXEC_FILE | |
64 | #define CHILD_POST_STARTUP_INFERIOR | |
65 | #define CHILD_ACKNOWLEDGE_CREATED_INFERIOR | |
66 | #define CHILD_INSERT_FORK_CATCHPOINT | |
67 | #define CHILD_REMOVE_FORK_CATCHPOINT | |
68 | #define CHILD_INSERT_VFORK_CATCHPOINT | |
69 | #define CHILD_REMOVE_VFORK_CATCHPOINT | |
70 | #define CHILD_HAS_FORKED | |
71 | #define CHILD_HAS_VFORKED | |
72 | #define CHILD_CAN_FOLLOW_VFORK_PRIOR_TO_EXEC | |
73 | #define CHILD_INSERT_EXEC_CATCHPOINT | |
74 | #define CHILD_REMOVE_EXEC_CATCHPOINT | |
75 | #define CHILD_HAS_EXECD | |
76 | #define CHILD_REPORTED_EXEC_EVENTS_PER_EXEC_CALL | |
77 | #define CHILD_HAS_SYSCALL_EVENT | |
78 | #define CHILD_POST_ATTACH | |
79 | #define CHILD_THREAD_ALIVE | |
80 | ||
81 | #define REQUIRE_ATTACH(pid) hppa_require_attach(pid) | |
82 | extern int hppa_require_attach PARAMS ((int)); | |
83 | ||
84 | #define REQUIRE_DETACH(pid,signal) hppa_require_detach(pid,signal) | |
85 | extern int hppa_require_detach PARAMS ((int,int)); | |
86 | ||
87 | /* In infptrace.c or infttrace.c: */ | |
88 | ||
89 | #define HPPA_GET_PROCESS_EVENTS | |
90 | ||
91 | /* These types and function provide an interface that is independent | |
92 | of ptrace or ttrace, and that may be used to determine the most | |
93 | recent event returned by a waited process. | |
94 | ||
95 | hppa_get_process_events may return multiple event kinds from a single | |
96 | call, by returning a bit-vector of event kinds. (However, no single | |
97 | event may be represented more than once in a single call. E.g., a | |
98 | call may indicate that both a fork and a signal occurred, but cannot | |
99 | indicate that two signals occurred.) | |
100 | ||
101 | Also, this function returns an indication (third parameter set to | |
102 | non-zero) of whether the query mandates that the process be continued | |
103 | afterwards. (This is required when using ptrace PT_GET_PROCESS_STATE; | |
104 | not continuing the process afterwards will cause subsequent waits to | |
105 | return the same event, ad infinitum. Sigh.) */ | |
106 | typedef enum { | |
107 | PEVT_NONE = 0, | |
108 | PEVT_SIGNAL = 0x01, | |
109 | PEVT_FORK = 0x02, | |
110 | PEVT_VFORK = 0x04, | |
111 | PEVT_EXEC = 0x08, | |
112 | PEVT_EXIT = 0x10 | |
113 | } process_event_kind; | |
114 | ||
115 | typedef int process_event_vector; | |
116 | ||
117 | extern process_event_vector hppa_get_process_events PARAMS ((int, int, int *)); | |
118 | ||
40df7e27 JL |
119 | |
120 | /* So we can cleanly use code in infptrace.c. */ | |
121 | #define PT_KILL PT_EXIT | |
122 | #define PT_STEP PT_SINGLE | |
123 | #define PT_CONTINUE PT_CONTIN | |
61ada545 DT |
124 | |
125 | /* FIXME HP MERGE : Previously, PT_RDUAREA. this is actually fixed | |
126 | in gdb-hp-snapshot-980509 */ | |
127 | #define PT_READ_U PT_RUAREA | |
40df7e27 JL |
128 | #define PT_WRITE_U PT_WUAREA |
129 | #define PT_READ_I PT_RIUSER | |
130 | #define PT_READ_D PT_RDUSER | |
131 | #define PT_WRITE_I PT_WIUSER | |
132 | #define PT_WRITE_D PT_WDUSER | |
133 | ||
22b4b223 JK |
134 | /* attach/detach works to some extent under BSD and HPUX. So long |
135 | as the process you're attaching to isn't blocked waiting on io, | |
136 | blocked waiting on a signal, or in a system call things work | |
137 | fine. (The problems in those cases are related to the fact that | |
138 | the kernel can't provide complete register information for the | |
139 | target process... Which really pisses off GDB.) */ | |
140 | ||
141 | #define ATTACH_DETACH | |
5d394f70 | 142 | |
61ada545 DT |
143 | /* In infptrace or infttrace.c: */ |
144 | ||
145 | /* Starting with HP-UX 10.30, support is provided (in the form of | |
146 | ttrace requests) for memory-protection-based hardware watchpoints. | |
147 | ||
148 | The 10.30 implementation of these functions reside in infttrace.c. | |
149 | ||
150 | Stubs of these functions will be provided in infptrace.c, so that | |
151 | 10.20 will at least link. However, the "can I use a fast watchpoint?" | |
152 | query will always return "No" for 10.20. */ | |
153 | ||
154 | #define TARGET_HAS_HARDWARE_WATCHPOINTS | |
155 | ||
156 | /* The PA can watch any number of locations (generic routines already check | |
157 | that all intermediates are in watchable memory locations). */ | |
158 | #define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) \ | |
159 | hppa_can_use_hw_watchpoint(type, cnt, ot) | |
160 | ||
161 | /* The PA can also watch memory regions of arbitrary size, since we're using | |
162 | a page-protection scheme. (On some targets, apparently watch registers | |
163 | are used, which can only accomodate regions of REGISTER_SIZE.) */ | |
164 | #define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(byte_count) \ | |
165 | (1) | |
166 | ||
167 | /* However, some addresses may not be profitable to use hardware to watch, | |
168 | or may be difficult to understand when the addressed object is out of | |
169 | scope, and hence should be unwatched. On some targets, this may have | |
170 | severe performance penalties, such that we might as well use regular | |
171 | watchpoints, and save (possibly precious) hardware watchpoints for other | |
172 | locations. | |
173 | ||
174 | On HP-UX, we choose not to watch stack-based addresses, because | |
175 | ||
176 | [1] Our implementation relies on page protection traps. The granularity | |
177 | of these is large and so can generate many false hits, which are expensive | |
178 | to respond to. | |
179 | ||
180 | [2] Watches of "*p" where we may not know the symbol that p points to, | |
181 | make it difficult to know when the addressed object is out of scope, and | |
182 | hence shouldn't be watched. Page protection that isn't removed when the | |
183 | addressed object is out of scope will either degrade execution speed | |
184 | (false hits) or give false triggers (when the address is recycled by | |
185 | other calls). | |
186 | ||
187 | Since either of these points results in a slow-running inferior, we might | |
188 | as well use normal watchpoints, aka single-step & test. */ | |
189 | #define TARGET_RANGE_PROFITABLE_FOR_HW_WATCHPOINT(pid,start,len) \ | |
190 | hppa_range_profitable_for_hw_watchpoint(pid, start, (LONGEST)(len)) | |
191 | ||
192 | /* On HP-UX, we're using page-protection to implement hardware watchpoints. | |
193 | When an instruction attempts to write to a write-protected memory page, | |
194 | a SIGBUS is raised. At that point, the write has not actually occurred. | |
195 | ||
196 | We must therefore remove page-protections; single-step the inferior (to | |
197 | allow the write to happen); restore page-protections; and check whether | |
198 | any watchpoint triggered. | |
199 | ||
200 | If none did, then the write was to a "nearby" location that just happens | |
201 | to fall on the same page as a watched location, and so can be ignored. | |
202 | ||
203 | The only intended client of this macro is wait_for_inferior(), in infrun.c. | |
204 | When HAVE_NONSTEPPABLE_WATCHPOINT is true, that function will take care | |
205 | of the stepping & etc. */ | |
206 | ||
207 | #define STOPPED_BY_WATCHPOINT(W) \ | |
208 | ((W.kind == TARGET_WAITKIND_STOPPED) && \ | |
209 | (stop_signal == TARGET_SIGNAL_BUS) && \ | |
210 | ! stepped_after_stopped_by_watchpoint && \ | |
211 | bpstat_have_active_hw_watchpoints ()) | |
212 | ||
213 | /* When a hardware watchpoint triggers, we'll move the inferior past it | |
214 | by removing all eventpoints; stepping past the instruction that caused | |
215 | the trigger; reinserting eventpoints; and checking whether any watched | |
216 | location changed. */ | |
217 | #define HAVE_NONSTEPPABLE_WATCHPOINT | |
218 | ||
219 | /* Our implementation of "hardware" watchpoints uses memory page-protection | |
220 | faults. However, HP-UX has unfortunate interactions between these and | |
221 | system calls; basically, it's unsafe to have page protections on when a | |
222 | syscall is running. Therefore, we also ask for notification of syscall | |
223 | entries and returns. When the inferior enters a syscall, we disable | |
224 | h/w watchpoints. When the inferior returns from a syscall, we reenable | |
225 | h/w watchpoints. | |
226 | ||
227 | infptrace.c supplies dummy versions of these; infttrace.c is where the | |
228 | meaningful implementations are. | |
229 | */ | |
230 | #define TARGET_ENABLE_HW_WATCHPOINTS(pid) \ | |
231 | hppa_enable_page_protection_events (pid) | |
232 | extern void hppa_enable_hw_watchpoints PARAMS ((int)); | |
233 | ||
234 | #define TARGET_DISABLE_HW_WATCHPOINTS(pid) \ | |
235 | hppa_disable_page_protection_events (pid) | |
236 | extern void hppa_disable_hw_watchpoints PARAMS ((int)); | |
237 | ||
238 | /* Use these macros for watchpoint insertion/deletion. */ | |
239 | #define target_insert_watchpoint(addr, len, type) \ | |
240 | hppa_insert_hw_watchpoint (inferior_pid, addr, (LONGEST)(len), type) | |
241 | ||
242 | #define target_remove_watchpoint(addr, len, type) \ | |
243 | hppa_remove_hw_watchpoint (inferior_pid, addr, (LONGEST)(len), type) | |
244 | ||
245 | /* We call our k-thread processes "threads", rather | |
246 | * than processes. So we need a new way to print | |
247 | * the string. Code is in hppah-nat.c. | |
248 | */ | |
249 | #define target_pid_to_str( pid ) \ | |
250 | hppa_pid_to_str( pid ) | |
251 | extern char * hppa_pid_to_str PARAMS ((pid_t)); | |
252 | ||
253 | #define target_tid_to_str( pid ) \ | |
254 | hppa_tid_to_str( pid ) | |
255 | extern char * hppa_tid_to_str PARAMS ((pid_t)); | |
256 | ||
257 | /* For this, ID can be either a process or thread ID, and the function | |
258 | will describe it appropriately, returning the description as a printable | |
259 | string. | |
260 | ||
261 | The function that implements this macro is defined in infptrace.c and | |
262 | infttrace.c. | |
263 | */ | |
264 | #define target_pid_or_tid_to_str(ID) \ | |
265 | hppa_pid_or_tid_to_str (ID) | |
266 | extern char * hppa_pid_or_tid_to_str PARAMS ((pid_t)); | |
267 | ||
268 | /* This is used when handling events caused by a call to vfork(). On ptrace- | |
269 | based HP-UXs, when you resume the vforked child, the parent automagically | |
270 | begins running again. To prevent this runaway, this function is used. | |
271 | ||
272 | Note that for vfork on HP-UX, we receive three events of interest: | |
273 | ||
274 | 1. the vfork event for the new child process | |
275 | 2. the exit or exec event of the new child process (actually, you get | |
276 | two exec events on ptrace-based HP-UXs) | |
277 | 3. the vfork event for the original parent process | |
278 | ||
279 | The first is always received first. The other two may be received in any | |
280 | order; HP-UX doesn't guarantee an order. | |
281 | */ | |
282 | #define ENSURE_VFORKING_PARENT_REMAINS_STOPPED(PID) \ | |
283 | hppa_ensure_vforking_parent_remains_stopped (PID) | |
284 | extern void hppa_ensure_vforking_parent_remains_stopped PARAMS((int)); | |
285 | ||
286 | /* This is used when handling events caused by a call to vfork(). | |
287 | ||
288 | On ttrace-based HP-UXs, the parent vfork and child exec arrive more or less | |
289 | together. That is, you could do two wait()s without resuming either parent | |
290 | or child, and get both events. | |
291 | ||
292 | On ptrace-based HP-UXs, you must resume the child after its exec event is | |
293 | delivered or you won't get the parent's vfork. I.e., you can't just wait() | |
294 | and get the parent vfork, after receiving the child exec. | |
295 | */ | |
296 | #define RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK() \ | |
297 | hppa_resume_execd_vforking_child_to_get_parent_vfork () | |
298 | extern int hppa_resume_execd_vforking_child_to_get_parent_vfork PARAMS ((void)); | |
299 | ||
5d394f70 SG |
300 | #ifdef HAVE_HPUX_THREAD_SUPPORT |
301 | ||
302 | #ifdef __STDC__ | |
303 | struct objfile; | |
304 | #endif | |
305 | ||
306 | void hpux_thread_new_objfile PARAMS ((struct objfile *objfile)); | |
307 | #define target_new_objfile(OBJFILE) hpux_thread_new_objfile (OBJFILE) | |
308 | ||
309 | extern char *hpux_pid_to_str PARAMS ((int pid)); | |
310 | #define target_pid_to_str(PID) hpux_pid_to_str (PID) | |
311 | ||
312 | #endif /* HAVE_HPUX_THREAD_SUPPORT */ | |
61ada545 DT |
313 | |
314 | #define HPUXHPPA |