1*bb15761eSchristos /* Copyright (C) 2020-2024 Free Software Foundation, Inc. 28dffb485Schristos 38dffb485Schristos This file is part of GDB. 48dffb485Schristos 58dffb485Schristos This program is free software; you can redistribute it and/or modify 68dffb485Schristos it under the terms of the GNU General Public License as published by 78dffb485Schristos the Free Software Foundation; either version 3 of the License, or 88dffb485Schristos (at your option) any later version. 98dffb485Schristos 108dffb485Schristos This program is distributed in the hope that it will be useful, 118dffb485Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 128dffb485Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 138dffb485Schristos GNU General Public License for more details. 148dffb485Schristos 158dffb485Schristos You should have received a copy of the GNU General Public License 168dffb485Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 178dffb485Schristos 188dffb485Schristos #include "target.h" 198dffb485Schristos #include "netbsd-low.h" 208dffb485Schristos #include "nat/netbsd-nat.h" 218dffb485Schristos 228dffb485Schristos #include <sys/param.h> 238dffb485Schristos #include <sys/types.h> 248dffb485Schristos 258dffb485Schristos #include <sys/ptrace.h> 268dffb485Schristos #include <sys/sysctl.h> 278dffb485Schristos 288dffb485Schristos #include <limits.h> 298dffb485Schristos #include <unistd.h> 308dffb485Schristos #include <signal.h> 318dffb485Schristos 328dffb485Schristos #include <elf.h> 338dffb485Schristos 348dffb485Schristos #include <type_traits> 358dffb485Schristos 368dffb485Schristos #include "gdbsupport/eintr.h" 378dffb485Schristos #include "gdbsupport/gdb_wait.h" 388dffb485Schristos #include "gdbsupport/filestuff.h" 398dffb485Schristos #include "gdbsupport/common-inferior.h" 408dffb485Schristos #include "nat/fork-inferior.h" 418dffb485Schristos #include "hostio.h" 428dffb485Schristos 438dffb485Schristos int using_threads = 1; 448dffb485Schristos 458dffb485Schristos /* Callback used by fork_inferior to start tracing the inferior. */ 468dffb485Schristos 478dffb485Schristos static void 488dffb485Schristos netbsd_ptrace_fun () 498dffb485Schristos { 508dffb485Schristos /* Switch child to its own process group so that signals won't 518dffb485Schristos directly affect GDBserver. */ 528dffb485Schristos if (setpgid (0, 0) < 0) 538dffb485Schristos trace_start_error_with_name (("setpgid")); 548dffb485Schristos 558dffb485Schristos if (ptrace (PT_TRACE_ME, 0, nullptr, 0) < 0) 568dffb485Schristos trace_start_error_with_name (("ptrace")); 578dffb485Schristos 588dffb485Schristos /* If GDBserver is connected to gdb via stdio, redirect the inferior's 598dffb485Schristos stdout to stderr so that inferior i/o doesn't corrupt the connection. 608dffb485Schristos Also, redirect stdin to /dev/null. */ 618dffb485Schristos if (remote_connection_is_stdio ()) 628dffb485Schristos { 638dffb485Schristos if (close (0) < 0) 648dffb485Schristos trace_start_error_with_name (("close")); 658dffb485Schristos if (open ("/dev/null", O_RDONLY) < 0) 668dffb485Schristos trace_start_error_with_name (("open")); 678dffb485Schristos if (dup2 (2, 1) < 0) 688dffb485Schristos trace_start_error_with_name (("dup2")); 698dffb485Schristos if (write (2, "stdin/stdout redirected\n", 708dffb485Schristos sizeof ("stdin/stdout redirected\n") - 1) < 0) 718dffb485Schristos { 728dffb485Schristos /* Errors ignored. */ 738dffb485Schristos } 748dffb485Schristos } 758dffb485Schristos } 768dffb485Schristos 778dffb485Schristos /* Implement the create_inferior method of the target_ops vector. */ 788dffb485Schristos 798dffb485Schristos int 808dffb485Schristos netbsd_process_target::create_inferior (const char *program, 818dffb485Schristos const std::vector<char *> &program_args) 828dffb485Schristos { 838dffb485Schristos std::string str_program_args = construct_inferior_arguments (program_args); 848dffb485Schristos 858dffb485Schristos pid_t pid = fork_inferior (program, str_program_args.c_str (), 868dffb485Schristos get_environ ()->envp (), netbsd_ptrace_fun, 878dffb485Schristos nullptr, nullptr, nullptr, nullptr); 888dffb485Schristos 894b169a6bSchristos add_process (pid, 0); 908dffb485Schristos 918dffb485Schristos post_fork_inferior (pid, program); 928dffb485Schristos 938dffb485Schristos return pid; 948dffb485Schristos } 958dffb485Schristos 968dffb485Schristos /* Implement the post_create_inferior target_ops method. */ 978dffb485Schristos 988dffb485Schristos void 998dffb485Schristos netbsd_process_target::post_create_inferior () 1008dffb485Schristos { 1018dffb485Schristos pid_t pid = current_process ()->pid; 1028dffb485Schristos netbsd_nat::enable_proc_events (pid); 1034b169a6bSchristos 1044b169a6bSchristos low_arch_setup (); 1058dffb485Schristos } 1068dffb485Schristos 1078dffb485Schristos /* Implement the attach target_ops method. */ 1088dffb485Schristos 1098dffb485Schristos int 1108dffb485Schristos netbsd_process_target::attach (unsigned long pid) 1118dffb485Schristos { 1128dffb485Schristos /* Unimplemented. */ 1138dffb485Schristos return -1; 1148dffb485Schristos } 1158dffb485Schristos 1168dffb485Schristos /* Returns true if GDB is interested in any child syscalls. */ 1178dffb485Schristos 1188dffb485Schristos static bool 1198dffb485Schristos gdb_catching_syscalls_p (pid_t pid) 1208dffb485Schristos { 1218dffb485Schristos struct process_info *proc = find_process_pid (pid); 1228dffb485Schristos return !proc->syscalls_to_catch.empty (); 1238dffb485Schristos } 1248dffb485Schristos 1258dffb485Schristos /* Implement the resume target_ops method. */ 1268dffb485Schristos 1278dffb485Schristos void 1288dffb485Schristos netbsd_process_target::resume (struct thread_resume *resume_info, size_t n) 1298dffb485Schristos { 1308dffb485Schristos ptid_t resume_ptid = resume_info[0].thread; 1318dffb485Schristos const int signal = resume_info[0].sig; 1328dffb485Schristos const bool step = resume_info[0].kind == resume_step; 1338dffb485Schristos 1348dffb485Schristos if (resume_ptid == minus_one_ptid) 1358dffb485Schristos resume_ptid = ptid_of (current_thread); 1368dffb485Schristos 1378dffb485Schristos const pid_t pid = resume_ptid.pid (); 1388dffb485Schristos const lwpid_t lwp = resume_ptid.lwp (); 1398dffb485Schristos regcache_invalidate_pid (pid); 1408dffb485Schristos 1418dffb485Schristos auto fn 1428dffb485Schristos = [&] (ptid_t ptid) 1438dffb485Schristos { 1448dffb485Schristos if (step) 1458dffb485Schristos { 1468dffb485Schristos if (ptid.lwp () == lwp || n != 1) 1478dffb485Schristos { 1488dffb485Schristos if (ptrace (PT_SETSTEP, pid, NULL, ptid.lwp ()) == -1) 1498dffb485Schristos perror_with_name (("ptrace")); 1508dffb485Schristos if (ptrace (PT_RESUME, pid, NULL, ptid.lwp ()) == -1) 1518dffb485Schristos perror_with_name (("ptrace")); 1528dffb485Schristos } 1538dffb485Schristos else 1548dffb485Schristos { 1558dffb485Schristos if (ptrace (PT_CLEARSTEP, pid, NULL, ptid.lwp ()) == -1) 1568dffb485Schristos perror_with_name (("ptrace")); 1578dffb485Schristos if (ptrace (PT_SUSPEND, pid, NULL, ptid.lwp ()) == -1) 1588dffb485Schristos perror_with_name (("ptrace")); 1598dffb485Schristos } 1608dffb485Schristos } 1618dffb485Schristos else 1628dffb485Schristos { 1638dffb485Schristos if (ptrace (PT_CLEARSTEP, pid, NULL, ptid.lwp ()) == -1) 1648dffb485Schristos perror_with_name (("ptrace")); 1658dffb485Schristos if (ptrace (PT_RESUME, pid, NULL, ptid.lwp ()) == -1) 1668dffb485Schristos perror_with_name (("ptrace")); 1678dffb485Schristos } 1688dffb485Schristos }; 1698dffb485Schristos 1708dffb485Schristos netbsd_nat::for_each_thread (pid, fn); 1718dffb485Schristos 1728dffb485Schristos int request = gdb_catching_syscalls_p (pid) ? PT_CONTINUE : PT_SYSCALL; 1738dffb485Schristos 1748dffb485Schristos errno = 0; 1758dffb485Schristos ptrace (request, pid, (void *)1, signal); 1768dffb485Schristos if (errno) 1778dffb485Schristos perror_with_name (("ptrace")); 1788dffb485Schristos } 1798dffb485Schristos 1808dffb485Schristos /* Returns true if GDB is interested in the reported SYSNO syscall. */ 1818dffb485Schristos 1828dffb485Schristos static bool 1838dffb485Schristos netbsd_catch_this_syscall (int sysno) 1848dffb485Schristos { 1858dffb485Schristos struct process_info *proc = current_process (); 1868dffb485Schristos 1878dffb485Schristos if (proc->syscalls_to_catch.empty ()) 1888dffb485Schristos return false; 1898dffb485Schristos 1908dffb485Schristos if (proc->syscalls_to_catch[0] == ANY_SYSCALL) 1918dffb485Schristos return true; 1928dffb485Schristos 1938dffb485Schristos for (int iter : proc->syscalls_to_catch) 1948dffb485Schristos if (iter == sysno) 1958dffb485Schristos return true; 1968dffb485Schristos 1978dffb485Schristos return false; 1988dffb485Schristos } 1998dffb485Schristos 2008dffb485Schristos /* Helper function for child_wait and the derivatives of child_wait. 2018dffb485Schristos HOSTSTATUS is the waitstatus from wait() or the equivalent; store our 2028dffb485Schristos translation of that in OURSTATUS. */ 2038dffb485Schristos 2048dffb485Schristos static void 2058dffb485Schristos netbsd_store_waitstatus (struct target_waitstatus *ourstatus, int hoststatus) 2068dffb485Schristos { 2078dffb485Schristos if (WIFEXITED (hoststatus)) 2084b169a6bSchristos ourstatus->set_exited (WEXITSTATUS (hoststatus)); 2098dffb485Schristos else if (!WIFSTOPPED (hoststatus)) 2104b169a6bSchristos ourstatus->set_signalled (gdb_signal_from_host (WTERMSIG (hoststatus))); 2118dffb485Schristos else 2124b169a6bSchristos ourstatus->set_stopped (gdb_signal_from_host (WSTOPSIG (hoststatus))); 2138dffb485Schristos } 2148dffb485Schristos 2158dffb485Schristos /* Implement a safe wrapper around waitpid(). */ 2168dffb485Schristos 2178dffb485Schristos static pid_t 2184b169a6bSchristos netbsd_waitpid (ptid_t ptid, struct target_waitstatus *ourstatus, 2194b169a6bSchristos target_wait_flags target_options) 2208dffb485Schristos { 2218dffb485Schristos int status; 2224b169a6bSchristos int options = (target_options & TARGET_WNOHANG) ? WNOHANG : 0; 2238dffb485Schristos 2248dffb485Schristos pid_t pid 2254b169a6bSchristos = gdb::handle_eintr (-1, ::waitpid, ptid.pid (), &status, options); 2268dffb485Schristos 2278dffb485Schristos if (pid == -1) 2288dffb485Schristos perror_with_name (_("Child process unexpectedly missing")); 2298dffb485Schristos 2308dffb485Schristos netbsd_store_waitstatus (ourstatus, status); 2318dffb485Schristos return pid; 2328dffb485Schristos } 2338dffb485Schristos 2348dffb485Schristos 2358dffb485Schristos /* Implement the wait target_ops method. 2368dffb485Schristos 2378dffb485Schristos Wait for the child specified by PTID to do something. Return the 2388dffb485Schristos process ID of the child, or MINUS_ONE_PTID in case of error; store 2398dffb485Schristos the status in *OURSTATUS. */ 2408dffb485Schristos 2418dffb485Schristos static ptid_t 2428dffb485Schristos netbsd_wait (ptid_t ptid, struct target_waitstatus *ourstatus, 2434b169a6bSchristos target_wait_flags target_options) 2448dffb485Schristos { 2458dffb485Schristos pid_t pid = netbsd_waitpid (ptid, ourstatus, target_options); 2468dffb485Schristos ptid_t wptid = ptid_t (pid); 2478dffb485Schristos 2488dffb485Schristos if (pid == 0) 2498dffb485Schristos { 2508dffb485Schristos gdb_assert (target_options & TARGET_WNOHANG); 2514b169a6bSchristos ourstatus->set_ignore (); 2528dffb485Schristos return null_ptid; 2538dffb485Schristos } 2548dffb485Schristos 2558dffb485Schristos gdb_assert (pid != -1); 2568dffb485Schristos 2578dffb485Schristos /* If the child stopped, keep investigating its status. */ 2584b169a6bSchristos if (ourstatus->kind () != TARGET_WAITKIND_STOPPED) 2598dffb485Schristos return wptid; 2608dffb485Schristos 2618dffb485Schristos /* Extract the event and thread that received a signal. */ 2628dffb485Schristos ptrace_siginfo_t psi; 2638dffb485Schristos if (ptrace (PT_GET_SIGINFO, pid, &psi, sizeof (psi)) == -1) 2648dffb485Schristos perror_with_name (("ptrace")); 2658dffb485Schristos 2668dffb485Schristos /* Pick child's siginfo_t. */ 2678dffb485Schristos siginfo_t *si = &psi.psi_siginfo; 2688dffb485Schristos 2698dffb485Schristos lwpid_t lwp = psi.psi_lwpid; 2708dffb485Schristos 2718dffb485Schristos int signo = si->si_signo; 2728dffb485Schristos const int code = si->si_code; 2738dffb485Schristos 2748dffb485Schristos /* Construct PTID with a specified thread that received the event. 2758dffb485Schristos If a signal was targeted to the whole process, lwp is 0. */ 2768dffb485Schristos wptid = ptid_t (pid, lwp, 0); 2778dffb485Schristos 2788dffb485Schristos /* Bail out on non-debugger oriented signals. */ 2798dffb485Schristos if (signo != SIGTRAP) 2808dffb485Schristos return wptid; 2818dffb485Schristos 2828dffb485Schristos /* Stop examining non-debugger oriented SIGTRAP codes. */ 2838dffb485Schristos if (code <= SI_USER || code == SI_NOINFO) 2848dffb485Schristos return wptid; 2858dffb485Schristos 2868dffb485Schristos /* Process state for threading events. */ 2878dffb485Schristos ptrace_state_t pst = {}; 2888dffb485Schristos if (code == TRAP_LWP) 2898dffb485Schristos if (ptrace (PT_GET_PROCESS_STATE, pid, &pst, sizeof (pst)) == -1) 2908dffb485Schristos perror_with_name (("ptrace")); 2918dffb485Schristos 2928dffb485Schristos if (code == TRAP_LWP && pst.pe_report_event == PTRACE_LWP_EXIT) 2938dffb485Schristos { 2948dffb485Schristos /* If GDB attaches to a multi-threaded process, exiting 2958dffb485Schristos threads might be skipped during post_attach that 2968dffb485Schristos have not yet reported their PTRACE_LWP_EXIT event. 2978dffb485Schristos Ignore exited events for an unknown LWP. */ 2988dffb485Schristos thread_info *thr = find_thread_ptid (wptid); 2998dffb485Schristos if (thr == nullptr) 3004b169a6bSchristos ourstatus->set_spurious (); 3018dffb485Schristos else 3028dffb485Schristos { 3038dffb485Schristos /* NetBSD does not store an LWP exit status. */ 3044b169a6bSchristos ourstatus->set_thread_exited (0); 3058dffb485Schristos 3068dffb485Schristos remove_thread (thr); 3078dffb485Schristos } 3088dffb485Schristos return wptid; 3098dffb485Schristos } 3108dffb485Schristos 3118dffb485Schristos if (find_thread_ptid (ptid_t (pid))) 3124b169a6bSchristos switch_to_thread (find_thread_ptid (wptid)); 3138dffb485Schristos 3148dffb485Schristos if (code == TRAP_LWP && pst.pe_report_event == PTRACE_LWP_CREATE) 3158dffb485Schristos { 3168dffb485Schristos /* If GDB attaches to a multi-threaded process, newborn 3178dffb485Schristos threads might be added by nbsd_add_threads that have 3188dffb485Schristos not yet reported their PTRACE_LWP_CREATE event. Ignore 3198dffb485Schristos born events for an already-known LWP. */ 3208dffb485Schristos if (find_thread_ptid (wptid)) 3214b169a6bSchristos ourstatus->set_spurious (); 3228dffb485Schristos else 3238dffb485Schristos { 3248dffb485Schristos add_thread (wptid, NULL); 3254b169a6bSchristos ourstatus->set_thread_created (); 3268dffb485Schristos } 3278dffb485Schristos return wptid; 3288dffb485Schristos } 3298dffb485Schristos 3308dffb485Schristos if (code == TRAP_EXEC) 3318dffb485Schristos { 3324b169a6bSchristos ourstatus->set_execd 3334b169a6bSchristos (make_unique_xstrdup (netbsd_nat::pid_to_exec_file (pid))); 3348dffb485Schristos return wptid; 3358dffb485Schristos } 3368dffb485Schristos 3378dffb485Schristos if (code == TRAP_TRACE) 3388dffb485Schristos return wptid; 3398dffb485Schristos 3408dffb485Schristos if (code == TRAP_SCE || code == TRAP_SCX) 3418dffb485Schristos { 3428dffb485Schristos int sysnum = si->si_sysnum; 3438dffb485Schristos 3448dffb485Schristos if (!netbsd_catch_this_syscall(sysnum)) 3458dffb485Schristos { 3468dffb485Schristos /* If the core isn't interested in this event, ignore it. */ 3474b169a6bSchristos ourstatus->set_spurious (); 3488dffb485Schristos return wptid; 3498dffb485Schristos } 3508dffb485Schristos 3514b169a6bSchristos if (code == TRAP_SCE) 3524b169a6bSchristos ourstatus->set_syscall_entry (sysnum); 3534b169a6bSchristos else 3544b169a6bSchristos ourstatus->set_syscall_return (sysnum); 3554b169a6bSchristos 3568dffb485Schristos return wptid; 3578dffb485Schristos } 3588dffb485Schristos 3598dffb485Schristos if (code == TRAP_BRKPT) 3608dffb485Schristos { 3618dffb485Schristos #ifdef PTRACE_BREAKPOINT_ADJ 3628dffb485Schristos CORE_ADDR pc; 3638dffb485Schristos struct reg r; 3648dffb485Schristos ptrace (PT_GETREGS, pid, &r, psi.psi_lwpid); 3658dffb485Schristos pc = PTRACE_REG_PC (&r); 3668dffb485Schristos PTRACE_REG_SET_PC (&r, pc - PTRACE_BREAKPOINT_ADJ); 3678dffb485Schristos ptrace (PT_SETREGS, pid, &r, psi.psi_lwpid); 3688dffb485Schristos #endif 3698dffb485Schristos return wptid; 3708dffb485Schristos } 3718dffb485Schristos 3728dffb485Schristos /* Unclassified SIGTRAP event. */ 3734b169a6bSchristos ourstatus->set_spurious (); 3748dffb485Schristos return wptid; 3758dffb485Schristos } 3768dffb485Schristos 3778dffb485Schristos /* Implement the wait target_ops method. */ 3788dffb485Schristos 3798dffb485Schristos ptid_t 3808dffb485Schristos netbsd_process_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, 3814b169a6bSchristos target_wait_flags target_options) 3828dffb485Schristos { 3838dffb485Schristos while (true) 3848dffb485Schristos { 3858dffb485Schristos ptid_t wptid = netbsd_wait (ptid, ourstatus, target_options); 3868dffb485Schristos 3878dffb485Schristos /* Register thread in the gdbcore if a thread was not reported earlier. 3888dffb485Schristos This is required after ::create_inferior, when the gdbcore does not 3898dffb485Schristos know about the first internal thread. 3908dffb485Schristos This may also happen on attach, when an event is registered on a thread 3918dffb485Schristos that was not fully initialized during the attach stage. */ 3928dffb485Schristos if (wptid.lwp () != 0 && !find_thread_ptid (wptid) 3934b169a6bSchristos && ourstatus->kind () != TARGET_WAITKIND_THREAD_EXITED) 3948dffb485Schristos add_thread (wptid, nullptr); 3958dffb485Schristos 3964b169a6bSchristos switch (ourstatus->kind ()) 3978dffb485Schristos { 3988dffb485Schristos case TARGET_WAITKIND_EXITED: 3998dffb485Schristos case TARGET_WAITKIND_STOPPED: 4008dffb485Schristos case TARGET_WAITKIND_SIGNALLED: 4018dffb485Schristos case TARGET_WAITKIND_FORKED: 4028dffb485Schristos case TARGET_WAITKIND_VFORKED: 4038dffb485Schristos case TARGET_WAITKIND_EXECD: 4048dffb485Schristos case TARGET_WAITKIND_VFORK_DONE: 4058dffb485Schristos case TARGET_WAITKIND_SYSCALL_ENTRY: 4068dffb485Schristos case TARGET_WAITKIND_SYSCALL_RETURN: 4078dffb485Schristos /* Pass the result to the generic code. */ 4088dffb485Schristos return wptid; 4098dffb485Schristos case TARGET_WAITKIND_THREAD_CREATED: 4108dffb485Schristos case TARGET_WAITKIND_THREAD_EXITED: 4118dffb485Schristos /* The core needlessly stops on these events. */ 412*bb15761eSchristos [[fallthrough]]; 4138dffb485Schristos case TARGET_WAITKIND_SPURIOUS: 4148dffb485Schristos /* Spurious events are unhandled by the gdbserver core. */ 4158dffb485Schristos if (ptrace (PT_CONTINUE, current_process ()->pid, (void *) 1, 0) 4168dffb485Schristos == -1) 4178dffb485Schristos perror_with_name (("ptrace")); 4188dffb485Schristos break; 4198dffb485Schristos default: 4208dffb485Schristos error (("Unknown stopped status")); 4218dffb485Schristos } 4228dffb485Schristos } 4238dffb485Schristos } 4248dffb485Schristos 4258dffb485Schristos /* Implement the kill target_ops method. */ 4268dffb485Schristos 4278dffb485Schristos int 4288dffb485Schristos netbsd_process_target::kill (process_info *process) 4298dffb485Schristos { 4308dffb485Schristos pid_t pid = process->pid; 4318dffb485Schristos if (ptrace (PT_KILL, pid, nullptr, 0) == -1) 4328dffb485Schristos return -1; 4338dffb485Schristos 4348dffb485Schristos int status; 4354b169a6bSchristos if (gdb::handle_eintr (-1, ::waitpid, pid, &status, 0) == -1) 4368dffb485Schristos return -1; 4378dffb485Schristos mourn (process); 4388dffb485Schristos return 0; 4398dffb485Schristos } 4408dffb485Schristos 4418dffb485Schristos /* Implement the detach target_ops method. */ 4428dffb485Schristos 4438dffb485Schristos int 4448dffb485Schristos netbsd_process_target::detach (process_info *process) 4458dffb485Schristos { 4468dffb485Schristos pid_t pid = process->pid; 4478dffb485Schristos 4488dffb485Schristos ptrace (PT_DETACH, pid, (void *) 1, 0); 4498dffb485Schristos mourn (process); 4508dffb485Schristos return 0; 4518dffb485Schristos } 4528dffb485Schristos 4538dffb485Schristos /* Implement the mourn target_ops method. */ 4548dffb485Schristos 4558dffb485Schristos void 4568dffb485Schristos netbsd_process_target::mourn (struct process_info *proc) 4578dffb485Schristos { 4588dffb485Schristos for_each_thread (proc->pid, remove_thread); 4598dffb485Schristos 4608dffb485Schristos remove_process (proc); 4618dffb485Schristos } 4628dffb485Schristos 4638dffb485Schristos /* Implement the join target_ops method. */ 4648dffb485Schristos 4658dffb485Schristos void 4668dffb485Schristos netbsd_process_target::join (int pid) 4678dffb485Schristos { 4688dffb485Schristos /* The PT_DETACH is sufficient to detach from the process. 4698dffb485Schristos So no need to do anything extra. */ 4708dffb485Schristos } 4718dffb485Schristos 4728dffb485Schristos /* Implement the thread_alive target_ops method. */ 4738dffb485Schristos 4748dffb485Schristos bool 4758dffb485Schristos netbsd_process_target::thread_alive (ptid_t ptid) 4768dffb485Schristos { 4778dffb485Schristos return netbsd_nat::thread_alive (ptid); 4788dffb485Schristos } 4798dffb485Schristos 4808dffb485Schristos /* Implement the fetch_registers target_ops method. */ 4818dffb485Schristos 4828dffb485Schristos void 4838dffb485Schristos netbsd_process_target::fetch_registers (struct regcache *regcache, int regno) 4848dffb485Schristos { 4854b169a6bSchristos const netbsd_regset_info *regset = get_regs_info (); 4868dffb485Schristos ptid_t inferior_ptid = ptid_of (current_thread); 4878dffb485Schristos 4888dffb485Schristos while (regset->size >= 0) 4898dffb485Schristos { 4908dffb485Schristos std::vector<char> buf; 4918dffb485Schristos buf.resize (regset->size); 4928dffb485Schristos int res = ptrace (regset->get_request, inferior_ptid.pid (), buf.data (), 4938dffb485Schristos inferior_ptid.lwp ()); 4948dffb485Schristos if (res == -1) 4958dffb485Schristos perror_with_name (("ptrace")); 4968dffb485Schristos regset->store_function (regcache, buf.data ()); 4978dffb485Schristos regset++; 4988dffb485Schristos } 4998dffb485Schristos } 5008dffb485Schristos 5018dffb485Schristos /* Implement the store_registers target_ops method. */ 5028dffb485Schristos 5038dffb485Schristos void 5048dffb485Schristos netbsd_process_target::store_registers (struct regcache *regcache, int regno) 5058dffb485Schristos { 5064b169a6bSchristos const netbsd_regset_info *regset = get_regs_info (); 5078dffb485Schristos ptid_t inferior_ptid = ptid_of (current_thread); 5088dffb485Schristos 5098dffb485Schristos while (regset->size >= 0) 5108dffb485Schristos { 5118dffb485Schristos std::vector<char> buf; 5128dffb485Schristos buf.resize (regset->size); 5138dffb485Schristos int res = ptrace (regset->get_request, inferior_ptid.pid (), buf.data (), 5148dffb485Schristos inferior_ptid.lwp ()); 5158dffb485Schristos if (res == -1) 5168dffb485Schristos perror_with_name (("ptrace")); 5178dffb485Schristos 5188dffb485Schristos /* Then overlay our cached registers on that. */ 5198dffb485Schristos regset->fill_function (regcache, buf.data ()); 5208dffb485Schristos /* Only now do we write the register set. */ 5218dffb485Schristos res = ptrace (regset->set_request, inferior_ptid.pid (), buf. data (), 5228dffb485Schristos inferior_ptid.lwp ()); 5238dffb485Schristos if (res == -1) 5248dffb485Schristos perror_with_name (("ptrace")); 5258dffb485Schristos regset++; 5268dffb485Schristos } 5278dffb485Schristos } 5288dffb485Schristos 5298dffb485Schristos /* Implement the read_memory target_ops method. */ 5308dffb485Schristos 5318dffb485Schristos int 5328dffb485Schristos netbsd_process_target::read_memory (CORE_ADDR memaddr, unsigned char *myaddr, 5338dffb485Schristos int size) 5348dffb485Schristos { 5358dffb485Schristos pid_t pid = current_process ()->pid; 5364b169a6bSchristos return netbsd_nat::read_memory (pid, myaddr, memaddr, size, nullptr); 5378dffb485Schristos } 5388dffb485Schristos 5398dffb485Schristos /* Implement the write_memory target_ops method. */ 5408dffb485Schristos 5418dffb485Schristos int 5428dffb485Schristos netbsd_process_target::write_memory (CORE_ADDR memaddr, 5438dffb485Schristos const unsigned char *myaddr, int size) 5448dffb485Schristos { 5458dffb485Schristos pid_t pid = current_process ()->pid; 5464b169a6bSchristos return netbsd_nat::write_memory (pid, myaddr, memaddr, size, nullptr); 5478dffb485Schristos } 5488dffb485Schristos 5498dffb485Schristos /* Implement the request_interrupt target_ops method. */ 5508dffb485Schristos 5518dffb485Schristos void 5528dffb485Schristos netbsd_process_target::request_interrupt () 5538dffb485Schristos { 5548dffb485Schristos ptid_t inferior_ptid = ptid_of (get_first_thread ()); 5558dffb485Schristos 5568dffb485Schristos ::kill (inferior_ptid.pid (), SIGINT); 5578dffb485Schristos } 5588dffb485Schristos 5598dffb485Schristos /* Read the AUX Vector for the specified PID, wrapping the ptrace(2) call 5608dffb485Schristos with the PIOD_READ_AUXV operation and using the PT_IO standard input 5618dffb485Schristos and output arguments. */ 5628dffb485Schristos 5638dffb485Schristos static size_t 5648dffb485Schristos netbsd_read_auxv(pid_t pid, void *offs, void *addr, size_t len) 5658dffb485Schristos { 5668dffb485Schristos struct ptrace_io_desc pio; 5678dffb485Schristos 5688dffb485Schristos pio.piod_op = PIOD_READ_AUXV; 5698dffb485Schristos pio.piod_offs = offs; 5708dffb485Schristos pio.piod_addr = addr; 5718dffb485Schristos pio.piod_len = len; 5728dffb485Schristos 5738dffb485Schristos if (ptrace (PT_IO, pid, &pio, 0) == -1) 5748dffb485Schristos perror_with_name (("ptrace")); 5758dffb485Schristos 5768dffb485Schristos return pio.piod_len; 5778dffb485Schristos } 5788dffb485Schristos 5798dffb485Schristos /* Copy LEN bytes from inferior's auxiliary vector starting at OFFSET 5808dffb485Schristos to debugger memory starting at MYADDR. */ 5818dffb485Schristos 5828dffb485Schristos int 583*bb15761eSchristos netbsd_process_target::read_auxv (int pid, CORE_ADDR offset, 5848dffb485Schristos unsigned char *myaddr, unsigned int len) 5858dffb485Schristos { 5868dffb485Schristos return netbsd_read_auxv (pid, (void *) (intptr_t) offset, myaddr, len); 5878dffb485Schristos } 5888dffb485Schristos 5898dffb485Schristos bool 5908dffb485Schristos netbsd_process_target::supports_z_point_type (char z_type) 5918dffb485Schristos { 5928dffb485Schristos switch (z_type) 5938dffb485Schristos { 5948dffb485Schristos case Z_PACKET_SW_BP: 5958dffb485Schristos return true; 5968dffb485Schristos case Z_PACKET_HW_BP: 5978dffb485Schristos case Z_PACKET_WRITE_WP: 5988dffb485Schristos case Z_PACKET_READ_WP: 5998dffb485Schristos case Z_PACKET_ACCESS_WP: 6008dffb485Schristos default: 6018dffb485Schristos return false; /* Not supported. */ 6028dffb485Schristos } 6038dffb485Schristos } 6048dffb485Schristos 6058dffb485Schristos /* Insert {break/watch}point at address ADDR. SIZE is not used. */ 6068dffb485Schristos 6078dffb485Schristos int 6088dffb485Schristos netbsd_process_target::insert_point (enum raw_bkpt_type type, CORE_ADDR addr, 6098dffb485Schristos int size, struct raw_breakpoint *bp) 6108dffb485Schristos { 6118dffb485Schristos switch (type) 6128dffb485Schristos { 6138dffb485Schristos case raw_bkpt_type_sw: 6148dffb485Schristos return insert_memory_breakpoint (bp); 6158dffb485Schristos case raw_bkpt_type_hw: 6168dffb485Schristos case raw_bkpt_type_write_wp: 6178dffb485Schristos case raw_bkpt_type_read_wp: 6188dffb485Schristos case raw_bkpt_type_access_wp: 6198dffb485Schristos default: 6208dffb485Schristos return 1; /* Not supported. */ 6218dffb485Schristos } 6228dffb485Schristos } 6238dffb485Schristos 6248dffb485Schristos /* Remove {break/watch}point at address ADDR. SIZE is not used. */ 6258dffb485Schristos 6268dffb485Schristos int 6278dffb485Schristos netbsd_process_target::remove_point (enum raw_bkpt_type type, CORE_ADDR addr, 6288dffb485Schristos int size, struct raw_breakpoint *bp) 6298dffb485Schristos { 6308dffb485Schristos switch (type) 6318dffb485Schristos { 6328dffb485Schristos case raw_bkpt_type_sw: 6338dffb485Schristos return remove_memory_breakpoint (bp); 6348dffb485Schristos case raw_bkpt_type_hw: 6358dffb485Schristos case raw_bkpt_type_write_wp: 6368dffb485Schristos case raw_bkpt_type_read_wp: 6378dffb485Schristos case raw_bkpt_type_access_wp: 6388dffb485Schristos default: 6398dffb485Schristos return 1; /* Not supported. */ 6408dffb485Schristos } 6418dffb485Schristos } 6428dffb485Schristos 6438dffb485Schristos /* Implement the stopped_by_sw_breakpoint target_ops method. */ 6448dffb485Schristos 6458dffb485Schristos bool 6468dffb485Schristos netbsd_process_target::stopped_by_sw_breakpoint () 6478dffb485Schristos { 6488dffb485Schristos ptrace_siginfo_t psi; 6498dffb485Schristos pid_t pid = current_process ()->pid; 6508dffb485Schristos 6518dffb485Schristos if (ptrace (PT_GET_SIGINFO, pid, &psi, sizeof (psi)) == -1) 6528dffb485Schristos perror_with_name (("ptrace")); 6538dffb485Schristos 6548dffb485Schristos return psi.psi_siginfo.si_signo == SIGTRAP && 6558dffb485Schristos psi.psi_siginfo.si_code == TRAP_BRKPT; 6568dffb485Schristos } 6578dffb485Schristos 6588dffb485Schristos /* Implement the supports_stopped_by_sw_breakpoint target_ops method. */ 6598dffb485Schristos 6608dffb485Schristos bool 6618dffb485Schristos netbsd_process_target::supports_stopped_by_sw_breakpoint () 6628dffb485Schristos { 6638dffb485Schristos return true; 6648dffb485Schristos } 6658dffb485Schristos 6668dffb485Schristos /* Implement the supports_qxfer_siginfo target_ops method. */ 6678dffb485Schristos 6688dffb485Schristos bool 6698dffb485Schristos netbsd_process_target::supports_qxfer_siginfo () 6708dffb485Schristos { 6718dffb485Schristos return true; 6728dffb485Schristos } 6738dffb485Schristos 6748dffb485Schristos /* Implement the qxfer_siginfo target_ops method. */ 6758dffb485Schristos 6768dffb485Schristos int 6778dffb485Schristos netbsd_process_target::qxfer_siginfo (const char *annex, unsigned char *readbuf, 6788dffb485Schristos unsigned const char *writebuf, 6798dffb485Schristos CORE_ADDR offset, int len) 6808dffb485Schristos { 6818dffb485Schristos if (current_thread == nullptr) 6828dffb485Schristos return -1; 6838dffb485Schristos 6848dffb485Schristos pid_t pid = current_process ()->pid; 6858dffb485Schristos 6868dffb485Schristos return netbsd_nat::qxfer_siginfo(pid, annex, readbuf, writebuf, offset, len); 6878dffb485Schristos } 6888dffb485Schristos 6898dffb485Schristos /* Implement the supports_non_stop target_ops method. */ 6908dffb485Schristos 6918dffb485Schristos bool 6928dffb485Schristos netbsd_process_target::supports_non_stop () 6938dffb485Schristos { 6948dffb485Schristos return false; 6958dffb485Schristos } 6968dffb485Schristos 6978dffb485Schristos /* Implement the supports_multi_process target_ops method. */ 6988dffb485Schristos 6998dffb485Schristos bool 7008dffb485Schristos netbsd_process_target::supports_multi_process () 7018dffb485Schristos { 7028dffb485Schristos return true; 7038dffb485Schristos } 7048dffb485Schristos 7058dffb485Schristos /* Check if fork events are supported. */ 7068dffb485Schristos 7078dffb485Schristos bool 7088dffb485Schristos netbsd_process_target::supports_fork_events () 7098dffb485Schristos { 7108dffb485Schristos return false; 7118dffb485Schristos } 7128dffb485Schristos 7138dffb485Schristos /* Check if vfork events are supported. */ 7148dffb485Schristos 7158dffb485Schristos bool 7168dffb485Schristos netbsd_process_target::supports_vfork_events () 7178dffb485Schristos { 7188dffb485Schristos return false; 7198dffb485Schristos } 7208dffb485Schristos 7218dffb485Schristos /* Check if exec events are supported. */ 7228dffb485Schristos 7238dffb485Schristos bool 7248dffb485Schristos netbsd_process_target::supports_exec_events () 7258dffb485Schristos { 7268dffb485Schristos return true; 7278dffb485Schristos } 7288dffb485Schristos 7298dffb485Schristos /* Implement the supports_disable_randomization target_ops method. */ 7308dffb485Schristos 7318dffb485Schristos bool 7328dffb485Schristos netbsd_process_target::supports_disable_randomization () 7338dffb485Schristos { 7348dffb485Schristos return false; 7358dffb485Schristos } 7368dffb485Schristos 7378dffb485Schristos /* Extract &phdr and num_phdr in the inferior. Return 0 on success. */ 7388dffb485Schristos 7398dffb485Schristos template <typename T> 7408dffb485Schristos int get_phdr_phnum_from_proc_auxv (const pid_t pid, 7418dffb485Schristos CORE_ADDR *phdr_memaddr, int *num_phdr) 7428dffb485Schristos { 7438dffb485Schristos typedef typename std::conditional<sizeof(T) == sizeof(int64_t), 7448dffb485Schristos Aux64Info, Aux32Info>::type auxv_type; 7458dffb485Schristos const size_t auxv_size = sizeof (auxv_type); 7468dffb485Schristos const size_t auxv_buf_size = 128 * sizeof (auxv_type); 7478dffb485Schristos 7488dffb485Schristos std::vector<char> auxv_buf; 7498dffb485Schristos auxv_buf.resize (auxv_buf_size); 7508dffb485Schristos 7518dffb485Schristos netbsd_read_auxv (pid, nullptr, auxv_buf.data (), auxv_buf_size); 7528dffb485Schristos 7538dffb485Schristos *phdr_memaddr = 0; 7548dffb485Schristos *num_phdr = 0; 7558dffb485Schristos 7568dffb485Schristos for (char *buf = auxv_buf.data (); 7578dffb485Schristos buf < (auxv_buf.data () + auxv_buf_size); 7588dffb485Schristos buf += auxv_size) 7598dffb485Schristos { 7608dffb485Schristos auxv_type *const aux = (auxv_type *) buf; 7618dffb485Schristos 7628dffb485Schristos switch (aux->a_type) 7638dffb485Schristos { 7648dffb485Schristos case AT_PHDR: 7658dffb485Schristos *phdr_memaddr = aux->a_v; 7668dffb485Schristos break; 7678dffb485Schristos case AT_PHNUM: 7688dffb485Schristos *num_phdr = aux->a_v; 7698dffb485Schristos break; 7708dffb485Schristos } 7718dffb485Schristos 7728dffb485Schristos if (*phdr_memaddr != 0 && *num_phdr != 0) 7738dffb485Schristos break; 7748dffb485Schristos } 7758dffb485Schristos 7768dffb485Schristos if (*phdr_memaddr == 0 || *num_phdr == 0) 7778dffb485Schristos { 7788dffb485Schristos warning ("Unexpected missing AT_PHDR and/or AT_PHNUM: " 7798dffb485Schristos "phdr_memaddr = %s, phdr_num = %d", 7808dffb485Schristos core_addr_to_string (*phdr_memaddr), *num_phdr); 7818dffb485Schristos return 2; 7828dffb485Schristos } 7838dffb485Schristos 7848dffb485Schristos return 0; 7858dffb485Schristos } 7868dffb485Schristos 7878dffb485Schristos /* Return &_DYNAMIC (via PT_DYNAMIC) in the inferior, or 0 if not present. */ 7888dffb485Schristos 7898dffb485Schristos template <typename T> 7908dffb485Schristos static CORE_ADDR 7914b169a6bSchristos get_dynamic (const pid_t pid) 7928dffb485Schristos { 7938dffb485Schristos typedef typename std::conditional<sizeof(T) == sizeof(int64_t), 7948dffb485Schristos Elf64_Phdr, Elf32_Phdr>::type phdr_type; 7958dffb485Schristos const int phdr_size = sizeof (phdr_type); 7968dffb485Schristos 7978dffb485Schristos CORE_ADDR phdr_memaddr; 7988dffb485Schristos int num_phdr; 7998dffb485Schristos if (get_phdr_phnum_from_proc_auxv<T> (pid, &phdr_memaddr, &num_phdr)) 8008dffb485Schristos return 0; 8018dffb485Schristos 8028dffb485Schristos std::vector<unsigned char> phdr_buf; 8038dffb485Schristos phdr_buf.resize (num_phdr * phdr_size); 8048dffb485Schristos 8054b169a6bSchristos if (netbsd_nat::read_memory (pid, phdr_buf.data (), phdr_memaddr, 8064b169a6bSchristos phdr_buf.size (), nullptr)) 8078dffb485Schristos return 0; 8088dffb485Schristos 8098dffb485Schristos /* Compute relocation: it is expected to be 0 for "regular" executables, 8108dffb485Schristos non-zero for PIE ones. */ 8118dffb485Schristos CORE_ADDR relocation = -1; 8128dffb485Schristos for (int i = 0; relocation == -1 && i < num_phdr; i++) 8138dffb485Schristos { 8148dffb485Schristos phdr_type *const p = (phdr_type *) (phdr_buf.data () + i * phdr_size); 8158dffb485Schristos 8168dffb485Schristos if (p->p_type == PT_PHDR) 8178dffb485Schristos relocation = phdr_memaddr - p->p_vaddr; 8188dffb485Schristos } 8198dffb485Schristos 8208dffb485Schristos if (relocation == -1) 8218dffb485Schristos { 8228dffb485Schristos /* PT_PHDR is optional, but necessary for PIE in general. Fortunately 8238dffb485Schristos any real world executables, including PIE executables, have always 8248dffb485Schristos PT_PHDR present. PT_PHDR is not present in some shared libraries or 8258dffb485Schristos in fpc (Free Pascal 2.4) binaries but neither of those have a need for 8268dffb485Schristos or present DT_DEBUG anyway (fpc binaries are statically linked). 8278dffb485Schristos 8288dffb485Schristos Therefore if there exists DT_DEBUG there is always also PT_PHDR. 8298dffb485Schristos 8308dffb485Schristos GDB could find RELOCATION also from AT_ENTRY - e_entry. */ 8318dffb485Schristos 8328dffb485Schristos return 0; 8338dffb485Schristos } 8348dffb485Schristos 8358dffb485Schristos for (int i = 0; i < num_phdr; i++) 8368dffb485Schristos { 8378dffb485Schristos phdr_type *const p = (phdr_type *) (phdr_buf.data () + i * phdr_size); 8388dffb485Schristos 8398dffb485Schristos if (p->p_type == PT_DYNAMIC) 8408dffb485Schristos return p->p_vaddr + relocation; 8418dffb485Schristos } 8428dffb485Schristos 8438dffb485Schristos return 0; 8448dffb485Schristos } 8458dffb485Schristos 8468dffb485Schristos /* Return &_r_debug in the inferior, or -1 if not present. Return value 8478dffb485Schristos can be 0 if the inferior does not yet have the library list initialized. 8488dffb485Schristos We look for DT_MIPS_RLD_MAP first. MIPS executables use this instead of 8498dffb485Schristos DT_DEBUG, although they sometimes contain an unused DT_DEBUG entry too. */ 8508dffb485Schristos 8518dffb485Schristos template <typename T> 8528dffb485Schristos static CORE_ADDR 8534b169a6bSchristos get_r_debug (const pid_t pid) 8548dffb485Schristos { 8558dffb485Schristos typedef typename std::conditional<sizeof(T) == sizeof(int64_t), 8568dffb485Schristos Elf64_Dyn, Elf32_Dyn>::type dyn_type; 8578dffb485Schristos const int dyn_size = sizeof (dyn_type); 8588dffb485Schristos unsigned char buf[sizeof (dyn_type)]; /* The larger of the two. */ 8598dffb485Schristos CORE_ADDR map = -1; 8608dffb485Schristos 8614b169a6bSchristos CORE_ADDR dynamic_memaddr = get_dynamic<T> (pid); 8628dffb485Schristos if (dynamic_memaddr == 0) 8638dffb485Schristos return map; 8648dffb485Schristos 8654b169a6bSchristos while (netbsd_nat::read_memory (pid, buf, dynamic_memaddr, dyn_size, nullptr) 8664b169a6bSchristos == 0) 8678dffb485Schristos { 8688dffb485Schristos dyn_type *const dyn = (dyn_type *) buf; 8698dffb485Schristos #if defined DT_MIPS_RLD_MAP 8708dffb485Schristos union 8718dffb485Schristos { 8728dffb485Schristos T map; 8738dffb485Schristos unsigned char buf[sizeof (T)]; 8748dffb485Schristos } 8758dffb485Schristos rld_map; 8768dffb485Schristos 8778dffb485Schristos if (dyn->d_tag == DT_MIPS_RLD_MAP) 8788dffb485Schristos { 8794b169a6bSchristos if (netbsd_nat::read_memory (pid, rld_map.buf, dyn->d_un.d_val, 8804b169a6bSchristos sizeof (rld_map.buf), nullptr) == 0) 8818dffb485Schristos return rld_map.map; 8828dffb485Schristos else 8838dffb485Schristos break; 8848dffb485Schristos } 8858dffb485Schristos #endif /* DT_MIPS_RLD_MAP */ 8868dffb485Schristos 8878dffb485Schristos if (dyn->d_tag == DT_DEBUG && map == -1) 8888dffb485Schristos map = dyn->d_un.d_val; 8898dffb485Schristos 8908dffb485Schristos if (dyn->d_tag == DT_NULL) 8918dffb485Schristos break; 8928dffb485Schristos 8938dffb485Schristos dynamic_memaddr += dyn_size; 8948dffb485Schristos } 8958dffb485Schristos 8968dffb485Schristos return map; 8978dffb485Schristos } 8988dffb485Schristos 8998dffb485Schristos /* Read one pointer from MEMADDR in the inferior. */ 9008dffb485Schristos 9018dffb485Schristos static int 9024b169a6bSchristos read_one_ptr (const pid_t pid, CORE_ADDR memaddr, CORE_ADDR *ptr, int ptr_size) 9038dffb485Schristos { 9048dffb485Schristos /* Go through a union so this works on either big or little endian 9058dffb485Schristos hosts, when the inferior's pointer size is smaller than the size 9068dffb485Schristos of CORE_ADDR. It is assumed the inferior's endianness is the 9078dffb485Schristos same of the superior's. */ 9088dffb485Schristos 9098dffb485Schristos union 9108dffb485Schristos { 9118dffb485Schristos CORE_ADDR core_addr; 9128dffb485Schristos unsigned int ui; 9138dffb485Schristos unsigned char uc; 9148dffb485Schristos } addr; 9158dffb485Schristos 9164b169a6bSchristos int ret = netbsd_nat::read_memory (pid, &addr.uc, memaddr, ptr_size, nullptr); 9178dffb485Schristos if (ret == 0) 9188dffb485Schristos { 9198dffb485Schristos if (ptr_size == sizeof (CORE_ADDR)) 9208dffb485Schristos *ptr = addr.core_addr; 9218dffb485Schristos else if (ptr_size == sizeof (unsigned int)) 9228dffb485Schristos *ptr = addr.ui; 9238dffb485Schristos else 9248dffb485Schristos gdb_assert_not_reached ("unhandled pointer size"); 9258dffb485Schristos } 9268dffb485Schristos return ret; 9278dffb485Schristos } 9288dffb485Schristos 9298dffb485Schristos /* Construct qXfer:libraries-svr4:read reply. */ 9308dffb485Schristos 9318dffb485Schristos template <typename T> 9328dffb485Schristos int 9334b169a6bSchristos netbsd_qxfer_libraries_svr4 (const pid_t pid, const char *annex, 9348dffb485Schristos unsigned char *readbuf, 9358dffb485Schristos unsigned const char *writebuf, 9368dffb485Schristos CORE_ADDR offset, int len) 9378dffb485Schristos { 9388dffb485Schristos struct link_map_offsets 9398dffb485Schristos { 9408dffb485Schristos /* Offset and size of r_debug.r_version. */ 9418dffb485Schristos int r_version_offset; 9428dffb485Schristos 9438dffb485Schristos /* Offset and size of r_debug.r_map. */ 9448dffb485Schristos int r_map_offset; 9458dffb485Schristos 9468dffb485Schristos /* Offset to l_addr field in struct link_map. */ 9478dffb485Schristos int l_addr_offset; 9488dffb485Schristos 9498dffb485Schristos /* Offset to l_name field in struct link_map. */ 9508dffb485Schristos int l_name_offset; 9518dffb485Schristos 9528dffb485Schristos /* Offset to l_ld field in struct link_map. */ 9538dffb485Schristos int l_ld_offset; 9548dffb485Schristos 9558dffb485Schristos /* Offset to l_next field in struct link_map. */ 9568dffb485Schristos int l_next_offset; 9578dffb485Schristos 9588dffb485Schristos /* Offset to l_prev field in struct link_map. */ 9598dffb485Schristos int l_prev_offset; 9608dffb485Schristos }; 9618dffb485Schristos 9628dffb485Schristos static const struct link_map_offsets lmo_32bit_offsets = 9638dffb485Schristos { 9648dffb485Schristos 0, /* r_version offset. */ 9658dffb485Schristos 4, /* r_debug.r_map offset. */ 9668dffb485Schristos 0, /* l_addr offset in link_map. */ 9678dffb485Schristos 4, /* l_name offset in link_map. */ 9688dffb485Schristos 8, /* l_ld offset in link_map. */ 9698dffb485Schristos 12, /* l_next offset in link_map. */ 9708dffb485Schristos 16 /* l_prev offset in link_map. */ 9718dffb485Schristos }; 9728dffb485Schristos 9738dffb485Schristos static const struct link_map_offsets lmo_64bit_offsets = 9748dffb485Schristos { 9758dffb485Schristos 0, /* r_version offset. */ 9768dffb485Schristos 8, /* r_debug.r_map offset. */ 9778dffb485Schristos 0, /* l_addr offset in link_map. */ 9788dffb485Schristos 8, /* l_name offset in link_map. */ 9798dffb485Schristos 16, /* l_ld offset in link_map. */ 9808dffb485Schristos 24, /* l_next offset in link_map. */ 9818dffb485Schristos 32 /* l_prev offset in link_map. */ 9828dffb485Schristos }; 9838dffb485Schristos 9848dffb485Schristos CORE_ADDR lm_addr = 0, lm_prev = 0; 9858dffb485Schristos CORE_ADDR l_name, l_addr, l_ld, l_next, l_prev; 9868dffb485Schristos int header_done = 0; 9878dffb485Schristos 9888dffb485Schristos const struct link_map_offsets *lmo 9898dffb485Schristos = ((sizeof (T) == sizeof (int64_t)) 9908dffb485Schristos ? &lmo_64bit_offsets : &lmo_32bit_offsets); 9918dffb485Schristos int ptr_size = sizeof (T); 9928dffb485Schristos 9938dffb485Schristos while (annex[0] != '\0') 9948dffb485Schristos { 9958dffb485Schristos const char *sep = strchr (annex, '='); 9968dffb485Schristos if (sep == nullptr) 9978dffb485Schristos break; 9988dffb485Schristos 9998dffb485Schristos int name_len = sep - annex; 10008dffb485Schristos CORE_ADDR *addrp; 10018dffb485Schristos if (name_len == 5 && startswith (annex, "start")) 10028dffb485Schristos addrp = &lm_addr; 10038dffb485Schristos else if (name_len == 4 && startswith (annex, "prev")) 10048dffb485Schristos addrp = &lm_prev; 10058dffb485Schristos else 10068dffb485Schristos { 10078dffb485Schristos annex = strchr (sep, ';'); 10088dffb485Schristos if (annex == nullptr) 10098dffb485Schristos break; 10108dffb485Schristos annex++; 10118dffb485Schristos continue; 10128dffb485Schristos } 10138dffb485Schristos 10148dffb485Schristos annex = decode_address_to_semicolon (addrp, sep + 1); 10158dffb485Schristos } 10168dffb485Schristos 10178dffb485Schristos if (lm_addr == 0) 10188dffb485Schristos { 10194b169a6bSchristos CORE_ADDR r_debug = get_r_debug<T> (pid); 10208dffb485Schristos 10218dffb485Schristos /* We failed to find DT_DEBUG. Such situation will not change 10228dffb485Schristos for this inferior - do not retry it. Report it to GDB as 10238dffb485Schristos E01, see for the reasons at the GDB solib-svr4.c side. */ 10248dffb485Schristos if (r_debug == (CORE_ADDR) -1) 10258dffb485Schristos return -1; 10268dffb485Schristos 10278dffb485Schristos if (r_debug != 0) 10288dffb485Schristos { 10298dffb485Schristos CORE_ADDR map_offset = r_debug + lmo->r_map_offset; 10304b169a6bSchristos if (read_one_ptr (pid, map_offset, &lm_addr, ptr_size) != 0) 10318dffb485Schristos warning ("unable to read r_map from %s", 10328dffb485Schristos core_addr_to_string (map_offset)); 10338dffb485Schristos } 10348dffb485Schristos } 10358dffb485Schristos 10368dffb485Schristos std::string document = "<library-list-svr4 version=\"1.0\""; 10378dffb485Schristos 10388dffb485Schristos while (lm_addr 10394b169a6bSchristos && read_one_ptr (pid, lm_addr + lmo->l_name_offset, 10408dffb485Schristos &l_name, ptr_size) == 0 10414b169a6bSchristos && read_one_ptr (pid, lm_addr + lmo->l_addr_offset, 10428dffb485Schristos &l_addr, ptr_size) == 0 10434b169a6bSchristos && read_one_ptr (pid, lm_addr + lmo->l_ld_offset, 10448dffb485Schristos &l_ld, ptr_size) == 0 10454b169a6bSchristos && read_one_ptr (pid, lm_addr + lmo->l_prev_offset, 10468dffb485Schristos &l_prev, ptr_size) == 0 10474b169a6bSchristos && read_one_ptr (pid, lm_addr + lmo->l_next_offset, 10488dffb485Schristos &l_next, ptr_size) == 0) 10498dffb485Schristos { 10508dffb485Schristos if (lm_prev != l_prev) 10518dffb485Schristos { 10528dffb485Schristos warning ("Corrupted shared library list: 0x%lx != 0x%lx", 10538dffb485Schristos (long) lm_prev, (long) l_prev); 10548dffb485Schristos break; 10558dffb485Schristos } 10568dffb485Schristos 10578dffb485Schristos /* Ignore the first entry even if it has valid name as the first entry 10588dffb485Schristos corresponds to the main executable. The first entry should not be 10598dffb485Schristos skipped if the dynamic loader was loaded late by a static executable 10608dffb485Schristos (see solib-svr4.c parameter ignore_first). But in such case the main 10618dffb485Schristos executable does not have PT_DYNAMIC present and this function already 10628dffb485Schristos exited above due to failed get_r_debug. */ 10638dffb485Schristos if (lm_prev == 0) 10648dffb485Schristos string_appendf (document, " main-lm=\"0x%lx\"", 10658dffb485Schristos (unsigned long) lm_addr); 10668dffb485Schristos else 10678dffb485Schristos { 10688dffb485Schristos unsigned char libname[PATH_MAX]; 10698dffb485Schristos 10708dffb485Schristos /* Not checking for error because reading may stop before 10718dffb485Schristos we've got PATH_MAX worth of characters. */ 10728dffb485Schristos libname[0] = '\0'; 10734b169a6bSchristos netbsd_nat::read_memory (pid, libname, l_name, sizeof (libname) - 1, 10744b169a6bSchristos nullptr); 10758dffb485Schristos libname[sizeof (libname) - 1] = '\0'; 10768dffb485Schristos if (libname[0] != '\0') 10778dffb485Schristos { 10788dffb485Schristos if (!header_done) 10798dffb485Schristos { 10808dffb485Schristos /* Terminate `<library-list-svr4'. */ 10818dffb485Schristos document += '>'; 10828dffb485Schristos header_done = 1; 10838dffb485Schristos } 10848dffb485Schristos 10858dffb485Schristos string_appendf (document, "<library name=\""); 10864b169a6bSchristos xml_escape_text_append (document, (char *) libname); 10878dffb485Schristos string_appendf (document, "\" lm=\"0x%lx\" " 10888dffb485Schristos "l_addr=\"0x%lx\" l_ld=\"0x%lx\"/>", 10898dffb485Schristos (unsigned long) lm_addr, (unsigned long) l_addr, 10908dffb485Schristos (unsigned long) l_ld); 10918dffb485Schristos } 10928dffb485Schristos } 10938dffb485Schristos 10948dffb485Schristos lm_prev = lm_addr; 10958dffb485Schristos lm_addr = l_next; 10968dffb485Schristos } 10978dffb485Schristos 10988dffb485Schristos if (!header_done) 10998dffb485Schristos { 11008dffb485Schristos /* Empty list; terminate `<library-list-svr4'. */ 11018dffb485Schristos document += "/>"; 11028dffb485Schristos } 11038dffb485Schristos else 11048dffb485Schristos document += "</library-list-svr4>"; 11058dffb485Schristos 11068dffb485Schristos int document_len = document.length (); 11078dffb485Schristos if (offset < document_len) 11088dffb485Schristos document_len -= offset; 11098dffb485Schristos else 11108dffb485Schristos document_len = 0; 11118dffb485Schristos if (len > document_len) 11128dffb485Schristos len = document_len; 11138dffb485Schristos 11148dffb485Schristos memcpy (readbuf, document.data () + offset, len); 11158dffb485Schristos 11168dffb485Schristos return len; 11178dffb485Schristos } 11188dffb485Schristos 11198dffb485Schristos /* Return true if FILE is a 64-bit ELF file, 11208dffb485Schristos false if the file is not a 64-bit ELF file, 11218dffb485Schristos and error if the file is not accessible or doesn't exist. */ 11228dffb485Schristos 11238dffb485Schristos static bool 11248dffb485Schristos elf_64_file_p (const char *file) 11258dffb485Schristos { 11264b169a6bSchristos int fd = gdb::handle_eintr (-1, ::open, file, O_RDONLY); 11278dffb485Schristos if (fd < 0) 11288dffb485Schristos perror_with_name (("open")); 11298dffb485Schristos 11308dffb485Schristos Elf64_Ehdr header; 11314b169a6bSchristos ssize_t ret = gdb::handle_eintr (-1, ::read, fd, &header, sizeof (header)); 11328dffb485Schristos if (ret == -1) 11338dffb485Schristos perror_with_name (("read")); 11344b169a6bSchristos gdb::handle_eintr (-1, ::close, fd); 11358dffb485Schristos if (ret != sizeof (header)) 11368dffb485Schristos error ("Cannot read ELF file header: %s", file); 11378dffb485Schristos 11388dffb485Schristos if (header.e_ident[EI_MAG0] != ELFMAG0 11398dffb485Schristos || header.e_ident[EI_MAG1] != ELFMAG1 11408dffb485Schristos || header.e_ident[EI_MAG2] != ELFMAG2 11418dffb485Schristos || header.e_ident[EI_MAG3] != ELFMAG3) 11428dffb485Schristos error ("Unrecognized ELF file header: %s", file); 11438dffb485Schristos 11448dffb485Schristos return header.e_ident[EI_CLASS] == ELFCLASS64; 11458dffb485Schristos } 11468dffb485Schristos 11478dffb485Schristos /* Construct qXfer:libraries-svr4:read reply. */ 11488dffb485Schristos 11498dffb485Schristos int 11508dffb485Schristos netbsd_process_target::qxfer_libraries_svr4 (const char *annex, 11518dffb485Schristos unsigned char *readbuf, 11528dffb485Schristos unsigned const char *writebuf, 11538dffb485Schristos CORE_ADDR offset, int len) 11548dffb485Schristos { 11558dffb485Schristos if (writebuf != nullptr) 11568dffb485Schristos return -2; 11578dffb485Schristos if (readbuf == nullptr) 11588dffb485Schristos return -1; 11598dffb485Schristos 11608dffb485Schristos struct process_info *proc = current_process (); 11618dffb485Schristos pid_t pid = proc->pid; 11628dffb485Schristos bool is_elf64 = elf_64_file_p (netbsd_nat::pid_to_exec_file (pid)); 11638dffb485Schristos 11648dffb485Schristos if (is_elf64) 11654b169a6bSchristos return netbsd_qxfer_libraries_svr4<int64_t> (pid, annex, readbuf, 11668dffb485Schristos writebuf, offset, len); 11678dffb485Schristos else 11684b169a6bSchristos return netbsd_qxfer_libraries_svr4<int32_t> (pid, annex, readbuf, 11698dffb485Schristos writebuf, offset, len); 11708dffb485Schristos } 11718dffb485Schristos 11728dffb485Schristos /* Implement the supports_qxfer_libraries_svr4 target_ops method. */ 11738dffb485Schristos 11748dffb485Schristos bool 11758dffb485Schristos netbsd_process_target::supports_qxfer_libraries_svr4 () 11768dffb485Schristos { 11778dffb485Schristos return true; 11788dffb485Schristos } 11798dffb485Schristos 11808dffb485Schristos /* Return the name of a file that can be opened to get the symbols for 11818dffb485Schristos the child process identified by PID. */ 11828dffb485Schristos 11834b169a6bSchristos const char * 11848dffb485Schristos netbsd_process_target::pid_to_exec_file (pid_t pid) 11858dffb485Schristos { 11864b169a6bSchristos return netbsd_nat::pid_to_exec_file (pid); 11878dffb485Schristos } 11888dffb485Schristos 11898dffb485Schristos /* Implementation of the target_ops method "supports_pid_to_exec_file". */ 11908dffb485Schristos 11918dffb485Schristos bool 11928dffb485Schristos netbsd_process_target::supports_pid_to_exec_file () 11938dffb485Schristos { 11948dffb485Schristos return true; 11958dffb485Schristos } 11968dffb485Schristos 11978dffb485Schristos /* Implementation of the target_ops method "supports_hardware_single_step". */ 11988dffb485Schristos bool 11998dffb485Schristos netbsd_process_target::supports_hardware_single_step () 12008dffb485Schristos { 12018dffb485Schristos return true; 12028dffb485Schristos } 12038dffb485Schristos 12048dffb485Schristos /* Implementation of the target_ops method "sw_breakpoint_from_kind". */ 12058dffb485Schristos 12068dffb485Schristos const gdb_byte * 12078dffb485Schristos netbsd_process_target::sw_breakpoint_from_kind (int kind, int *size) 12088dffb485Schristos { 12098dffb485Schristos static gdb_byte brkpt[PTRACE_BREAKPOINT_SIZE] = {*PTRACE_BREAKPOINT}; 12108dffb485Schristos 12118dffb485Schristos *size = PTRACE_BREAKPOINT_SIZE; 12128dffb485Schristos 12138dffb485Schristos return brkpt; 12148dffb485Schristos } 12158dffb485Schristos 12168dffb485Schristos /* Implement the thread_name target_ops method. */ 12178dffb485Schristos 12188dffb485Schristos const char * 12198dffb485Schristos netbsd_process_target::thread_name (ptid_t ptid) 12208dffb485Schristos { 12218dffb485Schristos return netbsd_nat::thread_name (ptid); 12228dffb485Schristos } 12238dffb485Schristos 12248dffb485Schristos /* Implement the supports_catch_syscall target_ops method. */ 12258dffb485Schristos 12268dffb485Schristos bool 12278dffb485Schristos netbsd_process_target::supports_catch_syscall () 12288dffb485Schristos { 12298dffb485Schristos return true; 12308dffb485Schristos } 12318dffb485Schristos 12328dffb485Schristos /* Implement the supports_read_auxv target_ops method. */ 12338dffb485Schristos 12348dffb485Schristos bool 12358dffb485Schristos netbsd_process_target::supports_read_auxv () 12368dffb485Schristos { 12378dffb485Schristos return true; 12388dffb485Schristos } 12398dffb485Schristos 12408dffb485Schristos void 12418dffb485Schristos initialize_low () 12428dffb485Schristos { 12434b169a6bSchristos set_target_ops (the_netbsd_target); 12448dffb485Schristos } 1245