1/* Module support. 2 3 Copyright 1996, 1997, 1998, 2003, 2007, 2008, 2009, 2010, 2011 4 Free Software Foundation, Inc. 5 6 Contributed by Cygnus Support. 7 8This file is part of GDB, the GNU debugger. 9 10This program is free software; you can redistribute it and/or modify 11it under the terms of the GNU General Public License as published by 12the Free Software Foundation; either version 3 of the License, or 13(at your option) any later version. 14 15This program is distributed in the hope that it will be useful, 16but WITHOUT ANY WARRANTY; without even the implied warranty of 17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18GNU General Public License for more details. 19 20You should have received a copy of the GNU General Public License 21along with this program. If not, see <http://www.gnu.org/licenses/>. */ 22 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#include "libiberty.h" 33 34/* List of all modules. */ 35static MODULE_INSTALL_FN * const modules[] = { 36 standard_install, 37 sim_events_install, 38#ifdef SIM_HAVE_MODEL 39 sim_model_install, 40#endif 41#if WITH_ENGINE 42 sim_engine_install, 43#endif 44#if WITH_TRACE 45 trace_install, 46#endif 47#if WITH_PROFILE 48 profile_install, 49#endif 50 sim_core_install, 51#ifndef SIM_HAVE_FLATMEM 52 /* FIXME: should handle flatmem as well FLATMEM */ 53 sim_memopt_install, 54#endif 55#if WITH_WATCHPOINTS 56 sim_watchpoint_install, 57#endif 58#if WITH_SCACHE 59 scache_install, 60#endif 61#if WITH_HW 62 sim_hw_install, 63#endif 64 /* Configured in [simulator specific] additional modules. */ 65#ifdef MODULE_LIST 66 MODULE_LIST 67#endif 68 0 69}; 70 71/* Functions called from sim_open. */ 72 73/* Initialize common parts before argument processing. */ 74 75SIM_RC 76sim_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 108SIM_RC 109sim_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. 129 If this fails, no modules are left installed. */ 130 131SIM_RC 132sim_module_install (SIM_DESC sd) 133{ 134 MODULE_INSTALL_FN * const *modp; 135 136 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 137 SIM_ASSERT (STATE_MODULES (sd) == NULL); 138 139 STATE_MODULES (sd) = ZALLOC (struct module_list); 140 for (modp = modules; *modp != NULL; ++modp) 141 { 142 if ((*modp) (sd) != SIM_RC_OK) 143 { 144 sim_module_uninstall (sd); 145 SIM_ASSERT (STATE_MODULES (sd) == NULL); 146 return SIM_RC_FAIL; 147 } 148 } 149 return SIM_RC_OK; 150} 151 152/* Called after all modules have been installed and after argv 153 has been processed. */ 154 155SIM_RC 156sim_module_init (SIM_DESC sd) 157{ 158 struct module_list *modules = STATE_MODULES (sd); 159 MODULE_INIT_LIST *modp; 160 161 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 162 SIM_ASSERT (STATE_MODULES (sd) != NULL); 163 164 for (modp = modules->init_list; modp != NULL; modp = modp->next) 165 { 166 if ((*modp->fn) (sd) != SIM_RC_OK) 167 return SIM_RC_FAIL; 168 } 169 return SIM_RC_OK; 170} 171 172/* Called when ever the simulator is resumed */ 173 174SIM_RC 175sim_module_resume (SIM_DESC sd) 176{ 177 struct module_list *modules = STATE_MODULES (sd); 178 MODULE_RESUME_LIST *modp; 179 180 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 181 SIM_ASSERT (STATE_MODULES (sd) != NULL); 182 183 for (modp = modules->resume_list; modp != NULL; modp = modp->next) 184 { 185 if ((*modp->fn) (sd) != SIM_RC_OK) 186 return SIM_RC_FAIL; 187 } 188 return SIM_RC_OK; 189} 190 191/* Called when ever the simulator is suspended */ 192 193SIM_RC 194sim_module_suspend (SIM_DESC sd) 195{ 196 struct module_list *modules = STATE_MODULES (sd); 197 MODULE_SUSPEND_LIST *modp; 198 199 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 200 SIM_ASSERT (STATE_MODULES (sd) != NULL); 201 202 for (modp = modules->suspend_list; modp != NULL; modp = modp->next) 203 { 204 if ((*modp->fn) (sd) != SIM_RC_OK) 205 return SIM_RC_FAIL; 206 } 207 return SIM_RC_OK; 208} 209 210/* Uninstall installed modules, called by sim_close. */ 211 212void 213sim_module_uninstall (SIM_DESC sd) 214{ 215 struct module_list *modules = STATE_MODULES (sd); 216 MODULE_UNINSTALL_LIST *modp; 217 218 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 219 SIM_ASSERT (STATE_MODULES (sd) != NULL); 220 221 /* Uninstall the modules. */ 222 for (modp = modules->uninstall_list; modp != NULL; modp = modp->next) 223 (*modp->fn) (sd); 224 225 /* clean-up init list */ 226 { 227 MODULE_INIT_LIST *n, *d; 228 for (d = modules->init_list; d != NULL; d = n) 229 { 230 n = d->next; 231 free (d); 232 } 233 } 234 235 /* clean-up resume list */ 236 { 237 MODULE_RESUME_LIST *n, *d; 238 for (d = modules->resume_list; d != NULL; d = n) 239 { 240 n = d->next; 241 free (d); 242 } 243 } 244 245 /* clean-up suspend list */ 246 { 247 MODULE_SUSPEND_LIST *n, *d; 248 for (d = modules->suspend_list; d != NULL; d = n) 249 { 250 n = d->next; 251 free (d); 252 } 253 } 254 255 /* clean-up uninstall list */ 256 { 257 MODULE_UNINSTALL_LIST *n, *d; 258 for (d = modules->uninstall_list; d != NULL; d = n) 259 { 260 n = d->next; 261 free (d); 262 } 263 } 264 265 /* clean-up info list */ 266 { 267 MODULE_INFO_LIST *n, *d; 268 for (d = modules->info_list; d != NULL; d = n) 269 { 270 n = d->next; 271 free (d); 272 } 273 } 274 275 free (modules); 276 STATE_MODULES (sd) = NULL; 277} 278 279/* Called when ever simulator info is needed */ 280 281void 282sim_module_info (SIM_DESC sd, int verbose) 283{ 284 struct module_list *modules = STATE_MODULES (sd); 285 MODULE_INFO_LIST *modp; 286 287 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 288 SIM_ASSERT (STATE_MODULES (sd) != NULL); 289 290 for (modp = modules->info_list; modp != NULL; modp = modp->next) 291 { 292 (*modp->fn) (sd, verbose); 293 } 294} 295 296/* Add FN to the init handler list. 297 init in the same order as the install. */ 298 299void 300sim_module_add_init_fn (SIM_DESC sd, MODULE_INIT_FN fn) 301{ 302 struct module_list *modules = STATE_MODULES (sd); 303 MODULE_INIT_LIST *l = ZALLOC (MODULE_INIT_LIST); 304 MODULE_INIT_LIST **last; 305 306 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 307 SIM_ASSERT (STATE_MODULES (sd) != NULL); 308 309 last = &modules->init_list; 310 while (*last != NULL) 311 last = &((*last)->next); 312 313 l->fn = fn; 314 l->next = NULL; 315 *last = l; 316} 317 318/* Add FN to the resume handler list. 319 resume in the same order as the install. */ 320 321void 322sim_module_add_resume_fn (SIM_DESC sd, MODULE_RESUME_FN fn) 323{ 324 struct module_list *modules = STATE_MODULES (sd); 325 MODULE_RESUME_LIST *l = ZALLOC (MODULE_RESUME_LIST); 326 MODULE_RESUME_LIST **last; 327 328 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 329 SIM_ASSERT (STATE_MODULES (sd) != NULL); 330 331 last = &modules->resume_list; 332 while (*last != NULL) 333 last = &((*last)->next); 334 335 l->fn = fn; 336 l->next = NULL; 337 *last = l; 338} 339 340/* Add FN to the init handler list. 341 suspend in the reverse order to install. */ 342 343void 344sim_module_add_suspend_fn (SIM_DESC sd, MODULE_SUSPEND_FN fn) 345{ 346 struct module_list *modules = STATE_MODULES (sd); 347 MODULE_SUSPEND_LIST *l = ZALLOC (MODULE_SUSPEND_LIST); 348 MODULE_SUSPEND_LIST **last; 349 350 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 351 SIM_ASSERT (STATE_MODULES (sd) != NULL); 352 353 last = &modules->suspend_list; 354 while (*last != NULL) 355 last = &((*last)->next); 356 357 l->fn = fn; 358 l->next = modules->suspend_list; 359 modules->suspend_list = l; 360} 361 362/* Add FN to the uninstall handler list. 363 Uninstall in reverse order to install. */ 364 365void 366sim_module_add_uninstall_fn (SIM_DESC sd, MODULE_UNINSTALL_FN fn) 367{ 368 struct module_list *modules = STATE_MODULES (sd); 369 MODULE_UNINSTALL_LIST *l = ZALLOC (MODULE_UNINSTALL_LIST); 370 371 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 372 SIM_ASSERT (STATE_MODULES (sd) != NULL); 373 374 l->fn = fn; 375 l->next = modules->uninstall_list; 376 modules->uninstall_list = l; 377} 378 379/* Add FN to the info handler list. 380 Report info in the same order as the install. */ 381 382void 383sim_module_add_info_fn (SIM_DESC sd, MODULE_INFO_FN fn) 384{ 385 struct module_list *modules = STATE_MODULES (sd); 386 MODULE_INFO_LIST *l = ZALLOC (MODULE_INFO_LIST); 387 MODULE_INFO_LIST **last; 388 389 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 390 SIM_ASSERT (STATE_MODULES (sd) != NULL); 391 392 last = &modules->info_list; 393 while (*last != NULL) 394 last = &((*last)->next); 395 396 l->fn = fn; 397 l->next = NULL; 398 *last = l; 399} 400