Easing in binfmt support

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1892 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2009-06-17 16:28:50 +00:00
parent 57650c2c6c
commit fdca08128e
15 changed files with 981 additions and 619 deletions

View file

@ -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)

View file

@ -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

View file

@ -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;
}

View file

@ -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
@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;

236
binfmt/nxflat.c Normal file
View file

@ -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);
}

View file

@ -1,5 +1,5 @@
/****************************************************************************
* debug.h
* include/debug.h
*
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
@ -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 */

View file

@ -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 <spudmonkey@racsa.co.cr>
*
* 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 */

100
include/nuttx/binfmt.h Normal file
View file

@ -0,0 +1,100 @@
/****************************************************************************
* include/nuttx/binfmt.h
*
* 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.
*
****************************************************************************/
#ifndef __INCLUDE_NUTTX_BINFMT_H
#define __INCLUDE_NUTTX_BINFMT_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <nxflat.h>
/****************************************************************************
* 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 */

View file

@ -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)

View file

@ -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[]);