Use ui_file_as_string in gdbarch.sh/gdbarch.c
[deliverable/binutils-gdb.git] / gdb / gdbserver / inferiors.c
CommitLineData
ce3a066d 1/* Inferior process information for the remote server for GDB.
618f726f 2 Copyright (C) 2002-2016 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/* Predicate function for matching thread entry's pid to the given
145 pid value passed by address in ARGS. */
146
147static int
148thread_pid_matches_callback (struct inferior_list_entry *entry, void *args)
149{
150 return (ptid_get_pid (entry->id) == *(pid_t *)args);
151}
152
153/* Find a thread associated with the given PROCESS, or NULL if no
154 such thread exists. */
155
156static struct thread_info *
157find_thread_process (const struct process_info *const process)
158{
159 pid_t pid = ptid_get_pid (ptid_of (process));
160
161 return (struct thread_info *)
162 find_inferior (&all_threads, thread_pid_matches_callback, &pid);
163}
164
34c65914
PA
165/* Helper for find_any_thread_of_pid. Returns true if a thread
166 matches a PID. */
167
168static int
169thread_of_pid (struct inferior_list_entry *entry, void *pid_p)
170{
171 int pid = *(int *) pid_p;
172
173 return (ptid_get_pid (entry->id) == pid);
174}
175
176/* See gdbthread.h. */
177
178struct thread_info *
179find_any_thread_of_pid (int pid)
180{
181 struct inferior_list_entry *entry;
182
183 entry = find_inferior (&all_threads, thread_of_pid, &pid);
184
185 return (struct thread_info *) entry;
186}
187
95954743
PA
188ptid_t
189gdb_id_to_thread_id (ptid_t gdb_id)
dae5f5cf 190{
e09875d4 191 struct thread_info *thread = find_thread_ptid (gdb_id);
dae5f5cf 192
95954743 193 return thread ? thread->entry.id : null_ptid;
0d62e5e8 194}
c04a1aa8 195
0d62e5e8
DJ
196static void
197free_one_thread (struct inferior_list_entry *inf)
198{
199 struct thread_info *thread = get_thread (inf);
200 free_register_cache (inferior_regcache_data (thread));
201 free (thread);
202}
203
204void
205remove_thread (struct thread_info *thread)
206{
9accd112
MM
207 if (thread->btrace != NULL)
208 target_disable_btrace (thread->btrace);
209
465a859e 210 discard_queued_stop_replies (ptid_of (thread));
0d62e5e8
DJ
211 remove_inferior (&all_threads, (struct inferior_list_entry *) thread);
212 free_one_thread (&thread->entry);
96e7a1eb
AR
213 if (current_thread == thread)
214 current_thread = NULL;
ce3a066d
DJ
215}
216
649ebbca
DE
217/* Return a pointer to the first inferior in LIST, or NULL if there isn't one.
218 This is for cases where the caller needs a thread, but doesn't care
219 which one. */
220
221struct inferior_list_entry *
222get_first_inferior (struct inferior_list *list)
223{
3b8361aa
DE
224 if (list->head != NULL)
225 return list->head;
649ebbca
DE
226 return NULL;
227}
228
0718675c
JB
229/* Find the first inferior_list_entry E in LIST for which FUNC (E, ARG)
230 returns non-zero. If no entry is found then return NULL. */
231
0d62e5e8
DJ
232struct inferior_list_entry *
233find_inferior (struct inferior_list *list,
234 int (*func) (struct inferior_list_entry *, void *), void *arg)
235{
236 struct inferior_list_entry *inf = list->head;
ce3a066d 237
0d62e5e8 238 while (inf != NULL)
ce3a066d 239 {
a07b2135
PA
240 struct inferior_list_entry *next;
241
242 next = inf->next;
0d62e5e8
DJ
243 if ((*func) (inf, arg))
244 return inf;
a07b2135 245 inf = next;
0d62e5e8 246 }
611cb4a5 247
0d62e5e8
DJ
248 return NULL;
249}
611cb4a5 250
89342618
YQ
251/* Find the random inferior_list_entry E in LIST for which FUNC (E, ARG)
252 returns non-zero. If no entry is found then return NULL. */
253
254struct inferior_list_entry *
255find_inferior_in_random (struct inferior_list *list,
256 int (*func) (struct inferior_list_entry *, void *),
257 void *arg)
258{
259 struct inferior_list_entry *inf = list->head;
260 int count = 0;
261 int random_selector;
262
263 /* First count how many interesting entries we have. */
264 while (inf != NULL)
265 {
266 struct inferior_list_entry *next;
267
268 next = inf->next;
269 if ((*func) (inf, arg))
270 count++;
271 inf = next;
272 }
273
274 if (count == 0)
275 return NULL;
276
277 /* Now randomly pick an entry out of those. */
278 random_selector = (int)
279 ((count * (double) rand ()) / (RAND_MAX + 1.0));
280
281 inf = list->head;
282 while (inf != NULL)
283 {
284 struct inferior_list_entry *next;
285
286 next = inf->next;
287 if ((*func) (inf, arg) && (random_selector-- == 0))
288 return inf;
289 inf = next;
290 }
291
292 gdb_assert_not_reached ("failed to find an inferior in random.");
293 return NULL;
294}
295
0d62e5e8 296struct inferior_list_entry *
95954743 297find_inferior_id (struct inferior_list *list, ptid_t id)
0d62e5e8
DJ
298{
299 struct inferior_list_entry *inf = list->head;
300
301 while (inf != NULL)
302 {
95954743 303 if (ptid_equal (inf->id, id))
0d62e5e8
DJ
304 return inf;
305 inf = inf->next;
ce3a066d
DJ
306 }
307
0d62e5e8 308 return NULL;
ce3a066d 309}
611cb4a5
DJ
310
311void *
0d62e5e8 312inferior_target_data (struct thread_info *inferior)
611cb4a5
DJ
313{
314 return inferior->target_data;
315}
316
317void
0d62e5e8 318set_inferior_target_data (struct thread_info *inferior, void *data)
611cb4a5
DJ
319{
320 inferior->target_data = data;
321}
c04a1aa8 322
a44892be 323struct regcache *
0d62e5e8 324inferior_regcache_data (struct thread_info *inferior)
c04a1aa8
DJ
325{
326 return inferior->regcache_data;
327}
328
329void
a44892be 330set_inferior_regcache_data (struct thread_info *inferior, struct regcache *data)
c04a1aa8
DJ
331{
332 inferior->regcache_data = data;
333}
255e7678 334
649ebbca
DE
335/* Return true if LIST has exactly one entry. */
336
337int
338one_inferior_p (struct inferior_list *list)
339{
340 return list->head != NULL && list->head == list->tail;
341}
342
343/* Reset head,tail of LIST, assuming all entries have already been freed. */
344
345void
346clear_inferior_list (struct inferior_list *list)
347{
348 list->head = NULL;
349 list->tail = NULL;
350}
255e7678
DJ
351
352void
353clear_inferiors (void)
354{
355 for_each_inferior (&all_threads, free_one_thread);
649ebbca 356 clear_inferior_list (&all_threads);
bf4c19f7
YQ
357
358 clear_dlls ();
7284e1be 359
0bfdf32f 360 current_thread = NULL;
255e7678 361}
24a09b5f 362
95954743
PA
363struct process_info *
364add_process (int pid, int attached)
365{
8d749320 366 struct process_info *process = XCNEW (struct process_info);
95954743 367
80894984 368 process->entry.id = pid_to_ptid (pid);
95954743
PA
369 process->attached = attached;
370
80894984 371 add_inferior_to_list (&all_processes, &process->entry);
95954743
PA
372
373 return process;
374}
375
5091eb23
DE
376/* Remove a process from the common process list and free the memory
377 allocated for it.
378 The caller is responsible for freeing private data first. */
379
95954743
PA
380void
381remove_process (struct process_info *process)
382{
383 clear_symbol_cache (&process->symbol_cache);
384 free_all_breakpoints (process);
96e7a1eb 385 gdb_assert (find_thread_process (process) == NULL);
80894984 386 remove_inferior (&all_processes, &process->entry);
82075af2 387 VEC_free (int, process->syscalls_to_catch);
5091eb23 388 free (process);
95954743
PA
389}
390
391struct process_info *
392find_process_pid (int pid)
393{
394 return (struct process_info *)
395 find_inferior_id (&all_processes, pid_to_ptid (pid));
396}
397
3d40fbb5
PA
398/* Wrapper around get_first_inferior to return a struct process_info *. */
399
400struct process_info *
401get_first_process (void)
402{
403 return (struct process_info *) get_first_inferior (&all_processes);
404}
405
9f767825
DE
406/* Return non-zero if INF, a struct process_info, was started by us,
407 i.e. not attached to. */
408
409static int
410started_inferior_callback (struct inferior_list_entry *entry, void *args)
411{
412 struct process_info *process = (struct process_info *) entry;
413
414 return ! process->attached;
415}
416
417/* Return non-zero if there are any inferiors that we have created
418 (as opposed to attached-to). */
419
420int
421have_started_inferiors_p (void)
422{
423 return (find_inferior (&all_processes, started_inferior_callback, NULL)
424 != NULL);
425}
426
427/* Return non-zero if INF, a struct process_info, was attached to. */
428
429static int
430attached_inferior_callback (struct inferior_list_entry *entry, void *args)
431{
432 struct process_info *process = (struct process_info *) entry;
433
434 return process->attached;
435}
436
437/* Return non-zero if there are any inferiors that we have attached to. */
438
439int
440have_attached_inferiors_p (void)
441{
442 return (find_inferior (&all_processes, attached_inferior_callback, NULL)
443 != NULL);
444}
445
7fe519cb 446struct process_info *
63c40ec7 447get_thread_process (const struct thread_info *thread)
95954743
PA
448{
449 int pid = ptid_get_pid (thread->entry.id);
450 return find_process_pid (pid);
451}
452
453struct process_info *
454current_process (void)
455{
0bfdf32f
GB
456 gdb_assert (current_thread != NULL);
457 return get_thread_process (current_thread);
95954743 458}
984a2c04
YQ
459
460static void
461do_restore_current_thread_cleanup (void *arg)
462{
463 current_thread = (struct thread_info *) arg;
464}
465
466struct cleanup *
467make_cleanup_restore_current_thread (void)
468{
469 return make_cleanup (do_restore_current_thread_cleanup, current_thread);
470}
This page took 1.968882 seconds and 4 git commands to generate.