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