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