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