]>
Commit | Line | Data |
---|---|---|
863e4da4 MK |
1 | /* Native-dependent code for OpenBSD. |
2 | ||
1d506c26 | 3 | Copyright (C) 2012-2024 Free Software Foundation, Inc. |
863e4da4 MK |
4 | |
5 | This file is part of GDB. | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 3 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
19 | ||
20 | #include "defs.h" | |
21 | #include "gdbthread.h" | |
22 | #include "inferior.h" | |
23 | #include "target.h" | |
24 | ||
863e4da4 MK |
25 | #include <sys/types.h> |
26 | #include <sys/ptrace.h> | |
268a13a5 | 27 | #include "gdbsupport/gdb_wait.h" |
863e4da4 | 28 | |
3d3f92f2 | 29 | #include "inf-ptrace.h" |
863e4da4 MK |
30 | #include "obsd-nat.h" |
31 | ||
32 | /* OpenBSD 5.2 and later include rthreads which uses a thread model | |
ab4756af | 33 | that maps userland threads directly onto kernel threads in a 1:1 |
863e4da4 MK |
34 | fashion. */ |
35 | ||
89b085ac | 36 | std::string |
f6ac5f3d | 37 | obsd_nat_target::pid_to_str (ptid_t ptid) |
863e4da4 | 38 | { |
e38504b3 | 39 | if (ptid.lwp () != 0) |
527b21ea | 40 | return string_printf ("thread %ld of process %d", ptid.lwp (), ptid.pid ()); |
863e4da4 MK |
41 | |
42 | return normal_pid_to_str (ptid); | |
43 | } | |
44 | ||
f6ac5f3d PA |
45 | void |
46 | obsd_nat_target::update_thread_list () | |
863e4da4 | 47 | { |
e99b03dc | 48 | pid_t pid = inferior_ptid.pid (); |
863e4da4 MK |
49 | struct ptrace_thread_state pts; |
50 | ||
e8032dde PA |
51 | prune_threads (); |
52 | ||
ab4756af | 53 | if (ptrace (PT_GET_THREAD_FIRST, pid, (caddr_t)&pts, sizeof pts) == -1) |
863e4da4 MK |
54 | perror_with_name (("ptrace")); |
55 | ||
56 | while (pts.pts_tid != -1) | |
57 | { | |
fd79271b | 58 | ptid_t ptid = ptid_t (pid, pts.pts_tid, 0); |
863e4da4 | 59 | |
c7d64809 | 60 | if (!in_thread_list (this, ptid)) |
863e4da4 | 61 | { |
e38504b3 | 62 | if (inferior_ptid.lwp () == 0) |
c7d64809 | 63 | thread_change_ptid (this, inferior_ptid, ptid); |
863e4da4 | 64 | else |
c7d64809 | 65 | add_thread (this, ptid); |
863e4da4 MK |
66 | } |
67 | ||
ab4756af | 68 | if (ptrace (PT_GET_THREAD_NEXT, pid, (caddr_t)&pts, sizeof pts) == -1) |
863e4da4 MK |
69 | perror_with_name (("ptrace")); |
70 | } | |
71 | } | |
72 | ||
42acc964 JB |
73 | /* Enable additional event reporting on a new or existing process. */ |
74 | ||
75 | static void | |
76 | obsd_enable_proc_events (pid_t pid) | |
77 | { | |
78 | ptrace_event_t pe; | |
79 | ||
80 | /* Set the initial event mask. */ | |
81 | memset (&pe, 0, sizeof pe); | |
82 | pe.pe_set_event |= PTRACE_FORK; | |
83 | if (ptrace (PT_SET_EVENT_MASK, pid, | |
84 | (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1) | |
85 | perror_with_name (("ptrace")); | |
86 | } | |
87 | ||
f6ac5f3d PA |
88 | ptid_t |
89 | obsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, | |
b60cea74 | 90 | target_wait_flags options) |
863e4da4 | 91 | { |
3d3f92f2 | 92 | ptid_t wptid = inf_ptrace_target::wait (ptid, ourstatus, options); |
183be222 | 93 | if (ourstatus->kind () == TARGET_WAITKIND_STOPPED) |
863e4da4 MK |
94 | { |
95 | ptrace_state_t pe; | |
863e4da4 | 96 | |
3d3f92f2 | 97 | pid_t pid = wptid.pid (); |
863e4da4 MK |
98 | if (ptrace (PT_GET_PROCESS_STATE, pid, (caddr_t)&pe, sizeof pe) == -1) |
99 | perror_with_name (("ptrace")); | |
100 | ||
42acc964 JB |
101 | wptid = ptid_t (pid, pe.pe_tid, 0); |
102 | ||
863e4da4 MK |
103 | switch (pe.pe_report_event) |
104 | { | |
105 | case PTRACE_FORK: | |
183be222 | 106 | ourstatus->set_forked (ptid_t (pe.pe_other_pid)); |
863e4da4 MK |
107 | |
108 | /* Make sure the other end of the fork is stopped too. */ | |
3d3f92f2 | 109 | pid_t fpid = waitpid (pe.pe_other_pid, nullptr, 0); |
863e4da4 MK |
110 | if (fpid == -1) |
111 | perror_with_name (("waitpid")); | |
112 | ||
113 | if (ptrace (PT_GET_PROCESS_STATE, fpid, | |
114 | (caddr_t)&pe, sizeof pe) == -1) | |
115 | perror_with_name (("ptrace")); | |
116 | ||
117 | gdb_assert (pe.pe_report_event == PTRACE_FORK); | |
118 | gdb_assert (pe.pe_other_pid == pid); | |
3d3f92f2 | 119 | if (find_inferior_pid (this, fpid) != nullptr) |
863e4da4 | 120 | { |
183be222 | 121 | ourstatus->set_forked (ptid_t (pe.pe_other_pid)); |
42acc964 | 122 | wptid = ptid_t (fpid, pe.pe_tid, 0); |
863e4da4 MK |
123 | } |
124 | ||
183be222 | 125 | obsd_enable_proc_events (ourstatus->child_ptid ().pid ()); |
42acc964 | 126 | break; |
863e4da4 MK |
127 | } |
128 | ||
42acc964 | 129 | /* Ensure the ptid is updated with an LWP id on the first stop |
287de656 | 130 | of a process. */ |
3d3f92f2 | 131 | if (!in_thread_list (this, wptid)) |
863e4da4 | 132 | { |
3d3f92f2 JB |
133 | if (in_thread_list (this, ptid_t (pid))) |
134 | thread_change_ptid (this, ptid_t (pid), wptid); | |
863e4da4 | 135 | else |
3d3f92f2 | 136 | add_thread (this, wptid); |
863e4da4 MK |
137 | } |
138 | } | |
3d3f92f2 | 139 | return wptid; |
863e4da4 MK |
140 | } |
141 | ||
7632c6ce KR |
142 | void |
143 | obsd_nat_target::post_attach (int pid) | |
144 | { | |
42acc964 | 145 | obsd_enable_proc_events (pid); |
7632c6ce KR |
146 | } |
147 | ||
200fd287 AB |
148 | /* Implement the virtual inf_ptrace_target::post_startup_inferior method. */ |
149 | ||
7632c6ce KR |
150 | void |
151 | obsd_nat_target::post_startup_inferior (ptid_t pid) | |
152 | { | |
42acc964 | 153 | obsd_enable_proc_events (pid.pid ()); |
7632c6ce KR |
154 | } |
155 | ||
82d1f134 | 156 | /* Target hook for follow_fork. */ |
7632c6ce | 157 | |
e97007b6 | 158 | void |
82d1f134 SM |
159 | obsd_nat_target::follow_fork (inferior *child_inf, ptid_t child_ptid, |
160 | target_waitkind fork_kind, | |
3a849a34 | 161 | bool follow_child, bool detach_fork) |
7632c6ce | 162 | { |
82d1f134 SM |
163 | inf_ptrace_target::follow_fork (child_inf, child_ptid, fork_kind, |
164 | follow_child, detach_fork); | |
165 | ||
42acc964 | 166 | if (!follow_child && detach_fork) |
7632c6ce | 167 | { |
7632c6ce KR |
168 | /* Breakpoints have already been detached from the child by |
169 | infrun.c. */ | |
170 | ||
3a849a34 | 171 | if (ptrace (PT_DETACH, child_ptid.pid (), (PTRACE_TYPE_ARG3)1, 0) == -1) |
7632c6ce KR |
172 | perror_with_name (("ptrace")); |
173 | } | |
7632c6ce KR |
174 | } |
175 | ||
176 | int | |
177 | obsd_nat_target::insert_fork_catchpoint (int pid) | |
178 | { | |
179 | return 0; | |
180 | } | |
181 | ||
182 | int | |
183 | obsd_nat_target::remove_fork_catchpoint (int pid) | |
184 | { | |
185 | return 0; | |
186 | } |