Home | History | Annotate | Line # | Download | only in common
sim-module.c revision 1.1.1.9
      1 /* Module support.
      2 
      3    Copyright 1996-2024 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 /* This must come before any other includes.  */
     23 #include "defs.h"
     24 
     25 #include <stdlib.h>
     26 
     27 #include "libiberty.h"
     28 
     29 #include "sim-main.h"
     30 #include "sim-io.h"
     31 #include "sim-options.h"
     32 #include "sim-assert.h"
     33 
     34 /* List of all early/core modules.
     35    TODO: Should trim this list by converting to sim_install_* framework.  */
     36 static MODULE_INSTALL_FN * const early_modules[] = {
     37   standard_install,
     38   sim_events_install,
     39   sim_model_install,
     40   sim_core_install,
     41   sim_memopt_install,
     42   sim_watchpoint_install,
     43 };
     44 static int early_modules_len = ARRAY_SIZE (early_modules);
     45 
     46 /* List of dynamically detected modules.  Declared in generated modules.c.  */
     47 extern MODULE_INSTALL_FN * const sim_modules_detected[];
     48 extern const int sim_modules_detected_len;
     49 
     50 /* Functions called from sim_open.  */
     52 
     53 /* Initialize common parts before argument processing.  */
     54 
     55 SIM_RC
     56 sim_pre_argv_init (SIM_DESC sd, const char *myname)
     57 {
     58   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
     59   SIM_ASSERT (STATE_MODULES (sd) == NULL);
     60 
     61   STATE_MY_NAME (sd) = lbasename (myname);
     62 
     63   /* Set the cpu names to default values.  */
     64   {
     65     int i;
     66     for (i = 0; i < MAX_NR_PROCESSORS; ++i)
     67       {
     68 	char *name;
     69 	if (asprintf (&name, "cpu%d", i) < 0)
     70 	  return SIM_RC_FAIL;
     71 	CPU_NAME (STATE_CPU (sd, i)) = name;
     72       }
     73   }
     74 
     75   sim_config_default (sd);
     76 
     77   /* Install all early configured-in modules.  */
     78   if (sim_module_install (sd) != SIM_RC_OK)
     79     return SIM_RC_FAIL;
     80 
     81   /* Install all remaining dynamically detected modules.  */
     82   return sim_module_install_list (sd, sim_modules_detected,
     83 				  sim_modules_detected_len);
     84 }
     85 
     86 /* Initialize common parts after argument processing.  */
     87 
     88 SIM_RC
     89 sim_post_argv_init (SIM_DESC sd)
     90 {
     91   int i;
     92   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
     93   SIM_ASSERT (STATE_MODULES (sd) != NULL);
     94 
     95   /* Set the cpu->state backlinks for each cpu.  */
     96   for (i = 0; i < MAX_NR_PROCESSORS; ++i)
     97     {
     98       CPU_STATE (STATE_CPU (sd, i)) = sd;
     99       CPU_INDEX (STATE_CPU (sd, i)) = i;
    100     }
    101 
    102   if (sim_module_init (sd) != SIM_RC_OK)
    103     return SIM_RC_FAIL;
    104 
    105   return SIM_RC_OK;
    106 }
    107 
    108 /* Install a list of modules.
    110    If this fails, no modules are left installed.  */
    111 SIM_RC
    112 sim_module_install_list (SIM_DESC sd, MODULE_INSTALL_FN * const *modules,
    113 			 size_t modules_len)
    114 {
    115   size_t i;
    116 
    117   for (i = 0; i < modules_len; ++i)
    118     {
    119       MODULE_INSTALL_FN *modp = modules[i];
    120 
    121       if (modp != NULL && modp (sd) != SIM_RC_OK)
    122 	{
    123 	  sim_module_uninstall (sd);
    124 	  SIM_ASSERT (STATE_MODULES (sd) == NULL);
    125 	  return SIM_RC_FAIL;
    126 	}
    127     }
    128 
    129   return SIM_RC_OK;
    130 }
    131 
    132 /* Install all modules.
    133    If this fails, no modules are left installed.  */
    134 
    135 SIM_RC
    136 sim_module_install (SIM_DESC sd)
    137 {
    138   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
    139   SIM_ASSERT (STATE_MODULES (sd) == NULL);
    140 
    141   STATE_MODULES (sd) = ZALLOC (struct module_list);
    142   return sim_module_install_list (sd, early_modules, early_modules_len);
    143 }
    144 
    145 /* Called after all modules have been installed and after argv
    146    has been processed.  */
    147 
    148 SIM_RC
    149 sim_module_init (SIM_DESC sd)
    150 {
    151   struct module_list *modules = STATE_MODULES (sd);
    152   MODULE_INIT_LIST *modp;
    153 
    154   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
    155   SIM_ASSERT (STATE_MODULES (sd) != NULL);
    156 
    157   for (modp = modules->init_list; modp != NULL; modp = modp->next)
    158     {
    159       if ((*modp->fn) (sd) != SIM_RC_OK)
    160 	return SIM_RC_FAIL;
    161     }
    162   return SIM_RC_OK;
    163 }
    164 
    165 /* Called when ever the simulator is resumed */
    166 
    167 SIM_RC
    168 sim_module_resume (SIM_DESC sd)
    169 {
    170   struct module_list *modules = STATE_MODULES (sd);
    171   MODULE_RESUME_LIST *modp;
    172 
    173   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
    174   SIM_ASSERT (STATE_MODULES (sd) != NULL);
    175 
    176   for (modp = modules->resume_list; modp != NULL; modp = modp->next)
    177     {
    178       if ((*modp->fn) (sd) != SIM_RC_OK)
    179 	return SIM_RC_FAIL;
    180     }
    181   return SIM_RC_OK;
    182 }
    183 
    184 /* Called when ever the simulator is suspended */
    185 
    186 SIM_RC
    187 sim_module_suspend (SIM_DESC sd)
    188 {
    189   struct module_list *modules = STATE_MODULES (sd);
    190   MODULE_SUSPEND_LIST *modp;
    191 
    192   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
    193   SIM_ASSERT (STATE_MODULES (sd) != NULL);
    194 
    195   for (modp = modules->suspend_list; modp != NULL; modp = modp->next)
    196     {
    197       if ((*modp->fn) (sd) != SIM_RC_OK)
    198 	return SIM_RC_FAIL;
    199     }
    200   return SIM_RC_OK;
    201 }
    202 
    203 /* Uninstall installed modules, called by sim_close.  */
    204 
    205 void
    206 sim_module_uninstall (SIM_DESC sd)
    207 {
    208   struct module_list *modules = STATE_MODULES (sd);
    209   MODULE_UNINSTALL_LIST *modp;
    210 
    211   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
    212   SIM_ASSERT (STATE_MODULES (sd) != NULL);
    213 
    214   /* Uninstall the modules.  */
    215   for (modp = modules->uninstall_list; modp != NULL; modp = modp->next)
    216     (*modp->fn) (sd);
    217 
    218   /* clean-up init list */
    219   {
    220     MODULE_INIT_LIST *n, *d;
    221     for (d = modules->init_list; d != NULL; d = n)
    222       {
    223 	n = d->next;
    224 	free (d);
    225       }
    226   }
    227 
    228   /* clean-up resume list */
    229   {
    230     MODULE_RESUME_LIST *n, *d;
    231     for (d = modules->resume_list; d != NULL; d = n)
    232       {
    233 	n = d->next;
    234 	free (d);
    235       }
    236   }
    237 
    238   /* clean-up suspend list */
    239   {
    240     MODULE_SUSPEND_LIST *n, *d;
    241     for (d = modules->suspend_list; d != NULL; d = n)
    242       {
    243 	n = d->next;
    244 	free (d);
    245       }
    246   }
    247 
    248   /* clean-up uninstall list */
    249   {
    250     MODULE_UNINSTALL_LIST *n, *d;
    251     for (d = modules->uninstall_list; d != NULL; d = n)
    252       {
    253 	n = d->next;
    254 	free (d);
    255       }
    256   }
    257 
    258   /* clean-up info list */
    259   {
    260     MODULE_INFO_LIST *n, *d;
    261     for (d = modules->info_list; d != NULL; d = n)
    262       {
    263 	n = d->next;
    264 	free (d);
    265       }
    266   }
    267 
    268   free (modules);
    269   STATE_MODULES (sd) = NULL;
    270 }
    271 
    272 /* Called when ever simulator info is needed */
    273 
    274 void
    275 sim_module_info (SIM_DESC sd, bool verbose)
    276 {
    277   struct module_list *modules = STATE_MODULES (sd);
    278   MODULE_INFO_LIST *modp;
    279 
    280   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
    281   SIM_ASSERT (STATE_MODULES (sd) != NULL);
    282 
    283   for (modp = modules->info_list; modp != NULL; modp = modp->next)
    284     {
    285       (*modp->fn) (sd, verbose);
    286     }
    287 }
    288 
    289 /* 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