Commit | Line | Data |
---|---|---|
bf4c19f7 YQ |
1 | /* Copyright (C) 2002, 2005, 2007-2012 Free Software Foundation, Inc. |
2 | ||
3 | This file is part of GDB. | |
4 | ||
5 | This program is free software; you can redistribute it and/or modify | |
6 | it under the terms of the GNU General Public License as published by | |
7 | the Free Software Foundation; either version 3 of the License, or | |
8 | (at your option) any later version. | |
9 | ||
10 | This program is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | GNU General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU General Public License | |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
17 | ||
18 | #include "server.h" | |
19 | ||
20 | #define get_dll(inf) ((struct dll_info *)(inf)) | |
21 | ||
22 | struct inferior_list all_dlls; | |
23 | int dlls_changed; | |
24 | ||
25 | static void | |
26 | free_one_dll (struct inferior_list_entry *inf) | |
27 | { | |
28 | struct dll_info *dll = get_dll (inf); | |
29 | if (dll->name != NULL) | |
30 | free (dll->name); | |
31 | free (dll); | |
32 | } | |
33 | ||
34 | /* Find a DLL with the same name and/or base address. A NULL name in | |
35 | the key is ignored; so is an all-ones base address. */ | |
36 | ||
37 | static int | |
38 | match_dll (struct inferior_list_entry *inf, void *arg) | |
39 | { | |
40 | struct dll_info *iter = (void *) inf; | |
41 | struct dll_info *key = arg; | |
42 | ||
43 | if (key->base_addr != ~(CORE_ADDR) 0 | |
44 | && iter->base_addr == key->base_addr) | |
45 | return 1; | |
46 | else if (key->name != NULL | |
47 | && iter->name != NULL | |
48 | && strcmp (key->name, iter->name) == 0) | |
49 | return 1; | |
50 | ||
51 | return 0; | |
52 | } | |
53 | ||
54 | /* Record a newly loaded DLL at BASE_ADDR. */ | |
55 | ||
56 | void | |
57 | loaded_dll (const char *name, CORE_ADDR base_addr) | |
58 | { | |
59 | struct dll_info *new_dll = xmalloc (sizeof (*new_dll)); | |
60 | memset (new_dll, 0, sizeof (*new_dll)); | |
61 | ||
62 | new_dll->entry.id = minus_one_ptid; | |
63 | ||
64 | new_dll->name = xstrdup (name); | |
65 | new_dll->base_addr = base_addr; | |
66 | ||
67 | add_inferior_to_list (&all_dlls, &new_dll->entry); | |
68 | dlls_changed = 1; | |
69 | } | |
70 | ||
71 | /* Record that the DLL with NAME and BASE_ADDR has been unloaded. */ | |
72 | ||
73 | void | |
74 | unloaded_dll (const char *name, CORE_ADDR base_addr) | |
75 | { | |
76 | struct dll_info *dll; | |
77 | struct dll_info key_dll; | |
78 | ||
79 | /* Be careful not to put the key DLL in any list. */ | |
80 | key_dll.name = (char *) name; | |
81 | key_dll.base_addr = base_addr; | |
82 | ||
83 | dll = (void *) find_inferior (&all_dlls, match_dll, &key_dll); | |
84 | ||
85 | if (dll == NULL) | |
86 | /* For some inferiors we might get unloaded_dll events without having | |
87 | a corresponding loaded_dll. In that case, the dll cannot be found | |
88 | in ALL_DLL, and there is nothing further for us to do. | |
89 | ||
90 | This has been observed when running 32bit executables on Windows64 | |
91 | (i.e. through WOW64, the interface between the 32bits and 64bits | |
92 | worlds). In that case, the inferior always does some strange | |
93 | unloading of unnamed dll. */ | |
94 | return; | |
95 | else | |
96 | { | |
97 | /* DLL has been found so remove the entry and free associated | |
98 | resources. */ | |
99 | remove_inferior (&all_dlls, &dll->entry); | |
100 | free_one_dll (&dll->entry); | |
101 | dlls_changed = 1; | |
102 | } | |
103 | } | |
104 | ||
105 | void | |
106 | clear_dlls (void) | |
107 | { | |
108 | for_each_inferior (&all_dlls, free_one_dll); | |
109 | all_dlls.head = all_dlls.tail = NULL; | |
110 | } |