From fdca08128e9848737a61a6b84a5e4b97a4015a02 Mon Sep 17 00:00:00 2001 From: patacongo Date: Wed, 17 Jun 2009 16:28:50 +0000 Subject: [PATCH] Easing in binfmt support git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1892 42af7a65-404d-4744-a932-0658087f49c3 --- binfmt/Makefile | 2 +- binfmt/libnxflat/Make.defs | 3 +- binfmt/libnxflat/libnxflat_init.c | 170 ++++++++++++ binfmt/libnxflat/libnxflat_load.c | 396 ++++++++-------------------- binfmt/libnxflat/libnxflat_read.c | 123 +++++++++ binfmt/libnxflat/libnxflat_stack.c | 224 ---------------- binfmt/libnxflat/libnxflat_uninit.c | 79 ++++++ binfmt/libnxflat/libnxflat_unload.c | 99 +++++++ binfmt/libnxflat/libnxflat_verify.c | 22 +- binfmt/nxflat.c | 236 +++++++++++++++++ include/debug.h | 32 ++- include/errno.h | 8 +- include/nuttx/binfmt.h | 100 +++++++ include/nuttx/nxflat.h | 104 ++------ include/sys/types.h | 2 +- 15 files changed, 981 insertions(+), 619 deletions(-) create mode 100644 binfmt/libnxflat/libnxflat_init.c create mode 100644 binfmt/libnxflat/libnxflat_read.c delete mode 100644 binfmt/libnxflat/libnxflat_stack.c create mode 100644 binfmt/libnxflat/libnxflat_uninit.c create mode 100644 binfmt/libnxflat/libnxflat_unload.c create mode 100644 binfmt/nxflat.c create mode 100644 include/nuttx/binfmt.h diff --git a/binfmt/Makefile b/binfmt/Makefile index 0e3d9720cc..deb6879a9b 100644 --- a/binfmt/Makefile +++ b/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/binfmt/libnxflat/Make.defs b/binfmt/libnxflat/Make.defs index 96cff471db..21d00f7f17 100644 --- a/binfmt/libnxflat/Make.defs +++ b/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/binfmt/libnxflat/libnxflat_init.c b/binfmt/libnxflat/libnxflat_init.c new file mode 100644 index 0000000000..4696d491a4 --- /dev/null +++ b/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 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +/**************************************************************************** + * 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/binfmt/libnxflat/libnxflat_load.c b/binfmt/libnxflat/libnxflat_load.c index d456ae3a18..0b143dad4e 100644 --- a/binfmt/libnxflat/libnxflat_load.c +++ b/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 @@ -39,10 +39,14 @@ #include #include +#include + +#include #include #include #include #include + #include #include @@ -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 @@ -87,27 +81,11 @@ static const char *segment[] = * Private Functions ****************************************************************************/ -/**************************************************************************** - * 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); } } @@ -208,236 +186,119 @@ static void nxflat_reloc(struct nxflat_loadinfo_s *load_info, uint32 rl) * Public Functions ****************************************************************************/ -/**************************************************************************** - * 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; + 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 + /* 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 0; + return OK; + +errout: + (void)nxflat_unload(loadinfo); + return ret; } diff --git a/binfmt/libnxflat/libnxflat_read.c b/binfmt/libnxflat/libnxflat_read.c new file mode 100644 index 0000000000..ff52001407 --- /dev/null +++ b/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 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +/**************************************************************************** + * 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/binfmt/libnxflat/libnxflat_stack.c b/binfmt/libnxflat/libnxflat_stack.c deleted file mode 100644 index 082a2e05e8..0000000000 --- a/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 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#include -#include -#include -#include - -/**************************************************************************** - * 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/binfmt/libnxflat/libnxflat_uninit.c b/binfmt/libnxflat/libnxflat_uninit.c new file mode 100644 index 0000000000..47d1a90a2b --- /dev/null +++ b/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 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +/**************************************************************************** + * 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/binfmt/libnxflat/libnxflat_unload.c b/binfmt/libnxflat/libnxflat_unload.c new file mode 100644 index 0000000000..d648c0ebd4 --- /dev/null +++ b/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 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include + +#include + +/**************************************************************************** + * 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/binfmt/libnxflat/libnxflat_verify.c b/binfmt/libnxflat/libnxflat_verify.c index b31994b8b4..db1069e9fb 100644 --- a/binfmt/libnxflat/libnxflat_verify.c +++ b/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 @@ -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/binfmt/nxflat.c b/binfmt/nxflat.c new file mode 100644 index 0000000000..d0456bebd1 --- /dev/null +++ b/binfmt/nxflat.c @@ -0,0 +1,236 @@ +/**************************************************************************** + * binfmt/nxflat.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +/**************************************************************************** + * 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); +} + diff --git a/include/debug.h b/include/debug.h index 8bd43a310e..7253d93e49 100644 --- a/include/debug.h +++ b/include/debug.h @@ -1,5 +1,5 @@ /**************************************************************************** - * debug.h + * include/debug.h * * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -33,8 +33,8 @@ * ****************************************************************************/ -#ifndef __DEBUG_H -#define __DEBUG_H +#ifndef __INCLUDE_DEBUG_H +#define __INCLUDE_DEBUG_H /**************************************************************************** * Included Files @@ -175,6 +175,18 @@ # define gllvdbg(x...) #endif +#ifdef CONFIG_DEBUG_BINFMT +# define bdbg(format, arg...) dbg(format, ##arg) +# define blldbg(format, arg...) lldbg(format, ##arg) +# define bvdbg(format, arg...) vdbg(format, ##arg) +# define bllvdbg(format, arg...) llvdbg(format, ##arg) +#else +# define bdbg(x...) +# define blldbg(x...) +# define bvdbg(x...) +# define bllvdbg(x...) +#endif + #ifdef CONFIG_DEBUG_LIB # define ldbg(format, arg...) dbg(format, ##arg) # define llldbg(format, arg...) lldbg(format, ##arg) @@ -284,6 +296,18 @@ # define gllvdbg (void) #endif +#ifdef CONFIG_DEBUG_BINFMT +# define bdbg dbg +# define blldbg lldbg +# define bvdbg vdbg +# define bllvdbg llvdbg +#else +# define bdbg (void) +# define blldbg (void) +# define bvdbg (void) +# define bllvdbg (void) +#endif + #ifdef CONFIG_DEBUG_LIB # define ldbg dbg # define llldbg lldbg @@ -357,4 +381,4 @@ EXTERN int llvdbg(const char *format, ...); } #endif -#endif /* __DEBUG_H */ +#endif /* __INCLUDE_DEBUG_H */ diff --git a/include/errno.h b/include/errno.h index 1dea0f4091..945f839570 100644 --- a/include/errno.h +++ b/include/errno.h @@ -1,7 +1,7 @@ /************************************************************************ * include/errno.h * - * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -33,8 +33,8 @@ * ************************************************************************/ -#ifndef __ERRNO_H -#define __ERRNO_H +#ifndef __INCLUDE_ERRNO_H +#define __INCLUDE_ERRNO_H /************************************************************************ * Included Files @@ -324,4 +324,4 @@ extern FAR int *get_errno_ptr(void); } #endif -#endif /* __ERRNO_H */ +#endif /* __INCLUDE_ERRNO_H */ diff --git a/include/nuttx/binfmt.h b/include/nuttx/binfmt.h new file mode 100644 index 0000000000..20b27987a6 --- /dev/null +++ b/include/nuttx/binfmt.h @@ -0,0 +1,100 @@ +/**************************************************************************** + * include/nuttx/binfmt.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_BINFMT_H +#define __INCLUDE_NUTTX_BINFMT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* This describes the file to be loaded */ + +struct binary_s +{ + /* Provided to the loader */ + + const char *filename; /* Full path to the binary */ + const char **argv; /* Argument list */ + + /* Provided by the loader (if successful) */ + + main_t entrypt; /* Entry point into a program module */ + void *picbase; /* Address of the allocate .data/.bss space */ +}; + +/* This describes one binary format handler */ + +struct binfmt_s +{ + struct binfmt_s *next; /* Supports a singly-linked list */ + int (*load)(struct binary_s *bin); /* Verify and load binary into memory */ +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" { +#else +#define EXTERN extern +#endif + +/* Register/unregister a binary format */ + +EXTERN int register_binfmt(struct binfmt_s *binfmt); +EXTERN int unregister_binfmt(struct binfmt_s *binfmt); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __INCLUDE_NUTTX_BINFMT_H */ diff --git a/include/nuttx/nxflat.h b/include/nuttx/nxflat.h index e3d19e1dea..20fabdf7c9 100644 --- a/include/nuttx/nxflat.h +++ b/include/nuttx/nxflat.h @@ -62,45 +62,6 @@ struct nxflat_ldso_info }; #define NXFLAT_DATA_OFFSET sizeof(struct nxflat_ldso_info) -/* An "opaque" handle that describes the xflat binary to be loaded. */ - -typedef void *bin_handle_t; - -/* An "opaque" handle that describes an open file */ - -typedef void *file_handle_t; - -/* This is a call table that is used by the xflat library to call - * obtain system information. The use of this call table allows the - * library to be designed in a platform independent way. - */ - -struct nxflat_vtbl_s -{ - /* Allocators. These imports keep the xflat library independent of - * the memory mapping and memory management facilities of the host - * system. - * - * map/unmap will map/unmap a program file onto an address; - * alloc/free will allocate/deallocate program memory. - */ - - void *(*map)(file_handle_t file_handle, uint32 nbytes); - void (*unmap)(void *address, uint32 nbytes); - void *(*alloc)(uint32 nbytes); - void (*free)(void *address, uint32 nbytes); - - /* File access utilities. These imports keep the xflat libary independent - * of the host system's file system. - */ - - file_handle_t (*open)(bin_handle_t bin_handle, const char *filename); - int (*read)(bin_handle_t bin_handle, file_handle_t file_handle, - char *dest, uint32 nbytes, - uint32 fpos); - void (*close)(file_handle_t file_handle); -}; - /* This struct provides a desciption of the currently loaded * instantiation of an xflat binary. */ @@ -113,8 +74,8 @@ struct nxflat_loadinfo_s */ uint32 ispace; /* Address where hdr/text is loaded */ - /* 1st: struct nxflat_hdr_s */ - /* 2nd: text section */ + /* 1st: struct nxflat_hdr_s */ + /* 2nd: text section */ uint32 entry_offset; /* Offset from ispace to entry point */ uint32 ispace_size; /* Size of ispace. */ @@ -142,25 +103,18 @@ struct nxflat_loadinfo_s uint32 reloc_start; /* Start of array of struct flat_reloc */ uint32 reloc_count; /* Number of elements in reloc array */ - /* These are hooks stored by nxflat_init for subsequent use. - * These constitute all points of contact between the flat - * library and the rest of the world. These allows the flat - * library to opperate in a variey of contexts without change. - */ + /* File descriptors */ - bin_handle_t bin_handle; /* Like a "this" pointer. Retains - * calling context information in callbacks */ - file_handle_t file_handle; /* Describes an open file */ + int filfd; /* Descriptor for the file being loaded */ const struct nxflat_hdr_s *header; /* A reference to the flat file header */ - const struct nxflat_vtbl_s *vtbl; /* Systam callback vtbl */ /* At most one memory allocation will be made. These describe that * allocation. */ - uint32 alloc_start; /* Start of the allocation */ - uint32 alloc_size; /* Size of the allocation */ + uint32 alloc_start; /* Start of the allocation */ + uint32 alloc_size; /* Size of the allocation */ }; /**************************************************************************** @@ -175,54 +129,42 @@ extern "C" { #define EXTERN extern #endif -/* Given the header from a possible xFLT executable, verify that it +/* Given the header from a possible NXFLAT executable, verify that it * is an NXFLAT executable. */ EXTERN int nxflat_verifyheader(const struct nxflat_hdr_s *header); -/* This function is called to configure xflatlib to process an xFLT - * program binary. Upon return, the controlling logic has the opportunity - * to adjust the contents of the load_info structure. +/* This function is called to configure the library to process an NXFLAT + * program binary. */ -EXTERN 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); - -/* This function unloads the object from memory. This essentially - * undoes the actions of nxflat_load. - */ - -EXTERN int nxflat_unload(struct nxflat_loadinfo_s *load_info); +EXTERN int nxflat_init(const char *filename, + struct nxflat_hdr_s *header, + struct nxflat_loadinfo_s *loadinfo); /* Releases any resources committed by nxflat_init(). This essentially - * undoes the actions of nxflat_init or nxflat_init_interpreter. */ + * undoes the actions of nxflat_init. + */ -EXTERN int nxflat_uninit(struct nxflat_loadinfo_s *load_info); +EXTERN int nxflat_uninit(struct nxflat_loadinfo_s *loadinfo); /* Loads the binary specified by nxflat_init into memory, * Completes all relocations, and clears BSS. */ -EXTERN int nxflat_load(struct nxflat_loadinfo_s *load_info); +EXTERN int nxflat_load(struct nxflat_loadinfo_s *loadinfo); -/* Adjust stack size to include argc, envc, xFLT internal usage and - * system internal usage. */ +/* Read 'readsize' bytes from the object file at 'offset' */ -EXTERN void nxflat_adjuststacksize(struct nxflat_loadinfo_s *load_info, - int argc, int envc, int system_usage); +EXTERN int nxflat_read(struct nxflat_loadinfo_s *loadinfo, char *buffer, + int readsize, int offset); -/* Initialize stack frame for execution */ +/* This function unloads the object from memory. This essentially + * undoes the actions of nxflat_load. + */ -EXTERN uint32 nxflat_initstack(struct nxflat_loadinfo_s *prog_load_info, - struct nxflat_loadinfo_s *lib_load_info, - int argc, int envc, char *p); - -/* Releases any resources committed by nxflat_init(). */ - -EXTERN int nxflat_uninit(struct nxflat_loadinfo_s *load_info); +EXTERN int nxflat_unload(struct nxflat_loadinfo_s *loadinfo); #undef EXTERN #if defined(__cplusplus) diff --git a/include/sys/types.h b/include/sys/types.h index 993c44e8d7..0c02042555 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -135,7 +135,7 @@ typedef int STATUS; typedef unsigned int socklen_t; typedef uint16 sa_family_t; -/* Process entry point */ +/* Task entry point */ typedef int (*main_t)(int argc, char *argv[]);