From: Mike Frysinger Date: Sat, 2 Jan 2016 15:50:46 +0000 (-0500) Subject: sim: add framework for declaring init callbacks locally X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8e5f15165784296f5b182f486817cd5945960c44;p=binutils-gdb.git sim: add framework for declaring init callbacks locally To facilitate decentralized module initialization/registration with an eye towards multi-target support, add a framework to detect init calls declared in the source and automatically call them. This is akin to gdb's _initialize_xxx framework for letting modules autodiscover. --- diff --git a/sim/common/ChangeLog b/sim/common/ChangeLog index 3983e2417cf..d00696354dd 100644 --- a/sim/common/ChangeLog +++ b/sim/common/ChangeLog @@ -1,3 +1,17 @@ +2021-05-01 Mike Frysinger + + * Make-common.in (LIB_OBJS): Add modules.o. + (generated_files): Add modules.c. + (modules.c): New target. + * sim-module.c (modules): Rename to ... + (early_modules): ... this. Delete 0 sentinel. + (early_modules_len): Define. + (sim_modules_detected, sim_modules_detected_len): Declare. + (sim_pre_argv_init): Call sim_module_install_list. + (sim_module_install): New function. + (sim_module_install_list): New function. + * sim-module.h (sim_module_install_list): Declare. + 2021-05-01 Mike Frysinger * nrun.c (strsignal): New prototype. diff --git a/sim/common/Make-common.in b/sim/common/Make-common.in index c7380144304..0f877490509 100644 --- a/sim/common/Make-common.in +++ b/sim/common/Make-common.in @@ -250,7 +250,8 @@ LIBDEPS = $(BFD_LIB) $(OPCODES_LIB) $(LIBINTL_DEP) $(LIBIBERTY_LIB) EXTRA_LIBS = $(BFD_LIB) $(OPCODES_LIB) $(LIBINTL) $(LIBIBERTY_LIB) \ $(CONFIG_LIBS) $(SIM_EXTRA_LIBS) $(LIBDL) -LIB_OBJS = callback.o syscall.o targ-map.o version.o $(SIM_OBJS) +LIB_OBJS = callback.o modules.o syscall.o targ-map.o version.o \ + $(SIM_OBJS) COMPILE_FOR_BUILD = $(CC_FOR_BUILD) $(BUILD_CFLAGS) LINK_FOR_BUILD = $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(LDFLAGS_FOR_BUILD) -o $@ @@ -420,6 +421,7 @@ all_object_files = $(LIB_OBJS) $(SIM_RUN_OBJS) generated_files = \ $(SIM_EXTRA_DEPS) \ hw-config.h \ + modules.c \ targ-map.c \ targ-vals.h \ version.c @@ -459,6 +461,26 @@ test-hw-events: $(srccom)/hw-events.c libsim.a $(CC) $(ALL_CFLAGS) -DMAIN -o test-hw-events$(EXEEXT) \ $(srccom)/hw-events.c libsim.a $(EXTRA_LIBS) +# See sim_pre_argv_init and sim_module_install in sim-module.c for more details. +modules.c: Makefile $(SIM_OBJS:.o=.c) + @echo Generating $@ + @LANG=C ; export LANG ; \ + LC_ALL=C ; export LC_ALL ; \ + sed -n -e '/^sim_install_/{s/^\(sim_install_[a-z_0-9A-Z]*\).*/\1/;p}' $^ | sort >$@.l-tmp + @set -e; (\ + echo '/* Do not modify this file. */'; \ + echo '/* It is created automatically by the Makefile. */'; \ + echo '#include "libiberty.h"'; \ + echo '#include "sim-module.h"'; \ + sed -e 's:\(.*\):extern __attribute__((__weak__)) MODULE_INIT_FN \1;:' $@.l-tmp; \ + echo 'MODULE_INSTALL_FN * const sim_modules_detected[] = {'; \ + sed -e 's:\(.*\): \1,:' $@.l-tmp; \ + echo '};'; \ + echo 'const int sim_modules_detected_len = ARRAY_SIZE (sim_modules_detected);'; \ + ) >$@.tmp + $(SHELL) $(srcroot)/move-if-change $@.tmp $@ + @rm -f $@.l-tmp $@.tmp + # CGEN support. # For use in Makefile.in for cpu-specific files. diff --git a/sim/common/sim-module.c b/sim/common/sim-module.c index ea436902439..a776a082176 100644 --- a/sim/common/sim-module.c +++ b/sim/common/sim-module.c @@ -38,8 +38,9 @@ along with this program. If not, see . */ #include -/* List of all modules. */ -static MODULE_INSTALL_FN * const modules[] = { +/* List of all early/core modules. + TODO: Should trim this list by converting to sim_install_* framework. */ +static MODULE_INSTALL_FN * const early_modules[] = { standard_install, sim_events_install, sim_model_install, @@ -63,8 +64,12 @@ static MODULE_INSTALL_FN * const modules[] = { /* TODO: Shouldn't have device models here. */ dv_sockser_install, #endif - 0 }; +static int early_modules_len = ARRAY_SIZE (early_modules); + +/* List of dynamically detected modules. Declared in generated modules.c. */ +extern MODULE_INSTALL_FN * const sim_modules_detected[]; +extern const int sim_modules_detected_len; /* Functions called from sim_open. */ @@ -92,11 +97,13 @@ sim_pre_argv_init (SIM_DESC sd, const char *myname) sim_config_default (sd); - /* Install all configured in modules. */ + /* Install all early configured-in modules. */ if (sim_module_install (sd) != SIM_RC_OK) return SIM_RC_FAIL; - return SIM_RC_OK; + /* Install all remaining dynamically detected modules. */ + return sim_module_install_list (sd, sim_modules_detected, + sim_modules_detected_len); } /* Initialize common parts after argument processing. */ @@ -121,30 +128,44 @@ sim_post_argv_init (SIM_DESC sd) return SIM_RC_OK; } -/* Install all modules. +/* Install a list of modules. If this fails, no modules are left installed. */ - SIM_RC -sim_module_install (SIM_DESC sd) +sim_module_install_list (SIM_DESC sd, MODULE_INSTALL_FN * const *modules, + size_t modules_len) { - MODULE_INSTALL_FN * const *modp; + size_t i; - SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); - SIM_ASSERT (STATE_MODULES (sd) == NULL); - - STATE_MODULES (sd) = ZALLOC (struct module_list); - for (modp = modules; *modp != NULL; ++modp) + for (i = 0; i < modules_len; ++i) { - if ((*modp) (sd) != SIM_RC_OK) + MODULE_INSTALL_FN *modp = modules[i]; + + if (modp != NULL && modp (sd) != SIM_RC_OK) { sim_module_uninstall (sd); SIM_ASSERT (STATE_MODULES (sd) == NULL); return SIM_RC_FAIL; } } + return SIM_RC_OK; } +/* Install all modules. + If this fails, no modules are left installed. */ + +SIM_RC +sim_module_install (SIM_DESC sd) +{ + MODULE_INSTALL_FN * const *modp; + + SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); + SIM_ASSERT (STATE_MODULES (sd) == NULL); + + STATE_MODULES (sd) = ZALLOC (struct module_list); + return sim_module_install_list (sd, early_modules, early_modules_len); +} + /* Called after all modules have been installed and after argv has been processed. */ diff --git a/sim/common/sim-module.h b/sim/common/sim-module.h index 38c34c28468..dad55719431 100644 --- a/sim/common/sim-module.h +++ b/sim/common/sim-module.h @@ -73,6 +73,7 @@ typedef struct module_info_list { /* Functions to register module with various handler lists */ SIM_RC sim_module_install (SIM_DESC); +SIM_RC sim_module_install_list (SIM_DESC, MODULE_INSTALL_FN * const[], size_t); void sim_module_uninstall (SIM_DESC); void sim_module_add_init_fn (SIM_DESC sd, MODULE_INIT_FN fn); void sim_module_add_resume_fn (SIM_DESC sd, MODULE_RESUME_FN fn);