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