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