[2/4] sim: add framework for declaring init callbacks locally

Message ID 20210424170909.5412-2-vapier@gentoo.org
State New
Headers show
Series
  • [1/4] sim: arm: move build logic to source files
Related show

Commit Message

Wei-min Pan via Gdb-patches April 24, 2021, 5:09 p.m.
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.
---
 sim/common/ChangeLog      | 14 +++++++++++
 sim/common/Make-common.in | 24 +++++++++++++++++-
 sim/common/sim-module.c   | 51 +++++++++++++++++++++++++++------------
 sim/common/sim-module.h   |  1 +
 4 files changed, 74 insertions(+), 16 deletions(-)

-- 
2.30.2

Patch

diff --git a/sim/common/ChangeLog b/sim/common/ChangeLog
index 516e214f0112..7ccaabf1cb11 100644
--- a/sim/common/ChangeLog
+++ b/sim/common/ChangeLog
@@ -1,3 +1,17 @@ 
+2021-04-24  Mike Frysinger  <vapier@gentoo.org>
+
+	* 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-04-24  Mike Frysinger  <vapier@gentoo.org>
 
 	* dv-cfi.c (attach_cfi_regs): Change %u to PRIiTC.
diff --git a/sim/common/Make-common.in b/sim/common/Make-common.in
index c73801443049..0f8774905098 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 ea436902439a..e508826922f0 100644
--- a/sim/common/sim-module.c
+++ b/sim/common/sim-module.c
@@ -38,8 +38,9 @@  along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <stdlib.h>
 
-/* 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 (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 38c34c284682..dad557194318 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);