From d90e66a024032604909d9749ba1f6c3d9180726d Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 22 Jan 2017 11:37:49 -0600 Subject: [PATCH] Kernel Modules: Module initializer may now return a symbol table (not yet used for anything) --- include/nuttx/module.h | 31 +++++++++++++++++++++++-------- sched/module/mod_insmod.c | 2 +- sched/module/mod_procfs.c | 7 ++++--- sched/module/mod_rmmod.c | 14 ++++++++------ sched/module/module.h | 5 ++--- 5 files changed, 38 insertions(+), 21 deletions(-) diff --git a/include/nuttx/module.h b/include/nuttx/module.h index 7ce8b80447..fe144825ca 100644 --- a/include/nuttx/module.h +++ b/include/nuttx/module.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/nuttx/module.h * - * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -94,24 +94,39 @@ typedef CODE int (*mod_uninitializer_t)(FAR void *arg); +/* The contect of this structure is returned by module_initialize(). + * + * uninitializer - The pointer to the uninitialization function. NULL may + * be returned if no uninitialization is needed (i.e, the + * the module memory can be deallocated at any time). + * arg - An argument that will be passed to the uninitialization + function. + * exports - A symbol table exported by the module + * nexports - The number of symbols in the exported symbol table. + */ + +struct mod_info_s +{ + mod_uninitializer_t uninitializer; /* Module uninitializer */ + FAR void *arg; /* Uninitializer argument */ + FAR struct symtab_s *exports; /* Symbols exported by module */ + unsigned int nexports; /* Number of symobols in exports list */ +}; + /* A NuttX module is expected to export a function called module_initialize() * that has the following function prototype. This function should appear as - * the entry point in the ELF module file and will be called bythe binfmt + * the entry point in the ELF module file and will be called by the binfmt * logic after the module has been loaded into kernel memory. * * Input Parameters: - * uninitializer - The pointer to the uninitialization function. NULL may - * be returned if no uninitialization is needed (i.e, the the module - * memory can be deallocated at any time). - * arg - An argument that will be passed to the uninitialization function. + * modinfo - Module information returned by mod_initialize(). * * Returned Value: * Zero (OK) on success; a negated errno value on any failure to * initialize the module. */ -typedef CODE int (*mod_initializer_t)(mod_uninitializer_t *uninitializer, - FAR void **arg); +typedef CODE int (*mod_initializer_t)(FAR struct mod_info_s *modinfo); #ifdef __KERNEL__ /* This is the type of the callback function used by mod_registry_foreach() */ diff --git a/sched/module/mod_insmod.c b/sched/module/mod_insmod.c index 3b4b5b3ceb..bda9d4dd2d 100644 --- a/sched/module/mod_insmod.c +++ b/sched/module/mod_insmod.c @@ -266,7 +266,7 @@ int insmod(FAR const char *filename, FAR const char *modulename) /* Call the module initializer */ - ret = initializer(&modp->uninitializer, &modp->arg); + ret = initializer(&modp->modinfo); if (ret < 0) { sinfo("Failed to initialize the module: %d\n", ret); diff --git a/sched/module/mod_procfs.c b/sched/module/mod_procfs.c index 50388d0d72..68285fd5fb 100644 --- a/sched/module/mod_procfs.c +++ b/sched/module/mod_procfs.c @@ -147,10 +147,11 @@ static int modprocfs_callback(FAR struct module_s *modp, FAR void *arg) DEBUGASSERT(modp != NULL && arg != NULL); priv = (FAR struct modprocfs_file_s *)arg; - linesize = snprintf(priv->line, MOD_LINELEN, "%s,%p,%p,%p,%p,%lu,%p,%lu\n", + linesize = snprintf(priv->line, MOD_LINELEN, "%s,%p,%p,%p,%u,%p,%lu,%p,%lu\n", modp->modulename, modp->initializer, - modp->uninitializer, modp->arg, - modp->alloc, (unsigned long)modp->textsize, + modp->modinfo.uninitializer, modp->modinfo.arg, + modp->modinfo.nexports, modp->alloc, + (unsigned long)modp->textsize, (FAR uint8_t *)modp->alloc + modp->textsize, (unsigned long)modp->datasize); copysize = procfs_memcpy(priv->line, linesize, priv->buffer, diff --git a/sched/module/mod_rmmod.c b/sched/module/mod_rmmod.c index 59f7d2f15d..e0ccad7744 100644 --- a/sched/module/mod_rmmod.c +++ b/sched/module/mod_rmmod.c @@ -95,11 +95,11 @@ int rmmod(FAR const char *modulename) /* Is there an uninitializer? */ - if (modp->uninitializer != NULL) + if (modp->modinfo.uninitializer != NULL) { - /* Try to uninitializer the module */ + /* Try to uninitialize the module */ - ret = modp->uninitializer(modp->arg); + ret = modp->modinfo.uninitializer(modp->modinfo.arg); /* Did the module sucessfully uninitialize? */ @@ -111,11 +111,13 @@ int rmmod(FAR const char *modulename) /* Nullify so that the uninitializer cannot be called again */ + modp->modinfo.uninitializer = NULL; #if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) - modp->initializer = NULL; + modp->initializer = NULL; + modp->modinfo.arg = NULL; + modp->modinfo.exports = NULL; + modp->modinfo.nexports = 0; #endif - modp->uninitializer = NULL; - modp->arg = NULL; } /* Release resources held by the module */ diff --git a/sched/module/module.h b/sched/module/module.h index 9bccc0c6e1..b64b9b3bd7 100644 --- a/sched/module/module.h +++ b/sched/module/module.h @@ -1,7 +1,7 @@ /**************************************************************************** * sched/module/module.h * - * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -62,8 +62,7 @@ struct module_s #if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) mod_initializer_t initializer; /* Module initializer function */ #endif - mod_uninitializer_t uninitializer; /* Module uninitializer function */ - FAR void *arg; /* Uninitializer argument */ + struct mod_info_s modinfo; /* Module information */ FAR void *alloc; /* Allocated kernel memory */ #if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) size_t textsize; /* Size of the kernel .text memory allocation */