examples/sotest: Add a test for shared libraries.

This commit is contained in:
Gregory Nutt 2017-01-23 08:23:28 -06:00
parent d195751a90
commit c027c19dde
12 changed files with 980 additions and 9 deletions

View File

@ -774,10 +774,10 @@ examples/mm
examples/module
^^^^^^^^^^^^^^
This example builds a small loadable module test case. This includes on
This example builds a small loadable module test case. This includes a
character driver under examples/module/drivers. This driver is built using
the relocatable ELF format and installed in a ROMFS file system. At run time,
the driver module is loaded and exercises. Requires CONFIG_MODULE.
the driver module is loaded and exercised. Requires CONFIG_MODULE.
Other configuration options:
CONFIG_EXAMPLES_ELF_DEVMINOR - The minor device number of the ROMFS block
@ -792,18 +792,18 @@ examples/module
NOTES:
1. CFLAGS should be provided in CELFFLAGS. RAM and FLASH memory regions
1. CFLAGS should be provided in CMODULEFLAGS. RAM and FLASH memory regions
may require long allcs. For ARM, this might be:
CELFFLAGS = $(CFLAGS) -mlong-calls
CMODULEFLAGS = $(CFLAGS) -mlong-calls
Similarly for C++ flags which must be provided in CXXELFFLAGS.
Similarly for C++ flags which must be provided in CXXMODULEFLAGS.
2. Your top-level nuttx/Make.defs file must also include an approproate definition,
LDELFFLAGS, to generate a relocatable ELF object. With GNU LD, this should
LDMODULEFLAGS, to generate a relocatable ELF object. With GNU LD, this should
include '-r' and '-e <entry point>'.
LDELFFLAGS = -r -e module_initialize
LDMODULEFLAGS = -r -e module_initialize
If you use GCC to link, you make also need to include '-nostdlib' or
'-nostartfiles' and '-nodefaultlibs'.
@ -828,10 +828,10 @@ examples/module
6. Linker scripts. You might also want to use a linker scripts to combine
sections better. An example linker script is at nuttx/sched/module/gnu-elf.ld.
That example might have to be tuned for your particular linker output to
position additional sections correctly. The GNU LD LDELFFLAGS then might
position additional sections correctly. The GNU LD LDMODULEFLAGS then might
be:
LDELFFLAGS = -r -e module_initialize -T$(TOPDIR)/sched/module/gnu-elf.ld
LDMODULEFLAGS = -r -e module_initialize -T$(TOPDIR)/sched/module/gnu-elf.ld
examples/modbus
^^^^^^^^^^^^^^^
@ -1855,6 +1855,66 @@ examples/smp
This is a simple test for SMP functionality. It is basically just the
pthread barrier test with some custom instrumentation.
examples/sotest
^^^^^^^^^^^^^^^
This example builds a small shared library module test case. The test
shared library is built using the relocatable ELF format and installed
in a ROMFS file system. At run time, the shared library is installed and exercised. Requires CONFIG_LIBC_DLLFCN. Other configuration options:
CONFIG_EXAMPLES_SOTEST_DEVMINOR - The minor device number of the ROMFS block
driver. For example, the N in /dev/ramN. Used for registering the RAM
block driver that will hold the ROMFS file system containing the ELF
executables to be tested. Default: 0
CONFIG_EXAMPLES_SOTEST_DEVPATH - The path to the ROMFS block driver device. This
must match EXAMPLES_ELF_DEVMINOR. Used for registering the RAM block driver
that will hold the ROMFS file system containing the ELF executables to be
tested. Default: "/dev/ram0"
NOTES:
1. CFLAGS should be provided in CMODULEFLAGS. RAM and FLASH memory regions
may require long allcs. For ARM, this might be:
CMODULEFLAGS = $(CFLAGS) -mlong-calls
Similarly for C++ flags which must be provided in CXXMODULEFLAGS.
2. Your top-level nuttx/Make.defs file must also include an approproate definition,
LDMODULEFLAGS, to generate a relocatable ELF object. With GNU LD, this should
include '-r' and '-e <entry point>'.
LDMODULEFLAGS = -r -e module_initialize
If you use GCC to link, you make also need to include '-nostdlib' or
'-nostartfiles' and '-nodefaultlibs'.
3. This example also requires genromfs. genromfs can be build as part of the
nuttx toolchain. Or can built from the genromfs sources that can be found
in the NuttX tools repository (genromfs-0.5.2.tar.gz). In any event, the
PATH variable must include the path to the genromfs executable.
4. ELF size: The ELF files in this example are, be default, quite large
because they include a lot of "build garbage". You can greatly reduce the
size of the ELF binaries are using the 'objcopy --strip-unneeded' command to
remove un-necessary information from the ELF files.
5. Simulator. You cannot use this example with the the NuttX simulator on
Cygwin. That is because the Cygwin GCC does not generate ELF file but
rather some Windows-native binary format.
If you really want to do this, you can create a NuttX x86 buildroot toolchain
and use that be build the ELF executables for the ROMFS file system.
6. Linker scripts. You might also want to use a linker scripts to combine
sections better. An example linker script is at nuttx/sched/module/gnu-elf.ld.
That example might have to be tuned for your particular linker output to
position additional sections correctly. The GNU LD LDMODULEFLAGS then might
be:
LDMODULEFLAGS = -r -e module_initialize -T$(TOPDIR)/sched/module/gnu-elf.ld
examples/system
^^^^^^^^^^^^^^^

3
examples/sotest/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/Make.dep
/.depend
/.built

55
examples/sotest/Kconfig Normal file
View File

@ -0,0 +1,55 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
config EXAMPLES_SOTEST
bool "Shared Library Example"
default n
depends on LIBC_DLLFCN
---help---
Enable the shared library example
if EXAMPLES_SOTEST
config EXAMPLES_SOTEST_LIBC
bool "Link with LIBC"
default n
depends on !BUILD_KERNEL && EXPERIMENTAL
---help---
Link with the C library (and also math library if it was built).
By default, all undefined symbols must be provided via a symbol
table. But if this option is selected, then each SOTEST test program
will link with the SYSCALL library and will interface with the OS
system calls. You probably will NOT want this option, however,
because it will substantially increase the size of code. For
example, a separate copy of printf() would be linked with every
program greatly increasing the total code size. This option is
primarily intended only for testing.
WARNING: Libc will not be built with -mlong-calls and this may
result in runtime linking failures due to out-of-range functions
calls.
config EXAMPLES_SOTEST_LIBGCC
bool "Link with LIBGCC"
default n
depends on !BUILD_KERNEL && EXPERIMENTAL
config EXAMPLES_SOTEST_DEVMINOR
int "ROMFS Minor Device Number"
default 0
---help---
The minor device number of the ROMFS block. For example, the N in /dev/ramN.
Used for registering the RAM block driver that will hold the ROMFS file system
containing the SOTEST executables to be tested. Default: 0
config EXAMPLES_SOTEST_DEVPATH
string "ROMFS Device Path"
default "/dev/ram0"
---help---
The path to the ROMFS block driver device. This must match EXAMPLES_SOTEST_DEVMINOR.
Used for registering the RAM block driver that will hold the ROMFS file system
containing the SOTEST executables to be tested. Default: "/dev/ram0"
endif

38
examples/sotest/Make.defs Normal file
View File

@ -0,0 +1,38 @@
############################################################################
# apps/examples/sotest/Make.defs
#
# Copyright (C) 2015 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# 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_EXAMPLES_SOTEST),y)
CONFIGURED_APPS += examples/sotest
endif

157
examples/sotest/Makefile Normal file
View File

@ -0,0 +1,157 @@
############################################################################
# apps/examples/sotest/Makefile
#
# Copyright (C) 2015-2016 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# 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.
#
############################################################################
-include $(TOPDIR)/.config
-include $(TOPDIR)/Make.defs
OBJEXT ?= .o
DELIM ?= /
include $(APPDIR)/Make.defs
# Shared library example built-in application info
APPNAME = sotest
PRIORITY = SCHED_PRIORITY_DEFAULT
STACKSIZE = 2048
# Shared Library Example
ASRCS =
CSRCS = symtab.c
MAINSRC = sotest_main.c
AOBJS = $(ASRCS:.S=$(OBJEXT))
COBJS = $(CSRCS:.c=$(OBJEXT))
MAINOBJ = $(MAINSRC:.c=$(OBJEXT))
SRCS = $(ASRCS) $(CSRCS) $(MAINSRC)
OBJS = $(AOBJS) $(COBJS)
ifneq ($(CONFIG_BUILD_KERNEL),y)
OBJS += $(MAINOBJ)
endif
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
BIN = ..\..\libapps$(LIBEXT)
else
ifeq ($(WINTOOL),y)
BIN = ..\\..\\libapps$(LIBEXT)
else
BIN = ../../libapps$(LIBEXT)
endif
endif
ifeq ($(WINTOOL),y)
INSTALL_DIR = "${shell cygpath -w $(BIN_DIR)}"
else
INSTALL_DIR = $(BIN_DIR)
endif
CONFIG_XYZ_PROGNAME ?= discover$(EXEEXT)
PROGNAME = $(CONFIG_XYZ_PROGNAME)
ROOTDEPPATH = --dep-path . --dep-path lib
# Build targets
VPATH = lib
all: .built
.PHONY: really_build clean_lib clean depend distclean
$(AOBJS): %$(OBJEXT): %.S
$(call ASSEMBLE, $<, $@)
$(COBJS) $(MAINOBJ): %$(OBJEXT): %.c
$(call COMPILE, $<, $@)
# This is a little messy. The build is broken into two pieces: (1) the
# lib/ subdir build that auto-generates several files, and (2) the real
# build. This is done because we need a fresh build context after auto-
# generating the source files.
really_build: $(OBJS)
$(call ARCHIVE, $(BIN), $(OBJS))
@touch .built
.built:
@$(MAKE) -C lib TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" CROSSDEV=$(CROSSDEV)
@$(MAKE) TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" really_build
ifeq ($(CONFIG_BUILD_KERNEL),y)
$(BIN_DIR)$(DELIM)$(PROGNAME): $(OBJS) $(MAINOBJ)
@echo "LD: $(PROGNAME)"
$(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME) $(ARCHCRT0OBJ) $(MAINOBJ) $(LDLIBS)
$(Q) $(NM) -u $(INSTALL_DIR)$(DELIM)$(PROGNAME)
install: $(BIN_DIR)$(DELIM)$(PROGNAME)
else
install:
endif
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
else
context:
endif
# We can't make dependencies in this directory because the required
# header files may not yet exist.
.depend:
@touch $@
depend: .depend
clean_lib:
@$(MAKE) -C lib TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" CROSSDEV=$(CROSSDEV) clean
clean: clean_lib
$(call DELFILE, .built)
$(call CLEAN)
distclean: clean
$(call DELFILE, Make.dep)
$(call DELFILE, .depend)
-include Make.dep
.PHONY: preconfig
preconfig:

5
examples/sotest/lib/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
/romfs
/romfs.h
/romfs.img
/symtab.c

View File

@ -0,0 +1,98 @@
############################################################################
# apps/examples/sotest/lib/Makefile
#
# Copyright (C) 2015 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# 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.
#
############################################################################
-include $(TOPDIR)/.config
-include $(TOPDIR)/Make.defs
include $(APPDIR)/Make.defs
ALL_SUBDIRS = sotest
BUILD_SUBDIRS = sotest
SOTEST_DIR = $(APPDIR)/examples/sotest
LIB_DIR = $(SOTEST_DIR)/lib
ROMFS_DIR = $(LIB_DIR)/romfs
ROMFS_IMG = $(LIB_DIR)/romfs.img
ROMFS_HDR = $(LIB_DIR)/romfs.h
SYMTAB_SRC = $(LIB_DIR)/symtab.c
define DIR_template
$(1)_$(2):
$(Q) $(MAKE) -C $(1) $(3) TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)" CROSSDEV=$(CROSSDEV)
endef
all: $(ROMFS_HDR) $(DIRLIST_HDR) $(SYMTAB_SRC)
.PHONY: all build clean install populate
$(foreach DIR, $(BUILD_SUBDIRS), $(eval $(call DIR_template,$(DIR),build, all)))
$(foreach DIR, $(ALL_SUBDIRS), $(eval $(call DIR_template,$(DIR),clean,clean)))
$(foreach DIR, $(BUILD_SUBDIRS), $(eval $(call DIR_template,$(DIR),install,install)))
# Build program(s) in each sud-directory
build: $(foreach DIR, $(BUILD_SUBDIRS), $(DIR)_build)
# Install each program in the romfs directory
install: $(foreach DIR, $(BUILD_SUBDIRS), $(DIR)_install)
# Create the romfs directory
$(ROMFS_DIR):
$(Q) mkdir $(ROMFS_DIR)
# Populate the romfs directory
populate: $(ROMFS_DIR) build install
# Create the romfs.img file from the populated romfs directory
$(ROMFS_IMG): populate
$(Q) genromfs -f $@ -d $(ROMFS_DIR) -V "SOTESTTEST"
# Create the romfs.h header file from the romfs.img file
$(ROMFS_HDR) : $(ROMFS_IMG)
$(Q) (cd $(LIB_DIR); xxd -i romfs.img | sed -e "s/^unsigned/static const unsigned/g" >$@)
# Create the exported symbol table
$(SYMTAB_SRC): build
$(Q) $(LIB_DIR)/mksymtab.sh $(ROMFS_DIR) >$@
# Clean each subdirectory
clean: $(foreach DIR, $(ALL_SUBDIRS), $(DIR)_clean)
$(Q) rm -f $(ROMFS_HDR) $(DIRLIST_HDR) $(ROMFS_IMG) $(SYMTAB_SRC)
$(Q) rm -rf $(ROMFS_DIR)

View File

@ -0,0 +1,51 @@
#!/bin/bash
usage="Usage: $0 <test-dir-path>"
# Check for the required ROMFS directory path
dir=$1
if [ -z "$dir" ]; then
echo "ERROR: Missing <test-dir-path>"
echo ""
echo $usage
exit 1
fi
if [ ! -d "$dir" ]; then
echo "ERROR: Directory $dir does not exist"
echo ""
echo $usage
exit 1
fi
# Extract all of the undefined symbols from the SOTEST files and create a
# list of sorted, unique undefined variable names.
varlist=`find ${dir} -executable -type f | xargs nm | fgrep ' U ' | sed -e "s/^[ ]*//g" | cut -d' ' -f2 | sort | uniq`
# Now output the symbol table as a structure in a C source file. All
# undefined symbols are declared as void* types. If the toolchain does
# any kind of checking for function vs. data objects, then this could
# faile
echo "#include <nuttx/compiler.h>"
echo "#include <nuttx/binfmt/symtab.h>"
echo ""
for var in $varlist; do
echo "extern void *${var};"
done
echo ""
echo "const struct symtab_s exports[] = "
echo "{"
for var in $varlist; do
echo " {\"${var}\", &${var}},"
done
echo "};"
echo ""
echo "const int nexports = sizeof(exports) / sizeof(struct symtab_s);"

2
examples/sotest/lib/sotest/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/sotest

View File

@ -0,0 +1,94 @@
############################################################################
# examples/sotest/lib/sotest/Makefile
#
# Copyright (C) 2015-2016 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# 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.
#
############################################################################
-include $(TOPDIR)/Make.defs
include $(APPDIR)/Make.defs
OBJEXT ?= .o
DELIM ?= /
ifeq ($(WINTOOL),y)
NUTTXLIB = "${shell cygpath -w $(TOPDIR)$(DELIM)lib}"
else
NUTTXLIB = "$(TOPDIR)$(DELIM)lib"
endif
KDEFINE = ${shell $(TOPDIR)/tools/define.sh "$(CC)" __KERNEL__}
CMODULEFLAGS += $(KDEFINE)
ifeq ($(CONFIG_EXAMPLES_SOTEST_LIBGCC),y)
LIBGCC = "${shell $(CC) $(ARCHCPUFLAGS) -print-libgcc-file-name 2>/dev/null}"
ifneq ($(LIBGCC),)
LDLIBPATH += -L "${shell dirname $(LIBGCC)}"
LDLIBS += -lgcc
endif
endif
ifeq ($(CONFIG_EXAMPLES_SOTEST_LIBC),y)
LDMODULEFLAGS += -Bstatic
LDLIBPATH += -L $(NUTTXLIB)
endif
ifeq ($(CONFIG_EXAMPLES_SOTEST_LIBC),y)
ifeq ($(CONFIG_BUILD_PROTECTED),y)
LDLIBS += -luc
else
LDLIBS += -lc
endif
endif
BIN = sotest
SRCS = $(BIN).c
OBJS = $(SRCS:.c=$(OBJEXT))
all: $(BIN)
.PHONY: clean install
$(OBJS): %$(OBJEXT): %.c
@echo "CC: $<"
$(Q) $(CC) -c $(CMODULEFLAGS) $< -o $@
$(BIN): $(OBJS)
@echo "LD: $<"
$(Q) $(LD) $(LDMODULEFLAGS) $(LDLIBPATH) -o $@ $(ARCHCRT0OBJ) $^ $(LDLIBS)
clean:
$(call DELFILE, $(BIN))
$(call CLEAN)
install:
$(Q) mkdir -p $(ROMFS_DIR)
$(Q) install $(BIN) $(ROMFS_DIR)/$(BIN)

View File

@ -0,0 +1,161 @@
/****************************************************************************
* apps/examples/sotest/libs/sotest/sotest.c
*
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <dllfcn.h>
#include <syslog.h>
#include <nuttx/module.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private data
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
static void testfunc1(FAR const char *msg);
static void testfunc2(FAR const char *msg);
static void testfunc3(FAR const char *msg);
static int module_uninitialize(FAR void *arg);
/****************************************************************************
* Private Data
****************************************************************************/
static const char g_msg1[] = "Hello to you too!";
static const char g_msg2[] = "Not so bad so far.";
static const char g_msg3[] = "Yes, don't be a stranger!";
static const struct symtab_s g_exports[6] =
{
{
(FAR const char *)"testfunc1", (FAR const void *)testfunc1,
},
{
(FAR const char *)"testfunc2", (FAR const void *)testfunc2,
},
{
(FAR const char *)"testfunc3", (FAR const void *)testfunc3,
},
{
(FAR const char *)"g_msg1", (FAR const void *)g_msg1,
},
{
(FAR const char *)"g_msg2", (FAR const void *)g_msg2,
},
{
(FAR const char *)"g_msg3", (FAR const void *)g_msg3,
},
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: testfunc1
****************************************************************************/
static void testfunc1(FAR const char *msg)
{
syslog(LOG_INFO, "testfunc1: Hello, everyone!\n");
syslog(LOG_INFO, " caller: %s\n", msg);
}
/****************************************************************************
* Name: testfunc2
****************************************************************************/
static void testfunc2(FAR const char *msg)
{
syslog(LOG_INFO, "testfunc2: Hope you are having a great day!\n");
syslog(LOG_INFO, " caller: %s\n", msg);
}
/****************************************************************************
* Name: testfunc3
****************************************************************************/
static void testfunc3(FAR const char *msg)
{
syslog(LOG_INFO, "testfunc3: Let's talk again very soon\n");
syslog(LOG_INFO, " caller: %s\n", msg);
}
/****************************************************************************
* Name: module_uninitialize
****************************************************************************/
static int module_uninitialize(FAR void *arg)
{
syslog(LOG_INFO, "module_uninitialize: arg=%p\n", arg);
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: module_initialize
*
* Description:
* Register /dev/sotest
*
****************************************************************************/
int module_initialize(FAR struct mod_info_s *modinfo)
{
syslog(LOG_INFO, "module_initialize:\n");
modinfo->uninitializer = module_uninitialize;
modinfo->arg = NULL;
modinfo->exports = g_exports;
modinfo->nexports = 6;
return OK;
}

View File

@ -0,0 +1,247 @@
/****************************************************************************
* examples/sotest/sotest_main.c
*
* Copyright (C) 2015, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/mount.h>
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#include <dllfcn.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/drivers/ramdisk.h>
#include <nuttx/binfmt/symtab.h>
#include "lib/romfs.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Check configuration. This is not all of the configuration settings that
* are required -- only the more obvious.
*/
#ifndef CONFIG_LIBC_DLLFCN
# error "You must select CONFIG_LIBC_DLLFCN in your configuration file"
#endif
#ifndef CONFIG_FS_ROMFS
# error "You must select CONFIG_FS_ROMFS in your configuration file"
#endif
#ifdef CONFIG_DISABLE_MOUNTPOINT
# error "You must not disable mountpoints via CONFIG_DISABLE_MOUNTPOINT in your configuration file"
#endif
/* Describe the ROMFS file system */
#define SECTORSIZE 64
#define NSECTORS(b) (((b)+SECTORSIZE-1)/SECTORSIZE)
#define MOUNTPT "/mnt/romfs"
#ifndef CONFIG_EXAMPLES_SOTEST_DEVMINOR
# define CONFIG_EXAMPLES_SOTEST_DEVMINOR 0
#endif
#ifndef CONFIG_EXAMPLES_SOTEST_DEVPATH
# define CONFIG_EXAMPLES_SOTEST_DEVPATH "/dev/ram0"
#endif
/****************************************************************************
* Private data
****************************************************************************/
/****************************************************************************
* Symbols from Auto-Generated Code
****************************************************************************/
extern const struct symtab_s exports[];
extern const int nexports;
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: sotest_main
****************************************************************************/
#ifdef CONFIG_BUILD_KERNEL
int main(int argc, FAR char *argv[])
#else
int sotest_main(int argc, char *argv[])
#endif
{
FAR void *handle;
CODE void (*testfunc)(FAR const char *msg);
FAR const char *msg;
int ret;
/* Set the shared library symbol table */
ret = dlsymtab((FAR struct symtab_s *)exports, nexports);
if (ret < 0)
{
fprintf(stderr, "ERROR: dlsymtab failed: %d\n", ret);
exit(EXIT_FAILURE);
}
/* Create a ROM disk for the ROMFS filesystem */
printf("main: Registering romdisk at /dev/ram%d\n",
CONFIG_EXAMPLES_SOTEST_DEVMINOR);
ret = romdisk_register(CONFIG_EXAMPLES_SOTEST_DEVMINOR,
(FAR uint8_t *)romfs_img,
NSECTORS(romfs_img_len), SECTORSIZE);
if (ret < 0)
{
/* This will happen naturally if we registered the ROM disk previously. */
if (ret != -EEXIST)
{
fprintf(stderr, "ERROR: romdisk_register failed: %d\n", ret);
exit(EXIT_FAILURE);
}
printf("main: ROM disk already registered\n");
}
/* Mount the file system */
printf("main: Mounting ROMFS filesystem at target=%s with source=%s\n",
MOUNTPT, CONFIG_EXAMPLES_SOTEST_DEVPATH);
ret = mount(CONFIG_EXAMPLES_SOTEST_DEVPATH, MOUNTPT, "romfs", MS_RDONLY, NULL);
if (ret < 0)
{
fprintf(stderr, "ERROR: mount(%s,%s,romfs) failed: %s\n",
CONFIG_EXAMPLES_SOTEST_DEVPATH, MOUNTPT, errno);
exit(EXIT_FAILURE);
}
/* Install the test shared library */
handle = dlopen(MOUNTPT "/sotest", RTLD_NOW | RTLD_LOCAL);
if (handle == NULL)
{
fprintf(stderr, "ERROR: dlopen failed\n");
exit(EXIT_FAILURE);
}
/* Get symbols testfunc1 and msg1 */
testfunc = (CODE void (*)(FAR const char *))dlsym(handle, "testfunc1");
if (testfunc == NULL)
{
fprintf(stderr, "ERROR: Failed to get symbol \"testfunc1\"\n");
exit(EXIT_FAILURE);
}
msg = (FAR const char *)dlsym(handle, "g_msg1");
if (msg == NULL)
{
fprintf(stderr, "ERROR: Failed to get symbol \"g_msg1\"\n");
exit(EXIT_FAILURE);
}
/* Execute testfunc1 */
testfunc(msg);
/* Get symbols testfunc2 and msg2 */
testfunc = (CODE void (*)(FAR const char *))dlsym(handle, "testfunc2");
if (testfunc == NULL)
{
fprintf(stderr, "ERROR: Failed to get symbol \"testfunc2\"\n");
exit(EXIT_FAILURE);
}
msg = (FAR const char *)dlsym(handle, "g_msg2");
if (msg == NULL)
{
fprintf(stderr, "ERROR: Failed to get symbol \"g_msg2\"\n");
exit(EXIT_FAILURE);
}
/* Execute testfunc2 */
testfunc(msg);
/* Get symbols testfunc3 and msg3 */
testfunc = (CODE void (*)(FAR const char *))dlsym(handle, "testfunc3");
if (testfunc == NULL)
{
fprintf(stderr, "ERROR: Failed to get symbol \"testfunc3\"\n");
exit(EXIT_FAILURE);
}
msg = (FAR const char *)dlsym(handle, "g_msg3");
if (msg == NULL)
{
fprintf(stderr, "ERROR: Failed to get symbol \"g_msg3\"\n");
exit(EXIT_FAILURE);
}
/* Execute testfunc3 */
testfunc(msg);
ret = dlclose(handle);
if (ret < 0)
{
fprintf(stderr, "ERROR: rmmod failed: %d\n", ret);
exit(EXIT_FAILURE);
}
ret = umount(MOUNTPT);
if (ret < 0)
{
fprintf(stderr, "ERROR: umount(%s) failed: %d\n",
MOUNTPT, errno);
exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
}