]>
Commit | Line | Data |
---|---|---|
0274a8ce | 1 | /* Native debugging support for GNU/Linux (LWP layer). |
10d6c8cd | 2 | |
1d506c26 | 3 | Copyright (C) 2000-2024 Free Software Foundation, Inc. |
0274a8ce MS |
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 | |
a9762ec7 | 9 | the Free Software Foundation; either version 3 of the License, or |
0274a8ce MS |
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 | |
a9762ec7 | 18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
0274a8ce | 19 | |
1a5c2598 TT |
20 | #ifndef LINUX_NAT_H |
21 | #define LINUX_NAT_H | |
22 | ||
6d4ee8c6 | 23 | #include "nat/linux-nat.h" |
f6ac5f3d | 24 | #include "inf-ptrace.h" |
a2f23071 | 25 | #include "target.h" |
9f0bdab8 DJ |
26 | #include <signal.h> |
27 | ||
f6ac5f3d PA |
28 | /* A prototype generic GNU/Linux target. A concrete instance should |
29 | override it with local methods. */ | |
30 | ||
31 | class linux_nat_target : public inf_ptrace_target | |
32 | { | |
33 | public: | |
34 | linux_nat_target (); | |
35 | ~linux_nat_target () override = 0; | |
36 | ||
37 | thread_control_capabilities get_thread_control_capabilities () override | |
38 | { return tc_schedlock; } | |
39 | ||
40 | void create_inferior (const char *, const std::string &, | |
41 | char **, int) override; | |
42 | ||
43 | void attach (const char *, int) override; | |
44 | ||
45 | void detach (inferior *, int) override; | |
46 | ||
47 | void resume (ptid_t, int, enum gdb_signal) override; | |
48 | ||
b60cea74 | 49 | ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override; |
f6ac5f3d | 50 | |
adc6a863 | 51 | void pass_signals (gdb::array_view<const unsigned char>) override; |
f6ac5f3d PA |
52 | |
53 | enum target_xfer_status xfer_partial (enum target_object object, | |
54 | const char *annex, | |
55 | gdb_byte *readbuf, | |
56 | const gdb_byte *writebuf, | |
57 | ULONGEST offset, ULONGEST len, | |
58 | ULONGEST *xfered_len) override; | |
59 | ||
60 | void kill () override; | |
61 | ||
62 | void mourn_inferior () override; | |
57810aa7 | 63 | bool thread_alive (ptid_t ptid) override; |
f6ac5f3d PA |
64 | |
65 | void update_thread_list () override; | |
66 | ||
a068643d | 67 | std::string pid_to_str (ptid_t) override; |
f6ac5f3d PA |
68 | |
69 | const char *thread_name (struct thread_info *) override; | |
70 | ||
57810aa7 | 71 | bool stopped_by_watchpoint () override; |
f6ac5f3d | 72 | |
57810aa7 | 73 | bool stopped_data_address (CORE_ADDR *) override; |
f6ac5f3d | 74 | |
57810aa7 PA |
75 | bool stopped_by_sw_breakpoint () override; |
76 | bool supports_stopped_by_sw_breakpoint () override; | |
f6ac5f3d | 77 | |
57810aa7 PA |
78 | bool stopped_by_hw_breakpoint () override; |
79 | bool supports_stopped_by_hw_breakpoint () override; | |
f6ac5f3d PA |
80 | |
81 | void thread_events (int) override; | |
82 | ||
25b16bc9 PA |
83 | bool supports_set_thread_options (gdb_thread_options options) override; |
84 | ||
57810aa7 | 85 | bool can_async_p () override; |
f6ac5f3d | 86 | |
57810aa7 PA |
87 | bool supports_non_stop () override; |
88 | bool always_non_stop_p () override; | |
f6ac5f3d | 89 | |
4a570176 | 90 | void async (bool) override; |
f6ac5f3d | 91 | |
f6ac5f3d PA |
92 | void stop (ptid_t) override; |
93 | ||
57810aa7 | 94 | bool supports_multi_process () override; |
f6ac5f3d | 95 | |
57810aa7 | 96 | bool supports_disable_randomization () override; |
f6ac5f3d PA |
97 | |
98 | int core_of_thread (ptid_t ptid) override; | |
99 | ||
57810aa7 | 100 | bool filesystem_is_local () override; |
f6ac5f3d PA |
101 | |
102 | int fileio_open (struct inferior *inf, const char *filename, | |
103 | int flags, int mode, int warn_if_slow, | |
b872057a | 104 | fileio_error *target_errno) override; |
f6ac5f3d | 105 | |
6b09f134 | 106 | std::optional<std::string> |
f6ac5f3d PA |
107 | fileio_readlink (struct inferior *inf, |
108 | const char *filename, | |
b872057a | 109 | fileio_error *target_errno) override; |
f6ac5f3d PA |
110 | |
111 | int fileio_unlink (struct inferior *inf, | |
112 | const char *filename, | |
b872057a | 113 | fileio_error *target_errno) override; |
f6ac5f3d PA |
114 | |
115 | int insert_fork_catchpoint (int) override; | |
116 | int remove_fork_catchpoint (int) override; | |
117 | int insert_vfork_catchpoint (int) override; | |
118 | int remove_vfork_catchpoint (int) override; | |
119 | ||
120 | int insert_exec_catchpoint (int) override; | |
121 | int remove_exec_catchpoint (int) override; | |
122 | ||
123 | int set_syscall_catchpoint (int pid, bool needed, int any_count, | |
124 | gdb::array_view<const int> syscall_counts) override; | |
125 | ||
0e90c441 | 126 | const char *pid_to_exec_file (int pid) override; |
f6ac5f3d | 127 | |
f6ac5f3d PA |
128 | void post_attach (int) override; |
129 | ||
82d1f134 | 130 | void follow_fork (inferior *, ptid_t, target_waitkind, bool, bool) override; |
f6ac5f3d | 131 | |
0d36baa9 PA |
132 | void follow_clone (ptid_t) override; |
133 | ||
f6ac5f3d PA |
134 | std::vector<static_tracepoint_marker> |
135 | static_tracepoint_markers_by_strid (const char *id) override; | |
136 | ||
137 | /* Methods that are meant to overridden by the concrete | |
138 | arch-specific target instance. */ | |
139 | ||
140 | virtual void low_resume (ptid_t ptid, int step, enum gdb_signal sig) | |
141 | { inf_ptrace_target::resume (ptid, step, sig); } | |
142 | ||
57810aa7 PA |
143 | virtual bool low_stopped_by_watchpoint () |
144 | { return false; } | |
f6ac5f3d | 145 | |
57810aa7 PA |
146 | virtual bool low_stopped_data_address (CORE_ADDR *addr_p) |
147 | { return false; } | |
135340af PA |
148 | |
149 | /* The method to call, if any, when a new thread is attached. */ | |
150 | virtual void low_new_thread (struct lwp_info *) | |
151 | {} | |
152 | ||
153 | /* The method to call, if any, when a thread is destroyed. */ | |
154 | virtual void low_delete_thread (struct arch_lwp_info *lp) | |
155 | { | |
156 | gdb_assert (lp == NULL); | |
157 | } | |
158 | ||
159 | /* The method to call, if any, when a new fork is attached. */ | |
160 | virtual void low_new_fork (struct lwp_info *parent, pid_t child_pid) | |
161 | {} | |
162 | ||
1310c1b0 PFC |
163 | /* The method to call, if any, when a new clone event is detected. */ |
164 | virtual void low_new_clone (struct lwp_info *parent, pid_t child_lwp) | |
165 | {} | |
166 | ||
135340af PA |
167 | /* The method to call, if any, when a process is no longer |
168 | attached. */ | |
169 | virtual void low_forget_process (pid_t pid) | |
170 | {} | |
171 | ||
172 | /* Hook to call prior to resuming a thread. */ | |
173 | virtual void low_prepare_to_resume (struct lwp_info *) | |
174 | {} | |
175 | ||
176 | /* Convert a ptrace/host siginfo object, into/from the siginfo in | |
177 | the layout of the inferiors' architecture. Returns true if any | |
178 | conversion was done; false otherwise, in which case the caller | |
179 | does a straight memcpy. If DIRECTION is 1, then copy from INF to | |
180 | PTRACE. If DIRECTION is 0, copy from PTRACE to INF. */ | |
181 | virtual bool low_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf, | |
182 | int direction) | |
183 | { return false; } | |
184 | ||
185 | /* SIGTRAP-like breakpoint status events recognizer. The default | |
186 | recognizes SIGTRAP only. */ | |
187 | virtual bool low_status_is_event (int status); | |
200fd287 AB |
188 | |
189 | protected: | |
190 | ||
191 | void post_startup_inferior (ptid_t) override; | |
f6ac5f3d PA |
192 | }; |
193 | ||
194 | /* The final/concrete instance. */ | |
195 | extern linux_nat_target *linux_target; | |
196 | ||
7b50312a PA |
197 | struct arch_lwp_info; |
198 | ||
901b9821 | 199 | /* Structure describing an LWP. */ |
0274a8ce | 200 | |
901b9821 | 201 | struct lwp_info : intrusive_list_node<lwp_info> |
0274a8ce | 202 | { |
b0f6c8d2 SM |
203 | lwp_info (ptid_t ptid) |
204 | : ptid (ptid) | |
183be222 | 205 | {} |
b0f6c8d2 | 206 | |
676362df SM |
207 | ~lwp_info (); |
208 | ||
209 | DISABLE_COPY_AND_ASSIGN (lwp_info); | |
210 | ||
0274a8ce MS |
211 | /* The process id of the LWP. This is a combination of the LWP id |
212 | and overall process id. */ | |
183be222 | 213 | ptid_t ptid = null_ptid; |
0274a8ce | 214 | |
8784d563 PA |
215 | /* If this flag is set, we need to set the event request flags the |
216 | next time we see this LWP stop. */ | |
b0f6c8d2 | 217 | int must_set_ptrace_flags = 0; |
8784d563 | 218 | |
0274a8ce MS |
219 | /* Non-zero if we sent this LWP a SIGSTOP (but the LWP didn't report |
220 | it back yet). */ | |
b0f6c8d2 | 221 | int signalled = 0; |
0274a8ce MS |
222 | |
223 | /* Non-zero if this LWP is stopped. */ | |
b0f6c8d2 | 224 | int stopped = 0; |
0274a8ce MS |
225 | |
226 | /* Non-zero if this LWP will be/has been resumed. Note that an LWP | |
227 | can be marked both as stopped and resumed at the same time. This | |
228 | happens if we try to resume an LWP that has a wait status | |
229 | pending. We shouldn't let the LWP run until that wait status has | |
230 | been processed, but we should not report that wait status if GDB | |
231 | didn't try to let the LWP run. */ | |
b0f6c8d2 | 232 | int resumed = 0; |
0274a8ce | 233 | |
25289eb2 | 234 | /* The last resume GDB requested on this thread. */ |
b0f6c8d2 | 235 | resume_kind last_resume_kind = resume_continue; |
25289eb2 | 236 | |
57573e54 PA |
237 | /* If non-zero, a pending wait status. A pending process exit is |
238 | recorded in WAITSTATUS, because W_EXITCODE(0,0) happens to be | |
239 | 0. */ | |
b0f6c8d2 | 240 | int status = 0; |
0274a8ce | 241 | |
9c02b525 PA |
242 | /* When 'stopped' is set, this is where the lwp last stopped, with |
243 | decr_pc_after_break already accounted for. If the LWP is | |
7da6a5b9 | 244 | running and stepping, this is the address at which the lwp was |
9c02b525 PA |
245 | resumed (that is, it's the previous stop PC). If the LWP is |
246 | running and not stepping, this is 0. */ | |
b0f6c8d2 | 247 | CORE_ADDR stop_pc = 0; |
9c02b525 | 248 | |
0274a8ce | 249 | /* Non-zero if we were stepping this LWP. */ |
b0f6c8d2 | 250 | int step = 0; |
0274a8ce | 251 | |
9c02b525 | 252 | /* The reason the LWP last stopped, if we need to track it |
7da6a5b9 | 253 | (breakpoint, watchpoint, etc.). */ |
b0f6c8d2 | 254 | target_stop_reason stop_reason = TARGET_STOPPED_BY_NO_REASON; |
ebec9a0f PA |
255 | |
256 | /* On architectures where it is possible to know the data address of | |
257 | a triggered watchpoint, STOPPED_DATA_ADDRESS_P is non-zero, and | |
258 | STOPPED_DATA_ADDRESS contains such data address. Otherwise, | |
259 | STOPPED_DATA_ADDRESS_P is false, and STOPPED_DATA_ADDRESS is | |
260 | undefined. Only valid if STOPPED_BY_WATCHPOINT is true. */ | |
b0f6c8d2 SM |
261 | int stopped_data_address_p = 0; |
262 | CORE_ADDR stopped_data_address = 0; | |
ebec9a0f | 263 | |
57380f4e | 264 | /* Non-zero if we expect a duplicated SIGINT. */ |
b0f6c8d2 | 265 | int ignore_sigint = 0; |
57380f4e | 266 | |
57573e54 PA |
267 | /* If WAITSTATUS->KIND != TARGET_WAITKIND_IGNORE, the waitstatus for |
268 | this LWP's last event. This usually corresponds to STATUS above, | |
269 | however because W_EXITCODE(0,0) happens to be 0, a process exit | |
270 | will be recorded here, while 'status == 0' is ambiguous. */ | |
a2f23071 DJ |
271 | struct target_waitstatus waitstatus; |
272 | ||
82075af2 | 273 | /* Signal whether we are in a SYSCALL_ENTRY or |
a96d9b2e SDJ |
274 | in a SYSCALL_RETURN event. |
275 | Values: | |
276 | - TARGET_WAITKIND_SYSCALL_ENTRY | |
277 | - TARGET_WAITKIND_SYSCALL_RETURN */ | |
f486487f | 278 | enum target_waitkind syscall_state; |
a96d9b2e | 279 | |
dc146f7c | 280 | /* The processor core this LWP was last seen on. */ |
b0f6c8d2 | 281 | int core = -1; |
dc146f7c | 282 | |
7b50312a | 283 | /* Arch-specific additions. */ |
b0f6c8d2 | 284 | struct arch_lwp_info *arch_private = nullptr; |
0274a8ce MS |
285 | }; |
286 | ||
901b9821 SM |
287 | /* lwp_info iterator and range types. */ |
288 | ||
289 | using lwp_info_iterator | |
290 | = reference_to_pointer_iterator<intrusive_list<lwp_info>::iterator>; | |
291 | using lwp_info_range = iterator_range<lwp_info_iterator>; | |
292 | using lwp_info_safe_range = basic_safe_range<lwp_info_range>; | |
293 | ||
294 | /* Get an iterable range over all lwps. */ | |
295 | ||
296 | lwp_info_range all_lwps (); | |
297 | ||
298 | /* Same as the above, but safe against deletion while iterating. */ | |
299 | ||
300 | lwp_info_safe_range all_lwps_safe (); | |
9f0bdab8 | 301 | |
433bbbf8 | 302 | /* Does the current host support PTRACE_GETREGSET? */ |
0bdb2f78 | 303 | extern enum tribool have_ptrace_getregset; |
433bbbf8 | 304 | |
2db9a427 PA |
305 | /* Called from the LWP layer to inform the thread_db layer that PARENT |
306 | spawned CHILD. Both LWPs are currently stopped. This function | |
307 | does whatever is required to have the child LWP under the | |
308 | thread_db's control --- e.g., enabling event reporting. Returns | |
309 | true on success, false if the process isn't using libpthread. */ | |
310 | extern int thread_db_notice_clone (ptid_t parent, ptid_t child); | |
4c28f408 | 311 | |
089436f7 TV |
312 | /* Return the number of signals used by the threads library. */ |
313 | extern unsigned int lin_thread_get_thread_signal_num (void); | |
314 | ||
315 | /* Return the i-th signal used by the threads library. */ | |
316 | extern int lin_thread_get_thread_signal (unsigned int i); | |
669211f5 | 317 | |
bfb39158 | 318 | /* Find process PID's pending signal set from /proc/pid/status. */ |
3e43a32a MS |
319 | void linux_proc_pending_signals (int pid, sigset_t *pending, |
320 | sigset_t *blocked, sigset_t *ignored); | |
bfb39158 | 321 | |
b2f7c7e8 | 322 | /* For linux_stop_lwp see nat/linux-nat.h. */ |
7b50312a | 323 | |
2db9a427 PA |
324 | /* Stop all LWPs, synchronously. (Any events that trigger while LWPs |
325 | are being stopped are left pending.) */ | |
326 | extern void linux_stop_and_wait_all_lwps (void); | |
327 | ||
328 | /* Set resumed LWPs running again, as they were before being stopped | |
329 | with linux_stop_and_wait_all_lwps. (LWPS with pending events are | |
330 | left stopped.) */ | |
331 | extern void linux_unstop_all_lwps (void); | |
332 | ||
f973ed9c DJ |
333 | /* Update linux-nat internal state when changing from one fork |
334 | to another. */ | |
335 | void linux_nat_switch_fork (ptid_t new_ptid); | |
9f0bdab8 | 336 | |
f865ee35 | 337 | /* Store the saved siginfo associated with PTID in *SIGINFO. |
ef632b4b | 338 | Return true if it was retrieved successfully, false otherwise (*SIGINFO is |
f865ee35 | 339 | uninitialized in such case). */ |
ef632b4b | 340 | bool linux_nat_get_siginfo (ptid_t ptid, siginfo_t *siginfo); |
1a5c2598 TT |
341 | |
342 | #endif /* LINUX_NAT_H */ |