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