netbsd-low.cc revision 1.1.1.2.2.1 1 1.1.1.2.2.1 perseant /* Copyright (C) 2020-2024 Free Software Foundation, Inc.
2 1.1 christos
3 1.1 christos This file is part of GDB.
4 1.1 christos
5 1.1 christos This program is free software; you can redistribute it and/or modify
6 1.1 christos it under the terms of the GNU General Public License as published by
7 1.1 christos the Free Software Foundation; either version 3 of the License, or
8 1.1 christos (at your option) any later version.
9 1.1 christos
10 1.1 christos This program is distributed in the hope that it will be useful,
11 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
12 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 1.1 christos GNU General Public License for more details.
14 1.1 christos
15 1.1 christos You should have received a copy of the GNU General Public License
16 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 1.1 christos
18 1.1 christos #include "target.h"
19 1.1 christos #include "netbsd-low.h"
20 1.1 christos #include "nat/netbsd-nat.h"
21 1.1 christos
22 1.1 christos #include <sys/param.h>
23 1.1 christos #include <sys/types.h>
24 1.1 christos
25 1.1 christos #include <sys/ptrace.h>
26 1.1 christos #include <sys/sysctl.h>
27 1.1 christos
28 1.1 christos #include <limits.h>
29 1.1 christos #include <unistd.h>
30 1.1 christos #include <signal.h>
31 1.1 christos
32 1.1 christos #include <elf.h>
33 1.1 christos
34 1.1 christos #include <type_traits>
35 1.1 christos
36 1.1 christos #include "gdbsupport/eintr.h"
37 1.1 christos #include "gdbsupport/gdb_wait.h"
38 1.1 christos #include "gdbsupport/filestuff.h"
39 1.1 christos #include "gdbsupport/common-inferior.h"
40 1.1 christos #include "nat/fork-inferior.h"
41 1.1 christos #include "hostio.h"
42 1.1 christos
43 1.1 christos int using_threads = 1;
44 1.1 christos
45 1.1 christos /* Callback used by fork_inferior to start tracing the inferior. */
46 1.1 christos
47 1.1 christos static void
48 1.1 christos netbsd_ptrace_fun ()
49 1.1 christos {
50 1.1 christos /* Switch child to its own process group so that signals won't
51 1.1 christos directly affect GDBserver. */
52 1.1 christos if (setpgid (0, 0) < 0)
53 1.1 christos trace_start_error_with_name (("setpgid"));
54 1.1 christos
55 1.1 christos if (ptrace (PT_TRACE_ME, 0, nullptr, 0) < 0)
56 1.1 christos trace_start_error_with_name (("ptrace"));
57 1.1 christos
58 1.1 christos /* If GDBserver is connected to gdb via stdio, redirect the inferior's
59 1.1 christos stdout to stderr so that inferior i/o doesn't corrupt the connection.
60 1.1 christos Also, redirect stdin to /dev/null. */
61 1.1 christos if (remote_connection_is_stdio ())
62 1.1 christos {
63 1.1 christos if (close (0) < 0)
64 1.1 christos trace_start_error_with_name (("close"));
65 1.1 christos if (open ("/dev/null", O_RDONLY) < 0)
66 1.1 christos trace_start_error_with_name (("open"));
67 1.1 christos if (dup2 (2, 1) < 0)
68 1.1 christos trace_start_error_with_name (("dup2"));
69 1.1 christos if (write (2, "stdin/stdout redirected\n",
70 1.1 christos sizeof ("stdin/stdout redirected\n") - 1) < 0)
71 1.1 christos {
72 1.1 christos /* Errors ignored. */
73 1.1 christos }
74 1.1 christos }
75 1.1 christos }
76 1.1 christos
77 1.1 christos /* Implement the create_inferior method of the target_ops vector. */
78 1.1 christos
79 1.1 christos int
80 1.1 christos netbsd_process_target::create_inferior (const char *program,
81 1.1 christos const std::vector<char *> &program_args)
82 1.1 christos {
83 1.1 christos std::string str_program_args = construct_inferior_arguments (program_args);
84 1.1 christos
85 1.1 christos pid_t pid = fork_inferior (program, str_program_args.c_str (),
86 1.1 christos get_environ ()->envp (), netbsd_ptrace_fun,
87 1.1 christos nullptr, nullptr, nullptr, nullptr);
88 1.1 christos
89 1.1.1.2 christos add_process (pid, 0);
90 1.1 christos
91 1.1 christos post_fork_inferior (pid, program);
92 1.1 christos
93 1.1 christos return pid;
94 1.1 christos }
95 1.1 christos
96 1.1 christos /* Implement the post_create_inferior target_ops method. */
97 1.1 christos
98 1.1 christos void
99 1.1 christos netbsd_process_target::post_create_inferior ()
100 1.1 christos {
101 1.1 christos pid_t pid = current_process ()->pid;
102 1.1 christos netbsd_nat::enable_proc_events (pid);
103 1.1.1.2 christos
104 1.1.1.2 christos low_arch_setup ();
105 1.1 christos }
106 1.1 christos
107 1.1 christos /* Implement the attach target_ops method. */
108 1.1 christos
109 1.1 christos int
110 1.1 christos netbsd_process_target::attach (unsigned long pid)
111 1.1 christos {
112 1.1 christos /* Unimplemented. */
113 1.1 christos return -1;
114 1.1 christos }
115 1.1 christos
116 1.1 christos /* Returns true if GDB is interested in any child syscalls. */
117 1.1 christos
118 1.1 christos static bool
119 1.1 christos gdb_catching_syscalls_p (pid_t pid)
120 1.1 christos {
121 1.1 christos struct process_info *proc = find_process_pid (pid);
122 1.1 christos return !proc->syscalls_to_catch.empty ();
123 1.1 christos }
124 1.1 christos
125 1.1 christos /* Implement the resume target_ops method. */
126 1.1 christos
127 1.1 christos void
128 1.1 christos netbsd_process_target::resume (struct thread_resume *resume_info, size_t n)
129 1.1 christos {
130 1.1 christos ptid_t resume_ptid = resume_info[0].thread;
131 1.1 christos const int signal = resume_info[0].sig;
132 1.1 christos const bool step = resume_info[0].kind == resume_step;
133 1.1 christos
134 1.1 christos if (resume_ptid == minus_one_ptid)
135 1.1 christos resume_ptid = ptid_of (current_thread);
136 1.1 christos
137 1.1 christos const pid_t pid = resume_ptid.pid ();
138 1.1 christos const lwpid_t lwp = resume_ptid.lwp ();
139 1.1 christos regcache_invalidate_pid (pid);
140 1.1 christos
141 1.1 christos auto fn
142 1.1 christos = [&] (ptid_t ptid)
143 1.1 christos {
144 1.1 christos if (step)
145 1.1 christos {
146 1.1 christos if (ptid.lwp () == lwp || n != 1)
147 1.1 christos {
148 1.1 christos if (ptrace (PT_SETSTEP, pid, NULL, ptid.lwp ()) == -1)
149 1.1 christos perror_with_name (("ptrace"));
150 1.1 christos if (ptrace (PT_RESUME, pid, NULL, ptid.lwp ()) == -1)
151 1.1 christos perror_with_name (("ptrace"));
152 1.1 christos }
153 1.1 christos else
154 1.1 christos {
155 1.1 christos if (ptrace (PT_CLEARSTEP, pid, NULL, ptid.lwp ()) == -1)
156 1.1 christos perror_with_name (("ptrace"));
157 1.1 christos if (ptrace (PT_SUSPEND, pid, NULL, ptid.lwp ()) == -1)
158 1.1 christos perror_with_name (("ptrace"));
159 1.1 christos }
160 1.1 christos }
161 1.1 christos else
162 1.1 christos {
163 1.1 christos if (ptrace (PT_CLEARSTEP, pid, NULL, ptid.lwp ()) == -1)
164 1.1 christos perror_with_name (("ptrace"));
165 1.1 christos if (ptrace (PT_RESUME, pid, NULL, ptid.lwp ()) == -1)
166 1.1 christos perror_with_name (("ptrace"));
167 1.1 christos }
168 1.1 christos };
169 1.1 christos
170 1.1 christos netbsd_nat::for_each_thread (pid, fn);
171 1.1 christos
172 1.1 christos int request = gdb_catching_syscalls_p (pid) ? PT_CONTINUE : PT_SYSCALL;
173 1.1 christos
174 1.1 christos errno = 0;
175 1.1 christos ptrace (request, pid, (void *)1, signal);
176 1.1 christos if (errno)
177 1.1 christos perror_with_name (("ptrace"));
178 1.1 christos }
179 1.1 christos
180 1.1 christos /* Returns true if GDB is interested in the reported SYSNO syscall. */
181 1.1 christos
182 1.1 christos static bool
183 1.1 christos netbsd_catch_this_syscall (int sysno)
184 1.1 christos {
185 1.1 christos struct process_info *proc = current_process ();
186 1.1 christos
187 1.1 christos if (proc->syscalls_to_catch.empty ())
188 1.1 christos return false;
189 1.1 christos
190 1.1 christos if (proc->syscalls_to_catch[0] == ANY_SYSCALL)
191 1.1 christos return true;
192 1.1 christos
193 1.1 christos for (int iter : proc->syscalls_to_catch)
194 1.1 christos if (iter == sysno)
195 1.1 christos return true;
196 1.1 christos
197 1.1 christos return false;
198 1.1 christos }
199 1.1 christos
200 1.1 christos /* Helper function for child_wait and the derivatives of child_wait.
201 1.1 christos HOSTSTATUS is the waitstatus from wait() or the equivalent; store our
202 1.1 christos translation of that in OURSTATUS. */
203 1.1 christos
204 1.1 christos static void
205 1.1 christos netbsd_store_waitstatus (struct target_waitstatus *ourstatus, int hoststatus)
206 1.1 christos {
207 1.1 christos if (WIFEXITED (hoststatus))
208 1.1.1.2 christos ourstatus->set_exited (WEXITSTATUS (hoststatus));
209 1.1 christos else if (!WIFSTOPPED (hoststatus))
210 1.1.1.2 christos ourstatus->set_signalled (gdb_signal_from_host (WTERMSIG (hoststatus)));
211 1.1 christos else
212 1.1.1.2 christos ourstatus->set_stopped (gdb_signal_from_host (WSTOPSIG (hoststatus)));
213 1.1 christos }
214 1.1 christos
215 1.1 christos /* Implement a safe wrapper around waitpid(). */
216 1.1 christos
217 1.1 christos static pid_t
218 1.1.1.2 christos netbsd_waitpid (ptid_t ptid, struct target_waitstatus *ourstatus,
219 1.1.1.2 christos target_wait_flags target_options)
220 1.1 christos {
221 1.1 christos int status;
222 1.1.1.2 christos int options = (target_options & TARGET_WNOHANG) ? WNOHANG : 0;
223 1.1 christos
224 1.1 christos pid_t pid
225 1.1.1.2 christos = gdb::handle_eintr (-1, ::waitpid, ptid.pid (), &status, options);
226 1.1 christos
227 1.1 christos if (pid == -1)
228 1.1 christos perror_with_name (_("Child process unexpectedly missing"));
229 1.1 christos
230 1.1 christos netbsd_store_waitstatus (ourstatus, status);
231 1.1 christos return pid;
232 1.1 christos }
233 1.1 christos
234 1.1 christos
235 1.1 christos /* Implement the wait target_ops method.
236 1.1 christos
237 1.1 christos Wait for the child specified by PTID to do something. Return the
238 1.1 christos process ID of the child, or MINUS_ONE_PTID in case of error; store
239 1.1 christos the status in *OURSTATUS. */
240 1.1 christos
241 1.1 christos static ptid_t
242 1.1 christos netbsd_wait (ptid_t ptid, struct target_waitstatus *ourstatus,
243 1.1.1.2 christos target_wait_flags target_options)
244 1.1 christos {
245 1.1 christos pid_t pid = netbsd_waitpid (ptid, ourstatus, target_options);
246 1.1 christos ptid_t wptid = ptid_t (pid);
247 1.1 christos
248 1.1 christos if (pid == 0)
249 1.1 christos {
250 1.1 christos gdb_assert (target_options & TARGET_WNOHANG);
251 1.1.1.2 christos ourstatus->set_ignore ();
252 1.1 christos return null_ptid;
253 1.1 christos }
254 1.1 christos
255 1.1 christos gdb_assert (pid != -1);
256 1.1 christos
257 1.1 christos /* If the child stopped, keep investigating its status. */
258 1.1.1.2 christos if (ourstatus->kind () != TARGET_WAITKIND_STOPPED)
259 1.1 christos return wptid;
260 1.1 christos
261 1.1 christos /* Extract the event and thread that received a signal. */
262 1.1 christos ptrace_siginfo_t psi;
263 1.1 christos if (ptrace (PT_GET_SIGINFO, pid, &psi, sizeof (psi)) == -1)
264 1.1 christos perror_with_name (("ptrace"));
265 1.1 christos
266 1.1 christos /* Pick child's siginfo_t. */
267 1.1 christos siginfo_t *si = &psi.psi_siginfo;
268 1.1 christos
269 1.1 christos lwpid_t lwp = psi.psi_lwpid;
270 1.1 christos
271 1.1 christos int signo = si->si_signo;
272 1.1 christos const int code = si->si_code;
273 1.1 christos
274 1.1 christos /* Construct PTID with a specified thread that received the event.
275 1.1 christos If a signal was targeted to the whole process, lwp is 0. */
276 1.1 christos wptid = ptid_t (pid, lwp, 0);
277 1.1 christos
278 1.1 christos /* Bail out on non-debugger oriented signals. */
279 1.1 christos if (signo != SIGTRAP)
280 1.1 christos return wptid;
281 1.1 christos
282 1.1 christos /* Stop examining non-debugger oriented SIGTRAP codes. */
283 1.1 christos if (code <= SI_USER || code == SI_NOINFO)
284 1.1 christos return wptid;
285 1.1 christos
286 1.1 christos /* Process state for threading events. */
287 1.1 christos ptrace_state_t pst = {};
288 1.1 christos if (code == TRAP_LWP)
289 1.1 christos if (ptrace (PT_GET_PROCESS_STATE, pid, &pst, sizeof (pst)) == -1)
290 1.1 christos perror_with_name (("ptrace"));
291 1.1 christos
292 1.1 christos if (code == TRAP_LWP && pst.pe_report_event == PTRACE_LWP_EXIT)
293 1.1 christos {
294 1.1 christos /* If GDB attaches to a multi-threaded process, exiting
295 1.1 christos threads might be skipped during post_attach that
296 1.1 christos have not yet reported their PTRACE_LWP_EXIT event.
297 1.1 christos Ignore exited events for an unknown LWP. */
298 1.1 christos thread_info *thr = find_thread_ptid (wptid);
299 1.1 christos if (thr == nullptr)
300 1.1.1.2 christos ourstatus->set_spurious ();
301 1.1 christos else
302 1.1 christos {
303 1.1 christos /* NetBSD does not store an LWP exit status. */
304 1.1.1.2 christos ourstatus->set_thread_exited (0);
305 1.1 christos
306 1.1 christos remove_thread (thr);
307 1.1 christos }
308 1.1 christos return wptid;
309 1.1 christos }
310 1.1 christos
311 1.1 christos if (find_thread_ptid (ptid_t (pid)))
312 1.1.1.2 christos switch_to_thread (find_thread_ptid (wptid));
313 1.1 christos
314 1.1 christos if (code == TRAP_LWP && pst.pe_report_event == PTRACE_LWP_CREATE)
315 1.1 christos {
316 1.1 christos /* If GDB attaches to a multi-threaded process, newborn
317 1.1 christos threads might be added by nbsd_add_threads that have
318 1.1 christos not yet reported their PTRACE_LWP_CREATE event. Ignore
319 1.1 christos born events for an already-known LWP. */
320 1.1 christos if (find_thread_ptid (wptid))
321 1.1.1.2 christos ourstatus->set_spurious ();
322 1.1 christos else
323 1.1 christos {
324 1.1 christos add_thread (wptid, NULL);
325 1.1.1.2 christos ourstatus->set_thread_created ();
326 1.1 christos }
327 1.1 christos return wptid;
328 1.1 christos }
329 1.1 christos
330 1.1 christos if (code == TRAP_EXEC)
331 1.1 christos {
332 1.1.1.2 christos ourstatus->set_execd
333 1.1.1.2 christos (make_unique_xstrdup (netbsd_nat::pid_to_exec_file (pid)));
334 1.1 christos return wptid;
335 1.1 christos }
336 1.1 christos
337 1.1 christos if (code == TRAP_TRACE)
338 1.1 christos return wptid;
339 1.1 christos
340 1.1 christos if (code == TRAP_SCE || code == TRAP_SCX)
341 1.1 christos {
342 1.1 christos int sysnum = si->si_sysnum;
343 1.1 christos
344 1.1 christos if (!netbsd_catch_this_syscall(sysnum))
345 1.1 christos {
346 1.1 christos /* If the core isn't interested in this event, ignore it. */
347 1.1.1.2 christos ourstatus->set_spurious ();
348 1.1 christos return wptid;
349 1.1 christos }
350 1.1 christos
351 1.1.1.2 christos if (code == TRAP_SCE)
352 1.1.1.2 christos ourstatus->set_syscall_entry (sysnum);
353 1.1.1.2 christos else
354 1.1.1.2 christos ourstatus->set_syscall_return (sysnum);
355 1.1.1.2 christos
356 1.1 christos return wptid;
357 1.1 christos }
358 1.1 christos
359 1.1 christos if (code == TRAP_BRKPT)
360 1.1 christos {
361 1.1 christos #ifdef PTRACE_BREAKPOINT_ADJ
362 1.1 christos CORE_ADDR pc;
363 1.1 christos struct reg r;
364 1.1 christos ptrace (PT_GETREGS, pid, &r, psi.psi_lwpid);
365 1.1 christos pc = PTRACE_REG_PC (&r);
366 1.1 christos PTRACE_REG_SET_PC (&r, pc - PTRACE_BREAKPOINT_ADJ);
367 1.1 christos ptrace (PT_SETREGS, pid, &r, psi.psi_lwpid);
368 1.1 christos #endif
369 1.1 christos return wptid;
370 1.1 christos }
371 1.1 christos
372 1.1 christos /* Unclassified SIGTRAP event. */
373 1.1.1.2 christos ourstatus->set_spurious ();
374 1.1 christos return wptid;
375 1.1 christos }
376 1.1 christos
377 1.1 christos /* Implement the wait target_ops method. */
378 1.1 christos
379 1.1 christos ptid_t
380 1.1 christos netbsd_process_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
381 1.1.1.2 christos target_wait_flags target_options)
382 1.1 christos {
383 1.1 christos while (true)
384 1.1 christos {
385 1.1 christos ptid_t wptid = netbsd_wait (ptid, ourstatus, target_options);
386 1.1 christos
387 1.1 christos /* Register thread in the gdbcore if a thread was not reported earlier.
388 1.1 christos This is required after ::create_inferior, when the gdbcore does not
389 1.1 christos know about the first internal thread.
390 1.1 christos This may also happen on attach, when an event is registered on a thread
391 1.1 christos that was not fully initialized during the attach stage. */
392 1.1 christos if (wptid.lwp () != 0 && !find_thread_ptid (wptid)
393 1.1.1.2 christos && ourstatus->kind () != TARGET_WAITKIND_THREAD_EXITED)
394 1.1 christos add_thread (wptid, nullptr);
395 1.1 christos
396 1.1.1.2 christos switch (ourstatus->kind ())
397 1.1 christos {
398 1.1 christos case TARGET_WAITKIND_EXITED:
399 1.1 christos case TARGET_WAITKIND_STOPPED:
400 1.1 christos case TARGET_WAITKIND_SIGNALLED:
401 1.1 christos case TARGET_WAITKIND_FORKED:
402 1.1 christos case TARGET_WAITKIND_VFORKED:
403 1.1 christos case TARGET_WAITKIND_EXECD:
404 1.1 christos case TARGET_WAITKIND_VFORK_DONE:
405 1.1 christos case TARGET_WAITKIND_SYSCALL_ENTRY:
406 1.1 christos case TARGET_WAITKIND_SYSCALL_RETURN:
407 1.1 christos /* Pass the result to the generic code. */
408 1.1 christos return wptid;
409 1.1 christos case TARGET_WAITKIND_THREAD_CREATED:
410 1.1 christos case TARGET_WAITKIND_THREAD_EXITED:
411 1.1 christos /* The core needlessly stops on these events. */
412 1.1.1.2.2.1 perseant [[fallthrough]];
413 1.1 christos case TARGET_WAITKIND_SPURIOUS:
414 1.1 christos /* Spurious events are unhandled by the gdbserver core. */
415 1.1 christos if (ptrace (PT_CONTINUE, current_process ()->pid, (void *) 1, 0)
416 1.1 christos == -1)
417 1.1 christos perror_with_name (("ptrace"));
418 1.1 christos break;
419 1.1 christos default:
420 1.1 christos error (("Unknown stopped status"));
421 1.1 christos }
422 1.1 christos }
423 1.1 christos }
424 1.1 christos
425 1.1 christos /* Implement the kill target_ops method. */
426 1.1 christos
427 1.1 christos int
428 1.1 christos netbsd_process_target::kill (process_info *process)
429 1.1 christos {
430 1.1 christos pid_t pid = process->pid;
431 1.1 christos if (ptrace (PT_KILL, pid, nullptr, 0) == -1)
432 1.1 christos return -1;
433 1.1 christos
434 1.1 christos int status;
435 1.1.1.2 christos if (gdb::handle_eintr (-1, ::waitpid, pid, &status, 0) == -1)
436 1.1 christos return -1;
437 1.1 christos mourn (process);
438 1.1 christos return 0;
439 1.1 christos }
440 1.1 christos
441 1.1 christos /* Implement the detach target_ops method. */
442 1.1 christos
443 1.1 christos int
444 1.1 christos netbsd_process_target::detach (process_info *process)
445 1.1 christos {
446 1.1 christos pid_t pid = process->pid;
447 1.1 christos
448 1.1 christos ptrace (PT_DETACH, pid, (void *) 1, 0);
449 1.1 christos mourn (process);
450 1.1 christos return 0;
451 1.1 christos }
452 1.1 christos
453 1.1 christos /* Implement the mourn target_ops method. */
454 1.1 christos
455 1.1 christos void
456 1.1 christos netbsd_process_target::mourn (struct process_info *proc)
457 1.1 christos {
458 1.1 christos for_each_thread (proc->pid, remove_thread);
459 1.1 christos
460 1.1 christos remove_process (proc);
461 1.1 christos }
462 1.1 christos
463 1.1 christos /* Implement the join target_ops method. */
464 1.1 christos
465 1.1 christos void
466 1.1 christos netbsd_process_target::join (int pid)
467 1.1 christos {
468 1.1 christos /* The PT_DETACH is sufficient to detach from the process.
469 1.1 christos So no need to do anything extra. */
470 1.1 christos }
471 1.1 christos
472 1.1 christos /* Implement the thread_alive target_ops method. */
473 1.1 christos
474 1.1 christos bool
475 1.1 christos netbsd_process_target::thread_alive (ptid_t ptid)
476 1.1 christos {
477 1.1 christos return netbsd_nat::thread_alive (ptid);
478 1.1 christos }
479 1.1 christos
480 1.1 christos /* Implement the fetch_registers target_ops method. */
481 1.1 christos
482 1.1 christos void
483 1.1 christos netbsd_process_target::fetch_registers (struct regcache *regcache, int regno)
484 1.1 christos {
485 1.1.1.2 christos const netbsd_regset_info *regset = get_regs_info ();
486 1.1 christos ptid_t inferior_ptid = ptid_of (current_thread);
487 1.1 christos
488 1.1 christos while (regset->size >= 0)
489 1.1 christos {
490 1.1 christos std::vector<char> buf;
491 1.1 christos buf.resize (regset->size);
492 1.1 christos int res = ptrace (regset->get_request, inferior_ptid.pid (), buf.data (),
493 1.1 christos inferior_ptid.lwp ());
494 1.1 christos if (res == -1)
495 1.1 christos perror_with_name (("ptrace"));
496 1.1 christos regset->store_function (regcache, buf.data ());
497 1.1 christos regset++;
498 1.1 christos }
499 1.1 christos }
500 1.1 christos
501 1.1 christos /* Implement the store_registers target_ops method. */
502 1.1 christos
503 1.1 christos void
504 1.1 christos netbsd_process_target::store_registers (struct regcache *regcache, int regno)
505 1.1 christos {
506 1.1.1.2 christos const netbsd_regset_info *regset = get_regs_info ();
507 1.1 christos ptid_t inferior_ptid = ptid_of (current_thread);
508 1.1 christos
509 1.1 christos while (regset->size >= 0)
510 1.1 christos {
511 1.1 christos std::vector<char> buf;
512 1.1 christos buf.resize (regset->size);
513 1.1 christos int res = ptrace (regset->get_request, inferior_ptid.pid (), buf.data (),
514 1.1 christos inferior_ptid.lwp ());
515 1.1 christos if (res == -1)
516 1.1 christos perror_with_name (("ptrace"));
517 1.1 christos
518 1.1 christos /* Then overlay our cached registers on that. */
519 1.1 christos regset->fill_function (regcache, buf.data ());
520 1.1 christos /* Only now do we write the register set. */
521 1.1 christos res = ptrace (regset->set_request, inferior_ptid.pid (), buf. data (),
522 1.1 christos inferior_ptid.lwp ());
523 1.1 christos if (res == -1)
524 1.1 christos perror_with_name (("ptrace"));
525 1.1 christos regset++;
526 1.1 christos }
527 1.1 christos }
528 1.1 christos
529 1.1 christos /* Implement the read_memory target_ops method. */
530 1.1 christos
531 1.1 christos int
532 1.1 christos netbsd_process_target::read_memory (CORE_ADDR memaddr, unsigned char *myaddr,
533 1.1 christos int size)
534 1.1 christos {
535 1.1 christos pid_t pid = current_process ()->pid;
536 1.1.1.2 christos return netbsd_nat::read_memory (pid, myaddr, memaddr, size, nullptr);
537 1.1 christos }
538 1.1 christos
539 1.1 christos /* Implement the write_memory target_ops method. */
540 1.1 christos
541 1.1 christos int
542 1.1 christos netbsd_process_target::write_memory (CORE_ADDR memaddr,
543 1.1 christos const unsigned char *myaddr, int size)
544 1.1 christos {
545 1.1 christos pid_t pid = current_process ()->pid;
546 1.1.1.2 christos return netbsd_nat::write_memory (pid, myaddr, memaddr, size, nullptr);
547 1.1 christos }
548 1.1 christos
549 1.1 christos /* Implement the request_interrupt target_ops method. */
550 1.1 christos
551 1.1 christos void
552 1.1 christos netbsd_process_target::request_interrupt ()
553 1.1 christos {
554 1.1 christos ptid_t inferior_ptid = ptid_of (get_first_thread ());
555 1.1 christos
556 1.1.1.2 christos ::kill (inferior_ptid.pid (), SIGINT);
557 1.1 christos }
558 1.1 christos
559 1.1 christos /* Read the AUX Vector for the specified PID, wrapping the ptrace(2) call
560 1.1 christos with the PIOD_READ_AUXV operation and using the PT_IO standard input
561 1.1 christos and output arguments. */
562 1.1 christos
563 1.1 christos static size_t
564 1.1 christos netbsd_read_auxv(pid_t pid, void *offs, void *addr, size_t len)
565 1.1 christos {
566 1.1 christos struct ptrace_io_desc pio;
567 1.1 christos
568 1.1 christos pio.piod_op = PIOD_READ_AUXV;
569 1.1 christos pio.piod_offs = offs;
570 1.1 christos pio.piod_addr = addr;
571 1.1 christos pio.piod_len = len;
572 1.1 christos
573 1.1 christos if (ptrace (PT_IO, pid, &pio, 0) == -1)
574 1.1 christos perror_with_name (("ptrace"));
575 1.1 christos
576 1.1 christos return pio.piod_len;
577 1.1 christos }
578 1.1 christos
579 1.1 christos /* Copy LEN bytes from inferior's auxiliary vector starting at OFFSET
580 1.1 christos to debugger memory starting at MYADDR. */
581 1.1 christos
582 1.1 christos int
583 1.1.1.2.2.1 perseant netbsd_process_target::read_auxv (int pid, CORE_ADDR offset,
584 1.1 christos unsigned char *myaddr, unsigned int len)
585 1.1 christos {
586 1.1 christos return netbsd_read_auxv (pid, (void *) (intptr_t) offset, myaddr, len);
587 1.1 christos }
588 1.1 christos
589 1.1 christos bool
590 1.1 christos netbsd_process_target::supports_z_point_type (char z_type)
591 1.1 christos {
592 1.1 christos switch (z_type)
593 1.1 christos {
594 1.1 christos case Z_PACKET_SW_BP:
595 1.1 christos return true;
596 1.1 christos case Z_PACKET_HW_BP:
597 1.1 christos case Z_PACKET_WRITE_WP:
598 1.1 christos case Z_PACKET_READ_WP:
599 1.1 christos case Z_PACKET_ACCESS_WP:
600 1.1 christos default:
601 1.1 christos return false; /* Not supported. */
602 1.1 christos }
603 1.1 christos }
604 1.1 christos
605 1.1 christos /* Insert {break/watch}point at address ADDR. SIZE is not used. */
606 1.1 christos
607 1.1 christos int
608 1.1 christos netbsd_process_target::insert_point (enum raw_bkpt_type type, CORE_ADDR addr,
609 1.1 christos int size, struct raw_breakpoint *bp)
610 1.1 christos {
611 1.1 christos switch (type)
612 1.1 christos {
613 1.1 christos case raw_bkpt_type_sw:
614 1.1 christos return insert_memory_breakpoint (bp);
615 1.1 christos case raw_bkpt_type_hw:
616 1.1 christos case raw_bkpt_type_write_wp:
617 1.1 christos case raw_bkpt_type_read_wp:
618 1.1 christos case raw_bkpt_type_access_wp:
619 1.1 christos default:
620 1.1 christos return 1; /* Not supported. */
621 1.1 christos }
622 1.1 christos }
623 1.1 christos
624 1.1 christos /* Remove {break/watch}point at address ADDR. SIZE is not used. */
625 1.1 christos
626 1.1 christos int
627 1.1 christos netbsd_process_target::remove_point (enum raw_bkpt_type type, CORE_ADDR addr,
628 1.1 christos int size, struct raw_breakpoint *bp)
629 1.1 christos {
630 1.1 christos switch (type)
631 1.1 christos {
632 1.1 christos case raw_bkpt_type_sw:
633 1.1 christos return remove_memory_breakpoint (bp);
634 1.1 christos case raw_bkpt_type_hw:
635 1.1 christos case raw_bkpt_type_write_wp:
636 1.1 christos case raw_bkpt_type_read_wp:
637 1.1 christos case raw_bkpt_type_access_wp:
638 1.1 christos default:
639 1.1 christos return 1; /* Not supported. */
640 1.1 christos }
641 1.1 christos }
642 1.1 christos
643 1.1 christos /* Implement the stopped_by_sw_breakpoint target_ops method. */
644 1.1 christos
645 1.1 christos bool
646 1.1 christos netbsd_process_target::stopped_by_sw_breakpoint ()
647 1.1 christos {
648 1.1 christos ptrace_siginfo_t psi;
649 1.1 christos pid_t pid = current_process ()->pid;
650 1.1 christos
651 1.1 christos if (ptrace (PT_GET_SIGINFO, pid, &psi, sizeof (psi)) == -1)
652 1.1 christos perror_with_name (("ptrace"));
653 1.1 christos
654 1.1 christos return psi.psi_siginfo.si_signo == SIGTRAP &&
655 1.1 christos psi.psi_siginfo.si_code == TRAP_BRKPT;
656 1.1 christos }
657 1.1 christos
658 1.1 christos /* Implement the supports_stopped_by_sw_breakpoint target_ops method. */
659 1.1 christos
660 1.1 christos bool
661 1.1 christos netbsd_process_target::supports_stopped_by_sw_breakpoint ()
662 1.1 christos {
663 1.1 christos return true;
664 1.1 christos }
665 1.1 christos
666 1.1 christos /* Implement the supports_qxfer_siginfo target_ops method. */
667 1.1 christos
668 1.1 christos bool
669 1.1 christos netbsd_process_target::supports_qxfer_siginfo ()
670 1.1 christos {
671 1.1 christos return true;
672 1.1 christos }
673 1.1 christos
674 1.1 christos /* Implement the qxfer_siginfo target_ops method. */
675 1.1 christos
676 1.1 christos int
677 1.1 christos netbsd_process_target::qxfer_siginfo (const char *annex, unsigned char *readbuf,
678 1.1 christos unsigned const char *writebuf,
679 1.1 christos CORE_ADDR offset, int len)
680 1.1 christos {
681 1.1 christos if (current_thread == nullptr)
682 1.1 christos return -1;
683 1.1 christos
684 1.1 christos pid_t pid = current_process ()->pid;
685 1.1 christos
686 1.1 christos return netbsd_nat::qxfer_siginfo(pid, annex, readbuf, writebuf, offset, len);
687 1.1 christos }
688 1.1 christos
689 1.1 christos /* Implement the supports_non_stop target_ops method. */
690 1.1 christos
691 1.1 christos bool
692 1.1 christos netbsd_process_target::supports_non_stop ()
693 1.1 christos {
694 1.1 christos return false;
695 1.1 christos }
696 1.1 christos
697 1.1 christos /* Implement the supports_multi_process target_ops method. */
698 1.1 christos
699 1.1 christos bool
700 1.1 christos netbsd_process_target::supports_multi_process ()
701 1.1 christos {
702 1.1 christos return true;
703 1.1 christos }
704 1.1 christos
705 1.1 christos /* Check if fork events are supported. */
706 1.1 christos
707 1.1 christos bool
708 1.1 christos netbsd_process_target::supports_fork_events ()
709 1.1 christos {
710 1.1 christos return false;
711 1.1 christos }
712 1.1 christos
713 1.1 christos /* Check if vfork events are supported. */
714 1.1 christos
715 1.1 christos bool
716 1.1 christos netbsd_process_target::supports_vfork_events ()
717 1.1 christos {
718 1.1 christos return false;
719 1.1 christos }
720 1.1 christos
721 1.1 christos /* Check if exec events are supported. */
722 1.1 christos
723 1.1 christos bool
724 1.1 christos netbsd_process_target::supports_exec_events ()
725 1.1 christos {
726 1.1 christos return true;
727 1.1 christos }
728 1.1 christos
729 1.1 christos /* Implement the supports_disable_randomization target_ops method. */
730 1.1 christos
731 1.1 christos bool
732 1.1 christos netbsd_process_target::supports_disable_randomization ()
733 1.1 christos {
734 1.1 christos return false;
735 1.1 christos }
736 1.1 christos
737 1.1 christos /* Extract &phdr and num_phdr in the inferior. Return 0 on success. */
738 1.1 christos
739 1.1 christos template <typename T>
740 1.1 christos int get_phdr_phnum_from_proc_auxv (const pid_t pid,
741 1.1 christos CORE_ADDR *phdr_memaddr, int *num_phdr)
742 1.1 christos {
743 1.1 christos typedef typename std::conditional<sizeof(T) == sizeof(int64_t),
744 1.1 christos Aux64Info, Aux32Info>::type auxv_type;
745 1.1 christos const size_t auxv_size = sizeof (auxv_type);
746 1.1 christos const size_t auxv_buf_size = 128 * sizeof (auxv_type);
747 1.1 christos
748 1.1 christos std::vector<char> auxv_buf;
749 1.1 christos auxv_buf.resize (auxv_buf_size);
750 1.1 christos
751 1.1 christos netbsd_read_auxv (pid, nullptr, auxv_buf.data (), auxv_buf_size);
752 1.1 christos
753 1.1 christos *phdr_memaddr = 0;
754 1.1 christos *num_phdr = 0;
755 1.1 christos
756 1.1 christos for (char *buf = auxv_buf.data ();
757 1.1 christos buf < (auxv_buf.data () + auxv_buf_size);
758 1.1 christos buf += auxv_size)
759 1.1 christos {
760 1.1 christos auxv_type *const aux = (auxv_type *) buf;
761 1.1 christos
762 1.1 christos switch (aux->a_type)
763 1.1 christos {
764 1.1 christos case AT_PHDR:
765 1.1 christos *phdr_memaddr = aux->a_v;
766 1.1 christos break;
767 1.1 christos case AT_PHNUM:
768 1.1 christos *num_phdr = aux->a_v;
769 1.1 christos break;
770 1.1 christos }
771 1.1 christos
772 1.1 christos if (*phdr_memaddr != 0 && *num_phdr != 0)
773 1.1 christos break;
774 1.1 christos }
775 1.1 christos
776 1.1 christos if (*phdr_memaddr == 0 || *num_phdr == 0)
777 1.1 christos {
778 1.1 christos warning ("Unexpected missing AT_PHDR and/or AT_PHNUM: "
779 1.1 christos "phdr_memaddr = %s, phdr_num = %d",
780 1.1 christos core_addr_to_string (*phdr_memaddr), *num_phdr);
781 1.1 christos return 2;
782 1.1 christos }
783 1.1 christos
784 1.1 christos return 0;
785 1.1 christos }
786 1.1 christos
787 1.1 christos /* Return &_DYNAMIC (via PT_DYNAMIC) in the inferior, or 0 if not present. */
788 1.1 christos
789 1.1 christos template <typename T>
790 1.1 christos static CORE_ADDR
791 1.1.1.2 christos get_dynamic (const pid_t pid)
792 1.1 christos {
793 1.1 christos typedef typename std::conditional<sizeof(T) == sizeof(int64_t),
794 1.1 christos Elf64_Phdr, Elf32_Phdr>::type phdr_type;
795 1.1 christos const int phdr_size = sizeof (phdr_type);
796 1.1 christos
797 1.1 christos CORE_ADDR phdr_memaddr;
798 1.1 christos int num_phdr;
799 1.1 christos if (get_phdr_phnum_from_proc_auxv<T> (pid, &phdr_memaddr, &num_phdr))
800 1.1 christos return 0;
801 1.1 christos
802 1.1 christos std::vector<unsigned char> phdr_buf;
803 1.1 christos phdr_buf.resize (num_phdr * phdr_size);
804 1.1 christos
805 1.1.1.2 christos if (netbsd_nat::read_memory (pid, phdr_buf.data (), phdr_memaddr,
806 1.1.1.2 christos phdr_buf.size (), nullptr))
807 1.1 christos return 0;
808 1.1 christos
809 1.1 christos /* Compute relocation: it is expected to be 0 for "regular" executables,
810 1.1 christos non-zero for PIE ones. */
811 1.1 christos CORE_ADDR relocation = -1;
812 1.1 christos for (int i = 0; relocation == -1 && i < num_phdr; i++)
813 1.1 christos {
814 1.1.1.2 christos phdr_type *const p = (phdr_type *) (phdr_buf.data () + i * phdr_size);
815 1.1 christos
816 1.1 christos if (p->p_type == PT_PHDR)
817 1.1 christos relocation = phdr_memaddr - p->p_vaddr;
818 1.1 christos }
819 1.1 christos
820 1.1 christos if (relocation == -1)
821 1.1 christos {
822 1.1 christos /* PT_PHDR is optional, but necessary for PIE in general. Fortunately
823 1.1 christos any real world executables, including PIE executables, have always
824 1.1 christos PT_PHDR present. PT_PHDR is not present in some shared libraries or
825 1.1 christos in fpc (Free Pascal 2.4) binaries but neither of those have a need for
826 1.1 christos or present DT_DEBUG anyway (fpc binaries are statically linked).
827 1.1 christos
828 1.1 christos Therefore if there exists DT_DEBUG there is always also PT_PHDR.
829 1.1 christos
830 1.1 christos GDB could find RELOCATION also from AT_ENTRY - e_entry. */
831 1.1 christos
832 1.1 christos return 0;
833 1.1 christos }
834 1.1 christos
835 1.1 christos for (int i = 0; i < num_phdr; i++)
836 1.1 christos {
837 1.1 christos phdr_type *const p = (phdr_type *) (phdr_buf.data () + i * phdr_size);
838 1.1 christos
839 1.1 christos if (p->p_type == PT_DYNAMIC)
840 1.1 christos return p->p_vaddr + relocation;
841 1.1 christos }
842 1.1 christos
843 1.1 christos return 0;
844 1.1 christos }
845 1.1 christos
846 1.1 christos /* Return &_r_debug in the inferior, or -1 if not present. Return value
847 1.1 christos can be 0 if the inferior does not yet have the library list initialized.
848 1.1 christos We look for DT_MIPS_RLD_MAP first. MIPS executables use this instead of
849 1.1 christos DT_DEBUG, although they sometimes contain an unused DT_DEBUG entry too. */
850 1.1 christos
851 1.1 christos template <typename T>
852 1.1 christos static CORE_ADDR
853 1.1.1.2 christos get_r_debug (const pid_t pid)
854 1.1 christos {
855 1.1 christos typedef typename std::conditional<sizeof(T) == sizeof(int64_t),
856 1.1 christos Elf64_Dyn, Elf32_Dyn>::type dyn_type;
857 1.1 christos const int dyn_size = sizeof (dyn_type);
858 1.1 christos unsigned char buf[sizeof (dyn_type)]; /* The larger of the two. */
859 1.1 christos CORE_ADDR map = -1;
860 1.1 christos
861 1.1.1.2 christos CORE_ADDR dynamic_memaddr = get_dynamic<T> (pid);
862 1.1 christos if (dynamic_memaddr == 0)
863 1.1 christos return map;
864 1.1 christos
865 1.1.1.2 christos while (netbsd_nat::read_memory (pid, buf, dynamic_memaddr, dyn_size, nullptr)
866 1.1.1.2 christos == 0)
867 1.1 christos {
868 1.1 christos dyn_type *const dyn = (dyn_type *) buf;
869 1.1 christos #if defined DT_MIPS_RLD_MAP
870 1.1 christos union
871 1.1 christos {
872 1.1 christos T map;
873 1.1 christos unsigned char buf[sizeof (T)];
874 1.1 christos }
875 1.1 christos rld_map;
876 1.1 christos
877 1.1 christos if (dyn->d_tag == DT_MIPS_RLD_MAP)
878 1.1 christos {
879 1.1.1.2 christos if (netbsd_nat::read_memory (pid, rld_map.buf, dyn->d_un.d_val,
880 1.1.1.2 christos sizeof (rld_map.buf), nullptr) == 0)
881 1.1 christos return rld_map.map;
882 1.1 christos else
883 1.1 christos break;
884 1.1 christos }
885 1.1 christos #endif /* DT_MIPS_RLD_MAP */
886 1.1 christos
887 1.1 christos if (dyn->d_tag == DT_DEBUG && map == -1)
888 1.1 christos map = dyn->d_un.d_val;
889 1.1 christos
890 1.1 christos if (dyn->d_tag == DT_NULL)
891 1.1 christos break;
892 1.1 christos
893 1.1 christos dynamic_memaddr += dyn_size;
894 1.1 christos }
895 1.1 christos
896 1.1 christos return map;
897 1.1 christos }
898 1.1 christos
899 1.1 christos /* Read one pointer from MEMADDR in the inferior. */
900 1.1 christos
901 1.1 christos static int
902 1.1.1.2 christos read_one_ptr (const pid_t pid, CORE_ADDR memaddr, CORE_ADDR *ptr, int ptr_size)
903 1.1 christos {
904 1.1 christos /* Go through a union so this works on either big or little endian
905 1.1 christos hosts, when the inferior's pointer size is smaller than the size
906 1.1 christos of CORE_ADDR. It is assumed the inferior's endianness is the
907 1.1 christos same of the superior's. */
908 1.1 christos
909 1.1 christos union
910 1.1 christos {
911 1.1 christos CORE_ADDR core_addr;
912 1.1 christos unsigned int ui;
913 1.1 christos unsigned char uc;
914 1.1 christos } addr;
915 1.1 christos
916 1.1.1.2 christos int ret = netbsd_nat::read_memory (pid, &addr.uc, memaddr, ptr_size, nullptr);
917 1.1 christos if (ret == 0)
918 1.1 christos {
919 1.1 christos if (ptr_size == sizeof (CORE_ADDR))
920 1.1 christos *ptr = addr.core_addr;
921 1.1 christos else if (ptr_size == sizeof (unsigned int))
922 1.1 christos *ptr = addr.ui;
923 1.1 christos else
924 1.1 christos gdb_assert_not_reached ("unhandled pointer size");
925 1.1 christos }
926 1.1 christos return ret;
927 1.1 christos }
928 1.1 christos
929 1.1 christos /* Construct qXfer:libraries-svr4:read reply. */
930 1.1 christos
931 1.1 christos template <typename T>
932 1.1 christos int
933 1.1.1.2 christos netbsd_qxfer_libraries_svr4 (const pid_t pid, const char *annex,
934 1.1 christos unsigned char *readbuf,
935 1.1 christos unsigned const char *writebuf,
936 1.1 christos CORE_ADDR offset, int len)
937 1.1 christos {
938 1.1 christos struct link_map_offsets
939 1.1 christos {
940 1.1 christos /* Offset and size of r_debug.r_version. */
941 1.1 christos int r_version_offset;
942 1.1 christos
943 1.1 christos /* Offset and size of r_debug.r_map. */
944 1.1 christos int r_map_offset;
945 1.1 christos
946 1.1 christos /* Offset to l_addr field in struct link_map. */
947 1.1 christos int l_addr_offset;
948 1.1 christos
949 1.1 christos /* Offset to l_name field in struct link_map. */
950 1.1 christos int l_name_offset;
951 1.1 christos
952 1.1 christos /* Offset to l_ld field in struct link_map. */
953 1.1 christos int l_ld_offset;
954 1.1 christos
955 1.1 christos /* Offset to l_next field in struct link_map. */
956 1.1 christos int l_next_offset;
957 1.1 christos
958 1.1 christos /* Offset to l_prev field in struct link_map. */
959 1.1 christos int l_prev_offset;
960 1.1 christos };
961 1.1 christos
962 1.1 christos static const struct link_map_offsets lmo_32bit_offsets =
963 1.1 christos {
964 1.1 christos 0, /* r_version offset. */
965 1.1 christos 4, /* r_debug.r_map offset. */
966 1.1 christos 0, /* l_addr offset in link_map. */
967 1.1 christos 4, /* l_name offset in link_map. */
968 1.1 christos 8, /* l_ld offset in link_map. */
969 1.1 christos 12, /* l_next offset in link_map. */
970 1.1 christos 16 /* l_prev offset in link_map. */
971 1.1 christos };
972 1.1 christos
973 1.1 christos static const struct link_map_offsets lmo_64bit_offsets =
974 1.1 christos {
975 1.1 christos 0, /* r_version offset. */
976 1.1 christos 8, /* r_debug.r_map offset. */
977 1.1 christos 0, /* l_addr offset in link_map. */
978 1.1 christos 8, /* l_name offset in link_map. */
979 1.1 christos 16, /* l_ld offset in link_map. */
980 1.1 christos 24, /* l_next offset in link_map. */
981 1.1 christos 32 /* l_prev offset in link_map. */
982 1.1 christos };
983 1.1 christos
984 1.1 christos CORE_ADDR lm_addr = 0, lm_prev = 0;
985 1.1 christos CORE_ADDR l_name, l_addr, l_ld, l_next, l_prev;
986 1.1 christos int header_done = 0;
987 1.1 christos
988 1.1 christos const struct link_map_offsets *lmo
989 1.1 christos = ((sizeof (T) == sizeof (int64_t))
990 1.1 christos ? &lmo_64bit_offsets : &lmo_32bit_offsets);
991 1.1 christos int ptr_size = sizeof (T);
992 1.1 christos
993 1.1 christos while (annex[0] != '\0')
994 1.1 christos {
995 1.1 christos const char *sep = strchr (annex, '=');
996 1.1 christos if (sep == nullptr)
997 1.1 christos break;
998 1.1 christos
999 1.1 christos int name_len = sep - annex;
1000 1.1 christos CORE_ADDR *addrp;
1001 1.1 christos if (name_len == 5 && startswith (annex, "start"))
1002 1.1 christos addrp = &lm_addr;
1003 1.1 christos else if (name_len == 4 && startswith (annex, "prev"))
1004 1.1 christos addrp = &lm_prev;
1005 1.1 christos else
1006 1.1 christos {
1007 1.1 christos annex = strchr (sep, ';');
1008 1.1 christos if (annex == nullptr)
1009 1.1 christos break;
1010 1.1 christos annex++;
1011 1.1 christos continue;
1012 1.1 christos }
1013 1.1 christos
1014 1.1 christos annex = decode_address_to_semicolon (addrp, sep + 1);
1015 1.1 christos }
1016 1.1 christos
1017 1.1 christos if (lm_addr == 0)
1018 1.1 christos {
1019 1.1.1.2 christos CORE_ADDR r_debug = get_r_debug<T> (pid);
1020 1.1 christos
1021 1.1 christos /* We failed to find DT_DEBUG. Such situation will not change
1022 1.1 christos for this inferior - do not retry it. Report it to GDB as
1023 1.1 christos E01, see for the reasons at the GDB solib-svr4.c side. */
1024 1.1 christos if (r_debug == (CORE_ADDR) -1)
1025 1.1 christos return -1;
1026 1.1 christos
1027 1.1 christos if (r_debug != 0)
1028 1.1 christos {
1029 1.1 christos CORE_ADDR map_offset = r_debug + lmo->r_map_offset;
1030 1.1.1.2 christos if (read_one_ptr (pid, map_offset, &lm_addr, ptr_size) != 0)
1031 1.1 christos warning ("unable to read r_map from %s",
1032 1.1 christos core_addr_to_string (map_offset));
1033 1.1 christos }
1034 1.1 christos }
1035 1.1 christos
1036 1.1 christos std::string document = "<library-list-svr4 version=\"1.0\"";
1037 1.1 christos
1038 1.1 christos while (lm_addr
1039 1.1.1.2 christos && read_one_ptr (pid, lm_addr + lmo->l_name_offset,
1040 1.1 christos &l_name, ptr_size) == 0
1041 1.1.1.2 christos && read_one_ptr (pid, lm_addr + lmo->l_addr_offset,
1042 1.1 christos &l_addr, ptr_size) == 0
1043 1.1.1.2 christos && read_one_ptr (pid, lm_addr + lmo->l_ld_offset,
1044 1.1 christos &l_ld, ptr_size) == 0
1045 1.1.1.2 christos && read_one_ptr (pid, lm_addr + lmo->l_prev_offset,
1046 1.1 christos &l_prev, ptr_size) == 0
1047 1.1.1.2 christos && read_one_ptr (pid, lm_addr + lmo->l_next_offset,
1048 1.1 christos &l_next, ptr_size) == 0)
1049 1.1 christos {
1050 1.1 christos if (lm_prev != l_prev)
1051 1.1 christos {
1052 1.1 christos warning ("Corrupted shared library list: 0x%lx != 0x%lx",
1053 1.1 christos (long) lm_prev, (long) l_prev);
1054 1.1 christos break;
1055 1.1 christos }
1056 1.1 christos
1057 1.1 christos /* Ignore the first entry even if it has valid name as the first entry
1058 1.1 christos corresponds to the main executable. The first entry should not be
1059 1.1 christos skipped if the dynamic loader was loaded late by a static executable
1060 1.1 christos (see solib-svr4.c parameter ignore_first). But in such case the main
1061 1.1 christos executable does not have PT_DYNAMIC present and this function already
1062 1.1 christos exited above due to failed get_r_debug. */
1063 1.1 christos if (lm_prev == 0)
1064 1.1 christos string_appendf (document, " main-lm=\"0x%lx\"",
1065 1.1 christos (unsigned long) lm_addr);
1066 1.1 christos else
1067 1.1 christos {
1068 1.1 christos unsigned char libname[PATH_MAX];
1069 1.1 christos
1070 1.1 christos /* Not checking for error because reading may stop before
1071 1.1 christos we've got PATH_MAX worth of characters. */
1072 1.1 christos libname[0] = '\0';
1073 1.1.1.2 christos netbsd_nat::read_memory (pid, libname, l_name, sizeof (libname) - 1,
1074 1.1.1.2 christos nullptr);
1075 1.1 christos libname[sizeof (libname) - 1] = '\0';
1076 1.1 christos if (libname[0] != '\0')
1077 1.1 christos {
1078 1.1 christos if (!header_done)
1079 1.1 christos {
1080 1.1 christos /* Terminate `<library-list-svr4'. */
1081 1.1 christos document += '>';
1082 1.1 christos header_done = 1;
1083 1.1 christos }
1084 1.1 christos
1085 1.1 christos string_appendf (document, "<library name=\"");
1086 1.1.1.2 christos xml_escape_text_append (document, (char *) libname);
1087 1.1 christos string_appendf (document, "\" lm=\"0x%lx\" "
1088 1.1 christos "l_addr=\"0x%lx\" l_ld=\"0x%lx\"/>",
1089 1.1 christos (unsigned long) lm_addr, (unsigned long) l_addr,
1090 1.1 christos (unsigned long) l_ld);
1091 1.1 christos }
1092 1.1 christos }
1093 1.1 christos
1094 1.1 christos lm_prev = lm_addr;
1095 1.1 christos lm_addr = l_next;
1096 1.1 christos }
1097 1.1 christos
1098 1.1 christos if (!header_done)
1099 1.1 christos {
1100 1.1 christos /* Empty list; terminate `<library-list-svr4'. */
1101 1.1 christos document += "/>";
1102 1.1 christos }
1103 1.1 christos else
1104 1.1 christos document += "</library-list-svr4>";
1105 1.1 christos
1106 1.1 christos int document_len = document.length ();
1107 1.1 christos if (offset < document_len)
1108 1.1 christos document_len -= offset;
1109 1.1 christos else
1110 1.1 christos document_len = 0;
1111 1.1 christos if (len > document_len)
1112 1.1 christos len = document_len;
1113 1.1 christos
1114 1.1 christos memcpy (readbuf, document.data () + offset, len);
1115 1.1 christos
1116 1.1 christos return len;
1117 1.1 christos }
1118 1.1 christos
1119 1.1 christos /* Return true if FILE is a 64-bit ELF file,
1120 1.1 christos false if the file is not a 64-bit ELF file,
1121 1.1 christos and error if the file is not accessible or doesn't exist. */
1122 1.1 christos
1123 1.1 christos static bool
1124 1.1 christos elf_64_file_p (const char *file)
1125 1.1 christos {
1126 1.1.1.2 christos int fd = gdb::handle_eintr (-1, ::open, file, O_RDONLY);
1127 1.1 christos if (fd < 0)
1128 1.1 christos perror_with_name (("open"));
1129 1.1 christos
1130 1.1 christos Elf64_Ehdr header;
1131 1.1.1.2 christos ssize_t ret = gdb::handle_eintr (-1, ::read, fd, &header, sizeof (header));
1132 1.1 christos if (ret == -1)
1133 1.1 christos perror_with_name (("read"));
1134 1.1.1.2 christos gdb::handle_eintr (-1, ::close, fd);
1135 1.1 christos if (ret != sizeof (header))
1136 1.1 christos error ("Cannot read ELF file header: %s", file);
1137 1.1 christos
1138 1.1 christos if (header.e_ident[EI_MAG0] != ELFMAG0
1139 1.1 christos || header.e_ident[EI_MAG1] != ELFMAG1
1140 1.1 christos || header.e_ident[EI_MAG2] != ELFMAG2
1141 1.1 christos || header.e_ident[EI_MAG3] != ELFMAG3)
1142 1.1 christos error ("Unrecognized ELF file header: %s", file);
1143 1.1 christos
1144 1.1 christos return header.e_ident[EI_CLASS] == ELFCLASS64;
1145 1.1 christos }
1146 1.1 christos
1147 1.1 christos /* Construct qXfer:libraries-svr4:read reply. */
1148 1.1 christos
1149 1.1 christos int
1150 1.1 christos netbsd_process_target::qxfer_libraries_svr4 (const char *annex,
1151 1.1 christos unsigned char *readbuf,
1152 1.1 christos unsigned const char *writebuf,
1153 1.1 christos CORE_ADDR offset, int len)
1154 1.1 christos {
1155 1.1 christos if (writebuf != nullptr)
1156 1.1 christos return -2;
1157 1.1 christos if (readbuf == nullptr)
1158 1.1 christos return -1;
1159 1.1 christos
1160 1.1 christos struct process_info *proc = current_process ();
1161 1.1 christos pid_t pid = proc->pid;
1162 1.1 christos bool is_elf64 = elf_64_file_p (netbsd_nat::pid_to_exec_file (pid));
1163 1.1 christos
1164 1.1 christos if (is_elf64)
1165 1.1.1.2 christos return netbsd_qxfer_libraries_svr4<int64_t> (pid, annex, readbuf,
1166 1.1 christos writebuf, offset, len);
1167 1.1 christos else
1168 1.1.1.2 christos return netbsd_qxfer_libraries_svr4<int32_t> (pid, annex, readbuf,
1169 1.1 christos writebuf, offset, len);
1170 1.1 christos }
1171 1.1 christos
1172 1.1 christos /* Implement the supports_qxfer_libraries_svr4 target_ops method. */
1173 1.1 christos
1174 1.1 christos bool
1175 1.1 christos netbsd_process_target::supports_qxfer_libraries_svr4 ()
1176 1.1 christos {
1177 1.1 christos return true;
1178 1.1 christos }
1179 1.1 christos
1180 1.1 christos /* Return the name of a file that can be opened to get the symbols for
1181 1.1 christos the child process identified by PID. */
1182 1.1 christos
1183 1.1.1.2 christos const char *
1184 1.1 christos netbsd_process_target::pid_to_exec_file (pid_t pid)
1185 1.1 christos {
1186 1.1.1.2 christos return netbsd_nat::pid_to_exec_file (pid);
1187 1.1 christos }
1188 1.1 christos
1189 1.1 christos /* Implementation of the target_ops method "supports_pid_to_exec_file". */
1190 1.1 christos
1191 1.1 christos bool
1192 1.1 christos netbsd_process_target::supports_pid_to_exec_file ()
1193 1.1 christos {
1194 1.1 christos return true;
1195 1.1 christos }
1196 1.1 christos
1197 1.1 christos /* Implementation of the target_ops method "supports_hardware_single_step". */
1198 1.1 christos bool
1199 1.1 christos netbsd_process_target::supports_hardware_single_step ()
1200 1.1 christos {
1201 1.1 christos return true;
1202 1.1 christos }
1203 1.1 christos
1204 1.1 christos /* Implementation of the target_ops method "sw_breakpoint_from_kind". */
1205 1.1 christos
1206 1.1 christos const gdb_byte *
1207 1.1 christos netbsd_process_target::sw_breakpoint_from_kind (int kind, int *size)
1208 1.1 christos {
1209 1.1 christos static gdb_byte brkpt[PTRACE_BREAKPOINT_SIZE] = {*PTRACE_BREAKPOINT};
1210 1.1 christos
1211 1.1 christos *size = PTRACE_BREAKPOINT_SIZE;
1212 1.1 christos
1213 1.1 christos return brkpt;
1214 1.1 christos }
1215 1.1 christos
1216 1.1 christos /* Implement the thread_name target_ops method. */
1217 1.1 christos
1218 1.1 christos const char *
1219 1.1 christos netbsd_process_target::thread_name (ptid_t ptid)
1220 1.1 christos {
1221 1.1 christos return netbsd_nat::thread_name (ptid);
1222 1.1 christos }
1223 1.1 christos
1224 1.1 christos /* Implement the supports_catch_syscall target_ops method. */
1225 1.1 christos
1226 1.1 christos bool
1227 1.1 christos netbsd_process_target::supports_catch_syscall ()
1228 1.1 christos {
1229 1.1 christos return true;
1230 1.1 christos }
1231 1.1 christos
1232 1.1 christos /* Implement the supports_read_auxv target_ops method. */
1233 1.1 christos
1234 1.1 christos bool
1235 1.1 christos netbsd_process_target::supports_read_auxv ()
1236 1.1 christos {
1237 1.1 christos return true;
1238 1.1 christos }
1239 1.1 christos
1240 1.1 christos void
1241 1.1 christos initialize_low ()
1242 1.1 christos {
1243 1.1.1.2 christos set_target_ops (the_netbsd_target);
1244 1.1 christos }
1245