summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/examples/README.txt47
-rw-r--r--apps/examples/elf/Kconfig16
-rw-r--r--apps/examples/elf/Makefile9
-rw-r--r--apps/examples/elf/elf_main.c (renamed from apps/examples/elf/elf_main)22
-rw-r--r--apps/examples/elf/tests/errno/Makefile2
-rw-r--r--apps/examples/elf/tests/hello++/Makefile2
-rw-r--r--apps/examples/elf/tests/hello/Makefile2
-rw-r--r--apps/examples/elf/tests/longjmp/Makefile2
-rw-r--r--apps/examples/elf/tests/mutex/Makefile2
-rw-r--r--apps/examples/elf/tests/pthread/Makefile2
-rw-r--r--apps/examples/elf/tests/signal/Makefile2
-rw-r--r--apps/examples/elf/tests/struct/Makefile2
-rw-r--r--apps/examples/elf/tests/task/Makefile2
-rw-r--r--nuttx/Makefile2
-rw-r--r--nuttx/arch/sim/src/up_elf.c4
-rw-r--r--nuttx/arch/x86/src/common/up_elf.c4
-rw-r--r--nuttx/binfmt/elf.c10
-rw-r--r--nuttx/binfmt/libelf/Make.defs2
-rw-r--r--nuttx/binfmt/libelf/libelf_load.c2
-rw-r--r--nuttx/binfmt/libnxflat/Make.defs2
-rw-r--r--nuttx/binfmt/nxflat.c4
-rw-r--r--nuttx/include/elf.h12
-rw-r--r--nuttx/tools/mkconfig.c2
23 files changed, 117 insertions, 39 deletions
diff --git a/apps/examples/README.txt b/apps/examples/README.txt
index 763427e32..fa97bd64e 100644
--- a/apps/examples/README.txt
+++ b/apps/examples/README.txt
@@ -297,6 +297,53 @@ examples/discover
CONFIG_EXAMPLES_DISCOVER_DRIPADDR - Router IP address
CONFIG_EXAMPLES_DISCOVER_NETMASK - Network Mask
+examples/elf
+^^^^^^^^^^^^
+
+ This example builds a small ELF loader test case. This includes several
+ test programs under examples/elf tests. These tests are build using
+ the relocatable ELF format and installed in a ROMFS file system. At run time,
+ each program in the ROMFS file system is executed. Requires CONFIG_ELF.
+ Other configuration options:
+
+ CONFIG_EXAMPLES_ELF_DEVMINOR - 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 ELF executables to be
+ tested. Default: 0
+
+ CONFIG_EXAMPLES_ELF_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. Your top-level nuttx/Make.defs file must 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).
+
+ LDELFFLAGS = -r -e main
+
+ 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
+ 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
+ because they include a lot of "build garbage". You can greately 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
+ 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.
+
examples/ftpc
^^^^^^^^^^^^^
diff --git a/apps/examples/elf/Kconfig b/apps/examples/elf/Kconfig
index aca36f1b9..c62a98486 100644
--- a/apps/examples/elf/Kconfig
+++ b/apps/examples/elf/Kconfig
@@ -10,4 +10,20 @@ config EXAMPLES_ELF
Enable the ELF loader example
if EXAMPLES_ELF
+config EXAMPLES_ELF_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 ELF executables to be tested. Default: 0
+
+config EXAMPLES_ELF_DEVPATH
+ string "ROMFS Devie Path"
+ default "/dev/ram0"
+ ---help---
+ 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"
+
endif
diff --git a/apps/examples/elf/Makefile b/apps/examples/elf/Makefile
index 640e8e427..23a6bcb6f 100644
--- a/apps/examples/elf/Makefile
+++ b/apps/examples/elf/Makefile
@@ -61,7 +61,7 @@ ROOTDEPPATH = --dep-path .
VPATH =
all: .built
-.PHONY: headers clean depend disclean
+.PHONY: headers clean_tests clean depend disclean
$(AOBJS): %$(OBJEXT): %.S
$(call ASSEMBLE, $<, $@)
@@ -72,7 +72,7 @@ $(COBJS): %$(OBJEXT): %.c
headers:
@$(MAKE) -C tests TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" CROSSDEV=$(CROSSDEV)
-.built: $(OBJS)
+.built: headers $(OBJS)
@( for obj in $(OBJS) ; do \
$(call ARCHIVE, $(BIN), $${obj}); \
done ; )
@@ -88,7 +88,10 @@ context:
depend: .depend
-clean:
+clean_tests:
+ @$(MAKE) -C tests TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" CROSSDEV=$(CROSSDEV) clean
+
+clean: clean_tests
@rm -f *.o *~ .*.swp .built
$(call CLEAN)
diff --git a/apps/examples/elf/elf_main b/apps/examples/elf/elf_main.c
index c58b13ffc..5699dd284 100644
--- a/apps/examples/elf/elf_main
+++ b/apps/examples/elf/elf_main.c
@@ -89,9 +89,16 @@
#define SECTORSIZE 512
#define NSECTORS(b) (((b)+SECTORSIZE-1)/SECTORSIZE)
-#define ROMFSDEV "/dev/ram0"
#define MOUNTPT "/mnt/romfs"
+#ifndef CONFIG_EXAMPLES_ELF_DEVMINOR
+# define CONFIG_EXAMPLES_ELF_DEVMINOR 0
+#endif
+
+#ifndef CONFIG_EXAMPLES_ELF_DEVPATH
+# define CONFIG_EXAMPLES_ELF_DEVPATH "/dev/ram0"
+#endif
+
/* If CONFIG_DEBUG is enabled, use dbg instead of printf so that the
* output will be synchronous with the debug output.
*/
@@ -166,8 +173,9 @@ int elf_main(int argc, char *argv[])
/* Create a ROM disk for the ROMFS filesystem */
- message("Registering romdisk\n");
- ret = romdisk_register(0, romfs_img, NSECTORS(romfs_img_len), SECTORSIZE);
+ message("Registering romdisk at /dev/ram%d\n", CONFIG_EXAMPLES_ELF_DEVMINOR);
+ ret = romdisk_register(CONFIG_EXAMPLES_ELF_DEVMINOR, romfs_img,
+ NSECTORS(romfs_img_len), SECTORSIZE);
if (ret < 0)
{
err("ERROR: romdisk_register failed: %d\n", ret);
@@ -178,13 +186,13 @@ int elf_main(int argc, char *argv[])
/* Mount the file system */
message("Mounting ROMFS filesystem at target=%s with source=%s\n",
- MOUNTPT, ROMFSDEV);
+ MOUNTPT, CONFIG_EXAMPLES_ELF_DEVPATH);
- ret = mount(ROMFSDEV, MOUNTPT, "romfs", MS_RDONLY, NULL);
+ ret = mount(CONFIG_EXAMPLES_ELF_DEVPATH, MOUNTPT, "romfs", MS_RDONLY, NULL);
if (ret < 0)
{
err("ERROR: mount(%s,%s,romfs) failed: %s\n",
- ROMFSDEV, MOUNTPT, errno);
+ CONFIG_EXAMPLES_ELF_DEVPATH, MOUNTPT, errno);
elf_uninitialize();
}
@@ -219,6 +227,6 @@ int elf_main(int argc, char *argv[])
sleep(4);
}
- message("End-of-Test.. Exit-ing\n");
+ message("End-of-Test.. Exiting\n");
return 0;
}
diff --git a/apps/examples/elf/tests/errno/Makefile b/apps/examples/elf/tests/errno/Makefile
index d3b12aa2e..3c299b16d 100644
--- a/apps/examples/elf/tests/errno/Makefile
+++ b/apps/examples/elf/tests/errno/Makefile
@@ -39,7 +39,7 @@
BIN = errno
SRCS = $(BIN).c
-OBJS = $(BIN:.c=.o)
+OBJS = $(SRCS:.c=.o)
all: $(BIN)
diff --git a/apps/examples/elf/tests/hello++/Makefile b/apps/examples/elf/tests/hello++/Makefile
index b3d07d262..9de52cfa1 100644
--- a/apps/examples/elf/tests/hello++/Makefile
+++ b/apps/examples/elf/tests/hello++/Makefile
@@ -64,7 +64,7 @@ all: $(BIN1) $(BIN2) $(BIN3) $(BIN4)
$(OBJS): %.o: %.cpp
@echo "CC: $<"
- @$(CXX) -c $(CXXPICFLAGS) $< -o $@
+ @$(CXX) -c $(CXXFLAGS) $< -o $@
# This contains libstdc++ stubs to that you can build C++ code
# without actually having libstdc++
diff --git a/apps/examples/elf/tests/hello/Makefile b/apps/examples/elf/tests/hello/Makefile
index 3b9b06ac4..c3a3dacaf 100644
--- a/apps/examples/elf/tests/hello/Makefile
+++ b/apps/examples/elf/tests/hello/Makefile
@@ -39,7 +39,7 @@
BIN = hello
SRCS = $(BIN).c
-OBJS = $(BIN:.c=.o)
+OBJS = $(SRCS:.c=.o)
all: $(BIN)
diff --git a/apps/examples/elf/tests/longjmp/Makefile b/apps/examples/elf/tests/longjmp/Makefile
index 12d6e443c..d737718e0 100644
--- a/apps/examples/elf/tests/longjmp/Makefile
+++ b/apps/examples/elf/tests/longjmp/Makefile
@@ -39,7 +39,7 @@
BIN = longjmp
SRCS = $(BIN).c
-OBJS = $(BIN:.c=.o)
+OBJS = $(SRCS:.c=.o)
all: $(BIN)
diff --git a/apps/examples/elf/tests/mutex/Makefile b/apps/examples/elf/tests/mutex/Makefile
index 632fed9dd..7f0a5493e 100644
--- a/apps/examples/elf/tests/mutex/Makefile
+++ b/apps/examples/elf/tests/mutex/Makefile
@@ -39,7 +39,7 @@
BIN = mutex
SRCS = $(BIN).c
-OBJS = $(BIN:.c=.o)
+OBJS = $(SRCS:.c=.o)
all: $(BIN)
diff --git a/apps/examples/elf/tests/pthread/Makefile b/apps/examples/elf/tests/pthread/Makefile
index fae6144c2..8db290e6e 100644
--- a/apps/examples/elf/tests/pthread/Makefile
+++ b/apps/examples/elf/tests/pthread/Makefile
@@ -39,7 +39,7 @@
BIN = pthread
SRCS = $(BIN).c
-OBJS = $(BIN:.c=.o)
+OBJS = $(SRCS:.c=.o)
all: $(BIN)
diff --git a/apps/examples/elf/tests/signal/Makefile b/apps/examples/elf/tests/signal/Makefile
index 270444032..4338aa48d 100644
--- a/apps/examples/elf/tests/signal/Makefile
+++ b/apps/examples/elf/tests/signal/Makefile
@@ -39,7 +39,7 @@
BIN = signal
SRCS = $(BIN).c
-OBJS = $(BIN:.c=.o)
+OBJS = $(SRCS:.c=.o)
all: $(BIN)
diff --git a/apps/examples/elf/tests/struct/Makefile b/apps/examples/elf/tests/struct/Makefile
index f98a65e25..c15d8fc47 100644
--- a/apps/examples/elf/tests/struct/Makefile
+++ b/apps/examples/elf/tests/struct/Makefile
@@ -38,7 +38,7 @@
CFLAGS += -I.
-BIN = struct
+BIN = struct
SRCS = struct_main.c struct_dummy.c
OBJS = $(SRCS:.c=.o)
diff --git a/apps/examples/elf/tests/task/Makefile b/apps/examples/elf/tests/task/Makefile
index 28047965e..208b228b3 100644
--- a/apps/examples/elf/tests/task/Makefile
+++ b/apps/examples/elf/tests/task/Makefile
@@ -39,7 +39,7 @@
BIN = task
SRCS = $(BIN).c
-OBJS = $(BIN:.c=.o)
+OBJS = $(SRCS:.c=.o)
all: $(BIN)
diff --git a/nuttx/Makefile b/nuttx/Makefile
index 7a058d88e..73bffc301 100644
--- a/nuttx/Makefile
+++ b/nuttx/Makefile
@@ -644,7 +644,7 @@ ifneq ($(APPDIR),)
fi
@$(MAKE) -C "$(TOPDIR)/$(APPDIR)" TOPDIR="$(TOPDIR)" distclean
@if [ -r _SAVED_APPS_config ]; then \
- @mv _SAVED_APPS_config "$(TOPDIR)/$(APPDIR)/.config" || \
+ mv _SAVED_APPS_config "$(TOPDIR)/$(APPDIR)/.config" || \
{ echo "Copy of _SAVED_APPS_config failed" ; exit 1 ; } \
fi
endif
diff --git a/nuttx/arch/sim/src/up_elf.c b/nuttx/arch/sim/src/up_elf.c
index c6aabdcef..ca3b642dc 100644
--- a/nuttx/arch/sim/src/up_elf.c
+++ b/nuttx/arch/sim/src/up_elf.c
@@ -40,7 +40,9 @@
#include <nuttx/config.h>
#include <stdlib.h>
+#include <elf.h>
#include <errno.h>
+#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/binfmt/elf.h>
@@ -113,7 +115,7 @@ int arch_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym,
{
FAR uint32_t *ptr = (FAR uint32_t *)addr;
- switch (ELF_REL_TYPE(rel->r_info))
+ switch (ELF32_R_TYPE(rel->r_info))
{
case R_386_32:
*ptr += sym->st_value;
diff --git a/nuttx/arch/x86/src/common/up_elf.c b/nuttx/arch/x86/src/common/up_elf.c
index f159c8e51..be166b480 100644
--- a/nuttx/arch/x86/src/common/up_elf.c
+++ b/nuttx/arch/x86/src/common/up_elf.c
@@ -40,7 +40,9 @@
#include <nuttx/config.h>
#include <stdlib.h>
+#include <elf.h>
#include <errno.h>
+#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/binfmt/elf.h>
@@ -113,7 +115,7 @@ int arch_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym,
{
FAR uint32_t *ptr = (FAR uint32_t *)addr;
- switch (ELF_REL_TYPE(rel->r_info))
+ switch (ELF32_R_TYPE(rel->r_info))
{
case R_386_32:
*ptr += sym->st_value;
diff --git a/nuttx/binfmt/elf.c b/nuttx/binfmt/elf.c
index ba12a22ea..d9c3d0b9c 100644
--- a/nuttx/binfmt/elf.c
+++ b/nuttx/binfmt/elf.c
@@ -139,11 +139,11 @@ static void elf_dumploadinfo(FAR struct elf_loadinfo_s *loadinfo)
bdbg(" e_shnum: %d\n", loadinfo->ehdr.e_shnum);
bdbg(" e_shstrndx: %d\n", loadinfo->ehdr.e_shstrndx);
- if (loadinfo->shdr && loadinfo->ehdr.e_shum > 0)
+ if (loadinfo->shdr && loadinfo->ehdr.e_shnum > 0)
{
- for (i = 0; i < loadinfo->ehdr.e_shum; i++)
+ for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
{
- FAR ELF32_Shdr *shdr = &loadinfo->shdr[i];
+ FAR Elf32_Shdr *shdr = &loadinfo->shdr[i];
bdbg("Sections %d:\n", i);
bdbg(" sh_name: %08x\n", shdr->sh_name);
bdbg(" sh_type: %08x\n", shdr->sh_type);
@@ -184,7 +184,7 @@ static int elf_loadbinary(struct binary_s *binp)
elf_dumploadinfo(&loadinfo);
if (ret != 0)
{
- bdbg("Failed to initialize for load of NXFLT program: %d\n", ret);
+ bdbg("Failed to initialize for load of ELF program: %d\n", ret);
goto errout;
}
@@ -194,7 +194,7 @@ static int elf_loadbinary(struct binary_s *binp)
elf_dumploadinfo(&loadinfo);
if (ret != 0)
{
- bdbg("Failed to load NXFLT program binary: %d\n", ret);
+ bdbg("Failed to load ELF program binary: %d\n", ret);
goto errout_with_init;
}
diff --git a/nuttx/binfmt/libelf/Make.defs b/nuttx/binfmt/libelf/Make.defs
index 9e06537bd..a70a127f8 100644
--- a/nuttx/binfmt/libelf/Make.defs
+++ b/nuttx/binfmt/libelf/Make.defs
@@ -41,7 +41,7 @@ BINFMT_CSRCS += elf.c
# ELF library
-BINFMT_CSRCS = libelf_init.c libelf_uninit.c libelf_load.c \
+BINFMT_CSRCS += libelf_init.c libelf_uninit.c libelf_load.c \
libelf_unload.c libelf_verify.c libelf_read.c \
libelf_bind.c libelf_symbols.c
diff --git a/nuttx/binfmt/libelf/libelf_load.c b/nuttx/binfmt/libelf/libelf_load.c
index 758f96548..4a1a561c3 100644
--- a/nuttx/binfmt/libelf/libelf_load.c
+++ b/nuttx/binfmt/libelf/libelf_load.c
@@ -283,8 +283,8 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
/* Update sh_addr to point to copy in memory */
+ bvdbg("%d. %08x->%08x\n", i, (long)shdr->sh_addr, (long)dest);
shdr->sh_addr = (uintptr_t)dest;
- bvdbg("%d. 0x%lx %s\n", (long)shdr->sh_addr, loadinfo->secstrings + shdr->sh_name);
/* Setup the memory pointer for the next time through the loop */
diff --git a/nuttx/binfmt/libnxflat/Make.defs b/nuttx/binfmt/libnxflat/Make.defs
index 4462e9a02..4f522e52b 100644
--- a/nuttx/binfmt/libnxflat/Make.defs
+++ b/nuttx/binfmt/libnxflat/Make.defs
@@ -41,7 +41,7 @@ BINFMT_CSRCS += nxflat.c
# NXFLAT library
-BINFMT_CSRCS = libnxflat_init.c libnxflat_uninit.c libnxflat_load.c \
+BINFMT_CSRCS += libnxflat_init.c libnxflat_uninit.c libnxflat_load.c \
libnxflat_unload.c libnxflat_verify.c libnxflat_read.c \
libnxflat_bind.c
diff --git a/nuttx/binfmt/nxflat.c b/nuttx/binfmt/nxflat.c
index babc51ff9..8d0ecfdcd 100644
--- a/nuttx/binfmt/nxflat.c
+++ b/nuttx/binfmt/nxflat.c
@@ -158,7 +158,7 @@ static int nxflat_loadbinary(struct binary_s *binp)
nxflat_dumploadinfo(&loadinfo);
if (ret != 0)
{
- bdbg("Failed to initialize for load of NXFLT program: %d\n", ret);
+ bdbg("Failed to initialize for load of NXFLAT program: %d\n", ret);
goto errout;
}
@@ -168,7 +168,7 @@ static int nxflat_loadbinary(struct binary_s *binp)
nxflat_dumploadinfo(&loadinfo);
if (ret != 0)
{
- bdbg("Failed to load NXFLT program binary: %d\n", ret);
+ bdbg("Failed to load NXFLAT program binary: %d\n", ret);
goto errout_with_init;
}
diff --git a/nuttx/include/elf.h b/nuttx/include/elf.h
index 1b36701fd..c3fb2732d 100644
--- a/nuttx/include/elf.h
+++ b/nuttx/include/elf.h
@@ -166,9 +166,9 @@
/* Definitions for Elf32_Sym::st_info */
-#define ELF32_ST_BIND(i) ((i)>>4)
-#define ELF32_ST_TYPE(i) ((i)&0xf)
-#define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
+#define ELF32_ST_BIND(i) ((i) >> 4)
+#define ELF32_ST_TYPE(i) ((i) & 0xf)
+#define ELF32_ST_INFO(b,t) (((b) << 4) | ((t) & 0xf))
/* Figure 4-16: Symbol Binding, ELF32_ST_BIND */
@@ -190,9 +190,9 @@
/* Definitions for Elf32_Rel*::r_info */
-#define ELF32_R_SYM(i) ((i)>>8)
-#define ELF32_R_TYPE(i) ((unsigned char)(i))
-#define ELF32_R_INFO(s,t) (((s)<<8)+(unsigned char)(t))
+#define ELF32_R_SYM(i) ((i) >> 8)
+#define ELF32_R_TYPE(i) ((i) & 0xff)
+#define ELF32_R_INFO(s,t) (((s)<< 8) | ((t) & 0xff))
/* Figure 5-2: Segment Types, p_type */
diff --git a/nuttx/tools/mkconfig.c b/nuttx/tools/mkconfig.c
index 2d2fff5c5..3e55f5097 100644
--- a/nuttx/tools/mkconfig.c
+++ b/nuttx/tools/mkconfig.c
@@ -116,7 +116,7 @@ int main(int argc, char **argv, char **envp)
printf(" * configured (at present, NXFLAT is the only supported binary.\n");
printf(" * format).\n");
printf(" */\n\n");
- printf("#if !defined(CONFIG_NXFLAT)\n");
+ printf("#if !defined(CONFIG_NXFLAT) && !defined(CONFIG_ELF)\n");
printf("# undef CONFIG_BINFMT_DISABLE\n");
printf("# define CONFIG_BINFMT_DISABLE 1\n");
printf("#endif\n\n");