mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 08:38:38 +08:00
Finish implemention of ELF loader static constructor support. Still some issues.
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5272 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
43f0c7bebc
commit
0f70f8c9e1
14 changed files with 525 additions and 344 deletions
|
@ -282,7 +282,7 @@ int arch_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym,
|
|||
|
||||
if (offset <= (int32_t)0xff000000 || offset >= (int32_t)0x01000000)
|
||||
{
|
||||
bdbg(" ERROR: JUMP24 [%d] relocation out of range, offset=%08lx\n",
|
||||
bdbg(" ERROR: JUMP24 [%d] relocation out of range, branch taget=%08lx\n",
|
||||
ELF32_R_TYPE(rel->r_info), offset);
|
||||
|
||||
return -EINVAL;
|
||||
|
|
|
@ -116,6 +116,7 @@ static void elf_dumploadinfo(FAR struct elf_loadinfo_s *loadinfo)
|
|||
bdbg(" filelen: %ld\n", (long)loadinfo->filelen);
|
||||
#ifdef CONFIG_ELF_CONSTRUCTORS
|
||||
bdbg(" ctors: %08lx\n", (long)loadinfo->ctors);
|
||||
bdbg(" nctors: %d\n", loadinfo->nctors);
|
||||
#endif
|
||||
bdbg(" filfd: %d\n", loadinfo->filfd);
|
||||
bdbg(" symtabidx: %d\n", loadinfo->symtabidx);
|
||||
|
|
|
@ -43,7 +43,7 @@ BINFMT_CSRCS += elf.c
|
|||
|
||||
BINFMT_CSRCS += libelf_init.c libelf_uninit.c libelf_load.c \
|
||||
libelf_unload.c libelf_verify.c libelf_read.c \
|
||||
libelf_bind.c libelf_symbols.c
|
||||
libelf_bind.c libelf_symbols.c libelf_iobuffer.c
|
||||
|
||||
ifeq ($(CONFIG_ELF_CONSTRUCTORS),y)
|
||||
BINFMT_CSRCS += libelf_ctors.c
|
||||
|
|
|
@ -141,6 +141,49 @@ int elf_readsym(FAR struct elf_loadinfo_s *loadinfo, int index,
|
|||
int elf_symvalue(FAR struct elf_loadinfo_s *loadinfo, FAR Elf32_Sym *sym,
|
||||
FAR const struct symtab_s *exports, int nexports);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_freebuffers
|
||||
*
|
||||
* Description:
|
||||
* Release all working buffers.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int elf_freebuffers(FAR struct elf_loadinfo_s *loadinfo);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_allocbuffer
|
||||
*
|
||||
* Description:
|
||||
* Perform the initial allocation of the I/O buffer, if it has not already
|
||||
* been allocated.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int elf_allocbuffer(FAR struct elf_loadinfo_s *loadinfo);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_reallocbuffer
|
||||
*
|
||||
* Description:
|
||||
* Increase the size of I/O buffer by the specified buffer increment.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int elf_reallocbuffer(FAR struct elf_loadinfo_s *loadinfo, size_t increment);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_findctors
|
||||
*
|
||||
|
@ -157,7 +200,7 @@ int elf_symvalue(FAR struct elf_loadinfo_s *loadinfo, FAR Elf32_Sym *sym,
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ELF_CONSTRUCTORS
|
||||
int elf_findctors(FAR struct elf_loadinfo_s *loadinfo);
|
||||
int elf_loadctors(FAR struct elf_loadinfo_s *loadinfo);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/binfmt/elf.h>
|
||||
#include <nuttx/binfmt/symtab.h>
|
||||
|
||||
|
@ -247,17 +246,16 @@ int elf_bind(FAR struct elf_loadinfo_s *loadinfo,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Allocate an I/O buffer. This buffer is used only by elf_symname() to
|
||||
/* Allocate an I/O buffer. This buffer is used by elf_symname() to
|
||||
* accumulate the variable length symbol name.
|
||||
*/
|
||||
|
||||
loadinfo->iobuffer = (FAR uint8_t *)kmalloc(CONFIG_ELF_BUFFERSIZE);
|
||||
if (!loadinfo->iobuffer)
|
||||
ret = elf_allocbuffer(loadinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("Failed to allocate an I/O buffer\n");
|
||||
bdbg("elf_allocbuffer failed: %d\n", ret);
|
||||
return -ENOMEM;
|
||||
}
|
||||
loadinfo->buflen = CONFIG_ELF_BUFFERSIZE;
|
||||
|
||||
/* Process relocations in every allocated section */
|
||||
|
||||
|
@ -303,11 +301,6 @@ int elf_bind(FAR struct elf_loadinfo_s *loadinfo,
|
|||
arch_flushicache((FAR void*)loadinfo->alloc, loadinfo->allocsize);
|
||||
#endif
|
||||
|
||||
/* Free the I/O buffer */
|
||||
|
||||
kfree(loadinfo->iobuffer);
|
||||
loadinfo->iobuffer = NULL;
|
||||
loadinfo->buflen = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,11 +39,15 @@
|
|||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/binfmt/elf.h>
|
||||
|
||||
#include "libelf"
|
||||
#include "libelf.h"
|
||||
|
||||
#ifdef CONFIG_ELF_CONSTRUCTORS
|
||||
|
||||
|
@ -55,8 +59,6 @@
|
|||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
typedef FAR void (*ctor_t)(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Constant Data
|
||||
****************************************************************************/
|
||||
|
@ -66,9 +68,111 @@ typedef FAR void (*ctor_t)(void);
|
|||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
* Name: elf_sectname
|
||||
*
|
||||
* Description:
|
||||
* Get the symbol name in loadinfo->iobuffer[].
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline int elf_sectname(FAR struct elf_loadinfo_s *loadinfo,
|
||||
FAR const Elf32_Shdr *shdr)
|
||||
{
|
||||
FAR Elf32_Shdr *shstr;
|
||||
FAR uint8_t *buffer;
|
||||
off_t offset;
|
||||
size_t readlen;
|
||||
size_t bytesread;
|
||||
int shstrndx;
|
||||
int ret;
|
||||
|
||||
/* Get the section header table index of the entry associated with the
|
||||
* section name string table. If the file has no section name string table,
|
||||
* this member holds the value SH_UNDEF.
|
||||
*/
|
||||
|
||||
shstrndx = loadinfo->ehdr.e_shstrndx;
|
||||
if (shstrndx == SHN_UNDEF)
|
||||
{
|
||||
bdbg("No section header string table\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Get the section name string table section header */
|
||||
|
||||
shstr = &loadinfo->shdr[shstrndx];
|
||||
|
||||
/* Get the file offset to the string that is the name of the section. This
|
||||
* is the sum of:
|
||||
*
|
||||
* shstr->sh_offset: The file offset to the first byte of the section
|
||||
* header string table data.
|
||||
* shdr->sh_name: The offset to the name of the section in the section
|
||||
* name table
|
||||
*/
|
||||
|
||||
offset = shstr->sh_offset + shdr->sh_name;
|
||||
|
||||
/* Loop until we get the entire section name into memory */
|
||||
|
||||
buffer = loadinfo->iobuffer;
|
||||
bytesread = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* Get the number of bytes to read */
|
||||
|
||||
readlen = loadinfo->buflen - bytesread;
|
||||
if (offset + readlen > loadinfo->filelen)
|
||||
{
|
||||
readlen = loadinfo->filelen - offset;
|
||||
if (readlen <= 0)
|
||||
{
|
||||
bdbg("At end of file\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read that number of bytes into the array */
|
||||
|
||||
buffer = &loadinfo->iobuffer[bytesread];
|
||||
ret = elf_read(loadinfo, buffer, readlen, offset);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("Failed to read section name\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
bytesread += readlen;
|
||||
|
||||
/* Did we read the NUL terminator? */
|
||||
|
||||
if (memchr(buffer, '\0', readlen) != NULL)
|
||||
{
|
||||
/* Yes, the buffer contains a NUL terminator. */
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* No.. then we have to read more */
|
||||
|
||||
ret = elf_reallocbuffer(loadinfo, CONFIG_ELF_BUFFERINCR);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("elf_reallocbuffer failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* We will not get here */
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_findctors
|
||||
*
|
||||
|
@ -79,27 +183,157 @@ typedef FAR void (*ctor_t)(void);
|
|||
* loadinfo - Load state information
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, the index to the CTOR section is returned; A negated errno
|
||||
* value is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline int elf_findctors(FAR struct elf_loadinfo_s *loadinfo)
|
||||
{
|
||||
FAR const Elf32_Shdr *shdr;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* Search through the shdr[] array in loadinfo for a section named .ctors */
|
||||
|
||||
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
||||
{
|
||||
/* Get the name of this section */
|
||||
|
||||
shdr = &loadinfo->shdr[i];
|
||||
ret = elf_sectname(loadinfo, shdr);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("elf_sectname failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Check if the name of this section if ".ctors" */
|
||||
|
||||
bvdbg("%d. Comparing \"%s\" and .ctors\"\n", i, loadinfo->iobuffer);
|
||||
|
||||
if (strcmp(".ctors", (FAR const char *)loadinfo->iobuffer) == 0)
|
||||
{
|
||||
/* We found it... return the index */
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
/* We failed to find the .ctors sections. This may not be an error; maybe
|
||||
* there are no static constructors.
|
||||
*/
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_loadctors
|
||||
*
|
||||
* Description:
|
||||
* Load points to static constructors into an in-memory array.
|
||||
*
|
||||
* Input Parameters:
|
||||
* loadinfo - Load state information
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int elf_findctors(FAR struct elf_loadinfo_s *loadinfo)
|
||||
int elf_loadctors(FAR struct elf_loadinfo_s *loadinfo)
|
||||
{
|
||||
/* Search through the shdr[] array in loadinfo for a section named .ctors */
|
||||
#warning "Missing logic"
|
||||
FAR Elf32_Shdr *shdr;
|
||||
size_t ctorsize;
|
||||
int ctoridx;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* Get the address of the beginning of the constructros from the sh_addr
|
||||
* field of the section. Save that in the ctors field of the loadinfo
|
||||
* structure.
|
||||
DEBUGASSERT(loadinfo->ctors == NULL);
|
||||
|
||||
/* Allocate an I/O buffer. This buffer is used by elf_sectname() to
|
||||
* accumulate the variable length symbol name.
|
||||
*/
|
||||
#warning "Missing logic"
|
||||
|
||||
/* Get the number of constructors from the sh_size field of the section.
|
||||
* Save that number in the nctors field of the loadinfo structure.
|
||||
*/
|
||||
#warning "Missing logic"
|
||||
return -ENOSYS;
|
||||
ret = elf_allocbuffer(loadinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("elf_allocbuffer failed: %d\n", ret);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Find the index to the section named ".ctors" */
|
||||
|
||||
ctoridx = elf_findctors(loadinfo);
|
||||
if (ctoridx < 0)
|
||||
{
|
||||
/* This may not be a failure. -ENOENT indicates that the file has no
|
||||
* static constructor section.
|
||||
*/
|
||||
|
||||
bvdbg("elf_findctors failed: %d\n", ctoridx);
|
||||
return ret == -ENOENT ? OK : ret;
|
||||
}
|
||||
|
||||
/* Now we can get a pointer to the .ctor section in the section header
|
||||
* table.
|
||||
*/
|
||||
|
||||
shdr = &loadinfo->shdr[ctoridx];
|
||||
|
||||
/* Allocate memory to hold a copy of the .ctor section */
|
||||
|
||||
ctorsize = shdr->sh_size;
|
||||
loadinfo->nctors = ctorsize / sizeof(elf_ctor_t);
|
||||
|
||||
bvdbg("ctoridx=%d ctorsize=%d sizeof(elf_ctor_t)=%d nctors=%d\n",
|
||||
ctoridx, ctorsize, sizeof(elf_ctor_t), loadinfo->nctors);
|
||||
|
||||
/* Check if there are any constructors. It is not an error if there
|
||||
* are none.
|
||||
*/
|
||||
|
||||
if (loadinfo->nctors > 0)
|
||||
{
|
||||
/* Check an assumption that we made above */
|
||||
|
||||
DEBUGASSERT(shdr->sh_entsize == sizeof(elf_ctor_t));
|
||||
|
||||
loadinfo->ctors = (elf_ctor_t)kmalloc(ctorsize);
|
||||
if (!loadinfo->ctors)
|
||||
{
|
||||
bdbg("Failed to allocate memory for .ctors\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Read the section header table into memory */
|
||||
|
||||
ret = elf_read(loadinfo, (FAR uint8_t*)loadinfo->ctors, ctorsize,
|
||||
shdr->sh_offset);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("Failed to allocate .ctors: %d\n", ret);
|
||||
}
|
||||
|
||||
/* Fix up all of the .ctor addresses */
|
||||
|
||||
for (i = 0; i < loadinfo->nctors; i++)
|
||||
{
|
||||
FAR uintptr_t *ptr = (uintptr_t *)((FAR void *)(&loadinfo->ctors)[i]);
|
||||
|
||||
bvdbg("ctor %d: %08lx + %08lx = %08lx\n", i,
|
||||
*ptr, loadinfo->alloc, *ptr + loadinfo->alloc);
|
||||
|
||||
*ptr += loadinfo->alloc;
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -119,16 +353,20 @@ int elf_findctors(FAR struct elf_loadinfo_s *loadinfo)
|
|||
|
||||
int elf_doctors(FAR struct elf_loadinfo_s *loadinfo)
|
||||
{
|
||||
ctor_t ctor = (ctor_t)loadinfo->ctors;
|
||||
elf_ctor_t ctor = (elf_ctor_t)loadinfo->ctors;
|
||||
int i;
|
||||
|
||||
/* Execute each constructor */
|
||||
|
||||
for (i = 0; i < loadinfo->nctors; i++)
|
||||
{
|
||||
bvdbg("Calling ctor %d at %p\n", i, (FAR void *)ctor);
|
||||
|
||||
ctor();
|
||||
ctor++;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ELF_CONSTRUCTORS
|
||||
#endif /* CONFIG_ELF_CONSTRUCTORS */
|
||||
|
|
136
binfmt/libelf/libelf_iobuffer.c
Normal file
136
binfmt/libelf/libelf_iobuffer.c
Normal file
|
@ -0,0 +1,136 @@
|
|||
/****************************************************************************
|
||||
* binfmt/libelf/elf_iobuffer.c
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* 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 <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/binfmt/elf.h>
|
||||
|
||||
#include "libelf.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Constant Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_allocbuffer
|
||||
*
|
||||
* Description:
|
||||
* Perform the initial allocation of the I/O buffer, if it has not already
|
||||
* been allocated.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int elf_allocbuffer(FAR struct elf_loadinfo_s *loadinfo)
|
||||
{
|
||||
/* Has a buffer been allocated> */
|
||||
|
||||
if (!loadinfo->iobuffer)
|
||||
{
|
||||
/* No.. allocate one now */
|
||||
|
||||
loadinfo->iobuffer = (FAR uint8_t *)kmalloc(CONFIG_ELF_BUFFERSIZE);
|
||||
if (!loadinfo->iobuffer)
|
||||
{
|
||||
bdbg("Failed to allocate an I/O buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
loadinfo->buflen = CONFIG_ELF_BUFFERSIZE;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_reallocbuffer
|
||||
*
|
||||
* Description:
|
||||
* Increase the size of I/O buffer by the specified buffer increment.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int elf_reallocbuffer(FAR struct elf_loadinfo_s *loadinfo, size_t increment)
|
||||
{
|
||||
FAR void *buffer;
|
||||
size_t newsize;
|
||||
|
||||
/* Get the new size of the allocation */
|
||||
|
||||
newsize = loadinfo->buflen + increment;
|
||||
|
||||
/* And perform the reallocation */
|
||||
|
||||
buffer = krealloc((FAR void *)loadinfo->iobuffer, newsize);
|
||||
if (!buffer)
|
||||
{
|
||||
bdbg("Failed to reallocate the I/O buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Save the new buffer info */
|
||||
|
||||
loadinfo->iobuffer = buffer;
|
||||
loadinfo->buflen = newsize;
|
||||
return OK;
|
||||
}
|
||||
|
|
@ -126,14 +126,8 @@ static inline int elf_loadshdrs(FAR struct elf_loadinfo_s *loadinfo)
|
|||
if (ret < 0)
|
||||
{
|
||||
bdbg("Failed to read section header table: %d\n", ret);
|
||||
goto errout_with_alloc;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
errout_with_alloc:
|
||||
kfree(loadinfo->shdr);
|
||||
loadinfo->shdr = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -233,7 +227,7 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
|
|||
if (ret < 0)
|
||||
{
|
||||
bdbg("Failed to read section %d: %d\n", i, ret);
|
||||
goto errout_with_alloc;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -248,11 +242,6 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
|
|||
}
|
||||
|
||||
return OK;
|
||||
|
||||
errout_with_alloc:
|
||||
kfree((FAR void*)loadinfo->alloc);
|
||||
loadinfo->alloc = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -285,7 +274,7 @@ int elf_load(FAR struct elf_loadinfo_s *loadinfo)
|
|||
if (ret < 0)
|
||||
{
|
||||
bdbg("elf_loadshdrs failed: %d\n", ret);
|
||||
return ret;
|
||||
goto errout_with_buffers;
|
||||
}
|
||||
|
||||
/* Determine total size to allocate */
|
||||
|
@ -298,16 +287,17 @@ int elf_load(FAR struct elf_loadinfo_s *loadinfo)
|
|||
if (ret < 0)
|
||||
{
|
||||
bdbg("elf_loadfile failed: %d\n", ret);
|
||||
goto errout_with_shdrs;
|
||||
goto errout_with_buffers;
|
||||
}
|
||||
|
||||
/* Find static constructors. */
|
||||
|
||||
#ifdef CONFIG_ELF_CONSTRUCTORS
|
||||
ret = elf_findctors(loadinfo);
|
||||
ret = elf_loadctors(loadinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("elf_findctors failed: %d\n", ret);
|
||||
goto errout_with_shdrs;
|
||||
bdbg("elf_loadctors failed: %d\n", ret);
|
||||
goto errout_with_buffers;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -315,9 +305,8 @@ int elf_load(FAR struct elf_loadinfo_s *loadinfo)
|
|||
|
||||
/* Error exits */
|
||||
|
||||
errout_with_shdrs:
|
||||
kfree(loadinfo->shdr);
|
||||
loadinfo->shdr = NULL;
|
||||
errout_with_buffers:
|
||||
elf_freebuffers(loadinfo);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -101,7 +101,6 @@ static int elf_symname(FAR struct elf_loadinfo_s *loadinfo,
|
|||
|
||||
/* Loop until we get the entire symbol name into memory */
|
||||
|
||||
buffer = loadinfo->iobuffer;
|
||||
bytesread = 0;
|
||||
|
||||
for (;;)
|
||||
|
@ -125,7 +124,7 @@ static int elf_symname(FAR struct elf_loadinfo_s *loadinfo,
|
|||
ret = elf_read(loadinfo, buffer, readlen, offset);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("Failed to read symbol name\n");
|
||||
bdbg("elf_read failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -142,18 +141,12 @@ static int elf_symname(FAR struct elf_loadinfo_s *loadinfo,
|
|||
|
||||
/* No.. then we have to read more */
|
||||
|
||||
buffer = realloc((FAR void *)loadinfo->iobuffer,
|
||||
loadinfo->buflen + CONFIG_ELF_BUFFERINCR);
|
||||
if (!buffer)
|
||||
ret = elf_reallocbuffer(loadinfo, CONFIG_ELF_BUFFERINCR);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("Failed to reallocate the I/O buffer\n");
|
||||
return -ENOMEM;
|
||||
bdbg("elf_reallocbuffer failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Save the new buffer info */
|
||||
|
||||
loadinfo->iobuffer = buffer;
|
||||
loadinfo->buflen += CONFIG_ELF_BUFFERINCR;
|
||||
}
|
||||
|
||||
/* We will not get here */
|
||||
|
|
|
@ -42,8 +42,12 @@
|
|||
#include <unistd.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/binfmt/elf.h>
|
||||
|
||||
#include "libelf.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-Processor Definitions
|
||||
****************************************************************************/
|
||||
|
@ -75,6 +79,12 @@
|
|||
|
||||
int elf_uninit(struct elf_loadinfo_s *loadinfo)
|
||||
{
|
||||
/* Free all working buffers */
|
||||
|
||||
elf_freebuffers(loadinfo);
|
||||
|
||||
/* Close the ELF file */
|
||||
|
||||
if (loadinfo->filfd >= 0)
|
||||
{
|
||||
close(loadinfo->filfd);
|
||||
|
@ -83,3 +93,43 @@ int elf_uninit(struct elf_loadinfo_s *loadinfo)
|
|||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_freebuffers
|
||||
*
|
||||
* Description:
|
||||
* Release all working buffers.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int elf_freebuffers(struct elf_loadinfo_s *loadinfo)
|
||||
{
|
||||
/* Release all working allocations */
|
||||
|
||||
if (loadinfo->shdr)
|
||||
{
|
||||
kfree((FAR void *)loadinfo->shdr);
|
||||
loadinfo->shdr = NULL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ELF_CONSTRUCTORS
|
||||
if (loadinfo->ctors)
|
||||
{
|
||||
kfree((FAR void *)loadinfo->ctors);
|
||||
loadinfo->ctors = NULL;
|
||||
loadinfo->nctors = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (loadinfo->iobuffer)
|
||||
{
|
||||
kfree((FAR void *)loadinfo->iobuffer);
|
||||
loadinfo->iobuffer = NULL;
|
||||
loadinfo->buflen = 0;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/binfmt/elf.h>
|
||||
|
||||
#include "libelf.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-Processor Definitions
|
||||
****************************************************************************/
|
||||
|
@ -76,7 +78,11 @@
|
|||
|
||||
int elf_unload(struct elf_loadinfo_s *loadinfo)
|
||||
{
|
||||
/* Release the all allocated memory */
|
||||
/* Free all working buffers */
|
||||
|
||||
elf_freebuffers(loadinfo);
|
||||
|
||||
/* Release memory holding the relocated ELF image */
|
||||
|
||||
if (loadinfo->alloc)
|
||||
{
|
||||
|
@ -85,19 +91,6 @@ int elf_unload(struct elf_loadinfo_s *loadinfo)
|
|||
loadinfo->allocsize = 0;
|
||||
}
|
||||
|
||||
if (loadinfo->shdr)
|
||||
{
|
||||
kfree((FAR void *)loadinfo->shdr);
|
||||
loadinfo->shdr = NULL;
|
||||
}
|
||||
|
||||
if (loadinfo->iobuffer)
|
||||
{
|
||||
kfree((FAR void *)loadinfo->iobuffer);
|
||||
loadinfo->iobuffer = NULL;
|
||||
loadinfo->buflen = 0;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -161,6 +161,8 @@ LDNXFLATFLAGS = -e main -s 2048
|
|||
# ELF module definitions
|
||||
|
||||
CELFFLAGS = $(CFLAGS) -mlong-calls
|
||||
CXXELFFLAGS = $(CXXFLAGS) -mlong-calls
|
||||
|
||||
LDELFFLAGS = -r -e main
|
||||
ifeq ($(WINTOOL),y)
|
||||
LDELFFLAGS += -T "${shell cygpath -w $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/gnu-elf.ld}"
|
||||
|
|
|
@ -28,6 +28,7 @@ CONFIG_INTELHEX_BINARY=y
|
|||
#
|
||||
# CONFIG_ARCH_STDBOOL_H is not set
|
||||
# CONFIG_ARCH_MATH_H is not set
|
||||
# CONFIG_ARCH_FLOAT_H is not set
|
||||
# CONFIG_ARCH_STDARG_H is not set
|
||||
|
||||
#
|
||||
|
@ -387,7 +388,7 @@ CONFIG_ELF_ALIGN_LOG2=2
|
|||
CONFIG_ELF_STACKSIZE=2048
|
||||
CONFIG_ELF_BUFFERSIZE=128
|
||||
CONFIG_ELF_BUFFERINCR=32
|
||||
# CONFIG_ELF_CONSTRUCTORS is not set
|
||||
CONFIG_ELF_CONSTRUCTORS=y
|
||||
CONFIG_SYMTAB_ORDEREDBYNAME=y
|
||||
|
||||
#
|
||||
|
@ -397,6 +398,7 @@ CONFIG_STDIO_BUFFER_SIZE=256
|
|||
CONFIG_STDIO_LINEBUFFER=y
|
||||
CONFIG_NUNGET_CHARS=2
|
||||
CONFIG_LIB_HOMEDIR="/"
|
||||
# CONFIG_LIBM is not set
|
||||
# CONFIG_NOPRINTF_FIELDWIDTH is not set
|
||||
# CONFIG_LIBC_FLOATINGPOINT is not set
|
||||
# CONFIG_EOL_IS_CR is not set
|
||||
|
@ -425,264 +427,57 @@ CONFIG_HAVE_CXX=y
|
|||
#
|
||||
# Examples
|
||||
#
|
||||
|
||||
#
|
||||
# ADC Example
|
||||
#
|
||||
|
||||
#
|
||||
# Buttons Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_BUTTONS is not set
|
||||
|
||||
#
|
||||
# CAN Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_CAN is not set
|
||||
|
||||
#
|
||||
# USB CDC/ACM Class Driver Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_CDCACM is not set
|
||||
|
||||
#
|
||||
# USB composite Class Driver Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_COMPOSITE is not set
|
||||
|
||||
#
|
||||
# DHCP Server Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_DHCPD is not set
|
||||
|
||||
#
|
||||
# ELF Loader Example
|
||||
#
|
||||
CONFIG_EXAMPLES_ELF=y
|
||||
CONFIG_EXAMPLES_ELF_DEVMINOR=0
|
||||
CONFIG_EXAMPLES_ELF_DEVPATH="/dev/ram0"
|
||||
|
||||
#
|
||||
# FTP Client Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_FTPC is not set
|
||||
|
||||
#
|
||||
# FTP Server Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_FTPD is not set
|
||||
|
||||
#
|
||||
# "Hello, World!" Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_HELLO is not set
|
||||
|
||||
#
|
||||
# "Hello, World!" C++ Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_HELLOXX is not set
|
||||
|
||||
#
|
||||
# USB HID Keyboard Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_JSON is not set
|
||||
# CONFIG_EXAMPLES_HIDKBD is not set
|
||||
|
||||
#
|
||||
# IGMP Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_IGMP is not set
|
||||
|
||||
#
|
||||
# LCD Read/Write Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_LCDRW is not set
|
||||
|
||||
#
|
||||
# Memory Management Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_MM is not set
|
||||
|
||||
#
|
||||
# File System Mount Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_MOUNT is not set
|
||||
|
||||
#
|
||||
# FreeModBus Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_MODBUS is not set
|
||||
|
||||
#
|
||||
# Network Test Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_NETTEST is not set
|
||||
|
||||
#
|
||||
# NuttShell (NSH) Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_NSH is not set
|
||||
|
||||
#
|
||||
# NULL Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_NULL is not set
|
||||
|
||||
#
|
||||
# NX Graphics Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_NX is not set
|
||||
|
||||
#
|
||||
# NxConsole Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_NXCONSOLE is not set
|
||||
|
||||
#
|
||||
# NXFFS File System Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_NXFFS is not set
|
||||
|
||||
#
|
||||
# NXFLAT Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_NXFLAT is not set
|
||||
|
||||
#
|
||||
# NX Graphics "Hello, World!" Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_NXHELLO is not set
|
||||
|
||||
#
|
||||
# NX Graphics image Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_NXIMAGE is not set
|
||||
|
||||
#
|
||||
# NX Graphics lines Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_NXLINES is not set
|
||||
|
||||
#
|
||||
# NX Graphics Text Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_NXTEXT is not set
|
||||
|
||||
#
|
||||
# OS Test Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_OSTEST is not set
|
||||
|
||||
#
|
||||
# Pascal "Hello, World!"example
|
||||
#
|
||||
# CONFIG_EXAMPLES_PASHELLO is not set
|
||||
|
||||
#
|
||||
# Pipe Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_PIPE is not set
|
||||
|
||||
#
|
||||
# Poll Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_POLL is not set
|
||||
|
||||
#
|
||||
# Pulse Width Modulation (PWM) Example
|
||||
#
|
||||
|
||||
#
|
||||
# Quadrature Encoder Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_QENCODER is not set
|
||||
|
||||
#
|
||||
# RGMP Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_RGMP is not set
|
||||
|
||||
#
|
||||
# ROMFS Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_ROMFS is not set
|
||||
|
||||
#
|
||||
# sendmail Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_SENDMAIL is not set
|
||||
|
||||
#
|
||||
# Serial Loopback Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_SERLOOP is not set
|
||||
|
||||
#
|
||||
# Telnet Daemon Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_TELNETD is not set
|
||||
|
||||
#
|
||||
# THTTPD Web Server Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_THTTPD is not set
|
||||
|
||||
#
|
||||
# TIFF Generation Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_TIFF is not set
|
||||
|
||||
#
|
||||
# Touchscreen Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_TOUCHSCREEN is not set
|
||||
|
||||
#
|
||||
# UDP Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_UDP is not set
|
||||
|
||||
#
|
||||
# UDP Discovery Daemon Example
|
||||
#
|
||||
|
||||
#
|
||||
# uIP Web Server Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_UIP is not set
|
||||
|
||||
#
|
||||
# USB Serial Test Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_USBSERIAL is not set
|
||||
|
||||
#
|
||||
# USB Mass Storage Class Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_USBMSC is not set
|
||||
|
||||
#
|
||||
# USB Serial Terminal Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_USBTERM is not set
|
||||
|
||||
#
|
||||
# Watchdog timer Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_WATCHDOG is not set
|
||||
|
||||
#
|
||||
# wget Example
|
||||
#
|
||||
|
||||
#
|
||||
# WLAN Example
|
||||
#
|
||||
# CONFIG_EXAMPLES_WLAN is not set
|
||||
|
||||
#
|
||||
# XML RPC Example
|
||||
#
|
||||
|
||||
#
|
||||
# Interpreters
|
||||
#
|
||||
|
@ -700,74 +495,19 @@ CONFIG_EXAMPLES_ELF_DEVPATH="/dev/ram0"
|
|||
#
|
||||
# Networking Utilities
|
||||
#
|
||||
|
||||
#
|
||||
# DHCP client
|
||||
#
|
||||
# CONFIG_NETUTILS_DHCPC is not set
|
||||
|
||||
#
|
||||
# DHCP server
|
||||
#
|
||||
# CONFIG_NETUTILS_DHCPD is not set
|
||||
|
||||
#
|
||||
# FTP client
|
||||
#
|
||||
# CONFIG_NETUTILS_FTPC is not set
|
||||
|
||||
#
|
||||
# FTP server
|
||||
#
|
||||
# CONFIG_NETUTILS_FTPD is not set
|
||||
|
||||
#
|
||||
# Name resolution
|
||||
#
|
||||
# CONFIG_NETUTILS_JSON is not set
|
||||
# CONFIG_NETUTILS_RESOLV is not set
|
||||
|
||||
#
|
||||
# SMTP
|
||||
#
|
||||
# CONFIG_NETUTILS_SMTP is not set
|
||||
|
||||
#
|
||||
# TFTP client
|
||||
#
|
||||
# CONFIG_NETUTILS_TELNETD is not set
|
||||
|
||||
#
|
||||
# TFTP client
|
||||
#
|
||||
# CONFIG_NETUTILS_TFTPC is not set
|
||||
|
||||
#
|
||||
# THTTPD web server
|
||||
#
|
||||
# CONFIG_NETUTILS_THTTPD is not set
|
||||
|
||||
#
|
||||
# uIP support library
|
||||
#
|
||||
# CONFIG_NETUTILS_UIPLIB is not set
|
||||
|
||||
#
|
||||
# uIP web client
|
||||
#
|
||||
# CONFIG_NETUTILS_WEBCLIENT is not set
|
||||
|
||||
#
|
||||
# uIP web server
|
||||
#
|
||||
|
||||
#
|
||||
# UDP Discovery Utility
|
||||
#
|
||||
|
||||
#
|
||||
# XML-RPC library
|
||||
#
|
||||
|
||||
#
|
||||
# ModBus
|
||||
#
|
||||
|
|
|
@ -59,6 +59,9 @@
|
|||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
/* The type of one C++ constructor */
|
||||
|
||||
typedef FAR void (*elf_ctor_t)(void);
|
||||
|
||||
/* This struct provides a desciption of the currently loaded instantiation
|
||||
* of an ELF binary.
|
||||
|
@ -71,7 +74,7 @@ struct elf_loadinfo_s
|
|||
off_t filelen; /* Length of the entire ELF file */
|
||||
int filfd; /* Descriptor for the file being loaded */
|
||||
#ifdef CONFIG_ELF_CONSTRUCTORS
|
||||
uintptr_t ctors; /* Location of static constructors in memory */
|
||||
elf_ctor_t ctors; /* Pointer to a list of constructors */
|
||||
uint16_t nctors; /* Number of constructors */
|
||||
#endif
|
||||
uint16_t symtabidx; /* Symbol table section index */
|
||||
|
|
Loading…
Reference in a new issue