From eb4582f416e3544ab43e51df38109ebfb4c484c0 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 7 May 2014 13:47:52 -0600 Subject: BINFMT: A framework to support a P-code binary format (a work in progress) --- nuttx/binfmt/Kconfig | 19 +++ nuttx/binfmt/Makefile | 1 + nuttx/binfmt/binfmt_schedunload.c | 2 +- nuttx/binfmt/builtin.c | 4 +- nuttx/binfmt/elf.c | 6 +- nuttx/binfmt/libelf/Kconfig | 2 +- nuttx/binfmt/libelf/libelf_load.c | 2 +- nuttx/binfmt/libnxflat/libnxflat_load.c | 2 +- nuttx/binfmt/libpcode/Kconfig | 23 +++ nuttx/binfmt/libpcode/Make.defs | 52 +++++++ nuttx/binfmt/nxflat.c | 4 +- nuttx/binfmt/pcode.c | 246 ++++++++++++++++++++++++++++++++ 12 files changed, 352 insertions(+), 11 deletions(-) create mode 100644 nuttx/binfmt/libpcode/Kconfig create mode 100644 nuttx/binfmt/libpcode/Make.defs create mode 100644 nuttx/binfmt/pcode.c (limited to 'nuttx/binfmt') diff --git a/nuttx/binfmt/Kconfig b/nuttx/binfmt/Kconfig index 6e5f7c251..4c99b8b2c 100644 --- a/nuttx/binfmt/Kconfig +++ b/nuttx/binfmt/Kconfig @@ -63,6 +63,25 @@ if BUILTIN source binfmt/libbuiltin/Kconfig endif +config PCODE + bool "Support P-Code Applications" + default n + depends on INTERPRETERS_PCODE + ---help--- + Enable support for interpreted P-Code binaries. P-Code binaries are + generated by the NuttX Pascal compiler. + + NOTE: You must first install and select the Pascal P-Code + interpreter before you can select this binary format. The P-Code + interpreter is in the pascal package and can also be fount in the + misc/pascal directory of the repository. Read the README.txt file + in the misc/pascal directory for more details. The correct + installation director is: apps/interpreters. + +if PCODE +source binfmt/libpcode/Kconfig +endif + endif config PIC diff --git a/nuttx/binfmt/Makefile b/nuttx/binfmt/Makefile index 4e4ad931a..4e1f18ebc 100644 --- a/nuttx/binfmt/Makefile +++ b/nuttx/binfmt/Makefile @@ -70,6 +70,7 @@ DEPPATH = --dep-path . include libnxflat$(DELIM)Make.defs include libelf$(DELIM)Make.defs include libbuiltin$(DELIM)Make.defs +include libpcode$(DELIM)Make.defs BINFMT_AOBJS = $(BINFMT_ASRCS:.S=$(OBJEXT)) BINFMT_COBJS = $(BINFMT_CSRCS:.c=$(OBJEXT)) diff --git a/nuttx/binfmt/binfmt_schedunload.c b/nuttx/binfmt/binfmt_schedunload.c index 7e7fa471f..15f8e3f7c 100644 --- a/nuttx/binfmt/binfmt_schedunload.c +++ b/nuttx/binfmt/binfmt_schedunload.c @@ -208,7 +208,7 @@ static void unload_callback(int signo, siginfo_t *info, void *ucontext) if (!info || signo != SIGCHLD) { - blldbg("ERROR:Bad signal callback: signo=%d info=%p\n", signo, callback); + blldbg("ERROR:Bad signal callback: signo=%d info=%p\n", signo, info); return; } diff --git a/nuttx/binfmt/builtin.c b/nuttx/binfmt/builtin.c index eb838db92..c532d056f 100644 --- a/nuttx/binfmt/builtin.c +++ b/nuttx/binfmt/builtin.c @@ -150,9 +150,9 @@ static int builtin_loadbinary(struct binary_s *binp) * Name: builtin_initialize * * Description: - * Builtin support is built unconditionally. However, it order to + * Builtin support is built unconditionally. However, in order to * use this binary format, this function must be called during system - * format in order to register the builtin binary format. + * initialzie in order to register the builtin binary format. * * Returned Value: * This is a NuttX internal function so it follows the convention that diff --git a/nuttx/binfmt/elf.c b/nuttx/binfmt/elf.c index 9dc59fbdd..6c84ca0e1 100644 --- a/nuttx/binfmt/elf.c +++ b/nuttx/binfmt/elf.c @@ -218,7 +218,7 @@ static int elf_loadbinary(struct binary_s *binp) binp->stacksize = CONFIG_ELF_STACKSIZE; /* Add the ELF allocation to the alloc[] only if there is no address - * enironment. If there is an address environment, it will automatically + * environment. If there is an address environment, it will automatically * be freed when the function exits * * REVISIT: If the module is loaded then unloaded, wouldn't this cause @@ -275,9 +275,9 @@ errout: * Name: elf_initialize * * Description: - * ELF support is built unconditionally. However, it order to + * ELF support is built unconditionally. However, in order to * use this binary format, this function must be called during system - * format in order to register the ELF binary format. + * initialization in order to register the ELF binary format. * * Returned Value: * This is a NuttX internal function so it follows the convention that diff --git a/nuttx/binfmt/libelf/Kconfig b/nuttx/binfmt/libelf/Kconfig index f6f579276..e63fd5382 100644 --- a/nuttx/binfmt/libelf/Kconfig +++ b/nuttx/binfmt/libelf/Kconfig @@ -13,7 +13,7 @@ config ELF_STACKSIZE int "ELF Stack Size" default 2048 ---help--- - This is the default stack size that will will be used when starting ELF binaries. + This is the default stack size that will be used when starting ELF binaries. config ELF_BUFFERSIZE int "ELF I/O Buffer Size" diff --git a/nuttx/binfmt/libelf/libelf_load.c b/nuttx/binfmt/libelf/libelf_load.c index 0e4ad9798..f5df09eda 100644 --- a/nuttx/binfmt/libelf/libelf_load.c +++ b/nuttx/binfmt/libelf/libelf_load.c @@ -222,7 +222,7 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo) * * Description: * Loads the binary into memory, allocating memory, performing relocations - * and inializing the data and bss segments. + * and initializing the data and bss segments. * * Returned Value: * 0 (OK) is returned on success and a negated errno is returned on diff --git a/nuttx/binfmt/libnxflat/libnxflat_load.c b/nuttx/binfmt/libnxflat/libnxflat_load.c index 886c16147..b386628a6 100644 --- a/nuttx/binfmt/libnxflat/libnxflat_load.c +++ b/nuttx/binfmt/libnxflat/libnxflat_load.c @@ -80,7 +80,7 @@ * Description: * Loads the binary specified by nxflat_init into memory, mapping * the I-space executable regions, allocating the D-Space region, - * and inializing the data segment (relocation information is + * and initializing the data segment (relocation information is * temporarily loaded into the BSS region. BSS will be cleared * by nxflat_bind() after the relocation data has been processed). * diff --git a/nuttx/binfmt/libpcode/Kconfig b/nuttx/binfmt/libpcode/Kconfig new file mode 100644 index 000000000..4845eab31 --- /dev/null +++ b/nuttx/binfmt/libpcode/Kconfig @@ -0,0 +1,23 @@ +# +# For a description of the syntax of this configuration file, +# see misc/tools/kconfig-language.txt. +# + +config PCODE_STACKSIZE + int "P-code interpreter stack size" + default 2048 + ---help--- + This is the stack size that will be used when starting P-code interpreter. + +config PCODE_PRIORITY + int "P-code interpreter priority" + default 100 + ---help--- + This is the task_priority that will be used when starting P-code interpreter. + +config PCODE_DUMPBUFFER + bool "Dump P-code buffers" + default n + depends on DEBUG && DEBUG_VERBOSE + ---help--- + Dump various P-code buffers for debug purposes diff --git a/nuttx/binfmt/libpcode/Make.defs b/nuttx/binfmt/libpcode/Make.defs new file mode 100644 index 000000000..a5d2fdc12 --- /dev/null +++ b/nuttx/binfmt/libpcode/Make.defs @@ -0,0 +1,52 @@ +############################################################################ +# binfmt/libpcode/Make.defs +# +# Copyright (C) 2014 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_PCODE),y) + +# P-code application interfaces + +# BINFMT_CSRCS += + +# P-code library interfaces + +# BINFMT_CSRCS += + +# Hook the libbuiltin subdirectory into the build + +#VPATH += libbuiltin +#SUBDIRS += libbuiltin +#DEPPATH += --dep-path libbuiltin + +endif diff --git a/nuttx/binfmt/nxflat.c b/nuttx/binfmt/nxflat.c index db29941ca..2d06aa7d9 100644 --- a/nuttx/binfmt/nxflat.c +++ b/nuttx/binfmt/nxflat.c @@ -234,9 +234,9 @@ errout: * Name: nxflat_initialize * * Description: - * NXFLAT support is built unconditionally. However, it order to + * NXFLAT support is built unconditionally. However, in order to * use this binary format, this function must be called during system - * format in order to register the NXFLAT binary format. + * initialization in order to register the NXFLAT binary format. * * Returned Value: * This is a NuttX internal function so it follows the convention that diff --git a/nuttx/binfmt/pcode.c b/nuttx/binfmt/pcode.c new file mode 100644 index 000000000..c5963b672 --- /dev/null +++ b/nuttx/binfmt/pcode.c @@ -0,0 +1,246 @@ +/**************************************************************************** + * binfmt/pcode.c + * + * Copyright (C) 2014 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_PCODE + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int pcode_loadbinary(FAR struct binary_s *binp); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct binfmt_s g_pcode_binfmt = +{ + NULL, /* next */ + pcode_loadbinary, /* load */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pcode_proxy + * + * Description: + * This is the proxy program that runs and starts the P-Code interpreter. + * + ****************************************************************************/ + +#ifndef CONFIG_NUTTX_KERNEL +static int pcode_proxy(int argc, char **argv) +{ + /* REVISIT: There are issues here when CONFIG_NUTTX_KERNEL is selected. */ + + bdbg("ERROR: Not implemented"); + return EXIT_FAILURE; +} +#else +# error Missing logic for the case of CONFIG_NUTTX_KERNEL +#endif + +/**************************************************************************** + * Name: pcode_loadbinary + * + * Description: + * Verify that the file is an pcode binary. + * + ****************************************************************************/ + +static int pcode_loadbinary(struct binary_s *binp) +{ + FAR struct poff_fileheader_s hdr; + FAR const struct pcode_s *b; + FAR uint8_t *ptr; + size_t remaining; + ssize_t nread; + int fd; + int ret; + + bvdbg("Loading file: %s\n", binp->filename); + + /* Open the binary file for reading (only) */ + + fd = open(binp->filename, O_RDONLY); + if (fd < 0) + { + int errval = errno; + bdbg("ERROR: Failed to open binary %s: %d\n", binp->filename, errval); + return -errval; + } + + /* Read the POFF file header */ + + for (remaining = sizeof(struct poff_fileheader_s), ptr = (FAR uint8_t *)&hdr; + remaining > 0; ) + { + /* Read the next GULP */ + + nread = read(fd, ptr, remaining); + if (nread < 0) + { + /* If errno is EINTR, then this is not an error; the read() was + * simply interrupted by a signal. + */ + + int errval = errno; + DEBUGASSERT(errval > 0); + + if (errval != EINTR) + { + bdbg("ERROR: read failed: %d\n", errval); + ret = -errval; + goto errout_with_fd; + } + + bdbg("Interrupted by a signal\n"); + } + else + { + /* Set up for the next gulp */ + + DEBUASSERT(nread > 0 && nread <=remaining); + remaining -= nread; + ptr += nread; + } + } + +#ifdef CONFIG_PCODE_DUMPBUFFER + lib_dumpbuffer("POFF File Header", &hdr, sizeof(poff_fileheader_s)); +#endif + + /* Verify that the file is a P-Code executable */ + + if (memcmp(&hdr.fh_ident, FHI_POFF_MAG, 4) != 0 || hdr.fh_type != FHT_EXEC) + { + dbg("ERROR: File is not a P-code executable: %d\n"); + ret = -ENOEXEC; + goto errout_with_fd; + } + + /* Return the load information. + * REVISIT: There are issues here when CONFIG_NUTTX_KERNEL is selected. + */ + + binp->entrypt = pcode_proxy; + binp->stacksize = CONFIG_PCODE_STACKSIZE; + binp->priority = CONFIG_PCODE_PRIORITY; + + /* Successfully identified a p-code binary */ + + ret = OK; + +errout_with_fd: + close(fd); + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pcode_initialize + * + * Description: + * P-code support is built based on the configuration. However, in order + * to use this binary format, this function must be called during system + * initialization in order to register the P-Code binary format. + * + * Returned Value: + * This is a NuttX internal function so it follows the convention that + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int pcode_initialize(void) +{ + int ret; + + /* Register ourselves as a binfmt loader */ + + bvdbg("Registering P-Code Loader\n"); + + ret = register_binfmt(&g_pcode_binfmt); + if (ret != 0) + { + bdbg("Failed to register binfmt: %d\n", ret); + } + + return ret; +} + +/**************************************************************************** + * Name: pcode_uninitialize + * + * Description: + * Unregister the pcode binary loader + * + * Returned Value: + * None + * + ****************************************************************************/ + +void pcode_uninitialize(void) +{ + unregister_binfmt(&g_pcode_binfmt); +} + +#endif /* CONFIG_PCODE */ + -- cgit v1.2.3