diff options
25 files changed, 287 insertions, 294 deletions
diff --git a/apps/ChangeLog.txt b/apps/ChangeLog.txt index d25c497399..14d107b3f4 100644 --- a/apps/ChangeLog.txt +++ b/apps/ChangeLog.txt @@ -383,4 +383,5 @@ * apps/Makefile: Small change that reduces the number of shell invocations by one (Mike Smith). * apps/examples/elf: Test example for the ELF loader. + * apps/examples/elf: The ELF module test example appears fully functional. diff --git a/apps/examples/README.txt b/apps/examples/README.txt index bfb92b6b79..70dffc9897 100644 --- a/apps/examples/README.txt +++ b/apps/examples/README.txt @@ -318,7 +318,12 @@ examples/elf NOTES: - 1. Your top-level nuttx/Make.defs file must include an approproate definition, + 1. CFLAGS should be provided in CELFFLAGS. RAM and FLASH memory regions + may require long allcs. For ARM, this might be: + + CELFFLAGS = $(CFLAGS) -mlong-calls + + 2. Your top-level nuttx/Make.defs file must alos include an approproate definition, LDELFFLAGS, to generate a relocatable ELF object. With GNU LD, this should include '-r' and '-e main' (or _main on some platforms). @@ -327,24 +332,24 @@ examples/elf If you use GCC to link, you make also need to include '-nostdlib' or '-nostartfiles' and '-nodefaultlibs'. - 2. This example also requires genromfs. genromfs can be build as part of the + 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 at misc/tools/genromfs-0.5.2.tar.gz. In any event, the PATH variable must include the path to the genromfs executable. - 3. ELF size: The ELF files in this example are, be default, quite large + 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. - 4. Simulator. You cannot use this example with the the NuttX simulator on + 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. - 5. Linker scripts. You might also want to use a linker scripts to combine + 6. Linker scripts. You might also want to use a linker scripts to combine sections better. An example linker script is at nuttx/binfmt/libelf/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 diff --git a/apps/examples/elf/Makefile b/apps/examples/elf/Makefile index 23a6bcb6fe..ea483e7a14 100644 --- a/apps/examples/elf/Makefile +++ b/apps/examples/elf/Makefile @@ -39,29 +39,29 @@ include $(APPDIR)/Make.defs # ELF Example -ASRCS = -CSRCS = elf_main.c +ASRCS = +CSRCS = elf_main.c symtab.c -AOBJS = $(ASRCS:.S=$(OBJEXT)) -COBJS = $(CSRCS:.c=$(OBJEXT)) +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) -SRCS = $(ASRCS) $(CSRCS) -OBJS = $(AOBJS) $(COBJS) +SRCS = $(ASRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) ifeq ($(WINTOOL),y) - BIN = "${shell cygpath -w $(APPDIR)/libapps$(LIBEXT)}" + BIN = "${shell cygpath -w $(APPDIR)/libapps$(LIBEXT)}" else - BIN = "$(APPDIR)/libapps$(LIBEXT)" + BIN = "$(APPDIR)/libapps$(LIBEXT)" endif -ROOTDEPPATH = --dep-path . +ROOTDEPPATH = --dep-path . --dep-path tests -# Common build +# Build targets -VPATH = +VPATH = tests all: .built -.PHONY: headers clean_tests clean depend disclean +.PHONY: really_build clean_tests clean depend disclean $(AOBJS): %$(OBJEXT): %.S $(call ASSEMBLE, $<, $@) @@ -69,15 +69,21 @@ $(AOBJS): %$(OBJEXT): %.S $(COBJS): %$(OBJEXT): %.c $(call COMPILE, $<, $@) -headers: - @$(MAKE) -C tests TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" CROSSDEV=$(CROSSDEV) +# This is a little messy. The build is broken into two pieces: (1) the +# tests/ 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. -.built: headers $(OBJS) +really_build: $(OBJS) @( for obj in $(OBJS) ; do \ $(call ARCHIVE, $(BIN), $${obj}); \ done ; ) @touch .built +.built: + @$(MAKE) -C tests TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" CROSSDEV=$(CROSSDEV) + @$(MAKE) TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" really_build + context: # We can't make dependencies in this directory because the required diff --git a/apps/examples/elf/elf_main.c b/apps/examples/elf/elf_main.c index 3a6eae9d9e..23a6b2d212 100644 --- a/apps/examples/elf/elf_main.c +++ b/apps/examples/elf/elf_main.c @@ -52,10 +52,10 @@ #include <nuttx/ramdisk.h> #include <nuttx/binfmt/binfmt.h> #include <nuttx/binfmt/elf.h> +#include <nuttx/binfmt/symtab.h> #include "tests/romfs.h" #include "tests/dirlist.h" -#include "tests/symtab.h" /**************************************************************************** * Definitions @@ -135,6 +135,13 @@ static const char delimiter[] = static char path[128]; /**************************************************************************** + * Symbols from Auto-Generated Code + ****************************************************************************/ + +extern const struct symtab_s exports[]; +extern const int nexports; + +/**************************************************************************** * Private Functions ****************************************************************************/ @@ -207,7 +214,7 @@ int elf_main(int argc, char *argv[]) bin.filename = path; bin.exports = exports; - bin.nexports = NEXPORTS; + bin.nexports = nexports; ret = load_module(&bin); if (ret < 0) diff --git a/apps/examples/elf/tests/Makefile b/apps/examples/elf/tests/Makefile index c4a0eec4ca..f834f6c780 100644 --- a/apps/examples/elf/tests/Makefile +++ b/apps/examples/elf/tests/Makefile @@ -34,35 +34,53 @@ ############################################################################ # Most of these do no build yet -SUBDIRS = errno hello hello++ longjmp mutex pthread signal task struct + +ALL_SUBDIRS = errno hello hello++ longjmp mutex pthread signal task struct +BUILD_SUBDIRS = errno hello task struct + +ifeq ($(CONFIG_HAVE_CXX),y) +BUILD_SUBDIRS += hello++ +endif + +ifeq ($(CONFIG_EXAMPLES_ELF_LONGJMP),y) +BUILD_SUBDIRS += longjmp +endif + +ifneq ($(CONFIG_DISABLE_PTHREAD),y) +BUILD_SUBDIRS += mutex pthread +endif + +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +BUILD_SUBDIRS += signal +endif ELF_DIR = $(APPDIR)/examples/elf TESTS_DIR = $(ELF_DIR)/tests ROMFS_DIR = $(TESTS_DIR)/romfs ROMFS_IMG = $(TESTS_DIR)/romfs.img ROMFS_HDR = $(TESTS_DIR)/romfs.h -ROMFS_DIRLIST = $(TESTS_DIR)/dirlist.h -SYMTAB = $(TESTS_DIR)/symtab.h +DIRLIST_HDR = $(TESTS_DIR)/dirlist.h +SYMTAB_SRC = $(TESTS_DIR)/symtab.c define DIR_template $(1)_$(2): @$(MAKE) -C $(1) $(3) TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)" CROSSDEV=$(CROSSDEV) endef -all: $(ROMFS_HDR) $(ROMFS_DIRLIST) $(SYMTAB) +all: $(ROMFS_HDR) $(DIRLIST_HDR) $(SYMTAB_SRC) .PHONY: all build clean install populate -$(foreach DIR, $(SUBDIRS), $(eval $(call DIR_template,$(DIR),build, all))) -$(foreach DIR, $(SUBDIRS), $(eval $(call DIR_template,$(DIR),clean,clean))) -$(foreach DIR, $(SUBDIRS), $(eval $(call DIR_template,$(DIR),install,install))) +$(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, $(SUBDIRS), $(DIR)_build) +build: $(foreach DIR, $(BUILD_SUBDIRS), $(DIR)_build) # Install each program in the romfs directory -install: $(foreach DIR, $(SUBDIRS), $(DIR)_install) +install: $(foreach DIR, $(BUILD_SUBDIRS), $(DIR)_install) # Create the romfs directory @@ -85,16 +103,16 @@ $(ROMFS_HDR) : $(ROMFS_IMG) # Create the dirlist.h header file from the romfs directory -$(ROMFS_DIRLIST) : populate +$(DIRLIST_HDR) : populate @$(TESTS_DIR)/mkdirlist.sh $(ROMFS_DIR) >$@ # Create the exported symbol table list from the derived *-thunk.S files -$(SYMTAB): build - @$(TESTS_DIR)/mksymtab.sh $(TESTS_DIR) >$@ +$(SYMTAB_SRC): build + @$(TESTS_DIR)/mksymtab.sh -t varlist.tmp $(ROMFS_DIR) >$@ # Clean each subdirectory -clean: $(foreach DIR, $(SUBDIRS), $(DIR)_clean) - @rm -f $(ROMFS_HDR) $(ROMFS_IMG) $(SYMTAB) +clean: $(foreach DIR, $(ALL_SUBDIRS), $(DIR)_clean) + @rm -f $(ROMFS_HDR) $(ROMFS_IMG) $(SYMTAB_SRC) varlist.tmp @rm -rf $(ROMFS_DIR) diff --git a/apps/examples/elf/tests/errno/Makefile b/apps/examples/elf/tests/errno/Makefile index 3c299b16df..92cff9e12f 100644 --- a/apps/examples/elf/tests/errno/Makefile +++ b/apps/examples/elf/tests/errno/Makefile @@ -45,7 +45,7 @@ all: $(BIN) $(OBJS): %.o: %.c @echo "CC: $<" - @$(CC) -c $(CFLAGS) $< -o $@ + @$(CC) -c $(CELFFLAGS) $< -o $@ $(BIN): $(OBJS) @echo "LD: $<" diff --git a/apps/examples/elf/tests/hello/Makefile b/apps/examples/elf/tests/hello/Makefile index c3a3dacaf1..e1c396c3c7 100644 --- a/apps/examples/elf/tests/hello/Makefile +++ b/apps/examples/elf/tests/hello/Makefile @@ -45,7 +45,7 @@ all: $(BIN) $(OBJS): %.o: %.c @echo "CC: $<" - @$(CC) -c $(CFLAGS) $< -o $@ + @$(CC) -c $(CELFFLAGS) $< -o $@ $(BIN): $(OBJS) @echo "LD: $<" diff --git a/apps/examples/elf/tests/longjmp/Makefile b/apps/examples/elf/tests/longjmp/Makefile index d737718e05..0cafe05e37 100644 --- a/apps/examples/elf/tests/longjmp/Makefile +++ b/apps/examples/elf/tests/longjmp/Makefile @@ -45,7 +45,7 @@ all: $(BIN) $(OBJS): %.o: %.c @echo "CC: $<" - @$(CC) -c $(CFLAGS) $< -o $@ + @$(CC) -c $(CELFFLAGS) $< -o $@ $(BIN): $(OBJS) @echo "LD: $<" diff --git a/apps/examples/elf/tests/mksymtab.sh b/apps/examples/elf/tests/mksymtab.sh index fa1a2d0302..56be10f73d 100755 --- a/apps/examples/elf/tests/mksymtab.sh +++ b/apps/examples/elf/tests/mksymtab.sh @@ -1,6 +1,24 @@ #!/bin/bash -usage="Usage: %0 <test-dir-path>" +usage="Usage: $0 [-t <tmp-file>] <test-dir-path>" + +# Check for the optional tempory file name + +tmpfile=varlist.tmp +if [ "X${1}" = "X-t" ]; then + shift + tmpfile=$1 + shift + + if [ -z "$tmpfile" ]; then + echo "ERROR: Missing <tmpfile>" + echo "" + echo $usage + exit 1 + fi +fi + +# Check for the required ROMFS directory path dir=$1 if [ -z "$dir" ]; then @@ -17,23 +35,33 @@ if [ ! -d "$dir" ]; then exit 1 fi -varlist=`find $dir -name "*-thunk.S"| xargs grep -h asciz | cut -f3 | sort | uniq` +# Extract all of the undefined symbols from the ELF files and create a +# list of sorted, unique undefined variable names. -echo "#ifndef __EXAMPLES_ELF_TESTS_SYMTAB_H" -echo "#define __EXAMPLES_ELF_TESTS_SYMTAB_H" -echo "" +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 "" -echo "static const struct symtab_s exports[] = " + +for var in $varlist; do + echo "extern void *${var};" +done + +echo "" +echo "const struct symtab_s exports[] = " echo "{" -for string in $varlist; do - var=`echo $string | sed -e "s/\"//g"` - echo " {$string, $var}," +for var in $varlist; do + echo " {\"${var}\", &${var}}," done echo "};" -echo "#define NEXPORTS (sizeof(exports)/sizeof(struct symtab_s))" echo "" -echo "#endif /* __EXAMPLES_ELF_TESTS_SYMTAB_H */" +echo "const int nexports = sizeof(exports) / sizeof(struct symtab_s);" diff --git a/apps/examples/elf/tests/mutex/Makefile b/apps/examples/elf/tests/mutex/Makefile index 7f0a5493e9..efce216d87 100644 --- a/apps/examples/elf/tests/mutex/Makefile +++ b/apps/examples/elf/tests/mutex/Makefile @@ -45,7 +45,7 @@ all: $(BIN) $(OBJS): %.o: %.c @echo "CC: $<" - @$(CC) -c $(CFLAGS) $< -o $@ + @$(CC) -c $(CELFFLAGS) $< -o $@ $(BIN): $(OBJS) @echo "LD: $<" diff --git a/apps/examples/elf/tests/pthread/Makefile b/apps/examples/elf/tests/pthread/Makefile index 8db290e6ea..134fabe01a 100644 --- a/apps/examples/elf/tests/pthread/Makefile +++ b/apps/examples/elf/tests/pthread/Makefile @@ -45,7 +45,7 @@ all: $(BIN) $(OBJS): %.o: %.c @echo "CC: $<" - @$(CC) -c $(CFLAGS) $< -o $@ + @$(CC) -c $(CELFFLAGS) $< -o $@ $(BIN): $(OBJS) @echo "LD: $<" diff --git a/apps/examples/elf/tests/signal/Makefile b/apps/examples/elf/tests/signal/Makefile index 4338aa48da..08710aeaa5 100644 --- a/apps/examples/elf/tests/signal/Makefile +++ b/apps/examples/elf/tests/signal/Makefile @@ -45,7 +45,7 @@ all: $(BIN) $(OBJS): %.o: %.c @echo "CC: $<" - @$(CC) -c $(CFLAGS) $< -o $@ + @$(CC) -c $(CELFFLAGS) $< -o $@ $(BIN): $(OBJS) @echo "LD: $<" diff --git a/apps/examples/elf/tests/signal/signal.c b/apps/examples/elf/tests/signal/signal.c index 0d2e9e6cc2..b40da7a864 100644 --- a/apps/examples/elf/tests/signal/signal.c +++ b/apps/examples/elf/tests/signal/signal.c @@ -38,6 +38,7 @@ ****************************************************************************/ #include <sys/types.h> + #include <stdio.h> #include <stdlib.h> #include <signal.h> @@ -66,22 +67,7 @@ static int sigusr2_rcvd = 0; ****************************************************************************/ /**************************************************************************** - * Name: sigusr1_sighandler - ****************************************************************************/ - -/* NOTE: it is necessary for functions that are referred to by function pointers - * pointer to be declared with global scope (at least for ARM). Otherwise, - * a relocation type that is not supported by ELF is generated by GCC. - */ - -void sigusr1_sighandler(int signo) -{ - printf("sigusr1_sighandler: Received SIGUSR1, signo=%d\n", signo); - sigusr1_rcvd = 1; -} - -/**************************************************************************** - * Name: sigusr2_sigaction + * Name: siguser_action ***************************************************************************/ /* NOTE: it is necessary for functions that are referred to by function pointers @@ -89,50 +75,33 @@ void sigusr1_sighandler(int signo) * a relocation type that is not supported by ELF is generated by GCC. */ -#ifdef __USE_POSIX199309 -void sigusr2_sigaction(int signo, siginfo_t *siginfo, void *arg) +void siguser_action(int signo, siginfo_t *siginfo, void *arg) { - printf("sigusr2_sigaction: Received SIGUSR2, signo=%d siginfo=%p arg=%p\n", + printf("siguser_action: Received signo=%d siginfo=%p arg=%p\n", signo, siginfo, arg); -#ifdef HAVE_SIGQUEUE + if (signo == SIGUSR1) + { + printf(" SIGUSR1 received\n"); + sigusr2_rcvd = 1; + } + else if (signo == SIGUSR2) + { + printf(" SIGUSR2 received\n"); + sigusr1_rcvd = 2; + } + else + { + printf(" ERROR: Unexpected signal\n"); + } + if (siginfo) { + printf("siginfo:\n"); printf(" si_signo = %d\n", siginfo->si_signo); - printf(" si_errno = %d\n", siginfo->si_errno); printf(" si_code = %d\n", siginfo->si_code); - printf(" si_pid = %d\n", siginfo->si_pid); - printf(" si_uid = %d\n", siginfo->si_uid); - printf(" si_status = %d\n", siginfo->si_status); - printf(" si_utime = %ld\n", (long)siginfo->si_utime); - printf(" si_stime = %ld\n", (long)siginfo->si_stime); printf(" si_value = %d\n", siginfo->si_value.sival_int); - printf(" si_int = %d\n", siginfo->si_int); - printf(" si_ptr = %p\n", siginfo->si_ptr); - printf(" si_addr = %p\n", siginfo->si_addr); - printf(" si_band = %ld\n", siginfo->si_band); - printf(" si_fd = %d\n", siginfo->si_fd); } -#endif - sigusr2_rcvd = 1; -} -#else -void sigusr2_sigaction(int signo) -{ - printf("sigusr2_sigaction: Received SIGUSR2, signo=%d\n", signo); - sigusr2_rcvd = 1; -} - -#endif - -/**************************************************************************** - * Name: sigusr2_sighandler - ****************************************************************************/ - -static void sigusr2_sighandler(int signo) -{ - printf("sigusr2_sighandler: Received SIGUSR2, signo=%d\n", signo); - sigusr2_rcvd = 1; } /**************************************************************************** @@ -146,39 +115,36 @@ static void sigusr2_sighandler(int signo) int main(int argc, char **argv) { struct sigaction act; - struct sigaction oact; - void (*old_sigusr1_sighandler)(int signo); - void (*old_sigusr2_sighandler)(int signo); + struct sigaction oact1; + struct sigaction oact2; pid_t mypid = getpid(); -#if defined(__USE_POSIX199309) && defined(HAVE_SIGQUEUE) - sigval_t sigval; -#endif + union sigval sigval; int status; printf("Setting up signal handlers from pid=%d\n", mypid); - /* Set up so that sigusr1_sighandler will respond to SIGUSR1 */ + /* Set up so that siguser_action will respond to SIGUSR1 */ - old_sigusr1_sighandler = signal(SIGUSR1, sigusr1_sighandler); - if (old_sigusr1_sighandler == SIG_ERR) + memset(&act, 0, sizeof(struct sigaction)); + act.sa_sigaction = siguser_action; + act.sa_flags = SA_SIGINFO; + + (void)sigemptyset(&act.sa_mask); + + status = sigaction(SIGUSR1, &act, &oact1); + if (status != 0) { fprintf(stderr, "Failed to install SIGUSR1 handler, errno=%d\n", errno); - exit(1); + exit(2); } - printf("Old SIGUSR1 sighandler at %p\n", old_sigusr1_sighandler); - printf("New SIGUSR1 sighandler at %p\n", sigusr1_sighandler); - - /* Set up so that sigusr2_sigaction will respond to SIGUSR2 */ - - memset(&act, 0, sizeof(struct sigaction)); - act.sa_sigaction = sigusr2_sigaction; - act.sa_flags = SA_SIGINFO; + printf("Old SIGUSR1 sighandler at %p\n", oact1.sa_handler); + printf("New SIGUSR1 sighandler at %p\n", siguser_action); - (void)sigemptyset(&act.sa_mask); + /* Set up so that siguser_action will respond to SIGUSR2 */ - status = sigaction(SIGUSR2, &act, &oact); + status = sigaction(SIGUSR2, &act, &oact2); if (status != 0) { fprintf(stderr, "Failed to install SIGUSR2 handler, errno=%d\n", @@ -186,18 +152,19 @@ int main(int argc, char **argv) exit(2); } - printf("Old SIGUSR2 sighandler at %p\n", oact.sa_handler); - printf("New SIGUSR2 sighandler at %p\n", sigusr2_sigaction); - printf("Raising SIGUSR1 from pid=%d\n", mypid); + printf("Old SIGUSR2 sighandler at %p\n", oact2.sa_handler); + printf("New SIGUSR2 sighandler at %p\n", siguser_action); + printf("Raising SIGUSR1 from pid=%d\n", mypid); fflush(stdout); usleep(SHORT_DELAY); - /* Send SIGUSR1 to ourselves via raise() */ + /* Send SIGUSR1 to ourselves via kill() */ - status = raise(SIGUSR1); + printf("Kill-ing SIGUSR1 from pid=%d\n", mypid); + status = kill(0, SIGUSR1); if (status != 0) { - fprintf(stderr, "Failed to raise SIGUSR1, errno=%d\n", errno); + fprintf(stderr, "Failed to kill SIGUSR1, errno=%d\n", errno); exit(3); } @@ -211,14 +178,14 @@ int main(int argc, char **argv) fprintf(stderr, "SIGUSR1 not received\n"); exit(4); } + sigusr1_rcvd = 0; /* Send SIGUSR2 to ourselves */ - printf("Killing SIGUSR2 from pid=%d\n", mypid); + printf("sigqueue-ing SIGUSR2 from pid=%d\n", mypid); fflush(stdout); usleep(SHORT_DELAY); -#if defined(__USE_POSIX199309) && defined(HAVE_SIGQUEUE) /* Send SIGUSR2 to ourselves via sigqueue() */ sigval.sival_int = 87; @@ -230,20 +197,8 @@ int main(int argc, char **argv) } usleep(SHORT_DELAY); - printf("SIGUSR2 queued from pid=%d, sigval=97\n", mypid); -#else - /* Send SIGUSR2 to ourselves via kill() */ - - status = kill(mypid, SIGUSR2); - if (status != 0) - { - fprintf(stderr, "Failed to kill SIGUSR2, errno=%d\n", errno); - exit(5); - } + printf("SIGUSR2 queued from pid=%d, sigval=87\n", mypid); - usleep(SHORT_DELAY); - printf("SIGUSR2 killed from pid=%d\n", mypid); -#endif /* Verify that SIGUSR2 was received */ if (sigusr2_rcvd == 0) @@ -251,32 +206,33 @@ int main(int argc, char **argv) fprintf(stderr, "SIGUSR2 not received\n"); exit(6); } + sigusr2_rcvd = 0; - /* Remove the sigusr2_sigaction handler and replace the SIGUSR2 + /* Remove the siguser_action handler and replace the SIGUSR2 * handler with sigusr2_sighandler. */ printf("Resetting SIGUSR2 signal handler from pid=%d\n", mypid); - old_sigusr2_sighandler = signal(SIGUSR2, sigusr2_sighandler); - if (old_sigusr2_sighandler == SIG_ERR) + status = sigaction(SIGUSR2, &oact2, &act); + if (status != 0) { - fprintf(stderr, "Failed to install SIGUSR2 handler, errno=%d\n", + fprintf(stderr, "Failed to install SIGUSR1 handler, errno=%d\n", errno); - exit(7); + exit(2); } - printf("Old SIGUSR2 sighandler at %p\n", old_sigusr2_sighandler); - printf("New SIGUSR2 sighandler at %p\n", sigusr2_sighandler); + printf("Old SIGUSR1 sighandler at %p\n", act.sa_handler); + printf("New SIGUSR1 sighandler at %p\n", oact1.sa_handler); - /* Verify that the handler that was removed was sigusr2_sigaction */ + /* Verify that the handler that was removed was siguser_action */ - if ((void*)old_sigusr2_sighandler != (void*)sigusr2_sigaction) + if ((void*)act.sa_handler != (void*)siguser_action) { fprintf(stderr, - "Old SIGUSR2 signhanlder (%p) is not sigusr2_sigation (%p)\n", - old_sigusr2_sighandler, sigusr2_sigaction); + "Old SIGUSR2 signal handler (%p) is not siguser_action (%p)\n", + act.sa_handler, siguser_action); exit(8); } @@ -302,6 +258,7 @@ int main(int argc, char **argv) fprintf(stderr, "SIGUSR2 not received\n"); exit(10); } + sigusr2_rcvd = 0; return 0; diff --git a/apps/examples/elf/tests/struct/Makefile b/apps/examples/elf/tests/struct/Makefile index c15d8fc476..3aa0e4a572 100644 --- a/apps/examples/elf/tests/struct/Makefile +++ b/apps/examples/elf/tests/struct/Makefile @@ -36,7 +36,7 @@ -include $(TOPDIR)/.config -include $(TOPDIR)/Make.defs -CFLAGS += -I. +CELFFLAGS += -I. BIN = struct SRCS = struct_main.c struct_dummy.c @@ -46,7 +46,7 @@ all: $(BIN) $(OBJS): %.o: %.c @echo "CC: $<" - @$(CC) -c $(CFLAGS) $< -o $@ + @$(CC) -c $(CELFFLAGS) $< -o $@ $(BIN): $(OBJS) @echo "LD: $<" diff --git a/apps/examples/elf/tests/task/Makefile b/apps/examples/elf/tests/task/Makefile index 208b228b3a..63a2eb211c 100644 --- a/apps/examples/elf/tests/task/Makefile +++ b/apps/examples/elf/tests/task/Makefile @@ -45,7 +45,7 @@ all: $(BIN) $(OBJS): %.o: %.c @echo "CC: $<" - @$(CC) -c $(CFLAGS) $< -o $@ + @$(CC) -c $(CELFFLAGS) $< -o $@ $(BIN): $(OBJS) @echo "LD: $<" diff --git a/apps/examples/nxflat/tests/mksymtab.sh b/apps/examples/nxflat/tests/mksymtab.sh index 4b5347f17f..27abc4b41a 100755 --- a/apps/examples/nxflat/tests/mksymtab.sh +++ b/apps/examples/nxflat/tests/mksymtab.sh @@ -1,6 +1,6 @@ #!/bin/bash -usage="Usage: %0 <test-dir-path>" +usage="Usage: $0 <test-dir-path>" dir=$1 if [ -z "$dir" ]; then diff --git a/apps/examples/nxflat/tests/signal/signal.c b/apps/examples/nxflat/tests/signal/signal.c index 2df5baaa24..c5ea6bdcc5 100644 --- a/apps/examples/nxflat/tests/signal/signal.c +++ b/apps/examples/nxflat/tests/signal/signal.c @@ -1,7 +1,7 @@ /**************************************************************************** * examples/nxflat/tests/signal/signal.c * - * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -67,73 +67,41 @@ static int sigusr2_rcvd = 0; ****************************************************************************/ /**************************************************************************** - * Name: sigusr1_sighandler - ****************************************************************************/ - -/* NOTE: it is necessary for functions that are referred to by function pointers - * pointer to be declared with global scope (at least for ARM). Otherwise, - * a relocation type that is not supported by NXFLAT is generated by GCC. - */ - -void sigusr1_sighandler(int signo) -{ - printf("sigusr1_sighandler: Received SIGUSR1, signo=%d\n", signo); - sigusr1_rcvd = 1; -} - -/**************************************************************************** - * Name: sigusr2_sigaction + * Name: siguser_action ***************************************************************************/ /* NOTE: it is necessary for functions that are referred to by function pointers * pointer to be declared with global scope (at least for ARM). Otherwise, - * a relocation type that is not supported by NXFLAT is generated by GCC. + * a relocation type that is not supported by ELF is generated by GCC. */ -#ifdef __USE_POSIX199309 -void sigusr2_sigaction(int signo, siginfo_t *siginfo, void *arg) +void siguser_action(int signo, siginfo_t *siginfo, void *arg) { - printf("sigusr2_sigaction: Received SIGUSR2, signo=%d siginfo=%p arg=%p\n", + printf("siguser_action: Received signo=%d siginfo=%p arg=%p\n", signo, siginfo, arg); -#ifdef HAVE_SIGQUEUE + if (signo == SIGUSR1) + { + printf(" SIGUSR1 received\n"); + sigusr2_rcvd = 1; + } + else if (signo == SIGUSR2) + { + printf(" SIGUSR2 received\n"); + sigusr1_rcvd = 2; + } + else + { + printf(" ERROR: Unexpected signal\n"); + } + if (siginfo) { + printf("siginfo:\n"); printf(" si_signo = %d\n", siginfo->si_signo); - printf(" si_errno = %d\n", siginfo->si_errno); printf(" si_code = %d\n", siginfo->si_code); - printf(" si_pid = %d\n", siginfo->si_pid); - printf(" si_uid = %d\n", siginfo->si_uid); - printf(" si_status = %d\n", siginfo->si_status); - printf(" si_utime = %ld\n", (long)siginfo->si_utime); - printf(" si_stime = %ld\n", (long)siginfo->si_stime); printf(" si_value = %d\n", siginfo->si_value.sival_int); - printf(" si_int = %d\n", siginfo->si_int); - printf(" si_ptr = %p\n", siginfo->si_ptr); - printf(" si_addr = %p\n", siginfo->si_addr); - printf(" si_band = %ld\n", siginfo->si_band); - printf(" si_fd = %d\n", siginfo->si_fd); } -#endif - sigusr2_rcvd = 1; -} -#else -void sigusr2_sigaction(int signo) -{ - printf("sigusr2_sigaction: Received SIGUSR2, signo=%d\n", signo); - sigusr2_rcvd = 1; -} - -#endif - -/**************************************************************************** - * Name: sigusr2_sighandler - ****************************************************************************/ - -static void sigusr2_sighandler(int signo) -{ - printf("sigusr2_sighandler: Received SIGUSR2, signo=%d\n", signo); - sigusr2_rcvd = 1; } /**************************************************************************** @@ -147,39 +115,36 @@ static void sigusr2_sighandler(int signo) int main(int argc, char **argv) { struct sigaction act; - struct sigaction oact; - void (*old_sigusr1_sighandler)(int signo); - void (*old_sigusr2_sighandler)(int signo); + struct sigaction oact1; + struct sigaction oact2; pid_t mypid = getpid(); -#if defined(__USE_POSIX199309) && defined(HAVE_SIGQUEUE) - sigval_t sigval; -#endif + union sigval sigval; int status; printf("Setting up signal handlers from pid=%d\n", mypid); - /* Set up so that sigusr1_sighandler will respond to SIGUSR1 */ + /* Set up so that siguser_action will respond to SIGUSR1 */ + + memset(&act, 0, sizeof(struct sigaction)); + act.sa_sigaction = siguser_action; + act.sa_flags = SA_SIGINFO; - old_sigusr1_sighandler = signal(SIGUSR1, sigusr1_sighandler); - if (old_sigusr1_sighandler == SIG_ERR) + (void)sigemptyset(&act.sa_mask); + + status = sigaction(SIGUSR1, &act, &oact1); + if (status != 0) { fprintf(stderr, "Failed to install SIGUSR1 handler, errno=%d\n", errno); - exit(1); + exit(2); } - printf("Old SIGUSR1 sighandler at %p\n", old_sigusr1_sighandler); - printf("New SIGUSR1 sighandler at %p\n", sigusr1_sighandler); - - /* Set up so that sigusr2_sigaction will respond to SIGUSR2 */ - - memset(&act, 0, sizeof(struct sigaction)); - act.sa_sigaction = sigusr2_sigaction; - act.sa_flags = SA_SIGINFO; + printf("Old SIGUSR1 sighandler at %p\n", oact1.sa_handler); + printf("New SIGUSR1 sighandler at %p\n", siguser_action); - (void)sigemptyset(&act.sa_mask); + /* Set up so that siguser_action will respond to SIGUSR2 */ - status = sigaction(SIGUSR2, &act, &oact); + status = sigaction(SIGUSR2, &act, &oact2); if (status != 0) { fprintf(stderr, "Failed to install SIGUSR2 handler, errno=%d\n", @@ -187,18 +152,19 @@ int main(int argc, char **argv) exit(2); } - printf("Old SIGUSR2 sighandler at %p\n", oact.sa_handler); - printf("New SIGUSR2 sighandler at %p\n", sigusr2_sigaction); - printf("Raising SIGUSR1 from pid=%d\n", mypid); + printf("Old SIGUSR2 sighandler at %p\n", oact2.sa_handler); + printf("New SIGUSR2 sighandler at %p\n", siguser_action); + printf("Raising SIGUSR1 from pid=%d\n", mypid); fflush(stdout); usleep(SHORT_DELAY); - /* Send SIGUSR1 to ourselves via raise() */ + /* Send SIGUSR1 to ourselves via kill() */ - status = raise(SIGUSR1); + printf("Kill-ing SIGUSR1 from pid=%d\n", mypid); + status = kill(0, SIGUSR1); if (status != 0) { - fprintf(stderr, "Failed to raise SIGUSR1, errno=%d\n", errno); + fprintf(stderr, "Failed to kill SIGUSR1, errno=%d\n", errno); exit(3); } @@ -212,14 +178,14 @@ int main(int argc, char **argv) fprintf(stderr, "SIGUSR1 not received\n"); exit(4); } + sigusr1_rcvd = 0; /* Send SIGUSR2 to ourselves */ - printf("Killing SIGUSR2 from pid=%d\n", mypid); + printf("sigqueue-ing SIGUSR2 from pid=%d\n", mypid); fflush(stdout); usleep(SHORT_DELAY); -#if defined(__USE_POSIX199309) && defined(HAVE_SIGQUEUE) /* Send SIGUSR2 to ourselves via sigqueue() */ sigval.sival_int = 87; @@ -231,20 +197,8 @@ int main(int argc, char **argv) } usleep(SHORT_DELAY); - printf("SIGUSR2 queued from pid=%d, sigval=97\n", mypid); -#else - /* Send SIGUSR2 to ourselves via kill() */ + printf("SIGUSR2 queued from pid=%d, sigval=87\n", mypid); - status = kill(mypid, SIGUSR2); - if (status != 0) - { - fprintf(stderr, "Failed to kill SIGUSR2, errno=%d\n", errno); - exit(5); - } - - usleep(SHORT_DELAY); - printf("SIGUSR2 killed from pid=%d\n", mypid); -#endif /* Verify that SIGUSR2 was received */ if (sigusr2_rcvd == 0) @@ -252,32 +206,33 @@ int main(int argc, char **argv) fprintf(stderr, "SIGUSR2 not received\n"); exit(6); } + sigusr2_rcvd = 0; - /* Remove the sigusr2_sigaction handler and replace the SIGUSR2 + /* Remove the siguser_action handler and replace the SIGUSR2 * handler with sigusr2_sighandler. */ printf("Resetting SIGUSR2 signal handler from pid=%d\n", mypid); - old_sigusr2_sighandler = signal(SIGUSR2, sigusr2_sighandler); - if (old_sigusr2_sighandler == SIG_ERR) + status = sigaction(SIGUSR2, &oact2, &act); + if (status != 0) { - fprintf(stderr, "Failed to install SIGUSR2 handler, errno=%d\n", + fprintf(stderr, "Failed to install SIGUSR1 handler, errno=%d\n", errno); - exit(7); + exit(2); } - printf("Old SIGUSR2 sighandler at %p\n", old_sigusr2_sighandler); - printf("New SIGUSR2 sighandler at %p\n", sigusr2_sighandler); + printf("Old SIGUSR1 sighandler at %p\n", act.sa_handler); + printf("New SIGUSR1 sighandler at %p\n", oact1.sa_handler); - /* Verify that the handler that was removed was sigusr2_sigaction */ + /* Verify that the handler that was removed was siguser_action */ - if ((void*)old_sigusr2_sighandler != (void*)sigusr2_sigaction) + if ((void*)act.sa_handler != (void*)siguser_action) { fprintf(stderr, - "Old SIGUSR2 signhanlder (%p) is not sigusr2_sigation (%p)\n", - old_sigusr2_sighandler, sigusr2_sigaction); + "Old SIGUSR2 signal handler (%p) is not siguser_action (%p)\n", + act.sa_handler, siguser_action); exit(8); } @@ -303,6 +258,7 @@ int main(int argc, char **argv) fprintf(stderr, "SIGUSR2 not received\n"); exit(10); } + sigusr2_rcvd = 0; return 0; diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 7c4a5a8cd8..a80e5009a8 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -3522,3 +3522,5 @@ * configs/stm32f4discovery/elf and configs/stm32f4discovery/scripts/gnu-elf.ld Add a configuration for testing the ARM ELF loader. * binfmt/libelf: Can't use fstat(). NuttX does not yet support it. Damn! + * binfmt/libelf: The basic ELF module execution appears fully functional. + diff --git a/nuttx/arch/arm/src/armv7-m/up_elf.c b/nuttx/arch/arm/src/armv7-m/up_elf.c index 5f77470fa1..202c902b4b 100644 --- a/nuttx/arch/arm/src/armv7-m/up_elf.c +++ b/nuttx/arch/arm/src/armv7-m/up_elf.c @@ -218,8 +218,8 @@ int arch_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym, * The branch target is encoded in these bits: * * S = upper_insn[10] - * imm10 = upper_insn[9:0] - * imm11 = lower_insn[10:0] + * imm10 = upper_insn[0:9] + * imm11 = lower_insn[0:10] * J1 = lower_insn[13] * J2 = lower_insn[11] */ @@ -227,7 +227,7 @@ int arch_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym, upper_insn = (uint32_t)(*(uint16_t*)addr); lower_insn = (uint32_t)(*(uint16_t*)(addr + 2)); - bvdbg("Performing JUMP24 [%d] link at addr=%08lx [%04x %04x] to sym=%p st_value=%08lx\n", + bvdbg("Performing THM_JUMP24 [%d] link at addr=%08lx [%04x %04x] to sym=%p st_value=%08lx\n", ELF32_R_TYPE(rel->r_info), (long)addr, (int)upper_insn, (int)lower_insn, sym, (long)sym->st_value); @@ -235,9 +235,9 @@ int arch_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym, * * offset[24] = S * offset[23] = ~(J1 ^ S) - * offset[22 = ~(J2 ^ S)] - * offset[21:12] = imm10 - * offset[11:1] = imm11 + * offset[22] = ~(J2 ^ S)] + * offset[12:21] = imm10 + * offset[1:11] = imm11 * offset[0] = 0 */ @@ -245,11 +245,12 @@ int arch_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym, J1 = (lower_insn >> 13) & 1; J2 = (lower_insn >> 11) & 1; - offset = (S << 24) | - ((~(J1 ^ S) & 1) << 23) | - ((~(J2 ^ S) & 1) << 22) | - ((upper_insn & 0x03ff) << 12) | - ((lower_insn & 0x07ff) << 1); + offset = (S << 24) | /* S - > offset[24] */ + ((~(J1 ^ S) & 1) << 23) | /* J1 -> offset[23] */ + ((~(J2 ^ S) & 1) << 22) | /* J2 -> offset[22] */ + ((upper_insn & 0x03ff) << 12) | /* imm10 -> offset[12:21] */ + ((lower_insn & 0x07ff) << 1); /* imm11 -> offset[1:11] */ + /* 0 -> offset[0] */ /* Sign extend */ @@ -374,31 +375,31 @@ int arch_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym, * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 * +---+---------------------------------------------------------+ * |OP | | 32-Bit Instructions - * +---+--+-------+--------------+-------------------------------+ - * |0 |1 | imm3 | Rd | imm8 | MOVT Instruction - * +---+--+-------+--------------+-------------------------------+ + * +---+----------+--------------+-------------------------------+ + * |0 | imm3 | Rd | imm8 | MOVT Instruction + * +---+----------+--------------+-------------------------------+ * * The 16-bit immediate value is encoded in these bits: * * i = imm16[11] = upper_insn[10] * imm4 = imm16[12:15] = upper_insn[3:0] - * imm3 = imm16[9:11] = lower_insn[14:12] - * imm8 = imm16[0:8] = lower_insn[7:0] + * imm3 = imm16[8:10] = lower_insn[14:12] + * imm8 = imm16[0:7] = lower_insn[7:0] */ upper_insn = (uint32_t)(*(uint16_t*)addr); lower_insn = (uint32_t)(*(uint16_t*)(addr + 2)); - bvdbg("Performing MOVx [%d] link at addr=%08lx [%04x %04x] to sym=%p st_value=%08lx\n", + bvdbg("Performing THM_MOVx [%d] link at addr=%08lx [%04x %04x] to sym=%p st_value=%08lx\n", ELF32_R_TYPE(rel->r_info), (long)addr, (int)upper_insn, (int)lower_insn, sym, (long)sym->st_value); /* Extract the 16-bit offset from the 32-bit instruction */ - offset = ((upper_insn & 0x000f) << 12) | - ((upper_insn & 0x0400) << 1) | - ((lower_insn & 0x7000) >> 4) | - (lower_insn & 0x00ff); + offset = ((upper_insn & 0x000f) << 12) | /* imm4 -> imm16[8:10] */ + ((upper_insn & 0x0400) << 1) | /* i -> imm16[11] */ + ((lower_insn & 0x7000) >> 4) | /* imm3 -> imm16[8:10] */ + (lower_insn & 0x00ff); /* imm8 -> imm16[0:7] */ /* Sign extend */ @@ -406,8 +407,8 @@ int arch_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym, /* And perform the relocation */ - bvdbg(" S=%d J1=%d J2=%d offset=%08lx branch target=%08lx\n", - S, J1, J2, (long)offset, offset + sym->st_value); + bvdbg(" offset=%08lx branch target=%08lx\n", + (long)offset, offset + sym->st_value); offset += sym->st_value; diff --git a/nuttx/arch/arm/src/stm32/Kconfig b/nuttx/arch/arm/src/stm32/Kconfig index 5fd0ae7a26..acfac81aa0 100644 --- a/nuttx/arch/arm/src/stm32/Kconfig +++ b/nuttx/arch/arm/src/stm32/Kconfig @@ -636,9 +636,11 @@ config ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG config STM32_CCMEXCLUDE bool "Exclude CCM SRAM from the heap" depends on STM32_STM32F20XX || STM32_STM32F40XX - default y if ARCH_DMA + default y if ARCH_DMA || ELF ---help--- - Exclude CCM SRAM from the HEAP because it cannot be used for DMA. + Exclude CCM SRAM from the HEAP because (1) it cannot be used for DMA + and (2) it appears to be impossible to execute ELF modules from CCM + RAM. config STM32_FSMC_SRAM bool "External SRAM on FSMC" diff --git a/nuttx/binfmt/libelf/libelf_bind.c b/nuttx/binfmt/libelf/libelf_bind.c index f41b5a0b6f..54ea8f1f04 100644 --- a/nuttx/binfmt/libelf/libelf_bind.c +++ b/nuttx/binfmt/libelf/libelf_bind.c @@ -142,7 +142,10 @@ static int elf_relocate(FAR struct elf_loadinfo_s *loadinfo, int relidx, int ret; int i; - /* Examine each relocation in the section */ + /* Examine each relocation in the section. 'relsec' is the section + * containing the relations. 'dstsec' is the section containing the data + * to be relocated. + */ for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++) { diff --git a/nuttx/binfmt/libelf/libelf_init.c b/nuttx/binfmt/libelf/libelf_init.c index e1b9f73d69..fa4b7983cb 100644 --- a/nuttx/binfmt/libelf/libelf_init.c +++ b/nuttx/binfmt/libelf/libelf_init.c @@ -154,6 +154,7 @@ int elf_init(FAR const char *filename, FAR struct elf_loadinfo_s *loadinfo) /* Get the length of the file. */ ret = elf_filelen(loadinfo, filename); + if (ret < 0) { bdbg("elf_filelen failed: %d\n", ret); return ret; diff --git a/nuttx/configs/stm32f4discovery/README.txt b/nuttx/configs/stm32f4discovery/README.txt index d1a55daa9d..e8f0ae166b 100644 --- a/nuttx/configs/stm32f4discovery/README.txt +++ b/nuttx/configs/stm32f4discovery/README.txt @@ -1007,6 +1007,10 @@ Where <subdir> is one of the following: 3. By default, this project assumes that you are *NOT* using the DFU bootloader. + 4. This configuration requires that you have the genromfs tool installed + on your system and that you have the full path to the installed genromfs + executable in PATH variable (see apps/examples/README.txt) + ostest: ------ This configuration directory, performs a simple OS test using diff --git a/nuttx/configs/stm32f4discovery/elf/Make.defs b/nuttx/configs/stm32f4discovery/elf/Make.defs index 7f5be08f06..c64102d174 100644 --- a/nuttx/configs/stm32f4discovery/elf/Make.defs +++ b/nuttx/configs/stm32f4discovery/elf/Make.defs @@ -160,6 +160,7 @@ LDNXFLATFLAGS = -e main -s 2048 # ELF module definitions +CELFFLAGS = $(CFLAGS) -mlong-calls LDELFFLAGS = -r -e main ifeq ($(WINTOOL),y) LDELFFLAGS += -T "${shell cygpath -w $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/gnu-elf.ld}" diff --git a/nuttx/configs/stm32f4discovery/elf/defconfig b/nuttx/configs/stm32f4discovery/elf/defconfig index dd5bd28298..6d72e4a9ee 100644 --- a/nuttx/configs/stm32f4discovery/elf/defconfig +++ b/nuttx/configs/stm32f4discovery/elf/defconfig @@ -179,7 +179,7 @@ CONFIG_STM32_USART2=y CONFIG_STM32_JTAG_SW_ENABLE=y # CONFIG_STM32_FORCEPOWER is not set # CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG is not set -# CONFIG_STM32_CCMEXCLUDE is not set +CONFIG_STM32_CCMEXCLUDE=y # # USB Host Configuration @@ -251,7 +251,7 @@ CONFIG_SDCLONE_DISABLE=y # CONFIG_SCHED_WAITPID is not set # CONFIG_SCHED_ATEXIT is not set # CONFIG_SCHED_ONEXIT is not set -CONFIG_USER_ENTRYPOINT="ostest_main" +CONFIG_USER_ENTRYPOINT="elf_main" CONFIG_DISABLE_OS_API=y # CONFIG_DISABLE_CLOCK is not set # CONFIG_DISABLE_POSIX_TIMERS is not set @@ -387,6 +387,7 @@ CONFIG_ELF_ALIGN_LOG2=2 CONFIG_ELF_STACKSIZE=2048 CONFIG_ELF_BUFFERSIZE=128 CONFIG_ELF_BUFFERINCR=32 +# CONFIG_ELF_CONSTRUCTORS is not set CONFIG_SYMTAB_ORDEREDBYNAME=y # @@ -409,7 +410,7 @@ CONFIG_ARCH_LOWPUTC=y CONFIG_LIB_SENDFILE_BUFSIZE=512 # CONFIG_ARCH_ROMGETC is not set # CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set -# CONFIG_HAVE_CXX is not set +CONFIG_HAVE_CXX=y # CONFIG_HAVE_CXXINITIALIZE is not set # CONFIG_CXX_NEWLONG is not set |