diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2009-06-17 16:28:50 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2009-06-17 16:28:50 +0000 |
commit | 3680397303890ce121c9f05082ffb407ced8d073 (patch) | |
tree | 0b62294db4d0519ee41bae914524d253b157321c /nuttx/binfmt | |
parent | 2a3f404d973bd45e16ed4def539458c905b6fbda (diff) | |
download | px4-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/Makefile | 2 | ||||
-rw-r--r-- | nuttx/binfmt/libnxflat/Make.defs | 3 | ||||
-rw-r--r-- | nuttx/binfmt/libnxflat/libnxflat_init.c | 170 | ||||
-rw-r--r-- | nuttx/binfmt/libnxflat/libnxflat_load.c | 396 | ||||
-rw-r--r-- | nuttx/binfmt/libnxflat/libnxflat_read.c | 123 | ||||
-rw-r--r-- | nuttx/binfmt/libnxflat/libnxflat_stack.c | 224 | ||||
-rw-r--r-- | nuttx/binfmt/libnxflat/libnxflat_uninit.c | 79 | ||||
-rw-r--r-- | nuttx/binfmt/libnxflat/libnxflat_unload.c | 99 | ||||
-rw-r--r-- | nuttx/binfmt/libnxflat/libnxflat_verify.c | 22 | ||||
-rw-r--r-- | nuttx/binfmt/nxflat.c | 236 |
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); +} + |