097326d7ce1b9299d9cbb979b25098b30eb59051
[deliverable/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
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 thread_info
27 {
28 struct inferior_list_entry entry;
29 void *target_data;
30 void *regcache_data;
31 unsigned int gdb_id;
32 };
33
34 struct inferior_list all_processes;
35 struct inferior_list all_threads;
36 struct inferior_list all_dlls;
37 int dlls_changed;
38
39 struct thread_info *current_inferior;
40
41
42 /* Oft used ptids */
43 ptid_t null_ptid;
44 ptid_t minus_one_ptid;
45
46 /* Create a ptid given the necessary PID, LWP, and TID components. */
47
48 ptid_t
49 ptid_build (int pid, long lwp, long tid)
50 {
51 ptid_t ptid;
52
53 ptid.pid = pid;
54 ptid.lwp = lwp;
55 ptid.tid = tid;
56 return ptid;
57 }
58
59 /* Create a ptid from just a pid. */
60
61 ptid_t
62 pid_to_ptid (int pid)
63 {
64 return ptid_build (pid, 0, 0);
65 }
66
67 /* Fetch the pid (process id) component from a ptid. */
68
69 int
70 ptid_get_pid (ptid_t ptid)
71 {
72 return ptid.pid;
73 }
74
75 /* Fetch the lwp (lightweight process) component from a ptid. */
76
77 long
78 ptid_get_lwp (ptid_t ptid)
79 {
80 return ptid.lwp;
81 }
82
83 /* Fetch the tid (thread id) component from a ptid. */
84
85 long
86 ptid_get_tid (ptid_t ptid)
87 {
88 return ptid.tid;
89 }
90
91 /* ptid_equal() is used to test equality of two ptids. */
92
93 int
94 ptid_equal (ptid_t ptid1, ptid_t ptid2)
95 {
96 return (ptid1.pid == ptid2.pid
97 && ptid1.lwp == ptid2.lwp
98 && ptid1.tid == ptid2.tid);
99 }
100
101 /* Return true if this ptid represents a process. */
102
103 int
104 ptid_is_pid (ptid_t ptid)
105 {
106 if (ptid_equal (minus_one_ptid, ptid))
107 return 0;
108 if (ptid_equal (null_ptid, ptid))
109 return 0;
110
111 return (ptid_get_pid (ptid) != 0
112 && ptid_get_lwp (ptid) == 0
113 && ptid_get_tid (ptid) == 0);
114 }
115
116 #define get_thread(inf) ((struct thread_info *)(inf))
117 #define get_dll(inf) ((struct dll_info *)(inf))
118
119 void
120 add_inferior_to_list (struct inferior_list *list,
121 struct inferior_list_entry *new_inferior)
122 {
123 new_inferior->next = NULL;
124 if (list->tail != NULL)
125 list->tail->next = new_inferior;
126 else
127 list->head = new_inferior;
128 list->tail = new_inferior;
129 }
130
131 /* Invoke ACTION for each inferior in LIST. */
132
133 void
134 for_each_inferior (struct inferior_list *list,
135 void (*action) (struct inferior_list_entry *))
136 {
137 struct inferior_list_entry *cur = list->head, *next;
138
139 while (cur != NULL)
140 {
141 next = cur->next;
142 (*action) (cur);
143 cur = next;
144 }
145 }
146
147 void
148 remove_inferior (struct inferior_list *list,
149 struct inferior_list_entry *entry)
150 {
151 struct inferior_list_entry **cur;
152
153 if (list->head == entry)
154 {
155 list->head = entry->next;
156 if (list->tail == entry)
157 list->tail = list->head;
158 return;
159 }
160
161 cur = &list->head;
162 while (*cur && (*cur)->next != entry)
163 cur = &(*cur)->next;
164
165 if (*cur == NULL)
166 return;
167
168 (*cur)->next = entry->next;
169
170 if (list->tail == entry)
171 list->tail = *cur;
172 }
173
174 void
175 add_thread (ptid_t thread_id, void *target_data)
176 {
177 struct thread_info *new_thread = xmalloc (sizeof (*new_thread));
178
179 memset (new_thread, 0, sizeof (*new_thread));
180
181 new_thread->entry.id = thread_id;
182
183 add_inferior_to_list (&all_threads, & new_thread->entry);
184
185 if (current_inferior == NULL)
186 current_inferior = new_thread;
187
188 new_thread->target_data = target_data;
189 set_inferior_regcache_data (new_thread, new_register_cache ());
190 }
191
192 ptid_t
193 thread_id_to_gdb_id (ptid_t thread_id)
194 {
195 struct inferior_list_entry *inf = all_threads.head;
196
197 while (inf != NULL)
198 {
199 if (ptid_equal (inf->id, thread_id))
200 return thread_id;
201 inf = inf->next;
202 }
203
204 return null_ptid;
205 }
206
207 ptid_t
208 thread_to_gdb_id (struct thread_info *thread)
209 {
210 return thread->entry.id;
211 }
212
213 struct thread_info *
214 find_thread_ptid (ptid_t ptid)
215 {
216 struct inferior_list_entry *inf = all_threads.head;
217
218 while (inf != NULL)
219 {
220 struct thread_info *thread = get_thread (inf);
221 if (ptid_equal (thread->entry.id, ptid))
222 return thread;
223 inf = inf->next;
224 }
225
226 return NULL;
227 }
228
229 ptid_t
230 gdb_id_to_thread_id (ptid_t gdb_id)
231 {
232 struct thread_info *thread = find_thread_ptid (gdb_id);
233
234 return thread ? thread->entry.id : null_ptid;
235 }
236
237 static void
238 free_one_thread (struct inferior_list_entry *inf)
239 {
240 struct thread_info *thread = get_thread (inf);
241 free_register_cache (inferior_regcache_data (thread));
242 free (thread);
243 }
244
245 void
246 remove_thread (struct thread_info *thread)
247 {
248 remove_inferior (&all_threads, (struct inferior_list_entry *) thread);
249 free_one_thread (&thread->entry);
250 }
251
252 /* Find the first inferior_list_entry E in LIST for which FUNC (E, ARG)
253 returns non-zero. If no entry is found then return NULL. */
254
255 struct inferior_list_entry *
256 find_inferior (struct inferior_list *list,
257 int (*func) (struct inferior_list_entry *, void *), void *arg)
258 {
259 struct inferior_list_entry *inf = list->head;
260
261 while (inf != NULL)
262 {
263 struct inferior_list_entry *next;
264
265 next = inf->next;
266 if ((*func) (inf, arg))
267 return inf;
268 inf = next;
269 }
270
271 return NULL;
272 }
273
274 struct inferior_list_entry *
275 find_inferior_id (struct inferior_list *list, ptid_t id)
276 {
277 struct inferior_list_entry *inf = list->head;
278
279 while (inf != NULL)
280 {
281 if (ptid_equal (inf->id, id))
282 return inf;
283 inf = inf->next;
284 }
285
286 return NULL;
287 }
288
289 void *
290 inferior_target_data (struct thread_info *inferior)
291 {
292 return inferior->target_data;
293 }
294
295 void
296 set_inferior_target_data (struct thread_info *inferior, void *data)
297 {
298 inferior->target_data = data;
299 }
300
301 void *
302 inferior_regcache_data (struct thread_info *inferior)
303 {
304 return inferior->regcache_data;
305 }
306
307 void
308 set_inferior_regcache_data (struct thread_info *inferior, void *data)
309 {
310 inferior->regcache_data = data;
311 }
312
313 static void
314 free_one_dll (struct inferior_list_entry *inf)
315 {
316 struct dll_info *dll = get_dll (inf);
317 if (dll->name != NULL)
318 free (dll->name);
319 free (dll);
320 }
321
322 /* Find a DLL with the same name and/or base address. A NULL name in
323 the key is ignored; so is an all-ones base address. */
324
325 static int
326 match_dll (struct inferior_list_entry *inf, void *arg)
327 {
328 struct dll_info *iter = (void *) inf;
329 struct dll_info *key = arg;
330
331 if (key->base_addr != ~(CORE_ADDR) 0
332 && iter->base_addr == key->base_addr)
333 return 1;
334 else if (key->name != NULL
335 && iter->name != NULL
336 && strcmp (key->name, iter->name) == 0)
337 return 1;
338
339 return 0;
340 }
341
342 /* Record a newly loaded DLL at BASE_ADDR. */
343
344 void
345 loaded_dll (const char *name, CORE_ADDR base_addr)
346 {
347 struct dll_info *new_dll = xmalloc (sizeof (*new_dll));
348 memset (new_dll, 0, sizeof (*new_dll));
349
350 new_dll->entry.id = minus_one_ptid;
351
352 new_dll->name = xstrdup (name);
353 new_dll->base_addr = base_addr;
354
355 add_inferior_to_list (&all_dlls, &new_dll->entry);
356 dlls_changed = 1;
357 }
358
359 /* Record that the DLL with NAME and BASE_ADDR has been unloaded. */
360
361 void
362 unloaded_dll (const char *name, CORE_ADDR base_addr)
363 {
364 struct dll_info *dll;
365 struct dll_info key_dll;
366
367 /* Be careful not to put the key DLL in any list. */
368 key_dll.name = (char *) name;
369 key_dll.base_addr = base_addr;
370
371 dll = (void *) find_inferior (&all_dlls, match_dll, &key_dll);
372
373 if (dll == NULL)
374 /* For some inferiors we might get unloaded_dll events without having
375 a corresponding loaded_dll. In that case, the dll cannot be found
376 in ALL_DLL, and there is nothing further for us to do.
377
378 This has been observed when running 32bit executables on Windows64
379 (i.e. through WOW64, the interface between the 32bits and 64bits
380 worlds). In that case, the inferior always does some strange
381 unloading of unnamed dll. */
382 return;
383 else
384 {
385 /* DLL has been found so remove the entry and free associated
386 resources. */
387 remove_inferior (&all_dlls, &dll->entry);
388 free_one_dll (&dll->entry);
389 dlls_changed = 1;
390 }
391 }
392
393 #define clear_list(LIST) \
394 do { (LIST)->head = (LIST)->tail = NULL; } while (0)
395
396 void
397 clear_inferiors (void)
398 {
399 for_each_inferior (&all_threads, free_one_thread);
400 for_each_inferior (&all_dlls, free_one_dll);
401
402 clear_list (&all_threads);
403 clear_list (&all_dlls);
404
405 current_inferior = NULL;
406 }
407
408 /* Two utility functions for a truly degenerate inferior_list: a simple
409 PID listing. */
410
411 void
412 add_pid_to_list (struct inferior_list *list, unsigned long pid)
413 {
414 struct inferior_list_entry *new_entry;
415
416 new_entry = xmalloc (sizeof (struct inferior_list_entry));
417 new_entry->id = pid_to_ptid (pid);
418 add_inferior_to_list (list, new_entry);
419 }
420
421 int
422 pull_pid_from_list (struct inferior_list *list, unsigned long pid)
423 {
424 struct inferior_list_entry *new_entry;
425
426 new_entry = find_inferior_id (list, pid_to_ptid (pid));
427 if (new_entry == NULL)
428 return 0;
429 else
430 {
431 remove_inferior (list, new_entry);
432 free (new_entry);
433 return 1;
434 }
435 }
436
437 struct process_info *
438 add_process (int pid, int attached)
439 {
440 struct process_info *process;
441
442 process = xcalloc (1, sizeof (*process));
443
444 process->head.id = pid_to_ptid (pid);
445 process->attached = attached;
446
447 add_inferior_to_list (&all_processes, &process->head);
448
449 return process;
450 }
451
452 /* Remove a process from the common process list and free the memory
453 allocated for it.
454 The caller is responsible for freeing private data first. */
455
456 void
457 remove_process (struct process_info *process)
458 {
459 clear_symbol_cache (&process->symbol_cache);
460 free_all_breakpoints (process);
461 remove_inferior (&all_processes, &process->head);
462 free (process);
463 }
464
465 struct process_info *
466 find_process_pid (int pid)
467 {
468 return (struct process_info *)
469 find_inferior_id (&all_processes, pid_to_ptid (pid));
470 }
471
472 /* Return non-zero if INF, a struct process_info, was started by us,
473 i.e. not attached to. */
474
475 static int
476 started_inferior_callback (struct inferior_list_entry *entry, void *args)
477 {
478 struct process_info *process = (struct process_info *) entry;
479
480 return ! process->attached;
481 }
482
483 /* Return non-zero if there are any inferiors that we have created
484 (as opposed to attached-to). */
485
486 int
487 have_started_inferiors_p (void)
488 {
489 return (find_inferior (&all_processes, started_inferior_callback, NULL)
490 != NULL);
491 }
492
493 /* Return non-zero if INF, a struct process_info, was attached to. */
494
495 static int
496 attached_inferior_callback (struct inferior_list_entry *entry, void *args)
497 {
498 struct process_info *process = (struct process_info *) entry;
499
500 return process->attached;
501 }
502
503 /* Return non-zero if there are any inferiors that we have attached to. */
504
505 int
506 have_attached_inferiors_p (void)
507 {
508 return (find_inferior (&all_processes, attached_inferior_callback, NULL)
509 != NULL);
510 }
511
512 struct process_info *
513 get_thread_process (struct thread_info *thread)
514 {
515 int pid = ptid_get_pid (thread->entry.id);
516 return find_process_pid (pid);
517 }
518
519 struct process_info *
520 current_process (void)
521 {
522 if (current_inferior == NULL)
523 fatal ("Current inferior requested, but current_inferior is NULL\n");
524
525 return get_thread_process (current_inferior);
526 }
527
528 void
529 initialize_inferiors (void)
530 {
531 null_ptid = ptid_build (0, 0, 0);
532 minus_one_ptid = ptid_build (-1, 0, 0);
533 }
This page took 0.040309 seconds and 4 git commands to generate.