OLD | NEW |
1 /* Inferior process information for the remote server for GDB. | 1 /* Inferior process information for the remote server for GDB. |
2 Copyright (C) 2002, 2005, 2007-2012 Free Software Foundation, Inc. | 2 Copyright (C) 2002, 2005, 2007-2012 Free Software Foundation, Inc. |
3 | 3 |
4 Contributed by MontaVista Software. | 4 Contributed by MontaVista Software. |
5 | 5 |
6 This file is part of GDB. | 6 This file is part of GDB. |
7 | 7 |
8 This program is free software; you can redistribute it and/or modify | 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 | 9 it under the terms of the GNU General Public License as published by |
10 the Free Software Foundation; either version 3 of the License, or | 10 the Free Software Foundation; either version 3 of the License, or |
11 (at your option) any later version. | 11 (at your option) any later version. |
12 | 12 |
13 This program is distributed in the hope that it will be useful, | 13 This program is distributed in the hope that it will be useful, |
14 but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 GNU General Public License for more details. | 16 GNU General Public License for more details. |
17 | 17 |
18 You should have received a copy of the GNU General Public License | 18 You should have received a copy of the GNU General Public License |
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */ | 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
20 | 20 |
21 #include <stdlib.h> | 21 #include <stdlib.h> |
22 | 22 |
23 #include "server.h" | 23 #include "server.h" |
| 24 #include "gdbthread.h" |
24 | 25 |
25 struct inferior_list all_processes; | 26 struct inferior_list all_processes; |
26 struct inferior_list all_threads; | 27 struct inferior_list all_threads; |
27 struct inferior_list all_dlls; | |
28 int dlls_changed; | |
29 | 28 |
30 struct thread_info *current_inferior; | 29 struct thread_info *current_inferior; |
31 | 30 |
32 #define get_thread(inf) ((struct thread_info *)(inf)) | 31 #define get_thread(inf) ((struct thread_info *)(inf)) |
33 #define get_dll(inf) ((struct dll_info *)(inf)) | |
34 | 32 |
35 void | 33 void |
36 add_inferior_to_list (struct inferior_list *list, | 34 add_inferior_to_list (struct inferior_list *list, |
37 struct inferior_list_entry *new_inferior) | 35 struct inferior_list_entry *new_inferior) |
38 { | 36 { |
39 new_inferior->next = NULL; | 37 new_inferior->next = NULL; |
40 if (list->tail != NULL) | 38 if (list->tail != NULL) |
41 list->tail->next = new_inferior; | 39 list->tail->next = new_inferior; |
42 else | 40 else |
43 list->head = new_inferior; | 41 list->head = new_inferior; |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 { | 219 { |
222 return inferior->regcache_data; | 220 return inferior->regcache_data; |
223 } | 221 } |
224 | 222 |
225 void | 223 void |
226 set_inferior_regcache_data (struct thread_info *inferior, void *data) | 224 set_inferior_regcache_data (struct thread_info *inferior, void *data) |
227 { | 225 { |
228 inferior->regcache_data = data; | 226 inferior->regcache_data = data; |
229 } | 227 } |
230 | 228 |
231 static void | |
232 free_one_dll (struct inferior_list_entry *inf) | |
233 { | |
234 struct dll_info *dll = get_dll (inf); | |
235 if (dll->name != NULL) | |
236 free (dll->name); | |
237 free (dll); | |
238 } | |
239 | |
240 /* Find a DLL with the same name and/or base address. A NULL name in | |
241 the key is ignored; so is an all-ones base address. */ | |
242 | |
243 static int | |
244 match_dll (struct inferior_list_entry *inf, void *arg) | |
245 { | |
246 struct dll_info *iter = (void *) inf; | |
247 struct dll_info *key = arg; | |
248 | |
249 if (key->base_addr != ~(CORE_ADDR) 0 | |
250 && iter->base_addr == key->base_addr) | |
251 return 1; | |
252 else if (key->name != NULL | |
253 && iter->name != NULL | |
254 && strcmp (key->name, iter->name) == 0) | |
255 return 1; | |
256 | |
257 return 0; | |
258 } | |
259 | |
260 /* Record a newly loaded DLL at BASE_ADDR. */ | |
261 | |
262 void | |
263 loaded_dll (const char *name, CORE_ADDR base_addr) | |
264 { | |
265 struct dll_info *new_dll = xmalloc (sizeof (*new_dll)); | |
266 memset (new_dll, 0, sizeof (*new_dll)); | |
267 | |
268 new_dll->entry.id = minus_one_ptid; | |
269 | |
270 new_dll->name = xstrdup (name); | |
271 new_dll->base_addr = base_addr; | |
272 | |
273 add_inferior_to_list (&all_dlls, &new_dll->entry); | |
274 dlls_changed = 1; | |
275 } | |
276 | |
277 /* Record that the DLL with NAME and BASE_ADDR has been unloaded. */ | |
278 | |
279 void | |
280 unloaded_dll (const char *name, CORE_ADDR base_addr) | |
281 { | |
282 struct dll_info *dll; | |
283 struct dll_info key_dll; | |
284 | |
285 /* Be careful not to put the key DLL in any list. */ | |
286 key_dll.name = (char *) name; | |
287 key_dll.base_addr = base_addr; | |
288 | |
289 dll = (void *) find_inferior (&all_dlls, match_dll, &key_dll); | |
290 | |
291 if (dll == NULL) | |
292 /* For some inferiors we might get unloaded_dll events without having | |
293 a corresponding loaded_dll. In that case, the dll cannot be found | |
294 in ALL_DLL, and there is nothing further for us to do. | |
295 | |
296 This has been observed when running 32bit executables on Windows64 | |
297 (i.e. through WOW64, the interface between the 32bits and 64bits | |
298 worlds). In that case, the inferior always does some strange | |
299 unloading of unnamed dll. */ | |
300 return; | |
301 else | |
302 { | |
303 /* DLL has been found so remove the entry and free associated | |
304 resources. */ | |
305 remove_inferior (&all_dlls, &dll->entry); | |
306 free_one_dll (&dll->entry); | |
307 dlls_changed = 1; | |
308 } | |
309 } | |
310 | |
311 #define clear_list(LIST) \ | 229 #define clear_list(LIST) \ |
312 do { (LIST)->head = (LIST)->tail = NULL; } while (0) | 230 do { (LIST)->head = (LIST)->tail = NULL; } while (0) |
313 | 231 |
314 void | 232 void |
315 clear_inferiors (void) | 233 clear_inferiors (void) |
316 { | 234 { |
317 for_each_inferior (&all_threads, free_one_thread); | 235 for_each_inferior (&all_threads, free_one_thread); |
318 for_each_inferior (&all_dlls, free_one_dll); | 236 clear_list (&all_threads); |
319 | 237 |
320 clear_list (&all_threads); | 238 clear_dlls (); |
321 clear_list (&all_dlls); | |
322 | 239 |
323 current_inferior = NULL; | 240 current_inferior = NULL; |
324 } | 241 } |
325 | 242 |
326 /* Two utility functions for a truly degenerate inferior_list: a simple | |
327 PID listing. */ | |
328 | |
329 void | |
330 add_pid_to_list (struct inferior_list *list, unsigned long pid) | |
331 { | |
332 struct inferior_list_entry *new_entry; | |
333 | |
334 new_entry = xmalloc (sizeof (struct inferior_list_entry)); | |
335 new_entry->id = pid_to_ptid (pid); | |
336 add_inferior_to_list (list, new_entry); | |
337 } | |
338 | |
339 int | |
340 pull_pid_from_list (struct inferior_list *list, unsigned long pid) | |
341 { | |
342 struct inferior_list_entry *new_entry; | |
343 | |
344 new_entry = find_inferior_id (list, pid_to_ptid (pid)); | |
345 if (new_entry == NULL) | |
346 return 0; | |
347 else | |
348 { | |
349 remove_inferior (list, new_entry); | |
350 free (new_entry); | |
351 return 1; | |
352 } | |
353 } | |
354 | |
355 struct process_info * | 243 struct process_info * |
356 add_process (int pid, int attached) | 244 add_process (int pid, int attached) |
357 { | 245 { |
358 struct process_info *process; | 246 struct process_info *process; |
359 | 247 |
360 process = xcalloc (1, sizeof (*process)); | 248 process = xcalloc (1, sizeof (*process)); |
361 | 249 |
362 process->head.id = pid_to_ptid (pid); | 250 process->head.id = pid_to_ptid (pid); |
363 process->attached = attached; | 251 process->attached = attached; |
364 | 252 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 } | 323 } |
436 | 324 |
437 struct process_info * | 325 struct process_info * |
438 current_process (void) | 326 current_process (void) |
439 { | 327 { |
440 if (current_inferior == NULL) | 328 if (current_inferior == NULL) |
441 fatal ("Current inferior requested, but current_inferior is NULL\n"); | 329 fatal ("Current inferior requested, but current_inferior is NULL\n"); |
442 | 330 |
443 return get_thread_process (current_inferior); | 331 return get_thread_process (current_inferior); |
444 } | 332 } |
OLD | NEW |