* linux-arm-low.c (struct arm_linux_hwbp_cap): Remove.
[binutils-gdb.git] / gdb / gdbserver / inferiors.c
1 /* Inferior process information for the remote server for GDB.
2 Copyright (C) 2002, 2005, 2007, 2008, 2009, 2010, 2011
3 Free Software Foundation, Inc.
4
5 Contributed by MontaVista Software.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21
22 #include <stdlib.h>
23
24 #include "server.h"
25
26 struct inferior_list all_processes;
27 struct inferior_list all_threads;
28 struct inferior_list all_dlls;
29 int dlls_changed;
30
31 struct thread_info *current_inferior;
32
33 #define get_thread(inf) ((struct thread_info *)(inf))
34 #define get_dll(inf) ((struct dll_info *)(inf))
35
36 void
37 add_inferior_to_list (struct inferior_list *list,
38 struct inferior_list_entry *new_inferior)
39 {
40 new_inferior->next = NULL;
41 if (list->tail != NULL)
42 list->tail->next = new_inferior;
43 else
44 list->head = new_inferior;
45 list->tail = new_inferior;
46 }
47
48 /* Invoke ACTION for each inferior in LIST. */
49
50 void
51 for_each_inferior (struct inferior_list *list,
52 void (*action) (struct inferior_list_entry *))
53 {
54 struct inferior_list_entry *cur = list->head, *next;
55
56 while (cur != NULL)
57 {
58 next = cur->next;
59 (*action) (cur);
60 cur = next;
61 }
62 }
63
64 void
65 remove_inferior (struct inferior_list *list,
66 struct inferior_list_entry *entry)
67 {
68 struct inferior_list_entry **cur;
69
70 if (list->head == entry)
71 {
72 list->head = entry->next;
73 if (list->tail == entry)
74 list->tail = list->head;
75 return;
76 }
77
78 cur = &list->head;
79 while (*cur && (*cur)->next != entry)
80 cur = &(*cur)->next;
81
82 if (*cur == NULL)
83 return;
84
85 (*cur)->next = entry->next;
86
87 if (list->tail == entry)
88 list->tail = *cur;
89 }
90
91 void
92 add_thread (ptid_t thread_id, void *target_data)
93 {
94 struct thread_info *new_thread = xmalloc (sizeof (*new_thread));
95
96 memset (new_thread, 0, sizeof (*new_thread));
97
98 new_thread->entry.id = thread_id;
99 new_thread->last_resume_kind = resume_continue;
100 new_thread->last_status.kind = TARGET_WAITKIND_IGNORE;
101
102 add_inferior_to_list (&all_threads, & new_thread->entry);
103
104 if (current_inferior == NULL)
105 current_inferior = new_thread;
106
107 new_thread->target_data = target_data;
108 set_inferior_regcache_data (new_thread, new_register_cache ());
109 }
110
111 ptid_t
112 thread_id_to_gdb_id (ptid_t thread_id)
113 {
114 struct inferior_list_entry *inf = all_threads.head;
115
116 while (inf != NULL)
117 {
118 if (ptid_equal (inf->id, thread_id))
119 return thread_id;
120 inf = inf->next;
121 }
122
123 return null_ptid;
124 }
125
126 ptid_t
127 thread_to_gdb_id (struct thread_info *thread)
128 {
129 return thread->entry.id;
130 }
131
132 struct thread_info *
133 find_thread_ptid (ptid_t ptid)
134 {
135 struct inferior_list_entry *inf = all_threads.head;
136
137 while (inf != NULL)
138 {
139 struct thread_info *thread = get_thread (inf);
140 if (ptid_equal (thread->entry.id, ptid))
141 return thread;
142 inf = inf->next;
143 }
144
145 return NULL;
146 }
147
148 ptid_t
149 gdb_id_to_thread_id (ptid_t gdb_id)
150 {
151 struct thread_info *thread = find_thread_ptid (gdb_id);
152
153 return thread ? thread->entry.id : null_ptid;
154 }
155
156 static void
157 free_one_thread (struct inferior_list_entry *inf)
158 {
159 struct thread_info *thread = get_thread (inf);
160 free_register_cache (inferior_regcache_data (thread));
161 free (thread);
162 }
163
164 void
165 remove_thread (struct thread_info *thread)
166 {
167 remove_inferior (&all_threads, (struct inferior_list_entry *) thread);
168 free_one_thread (&thread->entry);
169 }
170
171 /* Find the first inferior_list_entry E in LIST for which FUNC (E, ARG)
172 returns non-zero. If no entry is found then return NULL. */
173
174 struct inferior_list_entry *
175 find_inferior (struct inferior_list *list,
176 int (*func) (struct inferior_list_entry *, void *), void *arg)
177 {
178 struct inferior_list_entry *inf = list->head;
179
180 while (inf != NULL)
181 {
182 struct inferior_list_entry *next;
183
184 next = inf->next;
185 if ((*func) (inf, arg))
186 return inf;
187 inf = next;
188 }
189
190 return NULL;
191 }
192
193 struct inferior_list_entry *
194 find_inferior_id (struct inferior_list *list, ptid_t id)
195 {
196 struct inferior_list_entry *inf = list->head;
197
198 while (inf != NULL)
199 {
200 if (ptid_equal (inf->id, id))
201 return inf;
202 inf = inf->next;
203 }
204
205 return NULL;
206 }
207
208 void *
209 inferior_target_data (struct thread_info *inferior)
210 {
211 return inferior->target_data;
212 }
213
214 void
215 set_inferior_target_data (struct thread_info *inferior, void *data)
216 {
217 inferior->target_data = data;
218 }
219
220 void *
221 inferior_regcache_data (struct thread_info *inferior)
222 {
223 return inferior->regcache_data;
224 }
225
226 void
227 set_inferior_regcache_data (struct thread_info *inferior, void *data)
228 {
229 inferior->regcache_data = data;
230 }
231
232 static void
233 free_one_dll (struct inferior_list_entry *inf)
234 {
235 struct dll_info *dll = get_dll (inf);
236 if (dll->name != NULL)
237 free (dll->name);
238 free (dll);
239 }
240
241 /* Find a DLL with the same name and/or base address. A NULL name in
242 the key is ignored; so is an all-ones base address. */
243
244 static int
245 match_dll (struct inferior_list_entry *inf, void *arg)
246 {
247 struct dll_info *iter = (void *) inf;
248 struct dll_info *key = arg;
249
250 if (key->base_addr != ~(CORE_ADDR) 0
251 && iter->base_addr == key->base_addr)
252 return 1;
253 else if (key->name != NULL
254 && iter->name != NULL
255 && strcmp (key->name, iter->name) == 0)
256 return 1;
257
258 return 0;
259 }
260
261 /* Record a newly loaded DLL at BASE_ADDR. */
262
263 void
264 loaded_dll (const char *name, CORE_ADDR base_addr)
265 {
266 struct dll_info *new_dll = xmalloc (sizeof (*new_dll));
267 memset (new_dll, 0, sizeof (*new_dll));
268
269 new_dll->entry.id = minus_one_ptid;
270
271 new_dll->name = xstrdup (name);
272 new_dll->base_addr = base_addr;
273
274 add_inferior_to_list (&all_dlls, &new_dll->entry);
275 dlls_changed = 1;
276 }
277
278 /* Record that the DLL with NAME and BASE_ADDR has been unloaded. */
279
280 void
281 unloaded_dll (const char *name, CORE_ADDR base_addr)
282 {
283 struct dll_info *dll;
284 struct dll_info key_dll;
285
286 /* Be careful not to put the key DLL in any list. */
287 key_dll.name = (char *) name;
288 key_dll.base_addr = base_addr;
289
290 dll = (void *) find_inferior (&all_dlls, match_dll, &key_dll);
291
292 if (dll == NULL)
293 /* For some inferiors we might get unloaded_dll events without having
294 a corresponding loaded_dll. In that case, the dll cannot be found
295 in ALL_DLL, and there is nothing further for us to do.
296
297 This has been observed when running 32bit executables on Windows64
298 (i.e. through WOW64, the interface between the 32bits and 64bits
299 worlds). In that case, the inferior always does some strange
300 unloading of unnamed dll. */
301 return;
302 else
303 {
304 /* DLL has been found so remove the entry and free associated
305 resources. */
306 remove_inferior (&all_dlls, &dll->entry);
307 free_one_dll (&dll->entry);
308 dlls_changed = 1;
309 }
310 }
311
312 #define clear_list(LIST) \
313 do { (LIST)->head = (LIST)->tail = NULL; } while (0)
314
315 void
316 clear_inferiors (void)
317 {
318 for_each_inferior (&all_threads, free_one_thread);
319 for_each_inferior (&all_dlls, free_one_dll);
320
321 clear_list (&all_threads);
322 clear_list (&all_dlls);
323
324 current_inferior = NULL;
325 }
326
327 /* Two utility functions for a truly degenerate inferior_list: a simple
328 PID listing. */
329
330 void
331 add_pid_to_list (struct inferior_list *list, unsigned long pid)
332 {
333 struct inferior_list_entry *new_entry;
334
335 new_entry = xmalloc (sizeof (struct inferior_list_entry));
336 new_entry->id = pid_to_ptid (pid);
337 add_inferior_to_list (list, new_entry);
338 }
339
340 int
341 pull_pid_from_list (struct inferior_list *list, unsigned long pid)
342 {
343 struct inferior_list_entry *new_entry;
344
345 new_entry = find_inferior_id (list, pid_to_ptid (pid));
346 if (new_entry == NULL)
347 return 0;
348 else
349 {
350 remove_inferior (list, new_entry);
351 free (new_entry);
352 return 1;
353 }
354 }
355
356 struct process_info *
357 add_process (int pid, int attached)
358 {
359 struct process_info *process;
360
361 process = xcalloc (1, sizeof (*process));
362
363 process->head.id = pid_to_ptid (pid);
364 process->attached = attached;
365
366 add_inferior_to_list (&all_processes, &process->head);
367
368 return process;
369 }
370
371 /* Remove a process from the common process list and free the memory
372 allocated for it.
373 The caller is responsible for freeing private data first. */
374
375 void
376 remove_process (struct process_info *process)
377 {
378 clear_symbol_cache (&process->symbol_cache);
379 free_all_breakpoints (process);
380 remove_inferior (&all_processes, &process->head);
381 free (process);
382 }
383
384 struct process_info *
385 find_process_pid (int pid)
386 {
387 return (struct process_info *)
388 find_inferior_id (&all_processes, pid_to_ptid (pid));
389 }
390
391 /* Return non-zero if INF, a struct process_info, was started by us,
392 i.e. not attached to. */
393
394 static int
395 started_inferior_callback (struct inferior_list_entry *entry, void *args)
396 {
397 struct process_info *process = (struct process_info *) entry;
398
399 return ! process->attached;
400 }
401
402 /* Return non-zero if there are any inferiors that we have created
403 (as opposed to attached-to). */
404
405 int
406 have_started_inferiors_p (void)
407 {
408 return (find_inferior (&all_processes, started_inferior_callback, NULL)
409 != NULL);
410 }
411
412 /* Return non-zero if INF, a struct process_info, was attached to. */
413
414 static int
415 attached_inferior_callback (struct inferior_list_entry *entry, void *args)
416 {
417 struct process_info *process = (struct process_info *) entry;
418
419 return process->attached;
420 }
421
422 /* Return non-zero if there are any inferiors that we have attached to. */
423
424 int
425 have_attached_inferiors_p (void)
426 {
427 return (find_inferior (&all_processes, attached_inferior_callback, NULL)
428 != NULL);
429 }
430
431 struct process_info *
432 get_thread_process (struct thread_info *thread)
433 {
434 int pid = ptid_get_pid (thread->entry.id);
435 return find_process_pid (pid);
436 }
437
438 struct process_info *
439 current_process (void)
440 {
441 if (current_inferior == NULL)
442 fatal ("Current inferior requested, but current_inferior is NULL\n");
443
444 return get_thread_process (current_inferior);
445 }