| @@ -1,852 +1,852 @@ | | | @@ -1,852 +1,852 @@ |
1 | /* Low-level child interface to ptrace. | | 1 | /* Low-level child interface to ptrace. |
2 | | | 2 | |
3 | Copyright (C) 1988-2017 Free Software Foundation, Inc. | | 3 | Copyright (C) 1988-2017 Free Software Foundation, Inc. |
4 | | | 4 | |
5 | This file is part of GDB. | | 5 | This file is part of GDB. |
6 | | | 6 | |
7 | This program is free software; you can redistribute it and/or modify | | 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 | | 8 | it under the terms of the GNU General Public License as published by |
9 | the Free Software Foundation; either version 3 of the License, or | | 9 | the Free Software Foundation; either version 3 of the License, or |
10 | (at your option) any later version. | | 10 | (at your option) any later version. |
11 | | | 11 | |
12 | This program is distributed in the hope that it will be useful, | | 12 | This program is distributed in the hope that it will be useful, |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | | 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | | 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | GNU General Public License for more details. | | 15 | GNU General Public License for more details. |
16 | | | 16 | |
17 | You should have received a copy of the GNU General Public License | | 17 | You should have received a copy of the GNU General Public License |
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | | 18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
19 | | | 19 | |
20 | #include "defs.h" | | 20 | #include "defs.h" |
21 | #include "command.h" | | 21 | #include "command.h" |
22 | #include "inferior.h" | | 22 | #include "inferior.h" |
23 | #include "inflow.h" | | 23 | #include "inflow.h" |
24 | #include "terminal.h" | | 24 | #include "terminal.h" |
25 | #include "gdbcore.h" | | 25 | #include "gdbcore.h" |
26 | #include "regcache.h" | | 26 | #include "regcache.h" |
27 | #include "nat/gdb_ptrace.h" | | 27 | #include "nat/gdb_ptrace.h" |
28 | #include "gdb_wait.h" | | 28 | #include "gdb_wait.h" |
29 | #include <signal.h> | | 29 | #include <signal.h> |
30 | | | 30 | |
31 | #include "inf-ptrace.h" | | 31 | #include "inf-ptrace.h" |
32 | #include "inf-child.h" | | 32 | #include "inf-child.h" |
33 | #include "gdbthread.h" | | 33 | #include "gdbthread.h" |
34 | | | 34 | |
35 | | | 35 | |
36 | | | 36 | |
37 | #ifdef PT_GET_PROCESS_STATE | | 37 | #ifdef PT_GET_PROCESS_STATE |
38 | | | 38 | |
39 | /* Target hook for follow_fork. On entry and at return inferior_ptid is | | 39 | /* Target hook for follow_fork. On entry and at return inferior_ptid is |
40 | the ptid of the followed inferior. */ | | 40 | the ptid of the followed inferior. */ |
41 | | | 41 | |
42 | static int | | 42 | static int |
43 | inf_ptrace_follow_fork (struct target_ops *ops, int follow_child, | | 43 | inf_ptrace_follow_fork (struct target_ops *ops, int follow_child, |
44 | int detach_fork) | | 44 | int detach_fork) |
45 | { | | 45 | { |
46 | if (!follow_child) | | 46 | if (!follow_child) |
47 | { | | 47 | { |
48 | struct thread_info *tp = inferior_thread (); | | 48 | struct thread_info *tp = inferior_thread (); |
49 | pid_t child_pid = ptid_get_pid (tp->pending_follow.value.related_pid); | | 49 | pid_t child_pid = ptid_get_pid (tp->pending_follow.value.related_pid); |
50 | | | 50 | |
51 | /* Breakpoints have already been detached from the child by | | 51 | /* Breakpoints have already been detached from the child by |
52 | infrun.c. */ | | 52 | infrun.c. */ |
53 | | | 53 | |
54 | if (ptrace (PT_DETACH, child_pid, (PTRACE_TYPE_ARG3)1, 0) == -1) | | 54 | if (ptrace (PT_DETACH, child_pid, (PTRACE_TYPE_ARG3)1, 0) == -1) |
55 | perror_with_name (("ptrace")); | | 55 | perror_with_name (("ptrace")); |
56 | } | | 56 | } |
57 | | | 57 | |
58 | return 0; | | 58 | return 0; |
59 | } | | 59 | } |
60 | | | 60 | |
61 | static int | | 61 | static int |
62 | inf_ptrace_insert_fork_catchpoint (struct target_ops *self, int pid) | | 62 | inf_ptrace_insert_fork_catchpoint (struct target_ops *self, int pid) |
63 | { | | 63 | { |
64 | return 0; | | 64 | return 0; |
65 | } | | 65 | } |
66 | | | 66 | |
67 | static int | | 67 | static int |
68 | inf_ptrace_remove_fork_catchpoint (struct target_ops *self, int pid) | | 68 | inf_ptrace_remove_fork_catchpoint (struct target_ops *self, int pid) |
69 | { | | 69 | { |
70 | return 0; | | 70 | return 0; |
71 | } | | 71 | } |
72 | | | 72 | |
73 | #endif /* PT_GET_PROCESS_STATE */ | | 73 | #endif /* PT_GET_PROCESS_STATE */ |
74 | | | 74 | |
75 | | | 75 | |
76 | /* Prepare to be traced. */ | | 76 | /* Prepare to be traced. */ |
77 | | | 77 | |
78 | static void | | 78 | static void |
79 | inf_ptrace_me (void) | | 79 | inf_ptrace_me (void) |
80 | { | | 80 | { |
81 | /* "Trace me, Dr. Memory!" */ | | 81 | /* "Trace me, Dr. Memory!" */ |
82 | if (ptrace (PT_TRACE_ME, 0, (PTRACE_TYPE_ARG3) 0, 0) < 0) | | 82 | if (ptrace (PT_TRACE_ME, 0, (PTRACE_TYPE_ARG3) 0, 0) < 0) |
83 | trace_start_error_with_name ("ptrace"); | | 83 | trace_start_error_with_name ("ptrace"); |
84 | } | | 84 | } |
85 | | | 85 | |
86 | /* Start a new inferior Unix child process. EXEC_FILE is the file to | | 86 | /* Start a new inferior Unix child process. EXEC_FILE is the file to |
87 | run, ALLARGS is a string containing the arguments to the program. | | 87 | run, ALLARGS is a string containing the arguments to the program. |
88 | ENV is the environment vector to pass. If FROM_TTY is non-zero, be | | 88 | ENV is the environment vector to pass. If FROM_TTY is non-zero, be |
89 | chatty about it. */ | | 89 | chatty about it. */ |
90 | | | 90 | |
91 | static void | | 91 | static void |
92 | inf_ptrace_create_inferior (struct target_ops *ops, | | 92 | inf_ptrace_create_inferior (struct target_ops *ops, |
93 | const char *exec_file, const std::string &allargs, | | 93 | const char *exec_file, const std::string &allargs, |
94 | char **env, int from_tty) | | 94 | char **env, int from_tty) |
95 | { | | 95 | { |
96 | int pid; | | 96 | int pid; |
97 | | | 97 | |
98 | /* Do not change either targets above or the same target if already present. | | 98 | /* Do not change either targets above or the same target if already present. |
99 | The reason is the target stack is shared across multiple inferiors. */ | | 99 | The reason is the target stack is shared across multiple inferiors. */ |
100 | int ops_already_pushed = target_is_pushed (ops); | | 100 | int ops_already_pushed = target_is_pushed (ops); |
101 | struct cleanup *back_to = make_cleanup (null_cleanup, NULL); | | 101 | struct cleanup *back_to = make_cleanup (null_cleanup, NULL); |
102 | | | 102 | |
103 | if (! ops_already_pushed) | | 103 | if (! ops_already_pushed) |
104 | { | | 104 | { |
105 | /* Clear possible core file with its process_stratum. */ | | 105 | /* Clear possible core file with its process_stratum. */ |
106 | push_target (ops); | | 106 | push_target (ops); |
107 | make_cleanup_unpush_target (ops); | | 107 | make_cleanup_unpush_target (ops); |
108 | } | | 108 | } |
109 | | | 109 | |
110 | pid = fork_inferior (exec_file, allargs, env, inf_ptrace_me, NULL, | | 110 | pid = fork_inferior (exec_file, allargs, env, inf_ptrace_me, NULL, |
111 | NULL, NULL, NULL); | | 111 | NULL, NULL, NULL); |
112 | | | 112 | |
113 | discard_cleanups (back_to); | | 113 | discard_cleanups (back_to); |
114 | | | 114 | |
115 | startup_inferior (START_INFERIOR_TRAPS_EXPECTED); | | 115 | startup_inferior (START_INFERIOR_TRAPS_EXPECTED); |
116 | | | 116 | |
117 | /* On some targets, there must be some explicit actions taken after | | 117 | /* On some targets, there must be some explicit actions taken after |
118 | the inferior has been started up. */ | | 118 | the inferior has been started up. */ |
119 | target_post_startup_inferior (pid_to_ptid (pid)); | | 119 | target_post_startup_inferior (pid_to_ptid (pid)); |
120 | } | | 120 | } |
121 | | | 121 | |
122 | #ifdef PT_GET_PROCESS_STATE | | 122 | #ifdef PT_GET_PROCESS_STATE |
123 | | | 123 | |
124 | static void | | 124 | static void |
125 | inf_ptrace_post_startup_inferior (struct target_ops *self, ptid_t pid) | | 125 | inf_ptrace_post_startup_inferior (struct target_ops *self, ptid_t pid) |
126 | { | | 126 | { |
127 | ptrace_event_t pe; | | 127 | ptrace_event_t pe; |
128 | | | 128 | |
129 | /* Set the initial event mask. */ | | 129 | /* Set the initial event mask. */ |
130 | memset (&pe, 0, sizeof pe); | | 130 | memset (&pe, 0, sizeof pe); |
131 | pe.pe_set_event |= PTRACE_FORK; | | 131 | pe.pe_set_event |= PTRACE_FORK; |
132 | if (ptrace (PT_SET_EVENT_MASK, ptid_get_pid (pid), | | 132 | if (ptrace (PT_SET_EVENT_MASK, ptid_get_pid (pid), |
133 | (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1) | | 133 | (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1) |
134 | perror_with_name (("ptrace")); | | 134 | perror_with_name (("ptrace")); |
135 | } | | 135 | } |
136 | | | 136 | |
137 | #endif | | 137 | #endif |
138 | | | 138 | |
139 | /* Clean up a rotting corpse of an inferior after it died. */ | | 139 | /* Clean up a rotting corpse of an inferior after it died. */ |
140 | | | 140 | |
141 | static void | | 141 | static void |
142 | inf_ptrace_mourn_inferior (struct target_ops *ops) | | 142 | inf_ptrace_mourn_inferior (struct target_ops *ops) |
143 | { | | 143 | { |
144 | int status; | | 144 | int status; |
145 | | | 145 | |
146 | /* Wait just one more time to collect the inferior's exit status. | | 146 | /* Wait just one more time to collect the inferior's exit status. |
147 | Do not check whether this succeeds though, since we may be | | 147 | Do not check whether this succeeds though, since we may be |
148 | dealing with a process that we attached to. Such a process will | | 148 | dealing with a process that we attached to. Such a process will |
149 | only report its exit status to its original parent. */ | | 149 | only report its exit status to its original parent. */ |
150 | waitpid (ptid_get_pid (inferior_ptid), &status, 0); | | 150 | waitpid (ptid_get_pid (inferior_ptid), &status, 0); |
151 | | | 151 | |
152 | inf_child_mourn_inferior (ops); | | 152 | inf_child_mourn_inferior (ops); |
153 | } | | 153 | } |
154 | | | 154 | |
155 | /* Attach to the process specified by ARGS. If FROM_TTY is non-zero, | | 155 | /* Attach to the process specified by ARGS. If FROM_TTY is non-zero, |
156 | be chatty about it. */ | | 156 | be chatty about it. */ |
157 | | | 157 | |
158 | static void | | 158 | static void |
159 | inf_ptrace_attach (struct target_ops *ops, const char *args, int from_tty) | | 159 | inf_ptrace_attach (struct target_ops *ops, const char *args, int from_tty) |
160 | { | | 160 | { |
161 | char *exec_file; | | 161 | char *exec_file; |
162 | pid_t pid; | | 162 | pid_t pid; |
163 | struct inferior *inf; | | 163 | struct inferior *inf; |
164 | | | 164 | |
165 | /* Do not change either targets above or the same target if already present. | | 165 | /* Do not change either targets above or the same target if already present. |
166 | The reason is the target stack is shared across multiple inferiors. */ | | 166 | The reason is the target stack is shared across multiple inferiors. */ |
167 | int ops_already_pushed = target_is_pushed (ops); | | 167 | int ops_already_pushed = target_is_pushed (ops); |
168 | struct cleanup *back_to = make_cleanup (null_cleanup, NULL); | | 168 | struct cleanup *back_to = make_cleanup (null_cleanup, NULL); |
169 | | | 169 | |
170 | pid = parse_pid_to_attach (args); | | 170 | pid = parse_pid_to_attach (args); |
171 | | | 171 | |
172 | if (pid == getpid ()) /* Trying to masturbate? */ | | 172 | if (pid == getpid ()) /* Trying to masturbate? */ |
173 | error (_("I refuse to debug myself!")); | | 173 | error (_("I refuse to debug myself!")); |
174 | | | 174 | |
175 | if (! ops_already_pushed) | | 175 | if (! ops_already_pushed) |
176 | { | | 176 | { |
177 | /* target_pid_to_str already uses the target. Also clear possible core | | 177 | /* target_pid_to_str already uses the target. Also clear possible core |
178 | file with its process_stratum. */ | | 178 | file with its process_stratum. */ |
179 | push_target (ops); | | 179 | push_target (ops); |
180 | make_cleanup_unpush_target (ops); | | 180 | make_cleanup_unpush_target (ops); |
181 | } | | 181 | } |
182 | | | 182 | |
183 | if (from_tty) | | 183 | if (from_tty) |
184 | { | | 184 | { |
185 | exec_file = get_exec_file (0); | | 185 | exec_file = get_exec_file (0); |
186 | | | 186 | |
187 | if (exec_file) | | 187 | if (exec_file) |
188 | printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file, | | 188 | printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file, |
189 | target_pid_to_str (pid_to_ptid (pid))); | | 189 | target_pid_to_str (pid_to_ptid (pid))); |
190 | else | | 190 | else |
191 | printf_unfiltered (_("Attaching to %s\n"), | | 191 | printf_unfiltered (_("Attaching to %s\n"), |
192 | target_pid_to_str (pid_to_ptid (pid))); | | 192 | target_pid_to_str (pid_to_ptid (pid))); |
193 | | | 193 | |
194 | gdb_flush (gdb_stdout); | | 194 | gdb_flush (gdb_stdout); |
195 | } | | 195 | } |
196 | | | 196 | |
197 | #ifdef PT_ATTACH | | 197 | #ifdef PT_ATTACH |
198 | errno = 0; | | 198 | errno = 0; |
199 | ptrace (PT_ATTACH, pid, (PTRACE_TYPE_ARG3)0, 0); | | 199 | ptrace (PT_ATTACH, pid, (PTRACE_TYPE_ARG3)0, 0); |
200 | if (errno != 0) | | 200 | if (errno != 0) |
201 | perror_with_name (("ptrace")); | | 201 | perror_with_name (("ptrace")); |
202 | #else | | 202 | #else |
203 | error (_("This system does not support attaching to a process")); | | 203 | error (_("This system does not support attaching to a process")); |
204 | #endif | | 204 | #endif |
205 | | | 205 | |
206 | inf = current_inferior (); | | 206 | inf = current_inferior (); |
207 | inferior_appeared (inf, pid); | | 207 | inferior_appeared (inf, pid); |
208 | inf->attach_flag = 1; | | 208 | inf->attach_flag = 1; |
209 | inferior_ptid = pid_to_ptid (pid); | | 209 | inferior_ptid = pid_to_ptid (pid); |
210 | | | 210 | |
211 | /* Always add a main thread. If some target extends the ptrace | | 211 | /* Always add a main thread. If some target extends the ptrace |
212 | target, it should decorate the ptid later with more info. */ | | 212 | target, it should decorate the ptid later with more info. */ |
213 | add_thread_silent (inferior_ptid); | | 213 | add_thread_silent (inferior_ptid); |
214 | | | 214 | |
215 | discard_cleanups (back_to); | | 215 | discard_cleanups (back_to); |
216 | } | | 216 | } |
217 | | | 217 | |
218 | #ifdef PT_GET_PROCESS_STATE | | 218 | #ifdef PT_GET_PROCESS_STATE |
219 | | | 219 | |
220 | static void | | 220 | static void |
221 | inf_ptrace_post_attach (struct target_ops *self, int pid) | | 221 | inf_ptrace_post_attach (struct target_ops *self, int pid) |
222 | { | | 222 | { |
223 | ptrace_event_t pe; | | 223 | ptrace_event_t pe; |
224 | | | 224 | |
225 | /* Set the initial event mask. */ | | 225 | /* Set the initial event mask. */ |
226 | memset (&pe, 0, sizeof pe); | | 226 | memset (&pe, 0, sizeof pe); |
227 | pe.pe_set_event |= PTRACE_FORK; | | 227 | pe.pe_set_event |= PTRACE_FORK; |
228 | if (ptrace (PT_SET_EVENT_MASK, pid, | | 228 | if (ptrace (PT_SET_EVENT_MASK, pid, |
229 | (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1) | | 229 | (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1) |
230 | perror_with_name (("ptrace")); | | 230 | perror_with_name (("ptrace")); |
231 | } | | 231 | } |
232 | | | 232 | |
233 | #endif | | 233 | #endif |
234 | | | 234 | |
235 | /* Detach from the inferior, optionally passing it the signal | | 235 | /* Detach from the inferior, optionally passing it the signal |
236 | specified by ARGS. If FROM_TTY is non-zero, be chatty about it. */ | | 236 | specified by ARGS. If FROM_TTY is non-zero, be chatty about it. */ |
237 | | | 237 | |
238 | static void | | 238 | static void |
239 | inf_ptrace_detach (struct target_ops *ops, const char *args, int from_tty) | | 239 | inf_ptrace_detach (struct target_ops *ops, const char *args, int from_tty) |
240 | { | | 240 | { |
241 | pid_t pid = ptid_get_pid (inferior_ptid); | | 241 | pid_t pid = ptid_get_pid (inferior_ptid); |
242 | int sig = 0; | | 242 | int sig = 0; |
243 | | | 243 | |
244 | target_announce_detach (from_tty); | | 244 | target_announce_detach (from_tty); |
245 | if (args) | | 245 | if (args) |
246 | sig = atoi (args); | | 246 | sig = atoi (args); |
247 | | | 247 | |
248 | #ifdef PT_DETACH | | 248 | #ifdef PT_DETACH |
249 | /* We'd better not have left any breakpoints in the program or it'll | | 249 | /* We'd better not have left any breakpoints in the program or it'll |
250 | die when it hits one. Also note that this may only work if we | | 250 | die when it hits one. Also note that this may only work if we |
251 | previously attached to the inferior. It *might* work if we | | 251 | previously attached to the inferior. It *might* work if we |
252 | started the process ourselves. */ | | 252 | started the process ourselves. */ |
253 | errno = 0; | | 253 | errno = 0; |
254 | ptrace (PT_DETACH, pid, (PTRACE_TYPE_ARG3)1, sig); | | 254 | ptrace (PT_DETACH, pid, (PTRACE_TYPE_ARG3)1, sig); |
255 | if (errno != 0) | | 255 | if (errno != 0) |
256 | perror_with_name (("ptrace")); | | 256 | perror_with_name (("ptrace")); |
257 | #else | | 257 | #else |
258 | error (_("This system does not support detaching from a process")); | | 258 | error (_("This system does not support detaching from a process")); |
259 | #endif | | 259 | #endif |
260 | | | 260 | |
261 | inf_ptrace_detach_success (ops); | | 261 | inf_ptrace_detach_success (ops); |
262 | } | | 262 | } |
263 | | | 263 | |
264 | /* See inf-ptrace.h. */ | | 264 | /* See inf-ptrace.h. */ |
265 | | | 265 | |
266 | void | | 266 | void |
267 | inf_ptrace_detach_success (struct target_ops *ops) | | 267 | inf_ptrace_detach_success (struct target_ops *ops) |
268 | { | | 268 | { |
269 | pid_t pid = ptid_get_pid (inferior_ptid); | | 269 | pid_t pid = ptid_get_pid (inferior_ptid); |
270 | | | 270 | |
271 | inferior_ptid = null_ptid; | | 271 | inferior_ptid = null_ptid; |
272 | detach_inferior (pid); | | 272 | detach_inferior (pid); |
273 | | | 273 | |
274 | inf_child_maybe_unpush_target (ops); | | 274 | inf_child_maybe_unpush_target (ops); |
275 | } | | 275 | } |
276 | | | 276 | |
277 | /* Kill the inferior. */ | | 277 | /* Kill the inferior. */ |
278 | | | 278 | |
279 | static void | | 279 | static void |
280 | inf_ptrace_kill (struct target_ops *ops) | | 280 | inf_ptrace_kill (struct target_ops *ops) |
281 | { | | 281 | { |
282 | pid_t pid = ptid_get_pid (inferior_ptid); | | 282 | pid_t pid = ptid_get_pid (inferior_ptid); |
283 | int status; | | 283 | int status; |
284 | | | 284 | |
285 | if (pid == 0) | | 285 | if (pid == 0) |
286 | return; | | 286 | return; |
287 | | | 287 | |
288 | ptrace (PT_KILL, pid, (PTRACE_TYPE_ARG3)0, 0); | | 288 | ptrace (PT_KILL, pid, (PTRACE_TYPE_ARG3)0, 0); |
289 | waitpid (pid, &status, 0); | | 289 | waitpid (pid, &status, 0); |
290 | | | 290 | |
291 | target_mourn_inferior (inferior_ptid); | | 291 | target_mourn_inferior (inferior_ptid); |
292 | } | | 292 | } |
293 | | | 293 | |
294 | /* Interrupt the inferior. */ | | 294 | /* Interrupt the inferior. */ |
295 | | | 295 | |
296 | static void | | 296 | static void |
297 | inf_ptrace_interrupt (struct target_ops *self, ptid_t ptid) | | 297 | inf_ptrace_interrupt (struct target_ops *self, ptid_t ptid) |
298 | { | | 298 | { |
299 | /* Send a SIGINT to the process group. This acts just like the user | | 299 | /* Send a SIGINT to the process group. This acts just like the user |
300 | typed a ^C on the controlling terminal. Note that using a | | 300 | typed a ^C on the controlling terminal. Note that using a |
301 | negative process number in kill() is a System V-ism. The proper | | 301 | negative process number in kill() is a System V-ism. The proper |
302 | BSD interface is killpg(). However, all modern BSDs support the | | 302 | BSD interface is killpg(). However, all modern BSDs support the |
303 | System V interface too. */ | | 303 | System V interface too. */ |
304 | kill (-inferior_process_group (), SIGINT); | | 304 | kill (-inferior_process_group (), SIGINT); |
305 | } | | 305 | } |
306 | | | 306 | |
307 | /* Return which PID to pass to ptrace in order to observe/control the | | 307 | /* Return which PID to pass to ptrace in order to observe/control the |
308 | tracee identified by PTID. */ | | 308 | tracee identified by PTID. */ |
309 | | | 309 | |
310 | pid_t | | 310 | pid_t |
311 | get_ptrace_pid (ptid_t ptid) | | 311 | get_ptrace_pid (ptid_t ptid) |
312 | { | | 312 | { |
313 | pid_t pid; | | 313 | pid_t pid; |
314 | | | 314 | |
315 | #ifndef __NetBSD__ | | 315 | #ifndef __NetBSD__ |
316 | /* If we have an LWPID to work with, use it. Otherwise, we're | | 316 | /* If we have an LWPID to work with, use it. Otherwise, we're |
317 | dealing with a non-threaded program/target. */ | | 317 | dealing with a non-threaded program/target. */ |
318 | pid = ptid_get_lwp (ptid); | | 318 | pid = ptid_get_lwp (ptid); |
319 | if (pid == 0) | | 319 | if (pid == 0) |
320 | #endif | | 320 | #endif |
321 | pid = ptid_get_pid (ptid); | | 321 | pid = ptid_get_pid (ptid); |
322 | return pid; | | 322 | return pid; |
323 | } | | 323 | } |
324 | | | 324 | |
325 | /* Resume execution of thread PTID, or all threads if PTID is -1. If | | 325 | /* Resume execution of thread PTID, or all threads if PTID is -1. If |
326 | STEP is nonzero, single-step it. If SIGNAL is nonzero, give it | | 326 | STEP is nonzero, single-step it. If SIGNAL is nonzero, give it |
327 | that signal. */ | | 327 | that signal. */ |
328 | | | 328 | |
329 | static void | | 329 | static void |
330 | inf_ptrace_resume (struct target_ops *ops, | | 330 | inf_ptrace_resume (struct target_ops *ops, |
331 | ptid_t ptid, int step, enum gdb_signal signal) | | 331 | ptid_t ptid, int step, enum gdb_signal signal) |
332 | { | | 332 | { |
333 | pid_t pid; | | 333 | pid_t pid; |
334 | int request, sig; | | 334 | int request, sig; |
335 | | | 335 | |
336 | if (ptid_equal (minus_one_ptid, ptid)) | | 336 | if (ptid_equal (minus_one_ptid, ptid)) |
337 | /* Resume all threads. Traditionally ptrace() only supports | | 337 | /* Resume all threads. Traditionally ptrace() only supports |
338 | single-threaded processes, so simply resume the inferior. */ | | 338 | single-threaded processes, so simply resume the inferior. */ |
339 | pid = ptid_get_pid (inferior_ptid); | | 339 | pid = ptid_get_pid (inferior_ptid); |
340 | else | | 340 | else |
341 | pid = get_ptrace_pid (ptid); | | 341 | pid = get_ptrace_pid (ptid); |
342 | | | 342 | |
343 | if (catch_syscall_enabled () > 0) | | 343 | if (catch_syscall_enabled () > 0) |
344 | request = PT_SYSCALL; | | 344 | request = PT_SYSCALL; |
345 | else | | 345 | else |
346 | request = PT_CONTINUE; | | 346 | request = PT_CONTINUE; |
347 | | | 347 | |
348 | if (step) | | 348 | if (step) |
349 | { | | 349 | { |
350 | /* If this system does not support PT_STEP, a higher level | | 350 | /* If this system does not support PT_STEP, a higher level |
351 | function will have called single_step() to transmute the step | | 351 | function will have called single_step() to transmute the step |
352 | request into a continue request (by setting breakpoints on | | 352 | request into a continue request (by setting breakpoints on |
353 | all possible successor instructions), so we don't have to | | 353 | all possible successor instructions), so we don't have to |
354 | worry about that here. */ | | 354 | worry about that here. */ |
355 | request = PT_STEP; | | 355 | request = PT_STEP; |
356 | #ifdef __NetBSD__ | | 356 | #if 0 |
357 | /* | | 357 | /* |
358 | * On NetBSD the data field of PT_STEP contains the thread | | 358 | * On NetBSD the data field of PT_STEP contains the thread |
359 | * to be stepped; all other threads are continued if this value is > 0 | | 359 | * to be stepped; all other threads are continued if this value is > 0 |
360 | */ | | 360 | */ |
361 | sig = ptid_get_lwp(ptid); | | 361 | sig = ptid_get_lwp(ptid); |
362 | #else | | 362 | #else |
363 | sig = 0; | | 363 | sig = 0; |
364 | #endif | | 364 | #endif |
365 | } else | | 365 | } else |
366 | sig = gdb_signal_to_host (signal); | | 366 | sig = gdb_signal_to_host (signal); |
367 | | | 367 | |
368 | /* An address of (PTRACE_TYPE_ARG3)1 tells ptrace to continue from | | 368 | /* An address of (PTRACE_TYPE_ARG3)1 tells ptrace to continue from |
369 | where it was. If GDB wanted it to start some other way, we have | | 369 | where it was. If GDB wanted it to start some other way, we have |
370 | already written a new program counter value to the child. */ | | 370 | already written a new program counter value to the child. */ |
371 | errno = 0; | | 371 | errno = 0; |
372 | ptrace (request, pid, (PTRACE_TYPE_ARG3)1, sig); | | 372 | ptrace (request, pid, (PTRACE_TYPE_ARG3)1, sig); |
373 | if (errno != 0) | | 373 | if (errno != 0) |
374 | perror_with_name (("ptrace")); | | 374 | perror_with_name (("ptrace")); |
375 | } | | 375 | } |
376 | | | 376 | |
377 | /* Wait for the child specified by PTID to do something. Return the | | 377 | /* Wait for the child specified by PTID to do something. Return the |
378 | process ID of the child, or MINUS_ONE_PTID in case of error; store | | 378 | process ID of the child, or MINUS_ONE_PTID in case of error; store |
379 | the status in *OURSTATUS. */ | | 379 | the status in *OURSTATUS. */ |
380 | | | 380 | |
381 | static ptid_t | | 381 | static ptid_t |
382 | inf_ptrace_wait (struct target_ops *ops, | | 382 | inf_ptrace_wait (struct target_ops *ops, |
383 | ptid_t ptid, struct target_waitstatus *ourstatus, int options) | | 383 | ptid_t ptid, struct target_waitstatus *ourstatus, int options) |
384 | { | | 384 | { |
385 | pid_t pid; | | 385 | pid_t pid; |
386 | int status, save_errno; | | 386 | int status, save_errno; |
387 | | | 387 | |
388 | do | | 388 | do |
389 | { | | 389 | { |
390 | set_sigint_trap (); | | 390 | set_sigint_trap (); |
391 | | | 391 | |
392 | do | | 392 | do |
393 | { | | 393 | { |
394 | pid = waitpid (ptid_get_pid (ptid), &status, 0); | | 394 | pid = waitpid (ptid_get_pid (ptid), &status, 0); |
395 | save_errno = errno; | | 395 | save_errno = errno; |
396 | } | | 396 | } |
397 | while (pid == -1 && errno == EINTR); | | 397 | while (pid == -1 && errno == EINTR); |
398 | | | 398 | |
399 | clear_sigint_trap (); | | 399 | clear_sigint_trap (); |
400 | | | 400 | |
401 | if (pid == -1) | | 401 | if (pid == -1) |
402 | { | | 402 | { |
403 | fprintf_unfiltered (gdb_stderr, | | 403 | fprintf_unfiltered (gdb_stderr, |
404 | _("Child process unexpectedly missing: %s.\n"), | | 404 | _("Child process unexpectedly missing: %s.\n"), |
405 | safe_strerror (save_errno)); | | 405 | safe_strerror (save_errno)); |
406 | | | 406 | |
407 | /* Claim it exited with unknown signal. */ | | 407 | /* Claim it exited with unknown signal. */ |
408 | ourstatus->kind = TARGET_WAITKIND_SIGNALLED; | | 408 | ourstatus->kind = TARGET_WAITKIND_SIGNALLED; |
409 | ourstatus->value.sig = GDB_SIGNAL_UNKNOWN; | | 409 | ourstatus->value.sig = GDB_SIGNAL_UNKNOWN; |
410 | return inferior_ptid; | | 410 | return inferior_ptid; |
411 | } | | 411 | } |
412 | | | 412 | |
413 | /* Ignore terminated detached child processes. */ | | 413 | /* Ignore terminated detached child processes. */ |
414 | if (!WIFSTOPPED (status) && pid != ptid_get_pid (inferior_ptid)) | | 414 | if (!WIFSTOPPED (status) && pid != ptid_get_pid (inferior_ptid)) |
415 | pid = -1; | | 415 | pid = -1; |
416 | } | | 416 | } |
417 | while (pid == -1); | | 417 | while (pid == -1); |
418 | | | 418 | |
419 | #ifdef PT_GET_PROCESS_STATE | | 419 | #ifdef PT_GET_PROCESS_STATE |
420 | if (WIFSTOPPED (status)) | | 420 | if (WIFSTOPPED (status)) |
421 | { | | 421 | { |
422 | ptrace_state_t pe; | | 422 | ptrace_state_t pe; |
423 | pid_t fpid; | | 423 | pid_t fpid; |
424 | | | 424 | |
425 | if (ptrace (PT_GET_PROCESS_STATE, pid, | | 425 | if (ptrace (PT_GET_PROCESS_STATE, pid, |
426 | (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1) | | 426 | (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1) |
427 | perror_with_name (("ptrace")); | | 427 | perror_with_name (("ptrace")); |
428 | | | 428 | |
429 | switch (pe.pe_report_event) | | 429 | switch (pe.pe_report_event) |
430 | { | | 430 | { |
431 | case PTRACE_FORK: | | 431 | case PTRACE_FORK: |
432 | ourstatus->kind = TARGET_WAITKIND_FORKED; | | 432 | ourstatus->kind = TARGET_WAITKIND_FORKED; |
433 | ourstatus->value.related_pid = pid_to_ptid (pe.pe_other_pid); | | 433 | ourstatus->value.related_pid = pid_to_ptid (pe.pe_other_pid); |
434 | | | 434 | |
435 | /* Make sure the other end of the fork is stopped too. */ | | 435 | /* Make sure the other end of the fork is stopped too. */ |
436 | fpid = waitpid (pe.pe_other_pid, &status, 0); | | 436 | fpid = waitpid (pe.pe_other_pid, &status, 0); |
437 | if (fpid == -1) | | 437 | if (fpid == -1) |
438 | perror_with_name (("waitpid")); | | 438 | perror_with_name (("waitpid")); |
439 | | | 439 | |
440 | if (ptrace (PT_GET_PROCESS_STATE, fpid, | | 440 | if (ptrace (PT_GET_PROCESS_STATE, fpid, |
441 | (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1) | | 441 | (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1) |
442 | perror_with_name (("ptrace")); | | 442 | perror_with_name (("ptrace")); |
443 | | | 443 | |
444 | gdb_assert (pe.pe_report_event == PTRACE_FORK); | | 444 | gdb_assert (pe.pe_report_event == PTRACE_FORK); |
445 | gdb_assert (pe.pe_other_pid == pid); | | 445 | gdb_assert (pe.pe_other_pid == pid); |
446 | if (fpid == ptid_get_pid (inferior_ptid)) | | 446 | if (fpid == ptid_get_pid (inferior_ptid)) |
447 | { | | 447 | { |
448 | ourstatus->value.related_pid = pid_to_ptid (pe.pe_other_pid); | | 448 | ourstatus->value.related_pid = pid_to_ptid (pe.pe_other_pid); |
449 | return pid_to_ptid (fpid); | | 449 | return pid_to_ptid (fpid); |
450 | } | | 450 | } |
451 | | | 451 | |
452 | return pid_to_ptid (pid); | | 452 | return pid_to_ptid (pid); |
453 | } | | 453 | } |
454 | } | | 454 | } |
455 | #endif | | 455 | #endif |
456 | | | 456 | |
457 | store_waitstatus (ourstatus, status); | | 457 | store_waitstatus (ourstatus, status); |
458 | return pid_to_ptid (pid); | | 458 | return pid_to_ptid (pid); |
459 | } | | 459 | } |
460 | | | 460 | |
461 | /* Transfer data via ptrace into process PID's memory from WRITEBUF, or | | 461 | /* Transfer data via ptrace into process PID's memory from WRITEBUF, or |
462 | from process PID's memory into READBUF. Start at target address ADDR | | 462 | from process PID's memory into READBUF. Start at target address ADDR |
463 | and transfer up to LEN bytes. Exactly one of READBUF and WRITEBUF must | | 463 | and transfer up to LEN bytes. Exactly one of READBUF and WRITEBUF must |
464 | be non-null. Return the number of transferred bytes. */ | | 464 | be non-null. Return the number of transferred bytes. */ |
465 | | | 465 | |
466 | static ULONGEST | | 466 | static ULONGEST |
467 | inf_ptrace_peek_poke (pid_t pid, gdb_byte *readbuf, | | 467 | inf_ptrace_peek_poke (pid_t pid, gdb_byte *readbuf, |
468 | const gdb_byte *writebuf, | | 468 | const gdb_byte *writebuf, |
469 | ULONGEST addr, ULONGEST len) | | 469 | ULONGEST addr, ULONGEST len) |
470 | { | | 470 | { |
471 | ULONGEST n; | | 471 | ULONGEST n; |
472 | unsigned int chunk; | | 472 | unsigned int chunk; |
473 | | | 473 | |
474 | /* We transfer aligned words. Thus align ADDR down to a word | | 474 | /* We transfer aligned words. Thus align ADDR down to a word |
475 | boundary and determine how many bytes to skip at the | | 475 | boundary and determine how many bytes to skip at the |
476 | beginning. */ | | 476 | beginning. */ |
477 | ULONGEST skip = addr & (sizeof (PTRACE_TYPE_RET) - 1); | | 477 | ULONGEST skip = addr & (sizeof (PTRACE_TYPE_RET) - 1); |
478 | addr -= skip; | | 478 | addr -= skip; |
479 | | | 479 | |
480 | for (n = 0; | | 480 | for (n = 0; |
481 | n < len; | | 481 | n < len; |
482 | n += chunk, addr += sizeof (PTRACE_TYPE_RET), skip = 0) | | 482 | n += chunk, addr += sizeof (PTRACE_TYPE_RET), skip = 0) |
483 | { | | 483 | { |
484 | /* Restrict to a chunk that fits in the current word. */ | | 484 | /* Restrict to a chunk that fits in the current word. */ |
485 | chunk = std::min (sizeof (PTRACE_TYPE_RET) - skip, len - n); | | 485 | chunk = std::min (sizeof (PTRACE_TYPE_RET) - skip, len - n); |
486 | | | 486 | |
487 | /* Use a union for type punning. */ | | 487 | /* Use a union for type punning. */ |
488 | union | | 488 | union |
489 | { | | 489 | { |
490 | PTRACE_TYPE_RET word; | | 490 | PTRACE_TYPE_RET word; |
491 | gdb_byte byte[sizeof (PTRACE_TYPE_RET)]; | | 491 | gdb_byte byte[sizeof (PTRACE_TYPE_RET)]; |
492 | } buf; | | 492 | } buf; |
493 | | | 493 | |
494 | /* Read the word, also when doing a partial word write. */ | | 494 | /* Read the word, also when doing a partial word write. */ |
495 | if (readbuf != NULL || chunk < sizeof (PTRACE_TYPE_RET)) | | 495 | if (readbuf != NULL || chunk < sizeof (PTRACE_TYPE_RET)) |
496 | { | | 496 | { |
497 | errno = 0; | | 497 | errno = 0; |
498 | buf.word = ptrace (PT_READ_I, pid, | | 498 | buf.word = ptrace (PT_READ_I, pid, |
499 | (PTRACE_TYPE_ARG3)(uintptr_t) addr, 0); | | 499 | (PTRACE_TYPE_ARG3)(uintptr_t) addr, 0); |
500 | if (errno != 0) | | 500 | if (errno != 0) |
501 | break; | | 501 | break; |
502 | if (readbuf != NULL) | | 502 | if (readbuf != NULL) |
503 | memcpy (readbuf + n, buf.byte + skip, chunk); | | 503 | memcpy (readbuf + n, buf.byte + skip, chunk); |
504 | } | | 504 | } |
505 | if (writebuf != NULL) | | 505 | if (writebuf != NULL) |
506 | { | | 506 | { |
507 | memcpy (buf.byte + skip, writebuf + n, chunk); | | 507 | memcpy (buf.byte + skip, writebuf + n, chunk); |
508 | errno = 0; | | 508 | errno = 0; |
509 | ptrace (PT_WRITE_D, pid, (PTRACE_TYPE_ARG3)(uintptr_t) addr, | | 509 | ptrace (PT_WRITE_D, pid, (PTRACE_TYPE_ARG3)(uintptr_t) addr, |
510 | buf.word); | | 510 | buf.word); |
511 | if (errno != 0) | | 511 | if (errno != 0) |
512 | { | | 512 | { |
513 | /* Using the appropriate one (I or D) is necessary for | | 513 | /* Using the appropriate one (I or D) is necessary for |
514 | Gould NP1, at least. */ | | 514 | Gould NP1, at least. */ |
515 | errno = 0; | | 515 | errno = 0; |
516 | ptrace (PT_WRITE_I, pid, (PTRACE_TYPE_ARG3)(uintptr_t) addr, | | 516 | ptrace (PT_WRITE_I, pid, (PTRACE_TYPE_ARG3)(uintptr_t) addr, |
517 | buf.word); | | 517 | buf.word); |
518 | if (errno != 0) | | 518 | if (errno != 0) |
519 | break; | | 519 | break; |
520 | } | | 520 | } |
521 | } | | 521 | } |
522 | } | | 522 | } |
523 | | | 523 | |
524 | return n; | | 524 | return n; |
525 | } | | 525 | } |
526 | | | 526 | |
527 | /* Implement the to_xfer_partial target_ops method. */ | | 527 | /* Implement the to_xfer_partial target_ops method. */ |
528 | | | 528 | |
529 | static enum target_xfer_status | | 529 | static enum target_xfer_status |
530 | inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object, | | 530 | inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object, |
531 | const char *annex, gdb_byte *readbuf, | | 531 | const char *annex, gdb_byte *readbuf, |
532 | const gdb_byte *writebuf, | | 532 | const gdb_byte *writebuf, |
533 | ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) | | 533 | ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) |
534 | { | | 534 | { |
535 | pid_t pid = get_ptrace_pid (inferior_ptid); | | 535 | pid_t pid = get_ptrace_pid (inferior_ptid); |
536 | | | 536 | |
537 | switch (object) | | 537 | switch (object) |
538 | { | | 538 | { |
539 | case TARGET_OBJECT_MEMORY: | | 539 | case TARGET_OBJECT_MEMORY: |
540 | #ifdef PT_IO | | 540 | #ifdef PT_IO |
541 | /* OpenBSD 3.1, NetBSD 1.6 and FreeBSD 5.0 have a new PT_IO | | 541 | /* OpenBSD 3.1, NetBSD 1.6 and FreeBSD 5.0 have a new PT_IO |
542 | request that promises to be much more efficient in reading | | 542 | request that promises to be much more efficient in reading |
543 | and writing data in the traced process's address space. */ | | 543 | and writing data in the traced process's address space. */ |
544 | { | | 544 | { |
545 | struct ptrace_io_desc piod; | | 545 | struct ptrace_io_desc piod; |
546 | | | 546 | |
547 | /* NOTE: We assume that there are no distinct address spaces | | 547 | /* NOTE: We assume that there are no distinct address spaces |
548 | for instruction and data. However, on OpenBSD 3.9 and | | 548 | for instruction and data. However, on OpenBSD 3.9 and |
549 | later, PIOD_WRITE_D doesn't allow changing memory that's | | 549 | later, PIOD_WRITE_D doesn't allow changing memory that's |
550 | mapped read-only. Since most code segments will be | | 550 | mapped read-only. Since most code segments will be |
551 | read-only, using PIOD_WRITE_D will prevent us from | | 551 | read-only, using PIOD_WRITE_D will prevent us from |
552 | inserting breakpoints, so we use PIOD_WRITE_I instead. */ | | 552 | inserting breakpoints, so we use PIOD_WRITE_I instead. */ |
553 | piod.piod_op = writebuf ? PIOD_WRITE_I : PIOD_READ_D; | | 553 | piod.piod_op = writebuf ? PIOD_WRITE_I : PIOD_READ_D; |
554 | piod.piod_addr = writebuf ? (void *) writebuf : readbuf; | | 554 | piod.piod_addr = writebuf ? (void *) writebuf : readbuf; |
555 | piod.piod_offs = (void *) (long) offset; | | 555 | piod.piod_offs = (void *) (long) offset; |
556 | piod.piod_len = len; | | 556 | piod.piod_len = len; |
557 | | | 557 | |
558 | errno = 0; | | 558 | errno = 0; |
559 | if (ptrace (PT_IO, pid, (caddr_t)&piod, 0) == 0) | | 559 | if (ptrace (PT_IO, pid, (caddr_t)&piod, 0) == 0) |
560 | { | | 560 | { |
561 | /* Return the actual number of bytes read or written. */ | | 561 | /* Return the actual number of bytes read or written. */ |
562 | *xfered_len = piod.piod_len; | | 562 | *xfered_len = piod.piod_len; |
563 | return (piod.piod_len == 0) ? TARGET_XFER_EOF : TARGET_XFER_OK; | | 563 | return (piod.piod_len == 0) ? TARGET_XFER_EOF : TARGET_XFER_OK; |
564 | } | | 564 | } |
565 | /* If the PT_IO request is somehow not supported, fallback on | | 565 | /* If the PT_IO request is somehow not supported, fallback on |
566 | using PT_WRITE_D/PT_READ_D. Otherwise we will return zero | | 566 | using PT_WRITE_D/PT_READ_D. Otherwise we will return zero |
567 | to indicate failure. */ | | 567 | to indicate failure. */ |
568 | if (errno == EACCES) | | 568 | if (errno == EACCES) |
569 | { | | 569 | { |
570 | fprintf_unfiltered (gdb_stderr, "Cannot %s process at %p (%s). " | | 570 | fprintf_unfiltered (gdb_stderr, "Cannot %s process at %p (%s). " |
571 | "Is PaX MPROTECT active? See security(7), " | | 571 | "Is PaX MPROTECT active? See security(7), " |
572 | "sysctl(7), paxctl(8)\n", writebuf ? "write to" : | | 572 | "sysctl(7), paxctl(8)\n", writebuf ? "write to" : |
573 | "read from", piod.piod_offs, | | 573 | "read from", piod.piod_offs, |
574 | strerror(errno)); | | 574 | strerror(errno)); |
575 | return TARGET_XFER_E_IO; /* Some other error perhaps? */ | | 575 | return TARGET_XFER_E_IO; /* Some other error perhaps? */ |
576 | } | | 576 | } |
577 | if (errno != EINVAL) | | 577 | if (errno != EINVAL) |
578 | return TARGET_XFER_EOF; | | 578 | return TARGET_XFER_EOF; |
579 | } | | 579 | } |
580 | #endif | | 580 | #endif |
581 | *xfered_len = inf_ptrace_peek_poke (pid, readbuf, writebuf, | | 581 | *xfered_len = inf_ptrace_peek_poke (pid, readbuf, writebuf, |
582 | offset, len); | | 582 | offset, len); |
583 | return *xfered_len != 0 ? TARGET_XFER_OK : TARGET_XFER_EOF; | | 583 | return *xfered_len != 0 ? TARGET_XFER_OK : TARGET_XFER_EOF; |
584 | | | 584 | |
585 | case TARGET_OBJECT_UNWIND_TABLE: | | 585 | case TARGET_OBJECT_UNWIND_TABLE: |
586 | return TARGET_XFER_E_IO; | | 586 | return TARGET_XFER_E_IO; |
587 | | | 587 | |
588 | case TARGET_OBJECT_AUXV: | | 588 | case TARGET_OBJECT_AUXV: |
589 | #if defined (PT_IO) && defined (PIOD_READ_AUXV) | | 589 | #if defined (PT_IO) && defined (PIOD_READ_AUXV) |
590 | /* OpenBSD 4.5 has a new PIOD_READ_AUXV operation for the PT_IO | | 590 | /* OpenBSD 4.5 has a new PIOD_READ_AUXV operation for the PT_IO |
591 | request that allows us to read the auxilliary vector. Other | | 591 | request that allows us to read the auxilliary vector. Other |
592 | BSD's may follow if they feel the need to support PIE. */ | | 592 | BSD's may follow if they feel the need to support PIE. */ |
593 | { | | 593 | { |
594 | struct ptrace_io_desc piod; | | 594 | struct ptrace_io_desc piod; |
595 | | | 595 | |
596 | if (writebuf) | | 596 | if (writebuf) |
597 | return TARGET_XFER_E_IO; | | 597 | return TARGET_XFER_E_IO; |
598 | piod.piod_op = PIOD_READ_AUXV; | | 598 | piod.piod_op = PIOD_READ_AUXV; |
599 | piod.piod_addr = readbuf; | | 599 | piod.piod_addr = readbuf; |
600 | piod.piod_offs = (void *) (long) offset; | | 600 | piod.piod_offs = (void *) (long) offset; |
601 | piod.piod_len = len; | | 601 | piod.piod_len = len; |
602 | | | 602 | |
603 | errno = 0; | | 603 | errno = 0; |
604 | if (ptrace (PT_IO, pid, (caddr_t)&piod, 0) == 0) | | 604 | if (ptrace (PT_IO, pid, (caddr_t)&piod, 0) == 0) |
605 | { | | 605 | { |
606 | /* Return the actual number of bytes read or written. */ | | 606 | /* Return the actual number of bytes read or written. */ |
607 | *xfered_len = piod.piod_len; | | 607 | *xfered_len = piod.piod_len; |
608 | return (piod.piod_len == 0) ? TARGET_XFER_EOF : TARGET_XFER_OK; | | 608 | return (piod.piod_len == 0) ? TARGET_XFER_EOF : TARGET_XFER_OK; |
609 | } | | 609 | } |
610 | } | | 610 | } |
611 | #endif | | 611 | #endif |
612 | return TARGET_XFER_E_IO; | | 612 | return TARGET_XFER_E_IO; |
613 | | | 613 | |
614 | case TARGET_OBJECT_WCOOKIE: | | 614 | case TARGET_OBJECT_WCOOKIE: |
615 | return TARGET_XFER_E_IO; | | 615 | return TARGET_XFER_E_IO; |
616 | | | 616 | |
617 | default: | | 617 | default: |
618 | return TARGET_XFER_E_IO; | | 618 | return TARGET_XFER_E_IO; |
619 | } | | 619 | } |
620 | } | | 620 | } |
621 | | | 621 | |
622 | /* Return non-zero if the thread specified by PTID is alive. */ | | 622 | /* Return non-zero if the thread specified by PTID is alive. */ |
623 | | | 623 | |
624 | static int | | 624 | static int |
625 | inf_ptrace_thread_alive (struct target_ops *ops, ptid_t ptid) | | 625 | inf_ptrace_thread_alive (struct target_ops *ops, ptid_t ptid) |
626 | { | | 626 | { |
627 | /* ??? Is kill the right way to do this? */ | | 627 | /* ??? Is kill the right way to do this? */ |
628 | return (kill (ptid_get_pid (ptid), 0) != -1); | | 628 | return (kill (ptid_get_pid (ptid), 0) != -1); |
629 | } | | 629 | } |
630 | | | 630 | |
631 | /* Print status information about what we're accessing. */ | | 631 | /* Print status information about what we're accessing. */ |
632 | | | 632 | |
633 | static void | | 633 | static void |
634 | inf_ptrace_files_info (struct target_ops *ignore) | | 634 | inf_ptrace_files_info (struct target_ops *ignore) |
635 | { | | 635 | { |
636 | struct inferior *inf = current_inferior (); | | 636 | struct inferior *inf = current_inferior (); |
637 | | | 637 | |
638 | printf_filtered (_("\tUsing the running image of %s %s.\n"), | | 638 | printf_filtered (_("\tUsing the running image of %s %s.\n"), |
639 | inf->attach_flag ? "attached" : "child", | | 639 | inf->attach_flag ? "attached" : "child", |
640 | target_pid_to_str (inferior_ptid)); | | 640 | target_pid_to_str (inferior_ptid)); |
641 | } | | 641 | } |
642 | | | 642 | |
643 | static const char * | | 643 | static const char * |
644 | inf_ptrace_pid_to_str (struct target_ops *ops, ptid_t ptid) | | 644 | inf_ptrace_pid_to_str (struct target_ops *ops, ptid_t ptid) |
645 | { | | 645 | { |
646 | return normal_pid_to_str (ptid); | | 646 | return normal_pid_to_str (ptid); |
647 | } | | 647 | } |
648 | | | 648 | |
649 | #if defined (PT_IO) && defined (PIOD_READ_AUXV) | | 649 | #if defined (PT_IO) && defined (PIOD_READ_AUXV) |
650 | | | 650 | |
651 | /* Read one auxv entry from *READPTR, not reading locations >= ENDPTR. | | 651 | /* Read one auxv entry from *READPTR, not reading locations >= ENDPTR. |
652 | Return 0 if *READPTR is already at the end of the buffer. | | 652 | Return 0 if *READPTR is already at the end of the buffer. |
653 | Return -1 if there is insufficient buffer for a whole entry. | | 653 | Return -1 if there is insufficient buffer for a whole entry. |
654 | Return 1 if an entry was read into *TYPEP and *VALP. */ | | 654 | Return 1 if an entry was read into *TYPEP and *VALP. */ |
655 | | | 655 | |
656 | static int | | 656 | static int |
657 | inf_ptrace_auxv_parse (struct target_ops *ops, gdb_byte **readptr, | | 657 | inf_ptrace_auxv_parse (struct target_ops *ops, gdb_byte **readptr, |
658 | gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) | | 658 | gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) |
659 | { | | 659 | { |
660 | struct type *int_type = builtin_type (target_gdbarch ())->builtin_int; | | 660 | struct type *int_type = builtin_type (target_gdbarch ())->builtin_int; |
661 | struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr; | | 661 | struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr; |
662 | const int sizeof_auxv_type = TYPE_LENGTH (int_type); | | 662 | const int sizeof_auxv_type = TYPE_LENGTH (int_type); |
663 | const int sizeof_auxv_val = TYPE_LENGTH (ptr_type); | | 663 | const int sizeof_auxv_val = TYPE_LENGTH (ptr_type); |
664 | enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); | | 664 | enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); |
665 | gdb_byte *ptr = *readptr; | | 665 | gdb_byte *ptr = *readptr; |
666 | | | 666 | |
667 | if (endptr == ptr) | | 667 | if (endptr == ptr) |
668 | return 0; | | 668 | return 0; |
669 | | | 669 | |
670 | if (endptr - ptr < 2 * sizeof_auxv_val) | | 670 | if (endptr - ptr < 2 * sizeof_auxv_val) |
671 | return -1; | | 671 | return -1; |
672 | | | 672 | |
673 | *typep = extract_unsigned_integer (ptr, sizeof_auxv_type, byte_order); | | 673 | *typep = extract_unsigned_integer (ptr, sizeof_auxv_type, byte_order); |
674 | ptr += sizeof_auxv_val; /* Alignment. */ | | 674 | ptr += sizeof_auxv_val; /* Alignment. */ |
675 | *valp = extract_unsigned_integer (ptr, sizeof_auxv_val, byte_order); | | 675 | *valp = extract_unsigned_integer (ptr, sizeof_auxv_val, byte_order); |
676 | ptr += sizeof_auxv_val; | | 676 | ptr += sizeof_auxv_val; |
677 | | | 677 | |
678 | *readptr = ptr; | | 678 | *readptr = ptr; |
679 | return 1; | | 679 | return 1; |
680 | } | | 680 | } |
681 | | | 681 | |
682 | #endif | | 682 | #endif |
683 | | | 683 | |
684 | /* Create a prototype ptrace target. The client can override it with | | 684 | /* Create a prototype ptrace target. The client can override it with |
685 | local methods. */ | | 685 | local methods. */ |
686 | | | 686 | |
687 | struct target_ops * | | 687 | struct target_ops * |
688 | inf_ptrace_target (void) | | 688 | inf_ptrace_target (void) |
689 | { | | 689 | { |
690 | struct target_ops *t = inf_child_target (); | | 690 | struct target_ops *t = inf_child_target (); |
691 | | | 691 | |
692 | t->to_attach = inf_ptrace_attach; | | 692 | t->to_attach = inf_ptrace_attach; |
693 | t->to_detach = inf_ptrace_detach; | | 693 | t->to_detach = inf_ptrace_detach; |
694 | t->to_resume = inf_ptrace_resume; | | 694 | t->to_resume = inf_ptrace_resume; |
695 | t->to_wait = inf_ptrace_wait; | | 695 | t->to_wait = inf_ptrace_wait; |
696 | t->to_files_info = inf_ptrace_files_info; | | 696 | t->to_files_info = inf_ptrace_files_info; |
697 | t->to_kill = inf_ptrace_kill; | | 697 | t->to_kill = inf_ptrace_kill; |
698 | t->to_create_inferior = inf_ptrace_create_inferior; | | 698 | t->to_create_inferior = inf_ptrace_create_inferior; |
699 | #ifdef PT_GET_PROCESS_STATE | | 699 | #ifdef PT_GET_PROCESS_STATE |
700 | t->to_follow_fork = inf_ptrace_follow_fork; | | 700 | t->to_follow_fork = inf_ptrace_follow_fork; |
701 | t->to_insert_fork_catchpoint = inf_ptrace_insert_fork_catchpoint; | | 701 | t->to_insert_fork_catchpoint = inf_ptrace_insert_fork_catchpoint; |
702 | t->to_remove_fork_catchpoint = inf_ptrace_remove_fork_catchpoint; | | 702 | t->to_remove_fork_catchpoint = inf_ptrace_remove_fork_catchpoint; |
703 | t->to_post_startup_inferior = inf_ptrace_post_startup_inferior; | | 703 | t->to_post_startup_inferior = inf_ptrace_post_startup_inferior; |
704 | t->to_post_attach = inf_ptrace_post_attach; | | 704 | t->to_post_attach = inf_ptrace_post_attach; |
705 | #endif | | 705 | #endif |
706 | t->to_mourn_inferior = inf_ptrace_mourn_inferior; | | 706 | t->to_mourn_inferior = inf_ptrace_mourn_inferior; |
707 | t->to_thread_alive = inf_ptrace_thread_alive; | | 707 | t->to_thread_alive = inf_ptrace_thread_alive; |
708 | t->to_pid_to_str = inf_ptrace_pid_to_str; | | 708 | t->to_pid_to_str = inf_ptrace_pid_to_str; |
709 | t->to_interrupt = inf_ptrace_interrupt; | | 709 | t->to_interrupt = inf_ptrace_interrupt; |
710 | t->to_xfer_partial = inf_ptrace_xfer_partial; | | 710 | t->to_xfer_partial = inf_ptrace_xfer_partial; |
711 | #if defined (PT_IO) && defined (PIOD_READ_AUXV) | | 711 | #if defined (PT_IO) && defined (PIOD_READ_AUXV) |
712 | t->to_auxv_parse = inf_ptrace_auxv_parse; | | 712 | t->to_auxv_parse = inf_ptrace_auxv_parse; |
713 | #endif | | 713 | #endif |
714 | | | 714 | |
715 | return t; | | 715 | return t; |
716 | } | | 716 | } |
717 | | | 717 | |
718 | | | 718 | |
719 | /* Pointer to a function that returns the offset within the user area | | 719 | /* Pointer to a function that returns the offset within the user area |
720 | where a particular register is stored. */ | | 720 | where a particular register is stored. */ |
721 | static CORE_ADDR (*inf_ptrace_register_u_offset)(struct gdbarch *, int, int); | | 721 | static CORE_ADDR (*inf_ptrace_register_u_offset)(struct gdbarch *, int, int); |
722 | | | 722 | |
723 | /* Fetch register REGNUM from the inferior. */ | | 723 | /* Fetch register REGNUM from the inferior. */ |
724 | | | 724 | |
725 | static void | | 725 | static void |
726 | inf_ptrace_fetch_register (struct regcache *regcache, int regnum) | | 726 | inf_ptrace_fetch_register (struct regcache *regcache, int regnum) |
727 | { | | 727 | { |
728 | struct gdbarch *gdbarch = get_regcache_arch (regcache); | | 728 | struct gdbarch *gdbarch = get_regcache_arch (regcache); |
729 | CORE_ADDR addr; | | 729 | CORE_ADDR addr; |
730 | size_t size; | | 730 | size_t size; |
731 | PTRACE_TYPE_RET *buf; | | 731 | PTRACE_TYPE_RET *buf; |
732 | pid_t pid; | | 732 | pid_t pid; |
733 | int i; | | 733 | int i; |
734 | | | 734 | |
735 | /* This isn't really an address, but ptrace thinks of it as one. */ | | 735 | /* This isn't really an address, but ptrace thinks of it as one. */ |
736 | addr = inf_ptrace_register_u_offset (gdbarch, regnum, 0); | | 736 | addr = inf_ptrace_register_u_offset (gdbarch, regnum, 0); |
737 | if (addr == (CORE_ADDR)-1 | | 737 | if (addr == (CORE_ADDR)-1 |
738 | || gdbarch_cannot_fetch_register (gdbarch, regnum)) | | 738 | || gdbarch_cannot_fetch_register (gdbarch, regnum)) |
739 | { | | 739 | { |
740 | regcache_raw_supply (regcache, regnum, NULL); | | 740 | regcache_raw_supply (regcache, regnum, NULL); |
741 | return; | | 741 | return; |
742 | } | | 742 | } |
743 | | | 743 | |
744 | pid = get_ptrace_pid (regcache_get_ptid (regcache)); | | 744 | pid = get_ptrace_pid (regcache_get_ptid (regcache)); |
745 | | | 745 | |
746 | size = register_size (gdbarch, regnum); | | 746 | size = register_size (gdbarch, regnum); |
747 | gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0); | | 747 | gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0); |
748 | buf = (PTRACE_TYPE_RET *) alloca (size); | | 748 | buf = (PTRACE_TYPE_RET *) alloca (size); |
749 | | | 749 | |
750 | /* Read the register contents from the inferior a chunk at a time. */ | | 750 | /* Read the register contents from the inferior a chunk at a time. */ |
751 | for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++) | | 751 | for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++) |
752 | { | | 752 | { |
753 | errno = 0; | | 753 | errno = 0; |
754 | buf[i] = ptrace (PT_READ_U, pid, (PTRACE_TYPE_ARG3)(uintptr_t)addr, 0); | | 754 | buf[i] = ptrace (PT_READ_U, pid, (PTRACE_TYPE_ARG3)(uintptr_t)addr, 0); |
755 | if (errno != 0) | | 755 | if (errno != 0) |
756 | error (_("Couldn't read register %s (#%d): %s."), | | 756 | error (_("Couldn't read register %s (#%d): %s."), |
757 | gdbarch_register_name (gdbarch, regnum), | | 757 | gdbarch_register_name (gdbarch, regnum), |
758 | regnum, safe_strerror (errno)); | | 758 | regnum, safe_strerror (errno)); |
759 | | | 759 | |
760 | addr += sizeof (PTRACE_TYPE_RET); | | 760 | addr += sizeof (PTRACE_TYPE_RET); |
761 | } | | 761 | } |
762 | regcache_raw_supply (regcache, regnum, buf); | | 762 | regcache_raw_supply (regcache, regnum, buf); |
763 | } | | 763 | } |
764 | | | 764 | |
765 | /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this | | 765 | /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this |
766 | for all registers. */ | | 766 | for all registers. */ |
767 | | | 767 | |
768 | static void | | 768 | static void |
769 | inf_ptrace_fetch_registers (struct target_ops *ops, | | 769 | inf_ptrace_fetch_registers (struct target_ops *ops, |
770 | struct regcache *regcache, int regnum) | | 770 | struct regcache *regcache, int regnum) |
771 | { | | 771 | { |
772 | if (regnum == -1) | | 772 | if (regnum == -1) |
773 | for (regnum = 0; | | 773 | for (regnum = 0; |
774 | regnum < gdbarch_num_regs (get_regcache_arch (regcache)); | | 774 | regnum < gdbarch_num_regs (get_regcache_arch (regcache)); |
775 | regnum++) | | 775 | regnum++) |
776 | inf_ptrace_fetch_register (regcache, regnum); | | 776 | inf_ptrace_fetch_register (regcache, regnum); |
777 | else | | 777 | else |
778 | inf_ptrace_fetch_register (regcache, regnum); | | 778 | inf_ptrace_fetch_register (regcache, regnum); |
779 | } | | 779 | } |
780 | | | 780 | |
781 | /* Store register REGNUM into the inferior. */ | | 781 | /* Store register REGNUM into the inferior. */ |
782 | | | 782 | |
783 | static void | | 783 | static void |
784 | inf_ptrace_store_register (const struct regcache *regcache, int regnum) | | 784 | inf_ptrace_store_register (const struct regcache *regcache, int regnum) |
785 | { | | 785 | { |
786 | struct gdbarch *gdbarch = get_regcache_arch (regcache); | | 786 | struct gdbarch *gdbarch = get_regcache_arch (regcache); |
787 | CORE_ADDR addr; | | 787 | CORE_ADDR addr; |
788 | size_t size; | | 788 | size_t size; |
789 | PTRACE_TYPE_RET *buf; | | 789 | PTRACE_TYPE_RET *buf; |
790 | pid_t pid; | | 790 | pid_t pid; |
791 | int i; | | 791 | int i; |
792 | | | 792 | |
793 | /* This isn't really an address, but ptrace thinks of it as one. */ | | 793 | /* This isn't really an address, but ptrace thinks of it as one. */ |
794 | addr = inf_ptrace_register_u_offset (gdbarch, regnum, 1); | | 794 | addr = inf_ptrace_register_u_offset (gdbarch, regnum, 1); |
795 | if (addr == (CORE_ADDR)-1 | | 795 | if (addr == (CORE_ADDR)-1 |
796 | || gdbarch_cannot_store_register (gdbarch, regnum)) | | 796 | || gdbarch_cannot_store_register (gdbarch, regnum)) |
797 | return; | | 797 | return; |
798 | | | 798 | |
799 | pid = get_ptrace_pid (regcache_get_ptid (regcache)); | | 799 | pid = get_ptrace_pid (regcache_get_ptid (regcache)); |
800 | | | 800 | |
801 | size = register_size (gdbarch, regnum); | | 801 | size = register_size (gdbarch, regnum); |
802 | gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0); | | 802 | gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0); |
803 | buf = (PTRACE_TYPE_RET *) alloca (size); | | 803 | buf = (PTRACE_TYPE_RET *) alloca (size); |
804 | | | 804 | |
805 | /* Write the register contents into the inferior a chunk at a time. */ | | 805 | /* Write the register contents into the inferior a chunk at a time. */ |
806 | regcache_raw_collect (regcache, regnum, buf); | | 806 | regcache_raw_collect (regcache, regnum, buf); |
807 | for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++) | | 807 | for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++) |
808 | { | | 808 | { |
809 | errno = 0; | | 809 | errno = 0; |
810 | ptrace (PT_WRITE_U, pid, (PTRACE_TYPE_ARG3)(uintptr_t)addr, buf[i]); | | 810 | ptrace (PT_WRITE_U, pid, (PTRACE_TYPE_ARG3)(uintptr_t)addr, buf[i]); |
811 | if (errno != 0) | | 811 | if (errno != 0) |
812 | error (_("Couldn't write register %s (#%d): %s."), | | 812 | error (_("Couldn't write register %s (#%d): %s."), |
813 | gdbarch_register_name (gdbarch, regnum), | | 813 | gdbarch_register_name (gdbarch, regnum), |
814 | regnum, safe_strerror (errno)); | | 814 | regnum, safe_strerror (errno)); |
815 | | | 815 | |
816 | addr += sizeof (PTRACE_TYPE_RET); | | 816 | addr += sizeof (PTRACE_TYPE_RET); |
817 | } | | 817 | } |
818 | } | | 818 | } |
819 | | | 819 | |
820 | /* Store register REGNUM back into the inferior. If REGNUM is -1, do | | 820 | /* Store register REGNUM back into the inferior. If REGNUM is -1, do |
821 | this for all registers. */ | | 821 | this for all registers. */ |
822 | | | 822 | |
823 | static void | | 823 | static void |
824 | inf_ptrace_store_registers (struct target_ops *ops, | | 824 | inf_ptrace_store_registers (struct target_ops *ops, |
825 | struct regcache *regcache, int regnum) | | 825 | struct regcache *regcache, int regnum) |
826 | { | | 826 | { |
827 | if (regnum == -1) | | 827 | if (regnum == -1) |
828 | for (regnum = 0; | | 828 | for (regnum = 0; |
829 | regnum < gdbarch_num_regs (get_regcache_arch (regcache)); | | 829 | regnum < gdbarch_num_regs (get_regcache_arch (regcache)); |
830 | regnum++) | | 830 | regnum++) |
831 | inf_ptrace_store_register (regcache, regnum); | | 831 | inf_ptrace_store_register (regcache, regnum); |
832 | else | | 832 | else |
833 | inf_ptrace_store_register (regcache, regnum); | | 833 | inf_ptrace_store_register (regcache, regnum); |
834 | } | | 834 | } |
835 | | | 835 | |
836 | /* Create a "traditional" ptrace target. REGISTER_U_OFFSET should be | | 836 | /* Create a "traditional" ptrace target. REGISTER_U_OFFSET should be |
837 | a function returning the offset within the user area where a | | 837 | a function returning the offset within the user area where a |
838 | particular register is stored. */ | | 838 | particular register is stored. */ |
839 | | | 839 | |
840 | struct target_ops * | | 840 | struct target_ops * |
841 | inf_ptrace_trad_target (CORE_ADDR (*register_u_offset) | | 841 | inf_ptrace_trad_target (CORE_ADDR (*register_u_offset) |
842 | (struct gdbarch *, int, int)) | | 842 | (struct gdbarch *, int, int)) |
843 | { | | 843 | { |
844 | struct target_ops *t = inf_ptrace_target(); | | 844 | struct target_ops *t = inf_ptrace_target(); |
845 | | | 845 | |
846 | gdb_assert (register_u_offset); | | 846 | gdb_assert (register_u_offset); |
847 | inf_ptrace_register_u_offset = register_u_offset; | | 847 | inf_ptrace_register_u_offset = register_u_offset; |
848 | t->to_fetch_registers = inf_ptrace_fetch_registers; | | 848 | t->to_fetch_registers = inf_ptrace_fetch_registers; |
849 | t->to_store_registers = inf_ptrace_store_registers; | | 849 | t->to_store_registers = inf_ptrace_store_registers; |
850 | | | 850 | |
851 | return t; | | 851 | return t; |
852 | } | | 852 | } |