gdbserver: Remove gdb_id_to_thread_id
[deliverable/binutils-gdb.git] / gdb / gdbserver / inferiors.c
CommitLineData
ce3a066d 1/* Inferior process information for the remote server for GDB.
61baf725 2 Copyright (C) 2002-2017 Free Software Foundation, Inc.
ce3a066d
DJ
3
4 Contributed by MontaVista Software.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
ce3a066d
DJ
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
ce3a066d 20
ce3a066d 21#include "server.h"
623b6bdf 22#include "gdbthread.h"
799cdc37 23#include "dll.h"
ce3a066d 24
95954743 25struct inferior_list all_processes;
0d62e5e8
DJ
26struct inferior_list all_threads;
27
0bfdf32f 28struct thread_info *current_thread;
0d62e5e8
DJ
29
30#define get_thread(inf) ((struct thread_info *)(inf))
31
32void
33add_inferior_to_list (struct inferior_list *list,
34 struct inferior_list_entry *new_inferior)
35{
36 new_inferior->next = NULL;
37 if (list->tail != NULL)
38 list->tail->next = new_inferior;
39 else
40 list->head = new_inferior;
41 list->tail = new_inferior;
42}
43
9f767825
DE
44/* Invoke ACTION for each inferior in LIST. */
45
0d62e5e8
DJ
46void
47for_each_inferior (struct inferior_list *list,
48 void (*action) (struct inferior_list_entry *))
49{
50 struct inferior_list_entry *cur = list->head, *next;
51
52 while (cur != NULL)
53 {
54 next = cur->next;
55 (*action) (cur);
56 cur = next;
57 }
58}
ce3a066d 59
649ebbca
DE
60/* Invoke ACTION for each inferior in LIST, passing DATA to ACTION. */
61
62void
63for_each_inferior_with_data (struct inferior_list *list,
64 void (*action) (struct inferior_list_entry *,
65 void *),
66 void *data)
67{
68 struct inferior_list_entry *cur = list->head, *next;
69
70 while (cur != NULL)
71 {
72 next = cur->next;
73 (*action) (cur, data);
74 cur = next;
75 }
76}
77
0d62e5e8
DJ
78void
79remove_inferior (struct inferior_list *list,
80 struct inferior_list_entry *entry)
81{
82 struct inferior_list_entry **cur;
ce3a066d 83
0d62e5e8
DJ
84 if (list->head == entry)
85 {
86 list->head = entry->next;
87 if (list->tail == entry)
88 list->tail = list->head;
89 return;
90 }
91
92 cur = &list->head;
93 while (*cur && (*cur)->next != entry)
94 cur = &(*cur)->next;
95
96 if (*cur == NULL)
97 return;
ce3a066d 98
0d62e5e8
DJ
99 (*cur)->next = entry->next;
100
101 if (list->tail == entry)
102 list->tail = *cur;
103}
104
f7667f0d 105struct thread_info *
95954743 106add_thread (ptid_t thread_id, void *target_data)
0d62e5e8 107{
8d749320 108 struct thread_info *new_thread = XCNEW (struct thread_info);
0d62e5e8
DJ
109
110 new_thread->entry.id = thread_id;
8336d594 111 new_thread->last_resume_kind = resume_continue;
fc7238bb 112 new_thread->last_status.kind = TARGET_WAITKIND_IGNORE;
0d62e5e8 113
ecc6f45c 114 add_inferior_to_list (&all_threads, &new_thread->entry);
255e7678 115
0bfdf32f
GB
116 if (current_thread == NULL)
117 current_thread = new_thread;
ce3a066d 118
0d62e5e8 119 new_thread->target_data = target_data;
f7667f0d
DE
120
121 return new_thread;
a06660f7
DJ
122}
123
95954743 124ptid_t
a06660f7
DJ
125thread_to_gdb_id (struct thread_info *thread)
126{
95954743 127 return thread->entry.id;
a06660f7
DJ
128}
129
649ebbca
DE
130/* Wrapper around get_first_inferior to return a struct thread_info *. */
131
dae5f5cf 132struct thread_info *
649ebbca 133get_first_thread (void)
a06660f7 134{
649ebbca
DE
135 return (struct thread_info *) get_first_inferior (&all_threads);
136}
a06660f7 137
649ebbca
DE
138struct thread_info *
139find_thread_ptid (ptid_t ptid)
140{
141 return (struct thread_info *) find_inferior_id (&all_threads, ptid);
dae5f5cf
DJ
142}
143
96e7a1eb
AR
144/* Find a thread associated with the given PROCESS, or NULL if no
145 such thread exists. */
146
147static struct thread_info *
148find_thread_process (const struct process_info *const process)
149{
785922a5 150 return find_any_thread_of_pid (process->entry.id.pid ());
96e7a1eb
AR
151}
152
34c65914
PA
153/* Helper for find_any_thread_of_pid. Returns true if a thread
154 matches a PID. */
155
156static int
157thread_of_pid (struct inferior_list_entry *entry, void *pid_p)
158{
159 int pid = *(int *) pid_p;
160
161 return (ptid_get_pid (entry->id) == pid);
162}
163
164/* See gdbthread.h. */
165
166struct thread_info *
167find_any_thread_of_pid (int pid)
168{
169 struct inferior_list_entry *entry;
170
171 entry = find_inferior (&all_threads, thread_of_pid, &pid);
172
173 return (struct thread_info *) entry;
174}
175
0d62e5e8
DJ
176static void
177free_one_thread (struct inferior_list_entry *inf)
178{
179 struct thread_info *thread = get_thread (inf);
6afd337d 180 free_register_cache (thread_regcache_data (thread));
0d62e5e8
DJ
181 free (thread);
182}
183
184void
185remove_thread (struct thread_info *thread)
186{
9accd112
MM
187 if (thread->btrace != NULL)
188 target_disable_btrace (thread->btrace);
189
465a859e 190 discard_queued_stop_replies (ptid_of (thread));
0d62e5e8
DJ
191 remove_inferior (&all_threads, (struct inferior_list_entry *) thread);
192 free_one_thread (&thread->entry);
96e7a1eb
AR
193 if (current_thread == thread)
194 current_thread = NULL;
ce3a066d
DJ
195}
196
649ebbca
DE
197/* Return a pointer to the first inferior in LIST, or NULL if there isn't one.
198 This is for cases where the caller needs a thread, but doesn't care
199 which one. */
200
201struct inferior_list_entry *
202get_first_inferior (struct inferior_list *list)
203{
3b8361aa
DE
204 if (list->head != NULL)
205 return list->head;
649ebbca
DE
206 return NULL;
207}
208
0718675c
JB
209/* Find the first inferior_list_entry E in LIST for which FUNC (E, ARG)
210 returns non-zero. If no entry is found then return NULL. */
211
0d62e5e8
DJ
212struct inferior_list_entry *
213find_inferior (struct inferior_list *list,
214 int (*func) (struct inferior_list_entry *, void *), void *arg)
215{
216 struct inferior_list_entry *inf = list->head;
ce3a066d 217
0d62e5e8 218 while (inf != NULL)
ce3a066d 219 {
a07b2135
PA
220 struct inferior_list_entry *next;
221
222 next = inf->next;
0d62e5e8
DJ
223 if ((*func) (inf, arg))
224 return inf;
a07b2135 225 inf = next;
0d62e5e8 226 }
611cb4a5 227
0d62e5e8
DJ
228 return NULL;
229}
611cb4a5 230
89342618
YQ
231/* Find the random inferior_list_entry E in LIST for which FUNC (E, ARG)
232 returns non-zero. If no entry is found then return NULL. */
233
234struct inferior_list_entry *
235find_inferior_in_random (struct inferior_list *list,
236 int (*func) (struct inferior_list_entry *, void *),
237 void *arg)
238{
239 struct inferior_list_entry *inf = list->head;
240 int count = 0;
241 int random_selector;
242
243 /* First count how many interesting entries we have. */
244 while (inf != NULL)
245 {
246 struct inferior_list_entry *next;
247
248 next = inf->next;
249 if ((*func) (inf, arg))
250 count++;
251 inf = next;
252 }
253
254 if (count == 0)
255 return NULL;
256
257 /* Now randomly pick an entry out of those. */
258 random_selector = (int)
259 ((count * (double) rand ()) / (RAND_MAX + 1.0));
260
261 inf = list->head;
262 while (inf != NULL)
263 {
264 struct inferior_list_entry *next;
265
266 next = inf->next;
267 if ((*func) (inf, arg) && (random_selector-- == 0))
268 return inf;
269 inf = next;
270 }
271
272 gdb_assert_not_reached ("failed to find an inferior in random.");
273 return NULL;
274}
275
0d62e5e8 276struct inferior_list_entry *
95954743 277find_inferior_id (struct inferior_list *list, ptid_t id)
0d62e5e8
DJ
278{
279 struct inferior_list_entry *inf = list->head;
280
281 while (inf != NULL)
282 {
95954743 283 if (ptid_equal (inf->id, id))
0d62e5e8
DJ
284 return inf;
285 inf = inf->next;
ce3a066d
DJ
286 }
287
0d62e5e8 288 return NULL;
ce3a066d 289}
611cb4a5
DJ
290
291void *
6afd337d 292thread_target_data (struct thread_info *thread)
611cb4a5 293{
6afd337d 294 return thread->target_data;
611cb4a5
DJ
295}
296
a44892be 297struct regcache *
6afd337d 298thread_regcache_data (struct thread_info *thread)
c04a1aa8 299{
6afd337d 300 return thread->regcache_data;
c04a1aa8
DJ
301}
302
303void
6afd337d 304set_thread_regcache_data (struct thread_info *thread, struct regcache *data)
c04a1aa8 305{
6afd337d 306 thread->regcache_data = data;
c04a1aa8 307}
255e7678 308
649ebbca
DE
309/* Return true if LIST has exactly one entry. */
310
311int
312one_inferior_p (struct inferior_list *list)
313{
314 return list->head != NULL && list->head == list->tail;
315}
316
317/* Reset head,tail of LIST, assuming all entries have already been freed. */
318
319void
320clear_inferior_list (struct inferior_list *list)
321{
322 list->head = NULL;
323 list->tail = NULL;
324}
255e7678
DJ
325
326void
327clear_inferiors (void)
328{
329 for_each_inferior (&all_threads, free_one_thread);
649ebbca 330 clear_inferior_list (&all_threads);
bf4c19f7
YQ
331
332 clear_dlls ();
7284e1be 333
0bfdf32f 334 current_thread = NULL;
255e7678 335}
24a09b5f 336
95954743
PA
337struct process_info *
338add_process (int pid, int attached)
339{
8d749320 340 struct process_info *process = XCNEW (struct process_info);
95954743 341
80894984 342 process->entry.id = pid_to_ptid (pid);
95954743
PA
343 process->attached = attached;
344
80894984 345 add_inferior_to_list (&all_processes, &process->entry);
95954743
PA
346
347 return process;
348}
349
5091eb23
DE
350/* Remove a process from the common process list and free the memory
351 allocated for it.
352 The caller is responsible for freeing private data first. */
353
95954743
PA
354void
355remove_process (struct process_info *process)
356{
357 clear_symbol_cache (&process->symbol_cache);
358 free_all_breakpoints (process);
96e7a1eb 359 gdb_assert (find_thread_process (process) == NULL);
80894984 360 remove_inferior (&all_processes, &process->entry);
82075af2 361 VEC_free (int, process->syscalls_to_catch);
5091eb23 362 free (process);
95954743
PA
363}
364
365struct process_info *
366find_process_pid (int pid)
367{
368 return (struct process_info *)
369 find_inferior_id (&all_processes, pid_to_ptid (pid));
370}
371
3d40fbb5
PA
372/* Wrapper around get_first_inferior to return a struct process_info *. */
373
374struct process_info *
375get_first_process (void)
376{
377 return (struct process_info *) get_first_inferior (&all_processes);
378}
379
9f767825
DE
380/* Return non-zero if INF, a struct process_info, was started by us,
381 i.e. not attached to. */
382
383static int
384started_inferior_callback (struct inferior_list_entry *entry, void *args)
385{
386 struct process_info *process = (struct process_info *) entry;
387
388 return ! process->attached;
389}
390
391/* Return non-zero if there are any inferiors that we have created
392 (as opposed to attached-to). */
393
394int
395have_started_inferiors_p (void)
396{
397 return (find_inferior (&all_processes, started_inferior_callback, NULL)
398 != NULL);
399}
400
401/* Return non-zero if INF, a struct process_info, was attached to. */
402
403static int
404attached_inferior_callback (struct inferior_list_entry *entry, void *args)
405{
406 struct process_info *process = (struct process_info *) entry;
407
408 return process->attached;
409}
410
411/* Return non-zero if there are any inferiors that we have attached to. */
412
413int
414have_attached_inferiors_p (void)
415{
416 return (find_inferior (&all_processes, attached_inferior_callback, NULL)
417 != NULL);
418}
419
7fe519cb 420struct process_info *
63c40ec7 421get_thread_process (const struct thread_info *thread)
95954743
PA
422{
423 int pid = ptid_get_pid (thread->entry.id);
424 return find_process_pid (pid);
425}
426
427struct process_info *
428current_process (void)
429{
0bfdf32f
GB
430 gdb_assert (current_thread != NULL);
431 return get_thread_process (current_thread);
95954743 432}
984a2c04
YQ
433
434static void
435do_restore_current_thread_cleanup (void *arg)
436{
437 current_thread = (struct thread_info *) arg;
438}
439
440struct cleanup *
441make_cleanup_restore_current_thread (void)
442{
443 return make_cleanup (do_restore_current_thread_cleanup, current_thread);
444}
043a4934
SDJ
445
446/* See common/common-gdbthread.h. */
447
448void
449switch_to_thread (ptid_t ptid)
450{
451 if (!ptid_equal (ptid, minus_one_ptid))
452 current_thread = find_thread_ptid (ptid);
453}
This page took 1.248154 seconds and 4 git commands to generate.