ld x86_64 tests: Accept x86-64-v3 as a needed ISA
[binutils-gdb.git] / gdb / process-stratum-target.c
blob173c3ecad1345a3f4b94fcfea765c8daa2539b22
1 /* Abstract base class inherited by all process_stratum targets
3 Copyright (C) 2018-2023 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
20 #include "defs.h"
21 #include "process-stratum-target.h"
22 #include "inferior.h"
23 #include <algorithm>
25 process_stratum_target::~process_stratum_target ()
29 struct address_space *
30 process_stratum_target::thread_address_space (ptid_t ptid)
32 /* Fall-back to the "main" address space of the inferior. */
33 inferior *inf = find_inferior_ptid (this, ptid);
35 if (inf == NULL || inf->aspace == NULL)
36 internal_error (_("Can't determine the current "
37 "address space of thread %s\n"),
38 target_pid_to_str (ptid).c_str ());
40 return inf->aspace;
43 struct gdbarch *
44 process_stratum_target::thread_architecture (ptid_t ptid)
46 inferior *inf = find_inferior_ptid (this, ptid);
47 gdb_assert (inf != NULL);
48 return inf->arch ();
51 bool
52 process_stratum_target::has_all_memory ()
54 /* If no inferior selected, then we can't read memory here. */
55 return inferior_ptid != null_ptid;
58 bool
59 process_stratum_target::has_memory ()
61 /* If no inferior selected, then we can't read memory here. */
62 return inferior_ptid != null_ptid;
65 bool
66 process_stratum_target::has_stack ()
68 /* If no inferior selected, there's no stack. */
69 return inferior_ptid != null_ptid;
72 bool
73 process_stratum_target::has_registers ()
75 /* Can't read registers from no inferior. */
76 return inferior_ptid != null_ptid;
79 bool
80 process_stratum_target::has_execution (inferior *inf)
82 /* If there's a process running already, we can't make it run
83 through hoops. */
84 return inf->pid != 0;
87 /* See process-stratum-target.h. */
89 void
90 process_stratum_target::follow_exec (inferior *follow_inf, ptid_t ptid,
91 const char *execd_pathname)
93 inferior *orig_inf = current_inferior ();
95 if (orig_inf != follow_inf)
97 /* Execution continues in a new inferior, push the original inferior's
98 process target on the new inferior's target stack. The process target
99 may decide to unpush itself from the original inferior's target stack
100 after that, at its discretion. */
101 follow_inf->push_target (orig_inf->process_target ());
102 thread_info *t = add_thread (follow_inf->process_target (), ptid);
104 /* Leave the new inferior / thread as the current inferior / thread. */
105 switch_to_thread (t);
109 /* See process-stratum-target.h. */
111 void
112 process_stratum_target::follow_fork (inferior *child_inf, ptid_t child_ptid,
113 target_waitkind fork_kind,
114 bool follow_child,
115 bool detach_on_fork)
117 if (child_inf != nullptr)
119 child_inf->push_target (this);
120 add_thread_silent (this, child_ptid);
124 /* See process-stratum-target.h. */
126 void
127 process_stratum_target::maybe_add_resumed_with_pending_wait_status
128 (thread_info *thread)
130 gdb_assert (!thread->resumed_with_pending_wait_status_node.is_linked ());
132 if (thread->resumed () && thread->has_pending_waitstatus ())
134 infrun_debug_printf ("adding to resumed threads with event list: %s",
135 thread->ptid.to_string ().c_str ());
136 m_resumed_with_pending_wait_status.push_back (*thread);
140 /* See process-stratum-target.h. */
142 void
143 process_stratum_target::maybe_remove_resumed_with_pending_wait_status
144 (thread_info *thread)
146 if (thread->resumed () && thread->has_pending_waitstatus ())
148 infrun_debug_printf ("removing from resumed threads with event list: %s",
149 thread->ptid.to_string ().c_str ());
150 gdb_assert (thread->resumed_with_pending_wait_status_node.is_linked ());
151 auto it = m_resumed_with_pending_wait_status.iterator_to (*thread);
152 m_resumed_with_pending_wait_status.erase (it);
154 else
155 gdb_assert (!thread->resumed_with_pending_wait_status_node.is_linked ());
158 /* See process-stratum-target.h. */
160 thread_info *
161 process_stratum_target::random_resumed_with_pending_wait_status
162 (inferior *inf, ptid_t filter_ptid)
164 auto matches = [inf, filter_ptid] (const thread_info &thread)
166 return thread.inf == inf && thread.ptid.matches (filter_ptid);
169 /* First see how many matching events we have. */
170 const auto &l = m_resumed_with_pending_wait_status;
171 unsigned int count = std::count_if (l.begin (), l.end (), matches);
173 if (count == 0)
174 return nullptr;
176 /* Now randomly pick a thread out of those that match the criteria. */
177 int random_selector
178 = (int) ((count * (double) rand ()) / (RAND_MAX + 1.0));
180 if (count > 1)
181 infrun_debug_printf ("Found %u events, selecting #%d",
182 count, random_selector);
184 /* Select the Nth thread that matches. */
185 auto it = std::find_if (l.begin (), l.end (),
186 [&random_selector, &matches]
187 (const thread_info &thread)
189 if (!matches (thread))
190 return false;
192 return random_selector-- == 0;
195 gdb_assert (it != l.end ());
197 return &*it;
200 /* See process-stratum-target.h. */
202 thread_info *
203 process_stratum_target::find_thread (ptid_t ptid)
205 inferior *inf = find_inferior_ptid (this, ptid);
206 if (inf == NULL)
207 return NULL;
208 return inf->find_thread (ptid);
211 /* See process-stratum-target.h. */
213 std::set<process_stratum_target *>
214 all_non_exited_process_targets ()
216 /* Inferiors may share targets. To eliminate duplicates, use a set. */
217 std::set<process_stratum_target *> targets;
218 for (inferior *inf : all_non_exited_inferiors ())
219 targets.insert (inf->process_target ());
221 return targets;
224 /* See process-stratum-target.h. */
226 void
227 switch_to_target_no_thread (process_stratum_target *target)
229 for (inferior *inf : all_inferiors (target))
231 switch_to_inferior_no_thread (inf);
232 break;