sim-module.c revision 1.1.1.2 1 /* Module support.
2
3 Copyright 1996-2015 Free Software Foundation, Inc.
4
5 Contributed by Cygnus Support.
6
7 This file is part of GDB, the GNU debugger.
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 "sim-main.h"
23 #include "sim-io.h"
24 #include "sim-options.h"
25 #include "sim-assert.h"
26
27 #if WITH_HW
28 #include "sim-hw.h"
29 #endif
30
31 #include "libiberty.h"
32
33 /* List of all modules. */
34 static MODULE_INSTALL_FN * const modules[] = {
35 standard_install,
36 sim_events_install,
37 #ifdef SIM_HAVE_MODEL
38 sim_model_install,
39 #endif
40 #if WITH_ENGINE
41 sim_engine_install,
42 #endif
43 #if WITH_TRACE
44 trace_install,
45 #endif
46 #if WITH_PROFILE
47 profile_install,
48 #endif
49 sim_core_install,
50 #ifndef SIM_HAVE_FLATMEM
51 /* FIXME: should handle flatmem as well FLATMEM */
52 sim_memopt_install,
53 #endif
54 #if WITH_WATCHPOINTS
55 sim_watchpoint_install,
56 #endif
57 #if WITH_SCACHE
58 scache_install,
59 #endif
60 #if WITH_HW
61 sim_hw_install,
62 #endif
63 /* Configured in [simulator specific] additional modules. */
64 #ifdef MODULE_LIST
65 MODULE_LIST
66 #endif
67 0
68 };
69
70 /* Functions called from sim_open. */
72
73 /* Initialize common parts before argument processing. */
74
75 SIM_RC
76 sim_pre_argv_init (SIM_DESC sd, const char *myname)
77 {
78 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
79 SIM_ASSERT (STATE_MODULES (sd) == NULL);
80
81 STATE_MY_NAME (sd) = myname + strlen (myname);
82 while (STATE_MY_NAME (sd) > myname && STATE_MY_NAME (sd)[-1] != '/')
83 --STATE_MY_NAME (sd);
84
85 /* Set the cpu names to default values. */
86 {
87 int i;
88 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
89 {
90 char *name;
91 if (asprintf (&name, "cpu%d", i) < 0)
92 return SIM_RC_FAIL;
93 CPU_NAME (STATE_CPU (sd, i)) = name;
94 }
95 }
96
97 sim_config_default (sd);
98
99 /* Install all configured in modules. */
100 if (sim_module_install (sd) != SIM_RC_OK)
101 return SIM_RC_FAIL;
102
103 return SIM_RC_OK;
104 }
105
106 /* Initialize common parts after argument processing. */
107
108 SIM_RC
109 sim_post_argv_init (SIM_DESC sd)
110 {
111 int i;
112 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
113 SIM_ASSERT (STATE_MODULES (sd) != NULL);
114
115 /* Set the cpu->state backlinks for each cpu. */
116 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
117 {
118 CPU_STATE (STATE_CPU (sd, i)) = sd;
119 CPU_INDEX (STATE_CPU (sd, i)) = i;
120 }
121
122 if (sim_module_init (sd) != SIM_RC_OK)
123 return SIM_RC_FAIL;
124
125 return SIM_RC_OK;
126 }
127
128 /* Install all modules.
130 If this fails, no modules are left installed. */
131
132 SIM_RC
133 sim_module_install (SIM_DESC sd)
134 {
135 MODULE_INSTALL_FN * const *modp;
136
137 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
138 SIM_ASSERT (STATE_MODULES (sd) == NULL);
139
140 STATE_MODULES (sd) = ZALLOC (struct module_list);
141 for (modp = modules; *modp != NULL; ++modp)
142 {
143 if ((*modp) (sd) != SIM_RC_OK)
144 {
145 sim_module_uninstall (sd);
146 SIM_ASSERT (STATE_MODULES (sd) == NULL);
147 return SIM_RC_FAIL;
148 }
149 }
150 return SIM_RC_OK;
151 }
152
153 /* Called after all modules have been installed and after argv
154 has been processed. */
155
156 SIM_RC
157 sim_module_init (SIM_DESC sd)
158 {
159 struct module_list *modules = STATE_MODULES (sd);
160 MODULE_INIT_LIST *modp;
161
162 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
163 SIM_ASSERT (STATE_MODULES (sd) != NULL);
164
165 for (modp = modules->init_list; modp != NULL; modp = modp->next)
166 {
167 if ((*modp->fn) (sd) != SIM_RC_OK)
168 return SIM_RC_FAIL;
169 }
170 return SIM_RC_OK;
171 }
172
173 /* Called when ever the simulator is resumed */
174
175 SIM_RC
176 sim_module_resume (SIM_DESC sd)
177 {
178 struct module_list *modules = STATE_MODULES (sd);
179 MODULE_RESUME_LIST *modp;
180
181 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
182 SIM_ASSERT (STATE_MODULES (sd) != NULL);
183
184 for (modp = modules->resume_list; modp != NULL; modp = modp->next)
185 {
186 if ((*modp->fn) (sd) != SIM_RC_OK)
187 return SIM_RC_FAIL;
188 }
189 return SIM_RC_OK;
190 }
191
192 /* Called when ever the simulator is suspended */
193
194 SIM_RC
195 sim_module_suspend (SIM_DESC sd)
196 {
197 struct module_list *modules = STATE_MODULES (sd);
198 MODULE_SUSPEND_LIST *modp;
199
200 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
201 SIM_ASSERT (STATE_MODULES (sd) != NULL);
202
203 for (modp = modules->suspend_list; modp != NULL; modp = modp->next)
204 {
205 if ((*modp->fn) (sd) != SIM_RC_OK)
206 return SIM_RC_FAIL;
207 }
208 return SIM_RC_OK;
209 }
210
211 /* Uninstall installed modules, called by sim_close. */
212
213 void
214 sim_module_uninstall (SIM_DESC sd)
215 {
216 struct module_list *modules = STATE_MODULES (sd);
217 MODULE_UNINSTALL_LIST *modp;
218
219 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
220 SIM_ASSERT (STATE_MODULES (sd) != NULL);
221
222 /* Uninstall the modules. */
223 for (modp = modules->uninstall_list; modp != NULL; modp = modp->next)
224 (*modp->fn) (sd);
225
226 /* clean-up init list */
227 {
228 MODULE_INIT_LIST *n, *d;
229 for (d = modules->init_list; d != NULL; d = n)
230 {
231 n = d->next;
232 free (d);
233 }
234 }
235
236 /* clean-up resume list */
237 {
238 MODULE_RESUME_LIST *n, *d;
239 for (d = modules->resume_list; d != NULL; d = n)
240 {
241 n = d->next;
242 free (d);
243 }
244 }
245
246 /* clean-up suspend list */
247 {
248 MODULE_SUSPEND_LIST *n, *d;
249 for (d = modules->suspend_list; d != NULL; d = n)
250 {
251 n = d->next;
252 free (d);
253 }
254 }
255
256 /* clean-up uninstall list */
257 {
258 MODULE_UNINSTALL_LIST *n, *d;
259 for (d = modules->uninstall_list; d != NULL; d = n)
260 {
261 n = d->next;
262 free (d);
263 }
264 }
265
266 /* clean-up info list */
267 {
268 MODULE_INFO_LIST *n, *d;
269 for (d = modules->info_list; d != NULL; d = n)
270 {
271 n = d->next;
272 free (d);
273 }
274 }
275
276 free (modules);
277 STATE_MODULES (sd) = NULL;
278 }
279
280 /* Called when ever simulator info is needed */
281
282 void
283 sim_module_info (SIM_DESC sd, int verbose)
284 {
285 struct module_list *modules = STATE_MODULES (sd);
286 MODULE_INFO_LIST *modp;
287
288 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
289 SIM_ASSERT (STATE_MODULES (sd) != NULL);
290
291 for (modp = modules->info_list; modp != NULL; modp = modp->next)
292 {
293 (*modp->fn) (sd, verbose);
294 }
295 }
296
297 /* Add FN to the init handler list.
299 init in the same order as the install. */
300
301 void
302 sim_module_add_init_fn (SIM_DESC sd, MODULE_INIT_FN fn)
303 {
304 struct module_list *modules = STATE_MODULES (sd);
305 MODULE_INIT_LIST *l = ZALLOC (MODULE_INIT_LIST);
306 MODULE_INIT_LIST **last;
307
308 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
309 SIM_ASSERT (STATE_MODULES (sd) != NULL);
310
311 last = &modules->init_list;
312 while (*last != NULL)
313 last = &((*last)->next);
314
315 l->fn = fn;
316 l->next = NULL;
317 *last = l;
318 }
319
320 /* Add FN to the resume handler list.
321 resume in the same order as the install. */
322
323 void
324 sim_module_add_resume_fn (SIM_DESC sd, MODULE_RESUME_FN fn)
325 {
326 struct module_list *modules = STATE_MODULES (sd);
327 MODULE_RESUME_LIST *l = ZALLOC (MODULE_RESUME_LIST);
328 MODULE_RESUME_LIST **last;
329
330 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
331 SIM_ASSERT (STATE_MODULES (sd) != NULL);
332
333 last = &modules->resume_list;
334 while (*last != NULL)
335 last = &((*last)->next);
336
337 l->fn = fn;
338 l->next = NULL;
339 *last = l;
340 }
341
342 /* Add FN to the init handler list.
343 suspend in the reverse order to install. */
344
345 void
346 sim_module_add_suspend_fn (SIM_DESC sd, MODULE_SUSPEND_FN fn)
347 {
348 struct module_list *modules = STATE_MODULES (sd);
349 MODULE_SUSPEND_LIST *l = ZALLOC (MODULE_SUSPEND_LIST);
350 MODULE_SUSPEND_LIST **last;
351
352 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
353 SIM_ASSERT (STATE_MODULES (sd) != NULL);
354
355 last = &modules->suspend_list;
356 while (*last != NULL)
357 last = &((*last)->next);
358
359 l->fn = fn;
360 l->next = modules->suspend_list;
361 modules->suspend_list = l;
362 }
363
364 /* Add FN to the uninstall handler list.
365 Uninstall in reverse order to install. */
366
367 void
368 sim_module_add_uninstall_fn (SIM_DESC sd, MODULE_UNINSTALL_FN fn)
369 {
370 struct module_list *modules = STATE_MODULES (sd);
371 MODULE_UNINSTALL_LIST *l = ZALLOC (MODULE_UNINSTALL_LIST);
372
373 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
374 SIM_ASSERT (STATE_MODULES (sd) != NULL);
375
376 l->fn = fn;
377 l->next = modules->uninstall_list;
378 modules->uninstall_list = l;
379 }
380
381 /* Add FN to the info handler list.
382 Report info in the same order as the install. */
383
384 void
385 sim_module_add_info_fn (SIM_DESC sd, MODULE_INFO_FN fn)
386 {
387 struct module_list *modules = STATE_MODULES (sd);
388 MODULE_INFO_LIST *l = ZALLOC (MODULE_INFO_LIST);
389 MODULE_INFO_LIST **last;
390
391 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
392 SIM_ASSERT (STATE_MODULES (sd) != NULL);
393
394 last = &modules->info_list;
395 while (*last != NULL)
396 last = &((*last)->next);
397
398 l->fn = fn;
399 l->next = NULL;
400 *last = l;
401 }
402