Don't ignore "-m emulation" command line option
[deliverable/binutils-gdb.git] / gdb / gdbserver / inferiors.c
CommitLineData
ce3a066d 1/* Inferior process information for the remote server for GDB.
32d0add0 2 Copyright (C) 2002-2015 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
95954743
PA
144ptid_t
145gdb_id_to_thread_id (ptid_t gdb_id)
dae5f5cf 146{
e09875d4 147 struct thread_info *thread = find_thread_ptid (gdb_id);
dae5f5cf 148
95954743 149 return thread ? thread->entry.id : null_ptid;
0d62e5e8 150}
c04a1aa8 151
0d62e5e8
DJ
152static void
153free_one_thread (struct inferior_list_entry *inf)
154{
155 struct thread_info *thread = get_thread (inf);
156 free_register_cache (inferior_regcache_data (thread));
157 free (thread);
158}
159
160void
161remove_thread (struct thread_info *thread)
162{
9accd112
MM
163 if (thread->btrace != NULL)
164 target_disable_btrace (thread->btrace);
165
465a859e 166 discard_queued_stop_replies (ptid_of (thread));
0d62e5e8
DJ
167 remove_inferior (&all_threads, (struct inferior_list_entry *) thread);
168 free_one_thread (&thread->entry);
ce3a066d
DJ
169}
170
649ebbca
DE
171/* Return a pointer to the first inferior in LIST, or NULL if there isn't one.
172 This is for cases where the caller needs a thread, but doesn't care
173 which one. */
174
175struct inferior_list_entry *
176get_first_inferior (struct inferior_list *list)
177{
3b8361aa
DE
178 if (list->head != NULL)
179 return list->head;
649ebbca
DE
180 return NULL;
181}
182
0718675c
JB
183/* Find the first inferior_list_entry E in LIST for which FUNC (E, ARG)
184 returns non-zero. If no entry is found then return NULL. */
185
0d62e5e8
DJ
186struct inferior_list_entry *
187find_inferior (struct inferior_list *list,
188 int (*func) (struct inferior_list_entry *, void *), void *arg)
189{
190 struct inferior_list_entry *inf = list->head;
ce3a066d 191
0d62e5e8 192 while (inf != NULL)
ce3a066d 193 {
a07b2135
PA
194 struct inferior_list_entry *next;
195
196 next = inf->next;
0d62e5e8
DJ
197 if ((*func) (inf, arg))
198 return inf;
a07b2135 199 inf = next;
0d62e5e8 200 }
611cb4a5 201
0d62e5e8
DJ
202 return NULL;
203}
611cb4a5 204
0d62e5e8 205struct inferior_list_entry *
95954743 206find_inferior_id (struct inferior_list *list, ptid_t id)
0d62e5e8
DJ
207{
208 struct inferior_list_entry *inf = list->head;
209
210 while (inf != NULL)
211 {
95954743 212 if (ptid_equal (inf->id, id))
0d62e5e8
DJ
213 return inf;
214 inf = inf->next;
ce3a066d
DJ
215 }
216
0d62e5e8 217 return NULL;
ce3a066d 218}
611cb4a5
DJ
219
220void *
0d62e5e8 221inferior_target_data (struct thread_info *inferior)
611cb4a5
DJ
222{
223 return inferior->target_data;
224}
225
226void
0d62e5e8 227set_inferior_target_data (struct thread_info *inferior, void *data)
611cb4a5
DJ
228{
229 inferior->target_data = data;
230}
c04a1aa8 231
a44892be 232struct regcache *
0d62e5e8 233inferior_regcache_data (struct thread_info *inferior)
c04a1aa8
DJ
234{
235 return inferior->regcache_data;
236}
237
238void
a44892be 239set_inferior_regcache_data (struct thread_info *inferior, struct regcache *data)
c04a1aa8
DJ
240{
241 inferior->regcache_data = data;
242}
255e7678 243
649ebbca
DE
244/* Return true if LIST has exactly one entry. */
245
246int
247one_inferior_p (struct inferior_list *list)
248{
249 return list->head != NULL && list->head == list->tail;
250}
251
252/* Reset head,tail of LIST, assuming all entries have already been freed. */
253
254void
255clear_inferior_list (struct inferior_list *list)
256{
257 list->head = NULL;
258 list->tail = NULL;
259}
255e7678
DJ
260
261void
262clear_inferiors (void)
263{
264 for_each_inferior (&all_threads, free_one_thread);
649ebbca 265 clear_inferior_list (&all_threads);
bf4c19f7
YQ
266
267 clear_dlls ();
7284e1be 268
0bfdf32f 269 current_thread = NULL;
255e7678 270}
24a09b5f 271
95954743
PA
272struct process_info *
273add_process (int pid, int attached)
274{
8d749320 275 struct process_info *process = XCNEW (struct process_info);
95954743 276
80894984 277 process->entry.id = pid_to_ptid (pid);
95954743
PA
278 process->attached = attached;
279
80894984 280 add_inferior_to_list (&all_processes, &process->entry);
95954743
PA
281
282 return process;
283}
284
5091eb23
DE
285/* Remove a process from the common process list and free the memory
286 allocated for it.
287 The caller is responsible for freeing private data first. */
288
95954743
PA
289void
290remove_process (struct process_info *process)
291{
292 clear_symbol_cache (&process->symbol_cache);
293 free_all_breakpoints (process);
80894984 294 remove_inferior (&all_processes, &process->entry);
5091eb23 295 free (process);
95954743
PA
296}
297
298struct process_info *
299find_process_pid (int pid)
300{
301 return (struct process_info *)
302 find_inferior_id (&all_processes, pid_to_ptid (pid));
303}
304
3d40fbb5
PA
305/* Wrapper around get_first_inferior to return a struct process_info *. */
306
307struct process_info *
308get_first_process (void)
309{
310 return (struct process_info *) get_first_inferior (&all_processes);
311}
312
9f767825
DE
313/* Return non-zero if INF, a struct process_info, was started by us,
314 i.e. not attached to. */
315
316static int
317started_inferior_callback (struct inferior_list_entry *entry, void *args)
318{
319 struct process_info *process = (struct process_info *) entry;
320
321 return ! process->attached;
322}
323
324/* Return non-zero if there are any inferiors that we have created
325 (as opposed to attached-to). */
326
327int
328have_started_inferiors_p (void)
329{
330 return (find_inferior (&all_processes, started_inferior_callback, NULL)
331 != NULL);
332}
333
334/* Return non-zero if INF, a struct process_info, was attached to. */
335
336static int
337attached_inferior_callback (struct inferior_list_entry *entry, void *args)
338{
339 struct process_info *process = (struct process_info *) entry;
340
341 return process->attached;
342}
343
344/* Return non-zero if there are any inferiors that we have attached to. */
345
346int
347have_attached_inferiors_p (void)
348{
349 return (find_inferior (&all_processes, attached_inferior_callback, NULL)
350 != NULL);
351}
352
7fe519cb 353struct process_info *
95954743
PA
354get_thread_process (struct thread_info *thread)
355{
356 int pid = ptid_get_pid (thread->entry.id);
357 return find_process_pid (pid);
358}
359
360struct process_info *
361current_process (void)
362{
0bfdf32f
GB
363 gdb_assert (current_thread != NULL);
364 return get_thread_process (current_thread);
95954743 365}
This page took 1.03996 seconds and 4 git commands to generate.