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