summaryrefslogtreecommitdiff
path: root/nuttx/binfmt
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-06-17 16:28:50 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-06-17 16:28:50 +0000
commit3680397303890ce121c9f05082ffb407ced8d073 (patch)
tree0b62294db4d0519ee41bae914524d253b157321c /nuttx/binfmt
parent2a3f404d973bd45e16ed4def539458c905b6fbda (diff)
downloadpx4-nuttx-3680397303890ce121c9f05082ffb407ced8d073.tar.gz
px4-nuttx-3680397303890ce121c9f05082ffb407ced8d073.tar.bz2
px4-nuttx-3680397303890ce121c9f05082ffb407ced8d073.zip
Easing in binfmt support
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1892 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/binfmt')
-rw-r--r--nuttx/binfmt/Makefile2
-rw-r--r--nuttx/binfmt/libnxflat/Make.defs3
-rw-r--r--nuttx/binfmt/libnxflat/libnxflat_init.c170
-rw-r--r--nuttx/binfmt/libnxflat/libnxflat_load.c396
-rw-r--r--nuttx/binfmt/libnxflat/libnxflat_read.c123
-rw-r--r--nuttx/binfmt/libnxflat/libnxflat_stack.c224
-rw-r--r--nuttx/binfmt/libnxflat/libnxflat_uninit.c79
-rw-r--r--nuttx/binfmt/libnxflat/libnxflat_unload.c99
-rw-r--r--nuttx/binfmt/libnxflat/libnxflat_verify.c22
-rw-r--r--nuttx/binfmt/nxflat.c236
10 files changed, 825 insertions, 529 deletions
diff --git a/nuttx/binfmt/Makefile b/nuttx/binfmt/Makefile
index 0e3d9720c..deb6879a9 100644
--- a/nuttx/binfmt/Makefile
+++ b/nuttx/binfmt/Makefile
@@ -42,7 +42,7 @@ SUBDIRS = libnxflat
ASRCS = $(LIBNXFLAT_ASRCS)
AOBJS = $(ASRCS:.S=$(OBJEXT))
-CSRCS = $(LIBNXFLAT_CSRCS)
+CSRCS = nxflat.c $(LIBNXFLAT_CSRCS)
COBJS = $(CSRCS:.c=$(OBJEXT))
SRCS = $(ASRCS) $(CSRCS)
diff --git a/nuttx/binfmt/libnxflat/Make.defs b/nuttx/binfmt/libnxflat/Make.defs
index 96cff471d..21d00f7f1 100644
--- a/nuttx/binfmt/libnxflat/Make.defs
+++ b/nuttx/binfmt/libnxflat/Make.defs
@@ -34,4 +34,5 @@
############################################################################
LIBNXFLAT_ASRCS =
-LIBNXFLAT_CSRCS = libnxflat_load.c libnxflat_stack.c libnxflat_verify.c
+LIBNXFLAT_CSRCS = libnxflat_init.c libnxflat_uninit.c libnxflat_load.c \
+ libnxflat_unload.c libnxflat_verify.c libnxflat_read.c
diff --git a/nuttx/binfmt/libnxflat/libnxflat_init.c b/nuttx/binfmt/libnxflat/libnxflat_init.c
new file mode 100644
index 000000000..4696d491a
--- /dev/null
+++ b/nuttx/binfmt/libnxflat/libnxflat_init.c
@@ -0,0 +1,170 @@
+/****************************************************************************
+ * binfmt/libnxflat/libnxflat_init.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 <sys/stat.h>
+
+#include <string.h>
+#include <fcntl.h>
+#include <nxflat.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <arpa/inet.h>
+#include <nuttx/nxflat.h>
+
+/****************************************************************************
+ * Pre-Processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Constant Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxflat_init
+ ****************************************************************************/
+
+int nxflat_init(const char *filename, struct nxflat_hdr_s *header,
+ struct nxflat_loadinfo_s *loadinfo)
+{
+ uint32 datastart;
+ uint32 dataend;
+ uint32 bssstart;
+ uint32 bssend;
+ int ret;
+
+ bvdbg("filename: %s header: %p loadinfo: %p\n", filename, header, loadinfo);
+
+ /* Clear the load info structure */
+
+ memset(loadinfo, 0, sizeof(struct nxflat_loadinfo_s));
+
+ /* Open the binary file */
+
+ loadinfo->filfd = open(filename, O_RDONLY);
+ if (loadinfo->filfd < 0)
+ {
+ bdbg("Failed to open NXFLAT binary %s: %d\n", filename, ret);
+ return -errno;
+ }
+
+ /* Read the NXFLAT header from offset 0 */
+
+ ret = nxflat_read(loadinfo, (char*)&header, sizeof(struct nxflat_hdr_s), 0);
+ if (ret < 0)
+ {
+ bdbg("Failed to read NXFLAT header: %d\n", ret);
+ return ret;
+ }
+
+ /* Verify the NXFLAT header */
+
+ if (nxflat_verifyheader(header) != 0)
+ {
+ /* This is not an error because we will be called to attempt loading
+ * EVERY binary. Returning -ENOEXEC simply informs the system that
+ * the file is not an NXFLAT file. Besides, if there is something worth
+ * complaining about, nnxflat_verifyheader() has already
+ * done so.
+ */
+
+ bdbg("Bad NXFLAT header\n");
+ return -ENOEXEC;
+ }
+
+ /* Save all of the input values in the loadinfo structure */
+
+ loadinfo->header = header;
+
+ /* And extract some additional information from the xflat
+ * header. Note that the information in the xflat header is in
+ * network order.
+ */
+
+ datastart = ntohl(header->h_datastart);
+ dataend = ntohl(header->h_dataend);
+ bssstart = dataend;
+ bssend = ntohl(header->h_bssend);
+
+ /* And put this information into the loadinfo structure as well.
+ *
+ * Note that:
+ *
+ * ispace_size = the address range from 0 up to datastart.
+ * data_size = the address range from datastart up to dataend
+ * bss_size = the address range from dataend up to bssend.
+ */
+
+ loadinfo->entry_offset = ntohl(header->h_entry);
+ loadinfo->ispace_size = datastart;
+
+ loadinfo->data_size = dataend - datastart;
+ loadinfo->bss_size = bssend - dataend;
+ loadinfo->stack_size = ntohl(header->h_stacksize);
+
+ /* This is the initial dspace size. We'll recaculate this later
+ * after the memory has been allocated. So that the caller can feel
+ * free to modify dspace_size values from now until then.
+ */
+
+ loadinfo->dspace_size = /* Total DSpace Size is: */
+ (NXFLAT_DATA_OFFSET + /* Memory set aside for ldso */
+ bssend - datastart + /* Data and bss segment sizes */
+ loadinfo->stack_size); /* (Current) stack size */
+
+ /* Get the offset to the start of the relocations (we'll relocate
+ * this later).
+ */
+
+ loadinfo->reloc_start = ntohl(header->h_relocstart);
+ loadinfo->reloc_count = ntohl(header->h_reloccount);
+
+ return 0;
+}
+
diff --git a/nuttx/binfmt/libnxflat/libnxflat_load.c b/nuttx/binfmt/libnxflat/libnxflat_load.c
index d456ae3a1..0b143dad4 100644
--- a/nuttx/binfmt/libnxflat/libnxflat_load.c
+++ b/nuttx/binfmt/libnxflat/libnxflat_load.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * libnxflat/lib/libnxflat_load.c
+ * binfmt/libnxflat/libnxflat_load.c
*
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
@@ -39,10 +39,14 @@
#include <nuttx/config.h>
#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <stdlib.h>
#include <string.h>
#include <nxflat.h>
#include <debug.h>
#include <errno.h>
+
#include <arpa/inet.h>
#include <nuttx/nxflat.h>
@@ -50,16 +54,6 @@
* Pre-Processor Definitions
****************************************************************************/
-#define V_MAP (load_info->vtbl->map)
-#define V_UNMAP (load_info->vtbl->unmap)
-#define V_ALLOC (load_info->vtbl->alloc)
-#define V_FREE (load_info->vtbl->free)
-#define V_OPEN (load_info->vtbl->open)
-#define V_READ (load_info->vtbl->read)
-#define V_CLOSE (load_info->vtbl->close)
-
-#define NXFLAT_HDR_SIZE sizeof(struct nxflat_hdr_s)
-
#ifndef MAX
#define MAX(x,y) ((x) > (y) ? (x) : (y))
#endif
@@ -68,18 +62,18 @@
* Private Constant Data
****************************************************************************/
-#ifdef CONFIG_NXFLAT_DEBUG
-static const char text_segment[] = "TEXT";
-static const char data_segment[] = "DATA";
-static const char bss_segment[] = "BSS";
-static const char unknown[] = "UNKNOWN";
+#if defined(CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_BINFMT)
+static const char g_textsegment[] = "TEXT";
+static const char g_datasegment[] = "DATA";
+static const char g_bsssegment[] = "BSS";
+static const char g_unksegment[] = "UNKNOWN";
-static const char *segment[] =
+static const char *g_segment[] =
{
- text_segment,
- data_segment,
- bss_segment,
- unknown
+ g_textsegment,
+ g_datasegment,
+ g_bsssegment,
+ g_unksegment
};
#endif
@@ -88,26 +82,10 @@ static const char *segment[] =
****************************************************************************/
/****************************************************************************
- * Name: nxflat_swap32
- ****************************************************************************/
-
-#ifdef __BIG_ENDIAN
-static inline uint32 nxflat_swap32(uint32 little)
-{
- uint32 big =
- ((little >> 24) & 0xff) |
- (((little >> 16) & 0xff) << 8) |
- (((little >> 8) & 0xff) << 16) |
- ((little & 0xff) << 24);
- return big;
-}
-#endif
-
-/****************************************************************************
* Name: nxflat_reloc
****************************************************************************/
-static void nxflat_reloc(struct nxflat_loadinfo_s *load_info, uint32 rl)
+static void nxflat_reloc(struct nxflat_loadinfo_s *loadinfo, uint32 rl)
{
union
{
@@ -128,16 +106,16 @@ static void nxflat_reloc(struct nxflat_loadinfo_s *load_info, uint32 rl)
* section of the file image.
*/
- if (reloc.s.r_offset > load_info->data_size)
+ if (reloc.s.r_offset > loadinfo->data_size)
{
- dbg("ERROR: Relocation at 0x%08x invalid -- "
+ bdbg("ERROR: Relocation at 0x%08x invalid -- "
"does not lie in the data segment, size=0x%08x\n",
- reloc.s.r_offset, load_info->data_size);
- dbg(" Relocation not performed!\n");
+ reloc.s.r_offset, loadinfo->data_size);
+ bdbg(" Relocation not performed!\n");
}
else if ((reloc.s.r_offset & 0x00000003) != 0)
{
- dbg("ERROR: Relocation at 0x%08x invalid -- "
+ bdbg("ERROR: Relocation at 0x%08x invalid -- "
"Improperly aligned\n",
reloc.s.r_offset);
}
@@ -148,7 +126,7 @@ static void nxflat_reloc(struct nxflat_loadinfo_s *load_info, uint32 rl)
* DSpace to hold information needed by ld.so at run time.
*/
- datastart = load_info->dspace + NXFLAT_DATA_OFFSET;
+ datastart = loadinfo->dspace + NXFLAT_DATA_OFFSET;
/* Get a pointer to the value that needs relocation in
* DSpace.
@@ -156,18 +134,18 @@ static void nxflat_reloc(struct nxflat_loadinfo_s *load_info, uint32 rl)
ptr = (uint32*)(datastart + reloc.s.r_offset);
- vdbg("Relocation of variable at DATASEG+0x%08x "
+ bvdbg("Relocation of variable at DATASEG+0x%08x "
"(address 0x%p, currently 0x%08x) into segment %s\n",
- reloc.s.r_offset, ptr, *ptr, segment[reloc.s.r_type]);
+ reloc.s.r_offset, ptr, *ptr, g_segment[reloc.s.r_type]);
switch (reloc.s.r_type)
{
- /* TEXT is located at an offset of NXFLAT_HDR_SIZE from
+ /* TEXT is located at an offset of sizeof(struct nxflat_hdr_s) from
* the allocated/mapped ISpace region.
*/
case NXFLAT_RELOC_TYPE_TEXT:
- *ptr += load_info->ispace + NXFLAT_HDR_SIZE;
+ *ptr += loadinfo->ispace + sizeof(struct nxflat_hdr_s);
break;
/* DATA and BSS are always contiguous regions. DATA
@@ -179,7 +157,7 @@ static void nxflat_reloc(struct nxflat_loadinfo_s *load_info, uint32 rl)
* In other contexts, is it necessary to add the data_size
* to get the BSS offset like:
*
- * *ptr += datastart + load_info->data_size;
+ * *ptr += datastart + loadinfo->data_size;
*/
case NXFLAT_RELOC_TYPE_DATA:
@@ -192,15 +170,15 @@ static void nxflat_reloc(struct nxflat_loadinfo_s *load_info, uint32 rl)
*/
case NXFLAT_RELOC_TYPE_NONE:
- dbg("NULL relocation!\n");
+ bdbg("NULL relocation!\n");
break;
default:
- dbg("ERROR: Unknown relocation type=%d\n", reloc.s.r_type);
+ bdbg("ERROR: Unknown relocation type=%d\n", reloc.s.r_type);
break;
}
- vdbg("Relocation became 0x%08x\n", *ptr);
+ bvdbg("Relocation became 0x%08x\n", *ptr);
}
}
@@ -209,235 +187,118 @@ static void nxflat_reloc(struct nxflat_loadinfo_s *load_info, uint32 rl)
****************************************************************************/
/****************************************************************************
- * Name: nxflat_init
- ****************************************************************************/
-
-int nxflat_init(bin_handle_t bin_handle, file_handle_t file_handle,
- const struct nxflat_hdr_s *header, const struct nxflat_vtbl_s *vtbl,
- struct nxflat_loadinfo_s *load_info)
-{
- uint32 datastart;
- uint32 dataend;
- uint32 bssstart;
- uint32 bssend;
-
- vdbg("bin_handle=0x%p header=0x%p load_info=0x%p\n",
- bin_handle, header, load_info);
-
- /* Clear the load info structure */
-
- memset(load_info, 0, sizeof(struct nxflat_loadinfo_s));
-
- /* Verify the xFLT header */
-
- if (nxflat_verifyheader(header) != 0)
- {
- /* This is not an error because we will be called
- * to attempt loading EVERY binary. Returning -ENOEXEC
- * simply informs the system that the file is not
- * an xFLT file. Besides, if there is something worth
- * complaining about, nnxflat_verifyheader() has already
- * done so.
- */
-
- dbg("Bad xFLT header\n");
- return -ENOEXEC;
- }
-
- /* Save all of the input values in the load_info structure */
-
- load_info->bin_handle = bin_handle;
- load_info->file_handle = file_handle;
- load_info->header = header;
- load_info->vtbl = vtbl;
-
- /* And extract some additional information from the xflat
- * header. Note that the information in the xflat header is in
- * network order.
- */
-
- datastart = ntohl(header->h_datastart);
- dataend = ntohl(header->h_dataend);
- bssstart = dataend;
- bssend = ntohl(header->h_bssend);
-
- /* And put this information into the load_info structure as well.
- *
- * Note that:
- *
- * ispace_size = the address range from 0 up to datastart.
- * data_size = the address range from datastart up to dataend
- * bss_size = the address range from dataend up to bssend.
- */
-
- load_info->entry_offset = ntohl(header->h_entry);
- load_info->ispace_size = datastart;
-
- load_info->data_size = dataend - datastart;
- load_info->bss_size = bssend - dataend;
- load_info->stack_size = ntohl(header->h_stacksize);
-
- /* This is the initial dspace size. We'll recaculate this later
- * after the memory has been allocated. So that the caller can feel
- * free to modify dspace_size values from now until then.
- */
-
- load_info->dspace_size = /* Total DSpace Size is: */
- (NXFLAT_DATA_OFFSET + /* Memory set aside for ldso */
- bssend - datastart + /* Data and bss segment sizes */
- load_info->stack_size); /* (Current) stack size */
-
- /* Get the offset to the start of the relocations (we'll relocate
- * this later).
- */
-
- load_info->reloc_start = ntohl(header->h_relocstart);
- load_info->reloc_count = ntohl(header->h_reloccount);
-
- return 0;
-}
-
-/****************************************************************************
- * Name: nxflat_uninit
- ****************************************************************************/
-
-int nxflat_uninit(struct nxflat_loadinfo_s *load_info)
-{
- if (load_info->file_handle)
- {
- V_CLOSE(load_info->file_handle);
- }
- return 0;
-}
-
-/****************************************************************************
* Name: nxflat_load
****************************************************************************/
-int nxflat_load(struct nxflat_loadinfo_s *load_info)
+int nxflat_load(struct nxflat_loadinfo_s *loadinfo)
{
- uint32 dspace_read_size;
- uint32 data_offset;
- uint32 *reloc_tab;
- uint32 result;
- int i;
-
- /* Calculate the extra space we need to map in. This region
- * will be the BSS segment and the stack. It will also be used
- * temporarily to hold relocation information. So the size of this
- * region will either be the size of the BSS section and the
- * stack OR, it the size of the relocation entries, whichever
- * is larger
+ off_t doffset; /* Offset to .data in the NXFLAT file */
+ uint32 *reloctab; /* Address of the relocation table */
+ uint32 dreadsize; /* Total number of bytes of .data to be read */
+ uint32 ret;
+ int i;
+
+ /* Calculate the extra space we need to map in. This region will be the
+ * BSS segment and the stack. It will also be used temporarily to hold
+ * relocation information. So the size of this region will either be the
+ * size of the BSS section and the stack OR, it the size of the relocation
+ * entries, whichever is larger
*/
{
- uint32 extra_alloc;
- uint32 reloc_size;
+ uint32 relocsize;
+ uint32 extrasize;
- /* This is the amount of memory that we have to have to hold
- * the relocations.
+ /* This is the amount of memory that we have to have to hold the
+ * relocations.
*/
- reloc_size = load_info->reloc_count * sizeof(uint32);
+ relocsize = loadinfo->reloc_count * sizeof(uint32);
- /* In the file, the relocations should lie at the same offset
- * as BSS. The additional amount that we allocate have to
- * be either (1) the BSS size + the stack size, or (2) the
- * size of the relocation records, whicher is larger.
+ /* In the file, the relocations should lie at the same offset as BSS.
+ * The additional amount that we allocate have to be either (1) the
+ * BSS size + the stack size, or (2) the size of the relocation records,
+ * whicher is larger.
*/
- extra_alloc = MAX(load_info->bss_size + load_info->stack_size,
- reloc_size);
+ extrasize = MAX(loadinfo->bss_size + loadinfo->stack_size, relocsize);
- /* Use this addtional amount to adjust the total size of the
- * dspace region. */
+ /* Use this addtional amount to adjust the total size of the dspace
+ * region.
+ */
- load_info->dspace_size =
+ loadinfo->dspace_size =
NXFLAT_DATA_OFFSET + /* Memory used by ldso */
- load_info->data_size + /* Initialized data */
- extra_alloc; /* bss+stack/relocs */
+ loadinfo->data_size + /* Initialized data */
+ extrasize; /* bss+stack/relocs */
- /* The number of bytes of data that we have to read from the
- * file is the data size plus the size of the relocation table.
+ /* The number of bytes of data that we have to read from the file is
+ * the data size plus the size of the relocation table.
*/
- dspace_read_size = load_info->data_size + reloc_size;
+ dreadsize = loadinfo->data_size + relocsize;
}
/* We'll need this a few times as well. */
- data_offset = load_info->ispace_size;
+ doffset = loadinfo->ispace_size;
- /* We will make two mmap calls create an address space for
- * the executable. We will attempt to map the file to get
- * the ISpace address space and to allocate RAM to get the
- * DSpace address space. If the system does not support
- * file mapping, the V_MAP() implementation should do the
+ /* We will make two mmap calls create an address space for the executable.
+ * We will attempt to map the file to get the ISpace address space and
+ * to allocate RAM to get the DSpace address space. If the filesystem does
+ * not support file mapping, the map() implementation should do the
* right thing.
*/
- /* The following call will give as a pointer to the mapped
- * file ISpace. This may be in ROM, RAM, Flash, ...
- * We don't really care where the memory resides as long
- * as it is fully initialized and ready to execute.
- * However, the memory should be share-able between processes;
- * otherwise, we don't really have shared libraries.
+ /* The following call will give as a pointer to the mapped file ISpace.
+ * This may be in ROM, RAM, Flash, ... We don't really care where the memory
+ * resides as long as it is fully initialized and ready to execute.
*/
- load_info->ispace = (uint32)V_MAP(load_info->file_handle,
- load_info->ispace_size);
-
- if (load_info->ispace >= (uint32) -4096)
+ loadinfo->ispace = (uint32)mmap(NULL, loadinfo->ispace_size, PROT_READ,
+ MAP_SHARED|MAP_FILE, loadinfo->filfd, 0);
+ if (loadinfo->ispace == (uint32)MAP_FAILED)
{
- dbg("Failed to map xFLT ISpace, error=%d\n", -load_info->ispace);
- return load_info->ispace;
+ bdbg("Failed to map NXFLAT ISpace: %d\n", errno);
+ return -errno;
}
- vdbg("Mapped ISpace (%d bytes) at 0x%08x\n",
- load_info->ispace_size, load_info->ispace);
+ bvdbg("Mapped ISpace (%d bytes) at 0x%08x\n",
+ loadinfo->ispace_size, loadinfo->ispace);
- /* The following call will give a pointer to the allocated
- * but uninitialized ISpace memory.
+ /* The following call will give a pointer to the allocated but
+ * uninitialized ISpace memory.
*/
- load_info->dspace = (uint32)V_ALLOC(load_info->dspace_size);
-
- if (load_info->dspace >= (uint32) -4096)
+ loadinfo->dspace = (uint32)malloc(loadinfo->dspace_size);
+ if (loadinfo->dspace == 0)
{
- dbg("Failed to allocate DSpace, error=%d\n",
- -load_info->ispace);
- (void)nxflat_unload(load_info);
- return load_info->ispace;
+ bdbg("Failed to allocate DSpace\n");
+ ret = -ENOMEM;
+ goto errout;
}
- vdbg("Allocated DSpace (%d bytes) at 0x%08x\n",
- load_info->dspace_size, load_info->dspace);
+ bvdbg("Allocated DSpace (%d bytes) at %08x\n",
+ loadinfo->dspace_size, loadinfo->dspace);
- /* Now, read the data into allocated DSpace at an offset into
- * the allocated DSpace memory. This offset provides a small
- * amount of BSS for use by the loader.
+ /* Now, read the data into allocated DSpace at doffset into the
+ * allocated DSpace memory.
*/
- result = V_READ(load_info->bin_handle,
- load_info->file_handle,
- (char*)(load_info->dspace + NXFLAT_DATA_OFFSET),
- dspace_read_size,
- data_offset);
-
- if (result >= (uint32) -4096)
+ ret = nxflat_read(loadinfo, (char*)(loadinfo->dspace + NXFLAT_DATA_OFFSET), dreadsize, doffset);
+ if (ret < 0)
{
- dbg("Unable to read DSpace, errno %d\n", -result);
- (void)nxflat_unload(load_info);
- return result;
+ bdbg("Failed to read .data section: %d\n", ret);
+ goto errout;
}
-
+
/* Save information about the allocation. */
- load_info->alloc_start = load_info->dspace;
- load_info->alloc_size = load_info->dspace_size;
+ loadinfo->alloc_start = loadinfo->dspace;
+ loadinfo->alloc_size = loadinfo->dspace_size;
- vdbg("TEXT=0x%x Entry point offset=0x%08x, datastart is 0x%08x\n",
- load_info->ispace, load_info->entry_offset, data_offset);
+ bvdbg("TEXT=0x%x Entry point offset=0x%08x, datastart is 0x%08x\n",
+ loadinfo->ispace, loadinfo->entry_offset, doffset);
/* Resolve the address of the relocation table. In the file, the
* relocations should lie at the same offset as BSS. The current
@@ -445,69 +306,34 @@ int nxflat_load(struct nxflat_loadinfo_s *load_info)
* The following adjustment will convert it to an address in DSpace.
*/
- reloc_tab = (uint32*)
- (load_info->reloc_start /* File offset to reloc records */
- + load_info->dspace /* + Allocated DSpace memory */
+ reloctab = (uint32*)
+ (loadinfo->reloc_start /* File offset to reloc records */
+ + loadinfo->dspace /* + Allocated DSpace memory */
+ NXFLAT_DATA_OFFSET /* + Offset for ldso usage */
- - load_info->ispace_size); /* - File offset to DSpace */
+ - loadinfo->ispace_size); /* - File offset to DSpace */
- vdbg("Relocation table at 0x%p, reloc_count=%d\n",
- reloc_tab, load_info->reloc_count);
+ bvdbg("Relocation table at 0x%p, reloc_count=%d\n",
+ reloctab, loadinfo->reloc_count);
/* Now run through the relocation entries. */
- for (i=0; i < load_info->reloc_count; i++)
+ for (i=0; i < loadinfo->reloc_count; i++)
{
-#ifdef __BIG_ENDIAN
- nxflat_reloc(load_info, nxflat_swap32(reloc_tab[i]));
-#else
- nxflat_reloc(load_info, reloc_tab[i]);
-#endif
+ nxflat_reloc(loadinfo, htonl(reloctab[i]));
}
/* Zero the BSS, BRK and stack areas, trashing the relocations
* that lived in the corresponding space in the file. */
- memset((void*)(load_info->dspace + NXFLAT_DATA_OFFSET + load_info->data_size),
+ memset((void*)(loadinfo->dspace + NXFLAT_DATA_OFFSET + loadinfo->data_size),
0,
- (load_info->dspace_size - NXFLAT_DATA_OFFSET -
- load_info->data_size));
+ (loadinfo->dspace_size - NXFLAT_DATA_OFFSET -
+ loadinfo->data_size));
- return 0;
-}
-
-/****************************************************************************
- * Name: nxflat_unload
- *
- * Description:
- * This function unloads the object from memory. This essentially
- * undoes the actions of nxflat_load.
- *
- ****************************************************************************/
-
-int nxflat_unload(struct nxflat_loadinfo_s *load_info)
-{
- /* Reset the contents of the info structure. */
-
- /* Nothing is allocated */
-
- load_info->alloc_start = 0;
- load_info->alloc_size = 0;
-
- /* Release the memory segments */
-
- if (load_info->ispace)
- {
- V_UNMAP((void*)load_info->ispace, load_info->ispace_size);
- load_info->ispace = 0;
- }
-
- if (load_info->dspace)
- {
- V_FREE((void*)load_info->dspace, load_info->dspace_size);
- load_info->dspace = 0;
- }
+ return OK;
- return 0;
+errout:
+ (void)nxflat_unload(loadinfo);
+ return ret;
}
diff --git a/nuttx/binfmt/libnxflat/libnxflat_read.c b/nuttx/binfmt/libnxflat/libnxflat_read.c
new file mode 100644
index 000000000..ff5200140
--- /dev/null
+++ b/nuttx/binfmt/libnxflat/libnxflat_read.c
@@ -0,0 +1,123 @@
+/****************************************************************************
+ * binfmt/libnxflat/libnxflat_read.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 <unistd.h>
+#include <string.h>
+#include <nxflat.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <arpa/inet.h>
+#include <nuttx/nxflat.h>
+
+/****************************************************************************
+ * Pre-Processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Constant Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxflat_read
+ ****************************************************************************/
+
+int nxflat_read(struct nxflat_loadinfo_s *loadinfo, char *buffer, int readsize, int offset)
+{
+ ssize_t nbytes; /* Number of bytes read */
+ off_t rpos; /* Position returned by lseek */
+ char *bufptr; /* Next buffer location to read into */
+ int bytesleft; /* Number of bytes of .data left to read */
+ int bytesread; /* Total number of bytes read */
+
+ /* Seek to the position in the object file where the initialized
+ * data is saved.
+ */
+
+ bytesread = 0;
+ bufptr = buffer;
+ bytesleft = readsize;
+ do
+ {
+ rpos = lseek(loadinfo->filfd, offset, SEEK_SET);
+ if (rpos != offset)
+ {
+ bdbg("Failed to seek to position %d: %d\n", offset, errno);
+ return -errno;
+ }
+
+ /* Read the file data at offset into the user buffer */
+
+ nbytes = read(loadinfo->filfd, bufptr, bytesleft);
+ if (nbytes < 0)
+ {
+ if (errno != EINTR)
+ {
+ bdbg("Read of .data failed: %d\n", errno);
+ return -errno;
+ }
+ }
+ else if (nbytes == 0)
+ {
+ bdbg("Unexpected end of file\n");
+ return -ENODATA;
+ }
+ else
+ {
+ bytesread += nbytes;
+ bytesleft -= nbytes;
+ bufptr += nbytes;
+ offset += nbytes;
+ }
+ }
+ while (bytesread < readsize);
+ return OK;
+}
+
diff --git a/nuttx/binfmt/libnxflat/libnxflat_stack.c b/nuttx/binfmt/libnxflat/libnxflat_stack.c
deleted file mode 100644
index 082a2e05e..000000000
--- a/nuttx/binfmt/libnxflat/libnxflat_stack.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/****************************************************************************
- * libnxflat/lib/nxflat_stack.c
- *
- * Copyright (C) 2009 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
- *
- * 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 <debug.h>
-#include <errno.h>
-#include <nuttx/nxflat.h>
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: nxflat_adjuststacksize
- ****************************************************************************/
-
-void nxflat_adjuststacksize(struct nxflat_loadinfo_s *load_info,
- int argc, int envc, int system_usage)
-{
- uint32 total_usage = system_usage;
-
- /* For argc, we will store the array (argc elements), the argc
- * value itself, plus a null pointer.
- */
-
- total_usage += (argc + 2) * sizeof(uint32);
-
- /* For envc, we will store the array (envc elements) plus a null
- * pointer.
- */
-
- total_usage += (envc + 1) * sizeof(uint32);
-
- /* And we will store six additional words described the memory
- * layout.
- */
-
- total_usage += 6 * sizeof(uint32);
-
- /* Add this to the previously determined stack size */
-
- load_info->stack_size += total_usage;
-}
-
-/****************************************************************************
- * Name: nxflat_initstack
- *
- * Description:
- * When we enter the NXFLAT_ loader, it will expect to see a stack frame
- * like the following. NOTE: This logic assumes a push down stack
- * (i.e., we decrement the stack pointer to go from the "BOTTOM" to
- * the "TOP").
- *
- *
- * TOP->argc Argument count (integer)
- * argv[0...(argc-1)] Program arguments (pointers)
- * NULL Marks end of arguments
- * env[0...N] Environment variables (pointers)
- * NULL Marks end of environment variables
- * loader ispace Address of loader ISpace (NXFLAT_ header)
- * loader dspace Address of loader DSpace
- * loader dspace size Size of the allocated loader DSpace
- * program ispace Address of program ISpace (NXFLAT_ header)
- * program dspace Address of program DSpace
- * BOTTOM->program dspace size Size of the allocated program DSpace
- *
- ****************************************************************************/
-
-uint32 nxflat_initstack(struct nxflat_loadinfo_s *prog_load_info,
- struct nxflat_loadinfo_s *lib_load_info,
- int argc, int envc, char *p)
-{
- uint32 *argv;
- uint32 *envp;
- uint32 *sp;
- char dummy;
-
- /* p points to the beginning of the array of arguments;
- * sp points to the "bottom" of a push down stack.
- */
-
- sp = (uint32*)((-(uint32)sizeof(char*))&(uint32) p);
-
- /* Place program information on the stack */
-
- if (prog_load_info)
- {
- *sp-- = (uint32)prog_load_info->dspace_size;
- *sp-- = (uint32)prog_load_info->dspace;
- *sp-- = (uint32)prog_load_info->ispace;
- }
- else
- {
- dbg("No program load info provided\n");
- return -EINVAL;
- }
-
- /* Place loader information on the stack */
-
- if (lib_load_info)
- {
- *sp-- = (uint32)lib_load_info->dspace_size;
- *sp-- = (uint32)lib_load_info->dspace;
- *sp-- = (uint32)lib_load_info->ispace;
- }
- else
- {
- *sp-- = (uint32)0;
- *sp-- = (uint32)0;
- *sp-- = (uint32)0;
- }
-
- /* Allocate space on the stack for the envp array contents
- * (including space for a null terminator).
- */
-
- sp -= envc+1;
- envp = sp;
-
- /* Allocate space on the stack for the argv array contents
- * (including space for a null terminator).
- */
-
- sp -= argc+1;
- argv = sp;
-
- /* Put argc on the stack. sp now points to the "top" of the
- * stack as it will be received by the new task.
- */
-
- *sp-- = (uint32)argc;
-
- /* Copy argv pointers into the stack frame (terminated with
- * a null pointer).
- */
-
- prog_load_info->arg_start = (uint32)p;
- while (argc-->0)
- {
- /* Put the address of the beginning of the string */
-
- *argv++ = (uint32)p;
-
- /* Search for the end of the string */
-
- do
- {
- dummy = *p++;
- }
- while (dummy);
- }
- *argv = (uint32)NULL,argv;
-
- /* Copy envp pointers into the stack frame (terminated with
- * a null pointer).
- */
-
- prog_load_info->env_start = (uint32)p;
- while (envc-->0)
- {
- /* Put the address of the beginning of the string */
-
- *envp++ = (uint32)p;
-
- /* Search for the end of the string */
-
- do
- {
- dummy = *p++;
- }
- while (dummy);
- }
- *envp = (uint32)NULL;
-
- prog_load_info->env_end = (uint32)p;
-
- return (uint32)sp;
-}
-
diff --git a/nuttx/binfmt/libnxflat/libnxflat_uninit.c b/nuttx/binfmt/libnxflat/libnxflat_uninit.c
new file mode 100644
index 000000000..47d1a90a2
--- /dev/null
+++ b/nuttx/binfmt/libnxflat/libnxflat_uninit.c
@@ -0,0 +1,79 @@
+/****************************************************************************
+ * binfmt/libnxflat/libnxflat_uninit.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 <unistd.h>
+#include <debug.h>
+#include <errno.h>
+#include <nuttx/nxflat.h>
+
+/****************************************************************************
+ * Pre-Processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Constant Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxflat_swap32
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxflat_uninit
+ ****************************************************************************/
+
+int nxflat_uninit(struct nxflat_loadinfo_s *loadinfo)
+{
+ if (loadinfo->filfd >= 0)
+ {
+ close(loadinfo->filfd);
+ }
+ return OK;
+}
+
diff --git a/nuttx/binfmt/libnxflat/libnxflat_unload.c b/nuttx/binfmt/libnxflat/libnxflat_unload.c
new file mode 100644
index 000000000..d648c0ebd
--- /dev/null
+++ b/nuttx/binfmt/libnxflat/libnxflat_unload.c
@@ -0,0 +1,99 @@
+/****************************************************************************
+ * binfmt/libnxflat/libnxflat_unload.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 <sys/mman.h>
+
+#include <stdlib.h>
+#include <debug.h>
+
+#include <nuttx/nxflat.h>
+
+/****************************************************************************
+ * Pre-Processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Constant Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxflat_unload
+ *
+ * Description:
+ * This function unloads the object from memory. This essentially
+ * undoes the actions of nxflat_load.
+ *
+ ****************************************************************************/
+
+int nxflat_unload(struct nxflat_loadinfo_s *loadinfo)
+{
+ /* Reset the contents of the info structure. */
+
+ /* Nothing is allocated */
+
+ loadinfo->alloc_start = 0;
+ loadinfo->alloc_size = 0;
+
+ /* Release the memory segments */
+
+ if (loadinfo->ispace)
+ {
+ munmap((void*)loadinfo->ispace, loadinfo->ispace_size);
+ loadinfo->ispace = 0;
+ }
+
+ if (loadinfo->dspace)
+ {
+ free((void*)loadinfo->dspace);
+ loadinfo->dspace = 0;
+ }
+
+ return OK;
+}
+
diff --git a/nuttx/binfmt/libnxflat/libnxflat_verify.c b/nuttx/binfmt/libnxflat/libnxflat_verify.c
index b31994b8b..db1069e9f 100644
--- a/nuttx/binfmt/libnxflat/libnxflat_verify.c
+++ b/nuttx/binfmt/libnxflat/libnxflat_verify.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * nxflat/lib/nxflat_stack.c
+ * binfmt/libnxflat/nxflat_verify.c
*
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
@@ -49,20 +49,6 @@
* Pre-processor Definitions
****************************************************************************/
-#define V_MAP (load_info->vtbl->map)
-#define V_UNMAP (load_info->vtbl->unmap)
-#define V_ALLOC (load_info->vtbl->alloc)
-#define V_FREE (load_info->vtbl->free)
-#define V_OPEN (load_info->vtbl->open)
-#define V_READ (load_info->vtbl->read)
-#define V_CLOSE (load_info->vtbl->close)
-
-#define XFLT_HDR_SIZE sizeof(struct nxflat_hdr_s)
-
-#ifndef MAX
-# define MAX(x,y) ((x) > (y) ? (x) : (y))
-#endif
-
/****************************************************************************
* Private Constant Data
****************************************************************************/
@@ -85,7 +71,7 @@ int nxflat_verifyheader(const struct nxflat_hdr_s *header)
if (!header)
{
- dbg("NULL NXFLAT header!");
+ bdbg("NULL NXFLAT header!");
return -ENOEXEC;
}
@@ -97,7 +83,7 @@ int nxflat_verifyheader(const struct nxflat_hdr_s *header)
if (strncmp(header->h_magic, "NXFLAT", 4) != 0)
{
- dbg("Unrecognized magic=\"%c%c%c%c\"",
+ bdbg("Unrecognized magic=\"%c%c%c%c\"",
header->h_magic[0], header->h_magic[1],
header->h_magic[2], header->h_magic[3]);
return -ENOEXEC;
@@ -108,7 +94,7 @@ int nxflat_verifyheader(const struct nxflat_hdr_s *header)
revision = ntohs(header->h_rev);
if (revision != NXFLAT_VERSION_CURRENT)
{
- dbg("Unsupported NXFLAT version=%d\n", revision);
+ bdbg("Unsupported NXFLAT version=%d\n", revision);
return -ENOEXEC;
}
return 0;
diff --git a/nuttx/binfmt/nxflat.c b/nuttx/binfmt/nxflat.c
new file mode 100644
index 000000000..d0456bebd
--- /dev/null
+++ b/nuttx/binfmt/nxflat.c
@@ -0,0 +1,236 @@
+/****************************************************************************
+ * binfmt/nxflat.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 <string.h>
+#include <nxflat.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <arpa/inet.h>
+#include <nuttx/binfmt.h>
+#include <nuttx/nxflat.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int nxflat_loadbinary(struct binary_s *binp);
+#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_BINFMT)
+static void nxflat_dumpmemory(void *addr, int nbytes);
+static void nxflat_dumploadinfo(struct nxflat_loadinfo_s *loadinfo);
+#endif
+
+/****************************************************************************
+ * Private Constant Data
+ ****************************************************************************/
+
+static struct binfmt_s g_nxflatbinfmt =
+{
+ NULL, /* next */
+ nxflat_loadbinary, /* load */
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nnxflat_dumpmemory
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_BINFMT)
+static void nxflat_dumpmemory(void *addr, int nbytes)
+{
+ ubyte *ptr;
+
+ bdbg(" ADDRESS VALUE\n");
+ for (ptr = (ubyte*)addr; nbytes > 0; ptr += 4, nbytes -= 4)
+ {
+ bdbg(" %p: %02x %02x %02x %02x\n", ptr, ptr[0], ptr[1], ptr[2], ptr[3]);
+ }
+}
+#else /* CONFIG_XFLAT_DEBUG */
+# define nnxflat_dumpmemory(a,n)
+#endif /* CONFIG_XFLAT_DEBUG */
+
+/****************************************************************************
+ * Name: nxflat_dumploadinfo
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_BINFMT)
+static void nxflat_dumploadinfo(struct nxflat_loadinfo_s *loadinfo)
+{
+ unsigned long dspace_size =
+ NXFLAT_DATA_OFFSET +
+ loadinfo->data_size +
+ loadinfo->bss_size +
+ loadinfo->stack_size;
+
+ bdbg("LOAD_INFO:\n");
+ bdbg(" ISPACE:\n");
+ bdbg(" ispace: %08lx\n", loadinfo->ispace);
+ bdbg(" entry_offset: %08lx\n", loadinfo->entry_offset);
+ bdbg(" ispace_size: %08lx\n", loadinfo->ispace_size);
+
+ bdbg(" DSPACE:\n");
+ bdbg(" dspace: %08lx\n", loadinfo->dspace);
+ bdbg(" (ldso): %08x\n", NXFLAT_DATA_OFFSET);
+ bdbg(" data_size: %08lx\n", loadinfo->data_size);
+ bdbg(" bss_size: %08lx\n", loadinfo->bss_size);
+ bdbg(" (pad): %08lx\n", loadinfo->dspace_size - dspace_size);
+ bdbg(" stack_size: %08lx\n", loadinfo->stack_size);
+ bdbg(" dspace_size: %08lx\n", loadinfo->dspace_size);
+
+ bdbg(" ARGUMENTS:\n");
+ bdbg(" arg_start: %08lx\n", loadinfo->arg_start);
+ bdbg(" env_start: %08lx\n", loadinfo->env_start);
+ bdbg(" env_end: %08lx\n", loadinfo->env_end);
+
+ bdbg(" RELOCS:\n");
+ bdbg(" reloc_start: %08lx\n", loadinfo->reloc_start);
+ bdbg(" reloc_count: %08lx\n", loadinfo->reloc_count);
+
+ bdbg(" HANDLES:\n");
+ bdbg(" filfd: %d\n", loadinfo->filfd);
+
+ bdbg(" NXFLT HEADER:");
+ bdbg(" header: %p\n", loadinfo->header);
+
+ bdbg(" ALLOCATIONS:\n");
+ bdbg(" alloc_start: %08lx\n", loadinfo->alloc_start);
+ bdbg(" alloc_size: %08lx\n", loadinfo->alloc_size);
+}
+#else /* CONFIG_XFLAT_DEBUG */
+# define nxflat_dumploadinfo(i)
+#endif /* CONFIG_XFLAT_DEBUG */
+
+/****************************************************************************
+ * Name: nxflat_loadbinary
+ *
+ * Description:
+ * Verify that the file is an NXFLAT binary and, if so, load the NXFLAT
+ * binary into memory
+ *
+ ****************************************************************************/
+
+static int nxflat_loadbinary(struct binary_s *binp)
+{
+ struct nxflat_hdr_s header; /* Just allocated memory */
+ struct nxflat_loadinfo_s loadinfo; /* Contains globals for libnxflat */
+ int ret;
+
+ bvdbg("Loading file: %s\n", binp->filename);
+
+ /* Initialize the xflat library to load the program binary. */
+
+ ret = nxflat_init(binp->filename, &header, &loadinfo);
+ nxflat_dumploadinfo(&loadinfo);
+ if (ret != 0)
+ {
+ bdbg("Failed to initialize for load of NXFLT program: %d\n", ret);
+ return ret;
+ }
+
+ /* Load the program binary */
+
+ ret = nxflat_load(&loadinfo);
+ nxflat_dumploadinfo(&loadinfo);
+ if (ret != 0)
+ {
+ bdbg("Failed to load NXFLT program binary: %d\n", ret);
+ nxflat_uninit(&loadinfo);
+ return ret;
+ }
+
+ /* Return the load information */
+
+ binp->entrypt = (main_t)(loadinfo.ispace + loadinfo.entry_offset);
+ binp->picbase = (void*)loadinfo.dspace;
+
+ bvdbg("ENTRY CODE:\n");
+ nxflat_dumpmemory(binp->entrypt, 16*sizeof(unsigned long));
+ nxflat_uninit(&loadinfo);
+ return OK;
+}
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * Name: nxflat_initialize
+ *
+ * Description:
+ * NXFLAT support is built unconditionally. However, it order to
+ * use this binary format, this function must be called during system
+ * format in order to register the NXFLAT binary format.
+ *
+ ***********************************************************************/
+
+int nxflat_initialize(void)
+{
+ int ret;
+
+ /* Register ourselves as a binfmt loader */
+
+ bvdbg("Registering NXFLAT\n");
+ ret = register_binfmt(&g_nxflatbinfmt);
+ if (ret != 0)
+ {
+ bdbg("Failed to register binfmt: %d\n", ret);
+ }
+ return ret;
+}
+
+/****************************************************************************
+ * Name: nxflat_uninitialize
+ ****************************************************************************/
+
+void nxflat_uninitialize(void)
+{
+ unregister_binfmt(&g_nxflatbinfmt);
+}
+