diff --git a/configs/olimex-stm32-p407/README.txt b/configs/olimex-stm32-p407/README.txt index afdf74f5294..29085d53c95 100644 --- a/configs/olimex-stm32-p407/README.txt +++ b/configs/olimex-stm32-p407/README.txt @@ -265,9 +265,10 @@ must be is one of the following. CONFIG_FS_ROMFS=y CONFIG_LIBC_ARCH_ELF=y CONFIG_MODULE=y - CONFIG_MODULE_ALIGN_LOG2=2 - CONFIG_MODULE_BUFFERINCR=32 - CONFIG_MODULE_BUFFERSIZE=128 + CONFIG_LIBC_MODLIB=y + CONFIG_MODLIB_ALIGN_LOG2=2 + CONFIG_MODLIB_BUFFERINCR=32 + CONFIG_MODLIB_BUFFERSIZE=128 Add the following for testing shared libraries in the FLAT build: diff --git a/configs/samv71-xult/module/defconfig b/configs/samv71-xult/module/defconfig index fc9a08896f5..f73d5f04445 100644 --- a/configs/samv71-xult/module/defconfig +++ b/configs/samv71-xult/module/defconfig @@ -302,7 +302,7 @@ CONFIG_ARCH_HAVE_MPU=y # CONFIG_ARCH_NAND_HWECC is not set # CONFIG_ARCH_HAVE_EXTCLK is not set # CONFIG_ARCH_HAVE_POWEROFF is not set -# CONFIG_ARCH_HAVE_RESET is not set +CONFIG_ARCH_HAVE_RESET=y # CONFIG_ARCH_USE_MPU is not set # CONFIG_ARCH_IRQPRIO is not set CONFIG_ARCH_STACKDUMP=y @@ -366,6 +366,7 @@ CONFIG_ARCH_IRQBUTTONS=y # CONFIG_SAMV71XULT_MXTXPLND is not set # CONFIG_BOARD_CRASHDUMP is not set CONFIG_LIB_BOARDCTL=y +# CONFIG_BOARDCTL_RESET is not set # CONFIG_BOARDCTL_UNIQUEID is not set CONFIG_BOARDCTL_OS_SYMTAB=y # CONFIG_BOARDCTL_TSCTEST is not set @@ -465,9 +466,6 @@ CONFIG_SIG_SIGWORK=17 CONFIG_PREALLOC_MQ_MSGS=4 CONFIG_MQ_MAXMSGSIZE=32 CONFIG_MODULE=y -CONFIG_MODULE_ALIGN_LOG2=2 -CONFIG_MODULE_BUFFERSIZE=128 -CONFIG_MODULE_BUFFERINCR=32 # # Work queue support @@ -722,6 +720,16 @@ CONFIG_STDIO_BUFFER_SIZE=64 CONFIG_STDIO_LINEBUFFER=y CONFIG_NUNGET_CHARS=2 CONFIG_LIB_HOMEDIR="/" +# CONFIG_LIBC_DLLFCN is not set +CONFIG_LIBC_MODLIB=y + +# +# Module library configuration +# +CONFIG_MODLIB_MAXDEPEND=2 +CONFIG_MODLIB_ALIGN_LOG2=2 +CONFIG_MODLIB_BUFFERSIZE=128 +CONFIG_MODLIB_BUFFERINCR=32 # CONFIG_LIBM is not set # CONFIG_LIBC_ARCH_MEMCPY is not set # CONFIG_LIBC_ARCH_MEMCMP is not set diff --git a/include/nuttx/lib/modlib.h b/include/nuttx/lib/modlib.h index b74a163ba3c..4ddd0ee1ad3 100644 --- a/include/nuttx/lib/modlib.h +++ b/include/nuttx/lib/modlib.h @@ -48,6 +48,25 @@ #include #include +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifndef CONFIG_LIBC_MODLIB_ALIGN_LOG2 +# define CONFIG_LIBC_MODLIB_ALIGN_LOG2 2 +#endif + +#ifndef CONFIG_LIBC_MODLIB_BUFFERSIZE +# define CONFIG_LIBC_MODLIB_BUFFERSIZE 128 +#endif + +#ifndef CONFIG_LIBC_MODLIB_BUFFERINCR +# define CONFIG_LIBC_MODLIB_BUFFERINCR 32 +#endif + +#define MODULENAME_MAX 16 + /**************************************************************************** * Public Types ****************************************************************************/ @@ -69,14 +88,14 @@ struct module_s size_t datasize; /* Size of the kernel .bss/.data memory allocation */ #endif -#if CONFIG_MODULE_MAXDEPEND > 0 +#if CONFIG_LIBC_MODLIB_MAXDEPEND > 0 uint8_t dependents; /* Number of modules that depend on this module */ /* This is an upacked array of pointers to other modules that this module * depends upon. */ - FAR struct module_s *dependencies[CONFIG_MODULE_MAXDEPEND]; + FAR struct module_s *dependencies[CONFIG_LIBC_MODLIB_MAXDEPEND]; #endif }; @@ -217,7 +236,7 @@ int mod_unload(struct mod_loadinfo_s *loadinfo); * ****************************************************************************/ -#if CONFIG_MODULE_MAXDEPEND > 0 +#if CONFIG_LIBC_MODLIB_MAXDEPEND > 0 int mod_depend(FAR struct module_s *importer, FAR struct module_s *exporter); #endif @@ -238,7 +257,7 @@ int mod_depend(FAR struct module_s *importer, FAR struct module_s *exporter); * ****************************************************************************/ -#if CONFIG_MODULE_MAXDEPEND > 0 +#if CONFIG_LIBC_MODLIB_MAXDEPEND > 0 int mod_undepend(FAR struct module_s *importer); #endif diff --git a/include/nuttx/module.h b/include/nuttx/module.h index 83b04c5de7f..cf9eed5a9a7 100644 --- a/include/nuttx/module.h +++ b/include/nuttx/module.h @@ -52,25 +52,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ -/* Configuration ************************************************************/ - -#ifndef CONFIG_MODULE_ALIGN_LOG2 -# define CONFIG_MODULE_ALIGN_LOG2 2 -#endif - -#ifndef CONFIG_MODULE_BUFFERSIZE -# define CONFIG_MODULE_BUFFERSIZE 128 -#endif - -#ifndef CONFIG_MODULE_BUFFERINCR -# define CONFIG_MODULE_BUFFERINCR 32 -#endif - -#define MODULENAME_MAX 16 - /**************************************************************************** * Public Types ****************************************************************************/ diff --git a/libc/Kconfig b/libc/Kconfig index e533c6a4604..c3db169d9d1 100644 --- a/libc/Kconfig +++ b/libc/Kconfig @@ -33,6 +33,7 @@ config LIB_HOMEDIR The home directory to use with operations like such as 'cd ~' source libc/dllfcn/Kconfig +source libc/modlib/Kconfig source libc/math/Kconfig source libc/machine/Kconfig diff --git a/libc/Makefile b/libc/Makefile index 3944c7a9a0b..8d05825bf2e 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -72,6 +72,7 @@ include locale/Make.defs include machine/Make.defs include math/Make.defs include misc/Make.defs +include modlib/Make.defs include net/Make.defs include netdb/Make.defs include pthread/Make.defs diff --git a/libc/README.txt b/libc/README.txt index 313c71e7e50..67499e02a04 100644 --- a/libc/README.txt +++ b/libc/README.txt @@ -28,7 +28,7 @@ The files in the libc/ directory are organized (mostly) according which file in the include/ directory provides the prototype for library functions. So we have: - audio - This part of he audio system: nuttx/audio/audio.h + audio - This part of the audio system: nuttx/audio/audio.h dllfcn - dllfcn.h hex2bin - hex2bin.h libgen - libgen.h @@ -36,6 +36,7 @@ we have: fixedmath - fixedmath.h machine - Various architecture-specifica implementations. math - math.h + modlib - Part of module and shared libary logic: nuttx/lib/modlib.h net - Various network-related header files: netinet/ether.h, arpa/inet.h pthread - pthread.h queue - queue.h diff --git a/libc/dllfcn/Kconfig b/libc/dllfcn/Kconfig index e83d6d0616b..7fce284ed6a 100644 --- a/libc/dllfcn/Kconfig +++ b/libc/dllfcn/Kconfig @@ -7,8 +7,9 @@ config LIBC_DLLFCN bool "Shared library support" default n select LIBC_ARCH_ELF + select LIBC_MODLIB if !BUILD_KERNEL select MODULE if BUILD_FLAT - depends on EXPERIMENTAL || BUILD_FLAT + depends on EXPERIMENTAL || !BUILD_KERNEL ---help--- Enabled support for user-space shared libraries. diff --git a/libc/modlib/Kconfig b/libc/modlib/Kconfig new file mode 100644 index 00000000000..eeb5d05dcc9 --- /dev/null +++ b/libc/modlib/Kconfig @@ -0,0 +1,59 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config LIBC_MODLIB + bool + default n + +menu "Module library configuration" + depends on LIBC_MODLIB + +config MODLIB_MAXDEPEND + int "Max dependencies" + default 2 + ---help--- + This setting controls the number of other modules that a new module + may depend on. That is, when a new module in inserted via 'insmod' + it may depend on symbols exported by other, already installed + modules. This is the maximum number of modules that export symbols + to the new module. This maximum is artificial; it is used in the + current design because it uses some very simple, pre-allocated data + structures. + + All dependencies logic my be eliminated by sett CONFIG_MODLIB_MAXDEPEND + to zero. + +config MODLIB_ALIGN_LOG2 + int "Log2 Section Alignment" + default 2 + ---help--- + Align all sections to this Log2 value: 0->1, 1->2, 2->4, etc. + +config MODLIB_BUFFERSIZE + int "Module I/O Buffer Size" + default 128 + ---help--- + This is an I/O buffer that is used to access the module file. + Variable length items will need to be read (such as symbol names). + This is really just this initial size of the buffer; it will be + reallocated as necessary to hold large symbol names). Default: 128 + +config MODLIB_BUFFERINCR + int "Module I/O Buffer Realloc Increment" + default 32 + ---help--- + This is an I/O buffer that is used to access the module file. + Variable length items will need to be read (such as symbol names). + This value specifies the size increment to use each time the + buffer is reallocated. Default: 32 + +config MODLIB_DUMPBUFFER + bool "Dump module buffers" + default n + depends on DEBUG_INFO + ---help--- + Dump various module buffers for debug purposes + +endmenu # Module library configuration diff --git a/libc/modlib/Make.defs b/libc/modlib/Make.defs new file mode 100644 index 00000000000..49530960851 --- /dev/null +++ b/libc/modlib/Make.defs @@ -0,0 +1,45 @@ +############################################################################ +# libc/modlib/Make.defs +# +# Copyright (C) 2017 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +ifeq ($(CONFIG_LIBC_MODLIB),y) + +# Add the nuttx/lib/modlib.h files to the build + +# Add the modlib directory to the build + +DEPPATH += --dep-path modlib +VPATH += :modlib + +endif diff --git a/sched/Kconfig b/sched/Kconfig index 50ba4f914ef..db3e6950194 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -1119,63 +1119,14 @@ config MQ_MAXMSGSIZE endmenu # POSIX Message Queue Options -menuconfig MODULE +config MODULE bool "Enable loadable OS modules" default n + select LIBC_MODLIB select LIBC_ARCH_ELF ---help--- Enable support for loadable OS modules. Default: n -if MODULE - -config MODULE_MAXDEPEND - int "Max dependencies" - default 2 - ---help--- - This setting controls the number of other modules that a new module - may depend on. That is, when a new module in inserted via 'insmod' - it may depend on symbols exported by other, already installed - modules. This is the maximum number of modules that export symbols - to the new module. This maximum is artificial; it is used in the - current design because it uses some very simple, pre-allocated data - structures. - - All dependencies logic my be eliminated by sett CONFIG_MODULE_MAXDEPEND - to zero. - -config MODULE_ALIGN_LOG2 - int "Log2 Section Alignment" - default 2 - ---help--- - Align all sections to this Log2 value: 0->1, 1->2, 2->4, etc. - -config MODULE_BUFFERSIZE - int "Module I/O Buffer Size" - default 128 - ---help--- - This is an I/O buffer that is used to access the module file. - Variable length items will need to be read (such as symbol names). - This is really just this initial size of the buffer; it will be - reallocated as necessary to hold large symbol names). Default: 128 - -config MODULE_BUFFERINCR - int "Module I/O Buffer Realloc Increment" - default 32 - ---help--- - This is an I/O buffer that is used to access the module file. - Variable length items will need to be read (such as symbol names). - This value specifies the size increment to use each time the - buffer is reallocated. Default: 32 - -config MODULE_DUMPBUFFER - bool "Dump module buffers" - default n - depends on DEBUG_INFO - ---help--- - Dump various module buffers for debug purposes - -endif - menu "Work queue support" config SCHED_WORKQUEUE diff --git a/sched/module/mod_depend.c b/sched/module/mod_depend.c index 96d33d9bc1f..3de75fb23b3 100644 --- a/sched/module/mod_depend.c +++ b/sched/module/mod_depend.c @@ -70,7 +70,7 @@ int mod_depend(FAR struct module_s *importer, FAR struct module_s *exporter) { -#if CONFIG_MODULE_MAXDEPEND > 0 +#if CONFIG_LIBC_MODLIB_MAXDEPEND > 0 int freendx; int i; @@ -82,11 +82,11 @@ int mod_depend(FAR struct module_s *importer, FAR struct module_s *exporter) * list of dependencies. * * The list dependency list is a a dumb, upacked array of pointers. This - * should not be too inefficient if the number of CONFIG_MODULE_MAXDEPEND + * should not be too inefficient if the number of CONFIG_LIBC_MODLIB_MAXDEPEND * is small. Otherwise, a more dynamic data structure would be in order. */ - for (i = 0, freendx = -1; i < CONFIG_MODULE_MAXDEPEND; i++) + for (i = 0, freendx = -1; i < CONFIG_LIBC_MODLIB_MAXDEPEND; i++) { FAR const struct module_s *modp; @@ -167,7 +167,7 @@ int mod_depend(FAR struct module_s *importer, FAR struct module_s *exporter) int mod_undepend(FAR struct module_s *importer) { -#if CONFIG_MODULE_MAXDEPEND > 0 +#if CONFIG_LIBC_MODLIB_MAXDEPEND > 0 FAR struct module_s *exporter; int i; @@ -175,11 +175,11 @@ int mod_undepend(FAR struct module_s *importer) /* Decrement the dependency count on each of exporters of symbols used by * this importer module. This is an upacked array of pointers. This - * should not be too inefficient if the number of CONFIG_MODULE_MAXDEPEND + * should not be too inefficient if the number of CONFIG_LIBC_MODLIB_MAXDEPEND * is small. Otherwise, a more dynamic data structure would be in order. */ - for (i = 0; i < CONFIG_MODULE_MAXDEPEND; i++) + for (i = 0; i < CONFIG_LIBC_MODLIB_MAXDEPEND; i++) { exporter = importer->dependencies[i]; if (exporter != NULL) diff --git a/sched/module/mod_init.c b/sched/module/mod_init.c index bc088d79d27..cfb23642698 100644 --- a/sched/module/mod_init.c +++ b/sched/module/mod_init.c @@ -55,15 +55,15 @@ * Pre-processor Definitions ****************************************************************************/ -/* CONFIG_DEBUG_FEATURES, CONFIG_DEBUG_INFO, and CONFIG_MODULE_DUMPBUFFER have to - * be defined or CONFIG_MODULE_DUMPBUFFER does nothing. +/* CONFIG_DEBUG_FEATURES, CONFIG_DEBUG_INFO, and CONFIG_LIBC_MODLIB_DUMPBUFFER + * have to be defined or CONFIG_LIBC_MODLIB_DUMPBUFFER does nothing. */ -#if !defined(CONFIG_DEBUG_INFO) || !defined (CONFIG_MODULE_DUMPBUFFER) -# undef CONFIG_MODULE_DUMPBUFFER +#if !defined(CONFIG_DEBUG_INFO) || !defined (CONFIG_LIBC_MODLIB_DUMPBUFFER) +# undef CONFIG_LIBC_MODLIB_DUMPBUFFER #endif -#ifdef CONFIG_MODULE_DUMPBUFFER +#ifdef CONFIG_LIBC_MODLIB_DUMPBUFFER # define mod_dumpbuffer(m,b,n) sinfodumpbuffer(m,b,n) #else # define mod_dumpbuffer(m,b,n) diff --git a/sched/module/mod_insmod.c b/sched/module/mod_insmod.c index 5afb2b59de8..c0a17f33793 100644 --- a/sched/module/mod_insmod.c +++ b/sched/module/mod_insmod.c @@ -59,14 +59,14 @@ ****************************************************************************/ /* CONFIG_DEBUG_INFO, and CONFIG_DEBUG_BINFMT have to be defined or - * CONFIG_MODULE_DUMPBUFFER does nothing. + * CONFIG_LIBC_MODLIB_DUMPBUFFER does nothing. */ #if !defined(CONFIG_DEBUG_INFO) || !defined (CONFIG_DEBUG_BINFMT) -# undef CONFIG_MODULE_DUMPBUFFER +# undef CONFIG_LIBC_MODLIB_DUMPBUFFER #endif -#ifdef CONFIG_MODULE_DUMPBUFFER +#ifdef CONFIG_LIBC_MODLIB_DUMPBUFFER # define mod_dumpbuffer(m,b,n) sinfodumpbuffer(m,b,n) #else # define mod_dumpbuffer(m,b,n) @@ -144,7 +144,7 @@ static void mod_dumploadinfo(FAR struct mod_loadinfo_s *loadinfo) * Name: mod_dumpinitializer ****************************************************************************/ -#ifdef CONFIG_MODULE_DUMPBUFFER +#ifdef CONFIG_LIBC_MODLIB_DUMPBUFFER static void mod_dumpinitializer(mod_initializer_t initializer, FAR struct mod_loadinfo_s *loadinfo) { diff --git a/sched/module/mod_iobuffer.c b/sched/module/mod_iobuffer.c index 36504ee8297..b2e77efeece 100644 --- a/sched/module/mod_iobuffer.c +++ b/sched/module/mod_iobuffer.c @@ -71,14 +71,14 @@ int mod_allocbuffer(FAR struct mod_loadinfo_s *loadinfo) { /* No.. allocate one now */ - loadinfo->iobuffer = (FAR uint8_t *)kmm_malloc(CONFIG_MODULE_BUFFERSIZE); + loadinfo->iobuffer = (FAR uint8_t *)kmm_malloc(CONFIG_LIBC_MODLIB_BUFFERSIZE); if (!loadinfo->iobuffer) { serr("ERROR: Failed to allocate an I/O buffer\n"); return -ENOMEM; } - loadinfo->buflen = CONFIG_MODULE_BUFFERSIZE; + loadinfo->buflen = CONFIG_LIBC_MODLIB_BUFFERSIZE; } return OK; diff --git a/sched/module/mod_load.c b/sched/module/mod_load.c index 3c5d735c006..2a8738a84a5 100644 --- a/sched/module/mod_load.c +++ b/sched/module/mod_load.c @@ -58,7 +58,7 @@ * Pre-processor Definitions ****************************************************************************/ -#define ELF_ALIGN_MASK ((1 << CONFIG_MODULE_ALIGN_LOG2) - 1) +#define ELF_ALIGN_MASK ((1 << CONFIG_LIBC_MODLIB_ALIGN_LOG2) - 1) #define ELF_ALIGNUP(a) (((unsigned long)(a) + ELF_ALIGN_MASK) & ~ELF_ALIGN_MASK) #define ELF_ALIGNDOWN(a) ((unsigned long)(a) & ~ELF_ALIGN_MASK) diff --git a/sched/module/mod_rmmod.c b/sched/module/mod_rmmod.c index 4c43d2cb4ba..88b221fd763 100644 --- a/sched/module/mod_rmmod.c +++ b/sched/module/mod_rmmod.c @@ -88,7 +88,7 @@ int rmmod(FAR void *handle) goto errout_with_lock; } -#if CONFIG_MODULE_MAXDEPEND > 0 +#if CONFIG_LIBC_MODLIB_MAXDEPEND > 0 /* Refuse to remove any module that other modules may depend upon. */ if (modp->dependents > 0) @@ -152,7 +152,7 @@ int rmmod(FAR void *handle) goto errout_with_lock; } -#if CONFIG_MODULE_MAXDEPEND > 0 +#if CONFIG_LIBC_MODLIB_MAXDEPEND > 0 /* Eliminate any dependencies that this module has on other modules */ (void)mod_undepend(modp); diff --git a/sched/module/mod_sections.c b/sched/module/mod_sections.c index 4803a20eace..6e4dc2f5dd8 100644 --- a/sched/module/mod_sections.c +++ b/sched/module/mod_sections.c @@ -147,7 +147,7 @@ static inline int mod_sectname(FAR struct mod_loadinfo_s *loadinfo, /* No.. then we have to read more */ - ret = mod_reallocbuffer(loadinfo, CONFIG_MODULE_BUFFERINCR); + ret = mod_reallocbuffer(loadinfo, CONFIG_LIBC_MODLIB_BUFFERINCR); if (ret < 0) { serr("ERROR: mod_reallocbuffer failed: %d\n", ret); diff --git a/sched/module/mod_symbols.c b/sched/module/mod_symbols.c index 02af33731a3..80a52e75578 100644 --- a/sched/module/mod_symbols.c +++ b/sched/module/mod_symbols.c @@ -55,8 +55,8 @@ /* Amount to reallocate buffer when buffer is full */ -#ifndef CONFIG_MODULE_BUFFERINCR -# define CONFIG_MODULE_BUFFERINCR 32 +#ifndef CONFIG_LIBC_MODLIB_BUFFERINCR +# define CONFIG_LIBC_MODLIB_BUFFERINCR 32 #endif /* Return values search for exported modules */ @@ -159,7 +159,7 @@ static int mod_symname(FAR struct mod_loadinfo_s *loadinfo, /* No.. then we have to read more */ - ret = mod_reallocbuffer(loadinfo, CONFIG_MODULE_BUFFERINCR); + ret = mod_reallocbuffer(loadinfo, CONFIG_LIBC_MODLIB_BUFFERINCR); if (ret < 0) { serr("ERROR: mod_reallocbuffer failed: %d\n", ret);