gdbserver: update gitignore
[deliverable/binutils-gdb.git] / gdb / gdbserver / inferiors.c
CommitLineData
ce3a066d 1/* Inferior process information for the remote server for GDB.
0b302171 2 Copyright (C) 2002, 2005, 2007-2012 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
DJ
20
21#include <stdlib.h>
22
23#include "server.h"
24
95954743 25struct inferior_list all_processes;
0d62e5e8
DJ
26struct inferior_list all_threads;
27
28struct thread_info *current_inferior;
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
0d62e5e8
DJ
60void
61remove_inferior (struct inferior_list *list,
62 struct inferior_list_entry *entry)
63{
64 struct inferior_list_entry **cur;
ce3a066d 65
0d62e5e8
DJ
66 if (list->head == entry)
67 {
68 list->head = entry->next;
69 if (list->tail == entry)
70 list->tail = list->head;
71 return;
72 }
73
74 cur = &list->head;
75 while (*cur && (*cur)->next != entry)
76 cur = &(*cur)->next;
77
78 if (*cur == NULL)
79 return;
ce3a066d 80
0d62e5e8
DJ
81 (*cur)->next = entry->next;
82
83 if (list->tail == entry)
84 list->tail = *cur;
85}
86
87void
95954743 88add_thread (ptid_t thread_id, void *target_data)
0d62e5e8 89{
bca929d3 90 struct thread_info *new_thread = xmalloc (sizeof (*new_thread));
0d62e5e8
DJ
91
92 memset (new_thread, 0, sizeof (*new_thread));
93
94 new_thread->entry.id = thread_id;
8336d594 95 new_thread->last_resume_kind = resume_continue;
fc7238bb 96 new_thread->last_status.kind = TARGET_WAITKIND_IGNORE;
0d62e5e8
DJ
97
98 add_inferior_to_list (&all_threads, & new_thread->entry);
255e7678 99
ce3a066d 100 if (current_inferior == NULL)
0d62e5e8 101 current_inferior = new_thread;
ce3a066d 102
0d62e5e8
DJ
103 new_thread->target_data = target_data;
104 set_inferior_regcache_data (new_thread, new_register_cache ());
a06660f7
DJ
105}
106
95954743
PA
107ptid_t
108thread_id_to_gdb_id (ptid_t thread_id)
a06660f7
DJ
109{
110 struct inferior_list_entry *inf = all_threads.head;
111
112 while (inf != NULL)
113 {
95954743
PA
114 if (ptid_equal (inf->id, thread_id))
115 return thread_id;
a06660f7
DJ
116 inf = inf->next;
117 }
118
95954743 119 return null_ptid;
a06660f7
DJ
120}
121
95954743 122ptid_t
a06660f7
DJ
123thread_to_gdb_id (struct thread_info *thread)
124{
95954743 125 return thread->entry.id;
a06660f7
DJ
126}
127
dae5f5cf 128struct thread_info *
e09875d4 129find_thread_ptid (ptid_t ptid)
a06660f7
DJ
130{
131 struct inferior_list_entry *inf = all_threads.head;
132
133 while (inf != NULL)
134 {
135 struct thread_info *thread = get_thread (inf);
95954743 136 if (ptid_equal (thread->entry.id, ptid))
dae5f5cf 137 return thread;
a06660f7
DJ
138 inf = inf->next;
139 }
140
dae5f5cf
DJ
141 return NULL;
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{
163 remove_inferior (&all_threads, (struct inferior_list_entry *) thread);
164 free_one_thread (&thread->entry);
ce3a066d
DJ
165}
166
0718675c
JB
167/* Find the first inferior_list_entry E in LIST for which FUNC (E, ARG)
168 returns non-zero. If no entry is found then return NULL. */
169
0d62e5e8
DJ
170struct inferior_list_entry *
171find_inferior (struct inferior_list *list,
172 int (*func) (struct inferior_list_entry *, void *), void *arg)
173{
174 struct inferior_list_entry *inf = list->head;
ce3a066d 175
0d62e5e8 176 while (inf != NULL)
ce3a066d 177 {
a07b2135
PA
178 struct inferior_list_entry *next;
179
180 next = inf->next;
0d62e5e8
DJ
181 if ((*func) (inf, arg))
182 return inf;
a07b2135 183 inf = next;
0d62e5e8 184 }
611cb4a5 185
0d62e5e8
DJ
186 return NULL;
187}
611cb4a5 188
0d62e5e8 189struct inferior_list_entry *
95954743 190find_inferior_id (struct inferior_list *list, ptid_t id)
0d62e5e8
DJ
191{
192 struct inferior_list_entry *inf = list->head;
193
194 while (inf != NULL)
195 {
95954743 196 if (ptid_equal (inf->id, id))
0d62e5e8
DJ
197 return inf;
198 inf = inf->next;
ce3a066d
DJ
199 }
200
0d62e5e8 201 return NULL;
ce3a066d 202}
611cb4a5
DJ
203
204void *
0d62e5e8 205inferior_target_data (struct thread_info *inferior)
611cb4a5
DJ
206{
207 return inferior->target_data;
208}
209
210void
0d62e5e8 211set_inferior_target_data (struct thread_info *inferior, void *data)
611cb4a5
DJ
212{
213 inferior->target_data = data;
214}
c04a1aa8
DJ
215
216void *
0d62e5e8 217inferior_regcache_data (struct thread_info *inferior)
c04a1aa8
DJ
218{
219 return inferior->regcache_data;
220}
221
222void
0d62e5e8 223set_inferior_regcache_data (struct thread_info *inferior, void *data)
c04a1aa8
DJ
224{
225 inferior->regcache_data = data;
226}
255e7678 227
255e7678
DJ
228#define clear_list(LIST) \
229 do { (LIST)->head = (LIST)->tail = NULL; } while (0)
230
231void
232clear_inferiors (void)
233{
234 for_each_inferior (&all_threads, free_one_thread);
255e7678 235 clear_list (&all_threads);
bf4c19f7
YQ
236
237 clear_dlls ();
7284e1be
UW
238
239 current_inferior = NULL;
255e7678 240}
24a09b5f 241
95954743
PA
242struct process_info *
243add_process (int pid, int attached)
244{
245 struct process_info *process;
246
247 process = xcalloc (1, sizeof (*process));
248
249 process->head.id = pid_to_ptid (pid);
250 process->attached = attached;
251
252 add_inferior_to_list (&all_processes, &process->head);
253
254 return process;
255}
256
5091eb23
DE
257/* Remove a process from the common process list and free the memory
258 allocated for it.
259 The caller is responsible for freeing private data first. */
260
95954743
PA
261void
262remove_process (struct process_info *process)
263{
264 clear_symbol_cache (&process->symbol_cache);
265 free_all_breakpoints (process);
266 remove_inferior (&all_processes, &process->head);
5091eb23 267 free (process);
95954743
PA
268}
269
270struct process_info *
271find_process_pid (int pid)
272{
273 return (struct process_info *)
274 find_inferior_id (&all_processes, pid_to_ptid (pid));
275}
276
9f767825
DE
277/* Return non-zero if INF, a struct process_info, was started by us,
278 i.e. not attached to. */
279
280static int
281started_inferior_callback (struct inferior_list_entry *entry, void *args)
282{
283 struct process_info *process = (struct process_info *) entry;
284
285 return ! process->attached;
286}
287
288/* Return non-zero if there are any inferiors that we have created
289 (as opposed to attached-to). */
290
291int
292have_started_inferiors_p (void)
293{
294 return (find_inferior (&all_processes, started_inferior_callback, NULL)
295 != NULL);
296}
297
298/* Return non-zero if INF, a struct process_info, was attached to. */
299
300static int
301attached_inferior_callback (struct inferior_list_entry *entry, void *args)
302{
303 struct process_info *process = (struct process_info *) entry;
304
305 return process->attached;
306}
307
308/* Return non-zero if there are any inferiors that we have attached to. */
309
310int
311have_attached_inferiors_p (void)
312{
313 return (find_inferior (&all_processes, attached_inferior_callback, NULL)
314 != NULL);
315}
316
7fe519cb 317struct process_info *
95954743
PA
318get_thread_process (struct thread_info *thread)
319{
320 int pid = ptid_get_pid (thread->entry.id);
321 return find_process_pid (pid);
322}
323
324struct process_info *
325current_process (void)
326{
327 if (current_inferior == NULL)
328 fatal ("Current inferior requested, but current_inferior is NULL\n");
329
330 return get_thread_process (current_inferior);
331}
This page took 0.723603 seconds and 4 git commands to generate.