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