summaryrefslogtreecommitdiff
path: root/nuttx/binfmt
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-10-25 16:18:20 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-10-25 16:18:20 +0000
commit5da217b108089f9ea14ce8ebd1412908bb86f0a0 (patch)
treeeef8d62f4f6b69c9377ef1814144713d434eb43c /nuttx/binfmt
parentcb3be8c6e6920198440d9654f05b122853724868 (diff)
downloadnuttx-5da217b108089f9ea14ce8ebd1412908bb86f0a0.tar.gz
nuttx-5da217b108089f9ea14ce8ebd1412908bb86f0a0.tar.bz2
nuttx-5da217b108089f9ea14ce8ebd1412908bb86f0a0.zip
A little more ELF loader logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5257 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/binfmt')
-rw-r--r--nuttx/binfmt/Makefile4
-rw-r--r--nuttx/binfmt/elf.c86
-rw-r--r--nuttx/binfmt/libelf/Kconfig13
-rw-r--r--nuttx/binfmt/libelf/Make.defs3
-rw-r--r--nuttx/binfmt/libelf/arm.h53
-rw-r--r--nuttx/binfmt/libelf/libelf.h55
-rw-r--r--nuttx/binfmt/libelf/libelf_bind.c171
-rw-r--r--nuttx/binfmt/libelf/libelf_init.c4
-rw-r--r--nuttx/binfmt/libelf/libelf_load.c57
-rw-r--r--nuttx/binfmt/libelf/libelf_symbols.c134
-rw-r--r--nuttx/binfmt/libelf/libelf_unload.c10
-rw-r--r--nuttx/binfmt/libelf/libelf_verify.c8
-rw-r--r--nuttx/binfmt/libnxflat/Make.defs1
13 files changed, 465 insertions, 134 deletions
diff --git a/nuttx/binfmt/Makefile b/nuttx/binfmt/Makefile
index 1b98e3ede..4724abeff 100644
--- a/nuttx/binfmt/Makefile
+++ b/nuttx/binfmt/Makefile
@@ -56,6 +56,7 @@ BINFMT_CSRCS += symtab_findbyname.c symtab_findbyvalue.c \
VPATH =
SUBDIRS =
+DEPPATH = --dep-path .
include libnxflat/Make.defs
include libelf/Make.defs
@@ -82,8 +83,7 @@ $(BIN): $(BINFMT_OBJS)
done ; )
.depend: Makefile $(BINFMT_SRCS)
- @$(MKDEP) --dep-path . --dep-path libnxflat \
- $(CC) -- $(CFLAGS) -- $(BINFMT_SRCS) >Make.dep
+ @$(MKDEP) $(DEPPATH) $(CC) -- $(CFLAGS) -- $(BINFMT_SRCS) >Make.dep
@touch $@
depend: .depend
diff --git a/nuttx/binfmt/elf.c b/nuttx/binfmt/elf.c
index fb3b5acd2..ba12a22ea 100644
--- a/nuttx/binfmt/elf.c
+++ b/nuttx/binfmt/elf.c
@@ -64,6 +64,10 @@
# undef CONFIG_ELF_DUMPBUFFER
#endif
+#ifndef CONFIG_ELF_STACKSIZE
+# define CONFIG_ELF_STACKSIZE 2048
+#endif
+
#ifdef CONFIG_ELF_DUMPBUFFER
# define elf_dumpbuffer(m,b,n) bvdbgdumpbuffer(m,b,n)
#else
@@ -104,33 +108,55 @@ static struct binfmt_s g_elfbinfmt =
#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_BINFMT)
static void elf_dumploadinfo(FAR struct elf_loadinfo_s *loadinfo)
{
- unsigned long dsize = loadinfo->datasize + loadinfo->bsssize;
+ int i;
bdbg("LOAD_INFO:\n");
- bdbg(" ISPACE:\n");
- bdbg(" ispace: %08lx\n", loadinfo->ispace);
- bdbg(" entryoffs: %08lx\n", loadinfo->entryoffs);
- bdbg(" isize: %08lx\n", loadinfo->isize);
-
- bdbg(" DSPACE:\n");
- bdbg(" dspace: %08lx\n", loadinfo->dspace);
- if (loadinfo->dspace != NULL)
+ bdbg(" alloc: %08lx\n", (long)loadinfo->alloc);
+ bdbg(" allocsize: %ld\n", (long)loadinfo->allocsize);
+ bdbg(" filelen: %ld\n", (long)loadinfo->filelen);
+#ifdef CONFIG_ELF_CONSTRUCTORS
+ bdbg(" ctors: %08lx\n", (long)loadinfo->ctors);
+#endif
+ bdbg(" filfd: %d\n", loadinfo->filfd);
+ bdbg(" symtabidx: %d\n", loadinfo->symtabidx);
+ bdbg(" strtabidx: %d\n", loadinfo->strtabidx);
+
+ bdbg("ELF Header:\n");
+ bdbg(" e_ident: %02x %02x %02x %02x\n",
+ loadinfo->ehdr.e_ident[0], loadinfo->ehdr.e_ident[1],
+ loadinfo->ehdr.e_ident[2], loadinfo->ehdr.e_ident[3]);
+ bdbg(" e_type: %04x\n", loadinfo->ehdr.e_type);
+ bdbg(" e_machine: %04x\n", loadinfo->ehdr.e_machine);
+ bdbg(" e_version: %08x\n", loadinfo->ehdr.e_version);
+ bdbg(" e_entry: %08lx\n", (long)loadinfo->ehdr.e_entry);
+ bdbg(" e_phoff: %d\n", loadinfo->ehdr.e_phoff);
+ bdbg(" e_shoff: %d\n", loadinfo->ehdr.e_shoff);
+ bdbg(" e_flags: %08x\n" , loadinfo->ehdr.e_flags);
+ bdbg(" e_ehsize: %d\n", loadinfo->ehdr.e_ehsize);
+ bdbg(" e_phentsize: %d\n", loadinfo->ehdr.e_phentsize);
+ bdbg(" e_phnum: %d\n", loadinfo->ehdr.e_phnum);
+ bdbg(" e_shentsize: %d\n", loadinfo->ehdr.e_shentsize);
+ bdbg(" e_shnum: %d\n", loadinfo->ehdr.e_shnum);
+ bdbg(" e_shstrndx: %d\n", loadinfo->ehdr.e_shstrndx);
+
+ if (loadinfo->shdr && loadinfo->ehdr.e_shum > 0)
{
- bdbg(" crefs: %d\n", loadinfo->dspace->crefs);
- bdbg(" region: %08lx\n", loadinfo->dspace->region);
+ for (i = 0; i < loadinfo->ehdr.e_shum; i++)
+ {
+ FAR ELF32_Shdr *shdr = &loadinfo->shdr[i];
+ bdbg("Sections %d:\n", i);
+ bdbg(" sh_name: %08x\n", shdr->sh_name);
+ bdbg(" sh_type: %08x\n", shdr->sh_type);
+ bdbg(" sh_flags: %08x\n", shdr->sh_flags);
+ bdbg(" sh_addr: %08x\n", shdr->sh_addr);
+ bdbg(" sh_offset: %d\n", shdr->sh_offset);
+ bdbg(" sh_size: %d\n", shdr->sh_size);
+ bdbg(" sh_link: %d\n", shdr->sh_link);
+ bdbg(" sh_info: %d\n", shdr->sh_info);
+ bdbg(" sh_addralign: %d\n", shdr->sh_addralign);
+ bdbg(" sh_entsize: %d\n", shdr->sh_entsize);
+ }
}
- bdbg(" datasize: %08lx\n", loadinfo->datasize);
- bdbg(" bsssize: %08lx\n", loadinfo->bsssize);
- bdbg(" (pad): %08lx\n", loadinfo->dsize - dsize);
- bdbg(" stacksize: %08lx\n", loadinfo->stacksize);
- bdbg(" dsize: %08lx\n", loadinfo->dsize);
-
- bdbg(" RELOCS:\n");
- bdbg(" relocstart: %08lx\n", loadinfo->relocstart);
- bdbg(" reloccount: %d\n", loadinfo->reloccount);
-
- bdbg(" HANDLES:\n");
- bdbg(" filfd: %d\n", loadinfo->filfd);
}
#else
# define elf_dumploadinfo(i)
@@ -148,7 +174,7 @@ static void elf_dumploadinfo(FAR struct elf_loadinfo_s *loadinfo)
static int elf_loadbinary(struct binary_s *binp)
{
struct elf_loadinfo_s loadinfo; /* Contains globals for libelf */
- int ret;
+ int ret;
bvdbg("Loading file: %s\n", binp->filename);
@@ -183,14 +209,14 @@ static int elf_loadbinary(struct binary_s *binp)
/* Return the load information */
- binp->entrypt = (main_t)(loadinfo.ispace + loadinfo.entryoffs);
- binp->ispace = (void*)loadinfo.ispace;
- binp->dspace = (void*)loadinfo.dspace;
- binp->isize = loadinfo.isize;
- binp->stacksize = loadinfo.stacksize;
+ binp->entrypt = (main_t)(loadinfo.alloc + loadinfo.ehdr.e_entry);
+ binp->ispace = (void*)loadinfo.alloc;
+ binp->dspace = NULL;
+ binp->isize = loadinfo.allocsize;
+ binp->stacksize = CONFIG_ELF_STACKSIZE;
elf_dumpbuffer("Entry code", (FAR const uint8_t*)binp->entrypt,
- MIN(binp->isize - loadinfo.entryoffs,512));
+ MIN(binp->isize - loadinfo.ehdr.e_entry, 512));
elf_uninit(&loadinfo);
return OK;
diff --git a/nuttx/binfmt/libelf/Kconfig b/nuttx/binfmt/libelf/Kconfig
index ba931b57e..f16dd4e90 100644
--- a/nuttx/binfmt/libelf/Kconfig
+++ b/nuttx/binfmt/libelf/Kconfig
@@ -9,6 +9,12 @@ config ELF_ALIGN_LOG2
---help---
Align all sections to this Log2 value: 0->1, 1->2, 2->4, etc.
+config ELF_STACKSIZE
+ int "ELF Stack Size"
+ default 2048
+ ---help---
+ This is the default stack size that will will be used when starting ELF binaries.
+
config ELF_CONSTRUCTORS
bool "C++ Static Constructor Support"
default n
@@ -16,13 +22,6 @@ config ELF_CONSTRUCTORS
---help---
Build in support for C++ constructors in ELF modules.
-config ELF_SYMBOLS
- bool "Export symbols from ELF modules"
- default n
- ---help---
- Allow symbols from one ELF module to be used by another. NOT
- fully implemented!
-
config ELF_DUMPBUFFER
bool "Dump ELF buffers"
default n
diff --git a/nuttx/binfmt/libelf/Make.defs b/nuttx/binfmt/libelf/Make.defs
index 629961863..82f5f3e64 100644
--- a/nuttx/binfmt/libelf/Make.defs
+++ b/nuttx/binfmt/libelf/Make.defs
@@ -43,11 +43,12 @@ 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_bind.c libelf_symbols.c
# Hook the libelf subdirectory into the build
VPATH += libelf
SUBDIRS += libelf
+DEPPATH += --dep-path libelf
endif
diff --git a/nuttx/binfmt/libelf/arm.h b/nuttx/binfmt/libelf/arm.h
deleted file mode 100644
index e80457b6e..000000000
--- a/nuttx/binfmt/libelf/arm.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/****************************************************************************
- * binfmt/libelf/arm.h
- *
- * 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.
- *
- ****************************************************************************/
-
-#ifndef __BINFMT_LIBELF_ARM_H
-#define __BINFMT_LIBELF_ARM_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-#endif /* __BINFMT_LIBELF_ARM_H */
diff --git a/nuttx/binfmt/libelf/libelf.h b/nuttx/binfmt/libelf/libelf.h
index ed352865c..a7ffbc6a6 100644
--- a/nuttx/binfmt/libelf/libelf.h
+++ b/nuttx/binfmt/libelf/libelf.h
@@ -42,8 +42,11 @@
#include <nuttx/config.h>
+#include <sys/types.h>
#include <elf.h>
+#include <nuttx/binfmt/elf.h>
+
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
@@ -53,14 +56,58 @@
****************************************************************************/
/****************************************************************************
- * Name: arch_checkarch
+ * Name: elf_verifyheader
+ *
+ * Description:
+ * Given the header from a possible ELF executable, verify that it is
+ * an ELF executable.
+ *
+ * Returned Value:
+ * 0 (OK) is returned on success and a negated errno is returned on
+ * failure.
+ *
+ ****************************************************************************/
+
+int elf_verifyheader(FAR const Elf32_Ehdr *header);
+
+/****************************************************************************
+ * Name: elf_read
+ *
+ * Description:
+ * Read 'readsize' bytes from the object file at 'offset'
+ *
+ * Returned Value:
+ * 0 (OK) is returned on success and a negated errno is returned on
+ * failure.
+ *
+ ****************************************************************************/
+
+int elf_read(FAR struct elf_loadinfo_s *loadinfo, FAR uint8_t *buffer,
+ size_t readsize, off_t offset);
+
+/****************************************************************************
+ * Name: elf_findsymtab
+ *
+ * Description:
+ * Find the symbol table section.
+ *
+ * Returned Value:
+ * 0 (OK) is returned on success and a negated errno is returned on
+ * failure.
+ *
+ ****************************************************************************/
+
+int elf_findsymtab(FAR struct elf_loadinfo_s *loadinfo);
+
+/****************************************************************************
+ * Name: elf_readsym
*
* Description:
- * Given the ELF header in hdr, verify that the ELF file is appropriate
- * for the current, configured architecture.
+ * Read the ELFT symbol structure at the specfied index into memory.
*
****************************************************************************/
-bool arch_checkarch(const struct Elf32_Ehdr *hdr);
+int elf_readsym(FAR struct elf_loadinfo_s *loadinfo, int index,
+ FAR Elf32_Sym *sym);
#endif /* __BINFMT_LIBELF_LIBELF_H */
diff --git a/nuttx/binfmt/libelf/libelf_bind.c b/nuttx/binfmt/libelf/libelf_bind.c
index 74b713b9e..dd75809ec 100644
--- a/nuttx/binfmt/libelf/libelf_bind.c
+++ b/nuttx/binfmt/libelf/libelf_bind.c
@@ -49,6 +49,8 @@
#include <nuttx/binfmt/elf.h>
#include <nuttx/binfmt/symtab.h>
+#include "libelf.h"
+
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
@@ -80,6 +82,120 @@
****************************************************************************/
/****************************************************************************
+ * Name: elf_readsym
+ *
+ * Description:
+ * Read the ELFT symbol structure at the specfied index into memory.
+ *
+ ****************************************************************************/
+
+static inline int elf_readrel(FAR struct elf_loadinfo_s *loadinfo,
+ FAR const Elf32_Shdr *relsec,
+ int index, FAR Elf32_Rel *rel)
+{
+ off_t offset;
+
+ /* Verify that the symbol table index lies within symbol table */
+
+ if (index < 0 || index > (relsec->sh_size / sizeof(Elf32_Rel)))
+ {
+ bdbg("Bad relocation symbol index: %d\n", index);
+ return -EINVAL;
+ }
+
+ /* Get the file offset to the symbol table entry */
+
+ offset = relsec->sh_offset + sizeof(Elf32_Rel) * index;
+
+ /* And, finally, read the symbol table entry into memory */
+
+ return elf_read(loadinfo, (FAR uint8_t*)rel, sizeof(Elf32_Rel), offset);
+}
+
+/****************************************************************************
+ * Name: elf_relocate and elf_relocateadd
+ *
+ * Description:
+ * Perform all relocations associated with a section.
+ *
+ * Returned Value:
+ * 0 (OK) is returned on success and a negated errno is returned on
+ * failure.
+ *
+ ****************************************************************************/
+
+static int elf_relocate(FAR struct elf_loadinfo_s *loadinfo, int relidx)
+{
+ FAR Elf32_Shdr *relsec = &loadinfo->shdr[relidx];
+ FAR Elf32_Shdr *dstsec = &loadinfo->shdr[relsec->sh_info];
+ Elf32_Rel rel;
+ Elf32_Sym sym;
+ uintptr_t addr;
+ int symidx;
+ int ret;
+ int i;
+
+ /* Examine each relocation in the section */
+
+ for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++)
+ {
+ /* Read the relocation entry into memory */
+
+ ret = elf_readrel(loadinfo, relsec, i, &rel);
+ if (ret < 0)
+ {
+ bdbg("Section %d reloc %d: Failed to read relocation entry: %d\n",
+ relidx, i, ret);
+ return ret;
+ }
+
+ /* Get the symbol table index for the relocation. This is contained
+ * in a bit-field within the r_info element.
+ */
+
+ symidx = ELF32_R_SYM(rel.r_info);
+
+ /* Read the symbol table entry into memory */
+
+ ret = elf_readsym(loadinfo, symidx, &sym);
+ if (ret < 0)
+ {
+ bdbg("Section %d reloc %d: Failed to read symbol[%d]: %d\n",
+ relidx, i, symidx, ret);
+ return ret;
+ }
+
+ /* Calculate the relocation address */
+
+ if (rel.r_offset < 0 || rel.r_offset > dstsec->sh_size - sizeof(uint32_t))
+ {
+ bdbg("Section %d reloc %d: Relocation address out of range, offset %d size %d\n",
+ relidx, i, rel.r_offset, dstsec->sh_size);
+ return -EINVAL;
+ }
+
+ addr = dstsec->sh_addr + rel.r_offset;
+
+ /* Now perform the architecture-specific relocation */
+
+ ret = arch_relocate(&rel, &sym, addr);
+ if (ret < 0)
+ {
+ bdbg("Section %d reloc %d: Relocation failed: %d\n", ret);
+ return ret;
+ }
+ }
+
+ return OK;
+}
+
+static int elf_relocateadd(FAR struct elf_loadinfo_s *loadinfo, int relidx)
+{
+ bdbg("Not implemented\n");
+ return -ENOSYS;
+}
+
+/****************************************************************************
* Public Functions
****************************************************************************/
@@ -99,7 +215,58 @@
int elf_bind(FAR struct elf_loadinfo_s *loadinfo,
FAR const struct symtab_s *exports, int nexports)
{
-#warning "Missing logic"
- return -ENOSYS;
+ int ret;
+ int i;
+
+ /* Find the symbol and string tables */
+
+ ret = elf_findsymtab(loadinfo);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ /* Process relocations in every allocated section */
+
+ for (i = 1; i < loadinfo->ehdr.e_shnum; i++)
+ {
+ /* Get the index to the relocation section */
+
+ int infosec = loadinfo->shdr[i].sh_info;
+ if (infosec >= loadinfo->ehdr.e_shnum)
+ {
+ continue;
+ }
+
+ /* Make sure that the section is allocated. We can't relocated
+ * sections that were not loaded into memory.
+ */
+
+ if ((loadinfo->shdr[infosec].sh_flags & SHF_ALLOC) == 0)
+ {
+ continue;
+ }
+
+ /* Process the relocations by type */
+
+ if (loadinfo->shdr[i].sh_type == SHT_REL)
+ {
+ ret = elf_relocate(loadinfo, i);
+ }
+ else if (loadinfo->shdr[i].sh_type == SHT_RELA)
+ {
+ ret = elf_relocateadd(loadinfo, i);
+ }
+
+ if (ret < 0)
+ {
+ break;
+ }
+ }
+
+ /* Flush the instruction cache before starting the newly loaded module */
+
+ arch_flushicache((FAR void*)loadinfo->alloc, loadinfo->allocsize);
+ return ret;
}
diff --git a/nuttx/binfmt/libelf/libelf_init.c b/nuttx/binfmt/libelf/libelf_init.c
index cf62666b9..a3a320b16 100644
--- a/nuttx/binfmt/libelf/libelf_init.c
+++ b/nuttx/binfmt/libelf/libelf_init.c
@@ -49,6 +49,8 @@
#include <nuttx/binfmt/elf.h>
+#include "libelf.h"
+
/****************************************************************************
* Pre-Processor Definitions
****************************************************************************/
@@ -114,7 +116,7 @@ int elf_init(FAR const char *filename, FAR struct elf_loadinfo_s *loadinfo)
/* Read the ELF ehdr from offset 0 */
- ret = elf_read(loadinfo, (char*)&loadinfo->ehdr, sizeof(Elf32_Ehdr), 0);
+ ret = elf_read(loadinfo, (FAR uint8_t*)&loadinfo->ehdr, sizeof(Elf32_Ehdr), 0);
if (ret < 0)
{
bdbg("Failed to read ELF header: %d\n", ret);
diff --git a/nuttx/binfmt/libelf/libelf_load.c b/nuttx/binfmt/libelf/libelf_load.c
index c30c109ce..127ebb314 100644
--- a/nuttx/binfmt/libelf/libelf_load.c
+++ b/nuttx/binfmt/libelf/libelf_load.c
@@ -46,11 +46,15 @@
#include <stdlib.h>
#include <unistd.h>
#include <elf.h>
-#include <debug.h>
+#include <assert.h>
#include <errno.h>
+#include <debug.h>
+#include <nuttx/kmalloc.h>
#include <nuttx/binfmt/elf.h>
+#include "libelf.h"
+
/****************************************************************************
* Pre-Processor Definitions
****************************************************************************/
@@ -104,7 +108,7 @@ static inline int elf_filelen(FAR struct elf_loadinfo_s *loadinfo)
if (!S_ISREG(buf.st_mode))
{
bdbg("Not a regular file. mode: %d\n", buf.st_mode);
- return -errval;
+ return -ENOENT;
}
/* TODO: Verify that the file is readable */
@@ -132,20 +136,20 @@ static inline int elf_loadshdrs(FAR struct elf_loadinfo_s *loadinfo)
size_t shdrsize;
int ret;
- DEBUGASSERT(loadinfo->shdrs == NULL);
+ DEBUGASSERT(loadinfo->shdr == NULL);
/* Verify that there are sections */
- if (loadinfo->e_shum < 1)
+ if (loadinfo->ehdr.e_shnum < 1)
{
- bdbg("No section(?)\n");
+ bdbg("No sections(?)\n");
return -EINVAL;
}
/* Get the total size of the section header table */
- shdrsize = (size_t)loadinfo->ehdr.e_shentsize * (size_t)loadinfo->e_shum;
- if(loadinfo->e_shoff + shdrsize > loadinfo->filelen)
+ shdrsize = (size_t)loadinfo->ehdr.e_shentsize * (size_t)loadinfo->ehdr.e_shnum;
+ if(loadinfo->ehdr.e_shoff + shdrsize > loadinfo->filelen)
{
bdbg("Insufficent space in file for section header table\n");
return -ESPIPE;
@@ -153,8 +157,8 @@ static inline int elf_loadshdrs(FAR struct elf_loadinfo_s *loadinfo)
/* Allocate memory to hold a working copy of the sector header table */
- loadinfo->shdrs = (FAR Elf32_Shdr*)kmalloc(shdrsize);
- if (!loadinfo->shdrs)
+ loadinfo->shdr = (FAR Elf32_Shdr*)kmalloc(shdrsize);
+ if (!loadinfo->shdr)
{
bdbg("Failed to allocate the section header table. Size: %ld\n", (long)shdrsize);
return -ENOMEM;
@@ -162,7 +166,7 @@ static inline int elf_loadshdrs(FAR struct elf_loadinfo_s *loadinfo)
/* Read the section header table into memory */
- ret = elf_read(loadinfo, loadinfo->shdrs, shdrsize, loadinfo->e_shoff);
+ ret = elf_read(loadinfo, (FAR uint8_t*)loadinfo->shdr, shdrsize, loadinfo->ehdr.e_shoff);
if (ret < 0)
{
bdbg("Failed to read section header table: %d\n", ret);
@@ -172,8 +176,8 @@ static inline int elf_loadshdrs(FAR struct elf_loadinfo_s *loadinfo)
return OK;
errout_with_alloc:
- kfree(loadinfo->shdrs);
- loadinfo->shdrs = 0;
+ kfree(loadinfo->shdr);
+ loadinfo->shdr = 0;
return ret;
}
@@ -189,7 +193,7 @@ errout_with_alloc:
*
****************************************************************************/
-static void elf_allocsize(struct load_info *loadinfo)
+static void elf_allocsize(struct elf_loadinfo_s *loadinfo)
{
size_t allocsize;
int i;
@@ -199,7 +203,7 @@ static void elf_allocsize(struct load_info *loadinfo)
allocsize = 0;
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
{
- FAR Elf32_Shdr *shdr = &loadinfo->shdrs[i];
+ FAR Elf32_Shdr *shdr = &loadinfo->shdr[i];
/* SHF_ALLOC indicates that the section requires memory during
* execution.
@@ -213,7 +217,7 @@ static void elf_allocsize(struct load_info *loadinfo)
/* Save the allocation size */
- loadinfo->allocize = allocsize;
+ loadinfo->allocsize = allocsize;
}
/****************************************************************************
@@ -221,7 +225,8 @@ static void elf_allocsize(struct load_info *loadinfo)
*
* Description:
* Allocate memory for the file and read the section data into the
- * allocated memory.
+ * allocated memory. Section addresses in the shdr[] are updated to point
+ * to the corresponding position in the allocated memory.
*
* Returned Value:
* 0 (OK) is returned on success and a negated errno is returned on
@@ -229,14 +234,15 @@ static void elf_allocsize(struct load_info *loadinfo)
*
****************************************************************************/
-static inline int elf_loadfile(FAR struct load_info *loadinfo)
+static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
{
FAR uint8_t *dest;
+ int ret;
int i;
/* Allocate (and zero) memory for the ELF file. */
- loadinfo->alloc = kzalloc(loadinfo->allocsize);
+ loadinfo->alloc = (uintptr_t)kzalloc(loadinfo->allocsize);
if (!loadinfo->alloc)
{
return -ENOMEM;
@@ -249,7 +255,7 @@ static inline int elf_loadfile(FAR struct load_info *loadinfo)
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
{
- FAR Elf32_Shdr *shdr = &loadinfo->shdrs[i];
+ FAR Elf32_Shdr *shdr = &loadinfo->shdr[i];
/* SHF_ALLOC indicates that the section requires memory during
* execution */
@@ -275,7 +281,7 @@ static inline int elf_loadfile(FAR struct load_info *loadinfo)
}
}
- /* Update sh_addr to point to copy in image. */
+ /* Update sh_addr to point to copy in memory */
shdr->sh_addr = (uintptr_t)dest;
bvdbg("%d. 0x%lx %s\n", (long)shdr->sh_addr, loadinfo->secstrings + shdr->sh_name);
@@ -288,7 +294,7 @@ static inline int elf_loadfile(FAR struct load_info *loadinfo)
return OK;
errout_with_alloc:
- kfree(loadinfo->alloc);
+ kfree((FAR void*)loadinfo->alloc);
loadinfo->alloc = 0;
return ret;
}
@@ -344,15 +350,16 @@ int elf_load(FAR struct elf_loadinfo_s *loadinfo)
goto errout_with_shdrs;
}
+ /* Find static constructors. */
+#warning "Missing logic"
+
return OK;
/* Error exits */
-errout_with_alloc:
- kfree(loadinfo->alloc);
errout_with_shdrs:
- kfree(loadinfo->shdrs);
-errout:
+ kfree(loadinfo->shdr);
+ loadinfo->shdr = NULL;
return ret;
}
diff --git a/nuttx/binfmt/libelf/libelf_symbols.c b/nuttx/binfmt/libelf/libelf_symbols.c
new file mode 100644
index 000000000..4788c874c
--- /dev/null
+++ b/nuttx/binfmt/libelf/libelf_symbols.c
@@ -0,0 +1,134 @@
+/****************************************************************************
+ * binfmt/libelf/libelf_symbols.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 <elf.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/binfmt/elf.h>
+
+#include "libelf.h"
+
+/****************************************************************************
+ * Pre-Processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Constant Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: elf_findsymtab
+ *
+ * Description:
+ * Find the symbol table section.
+ *
+ * Returned Value:
+ * 0 (OK) is returned on success and a negated errno is returned on
+ * failure.
+ *
+ ****************************************************************************/
+
+int elf_findsymtab(FAR struct elf_loadinfo_s *loadinfo)
+{
+ int i;
+
+ /* Find the symbol table section header and its associated string table */
+
+ for (i = 1; i < loadinfo->ehdr.e_shnum; i++)
+ {
+ if (loadinfo->shdr[i].sh_type == SHT_SYMTAB)
+ {
+ loadinfo->symtabidx = i;
+ loadinfo->strtabidx = loadinfo->shdr[i].sh_link;
+ break;
+ }
+ }
+
+ /* Verify that there is a symbol and string table */
+
+ if (loadinfo->symtabidx == 0)
+ {
+ bdbg("No symbols in ELF file\n");
+ return -EINVAL;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: elf_readsym
+ *
+ * Description:
+ * Read the ELFT symbol structure at the specfied index into memory.
+ *
+ ****************************************************************************/
+
+int elf_readsym(FAR struct elf_loadinfo_s *loadinfo, int index,
+ FAR Elf32_Sym *sym)
+{
+ FAR Elf32_Shdr *symtab = &loadinfo->shdr[loadinfo->symtabidx];
+ off_t offset;
+
+ /* Verify that the symbol table index lies within symbol table */
+
+ if (index < 0 || index > (symtab->sh_size / sizeof(Elf32_Sym)))
+ {
+ bdbg("Bad relocation symbol index: %d\n", index);
+ return -EINVAL;
+ }
+
+ /* Get the file offset to the symbol table entry */
+
+ offset = symtab->sh_offset + sizeof(Elf32_Sym) * index;
+
+ /* And, finally, read the symbol table entry into memory */
+
+ return elf_read(loadinfo, (FAR uint8_t*)sym, sizeof(Elf32_Sym), offset);
+}
diff --git a/nuttx/binfmt/libelf/libelf_unload.c b/nuttx/binfmt/libelf/libelf_unload.c
index 217a1981e..ca8d2b708 100644
--- a/nuttx/binfmt/libelf/libelf_unload.c
+++ b/nuttx/binfmt/libelf/libelf_unload.c
@@ -39,10 +39,10 @@
#include <nuttx/config.h>
-#include <sys/mman.h>
#include <stdlib.h>
#include <debug.h>
+#include <nuttx/kmalloc.h>
#include <nuttx/binfmt/elf.h>
/****************************************************************************
@@ -81,14 +81,14 @@ int elf_unload(struct elf_loadinfo_s *loadinfo)
if (loadinfo->alloc)
{
kfree((void*)loadinfo->alloc);
- loadinfo->alloc = NULL;
+ loadinfo->alloc = 0;
loadinfo->allocsize = 0;
}
- if (loadinfo->shdrs)
+ if (loadinfo->shdr)
{
- kfree((void*)loadinfo->shdrs);
- loadinfo->shdrs = 0;
+ kfree((void*)loadinfo->shdr);
+ loadinfo->shdr = NULL;
}
return OK;
diff --git a/nuttx/binfmt/libelf/libelf_verify.c b/nuttx/binfmt/libelf/libelf_verify.c
index 0e0dd8e1a..c5f185ec3 100644
--- a/nuttx/binfmt/libelf/libelf_verify.c
+++ b/nuttx/binfmt/libelf/libelf_verify.c
@@ -53,7 +53,7 @@
* Private Constant Data
****************************************************************************/
-static const char g_elfmagic[EI_MAGIC_SIZE] = { 0x7f, 'E', 'L', 'F' }
+static const char g_elfmagic[EI_MAGIC_SIZE] = { 0x7f, 'E', 'L', 'F' };
/****************************************************************************
* Private Functions
@@ -75,12 +75,12 @@ static const char g_elfmagic[EI_MAGIC_SIZE] = { 0x7f, 'E', 'L', 'F' }
* failure.
*
* -ENOEXEC : Not an ELF file
- * -EINVALID : Not a relocatable ELF file or not supported by the current,
+ * -EINVAL : Not a relocatable ELF file or not supported by the current,
* configured architecture.
*
****************************************************************************/
-int elf_verifyheader(const Elf32_Ehdr *ehdr)
+int elf_verifyheader(FAR const Elf32_Ehdr *ehdr)
{
if (!ehdr)
{
@@ -102,7 +102,7 @@ int elf_verifyheader(const Elf32_Ehdr *ehdr)
if (ehdr->e_type != ET_REL)
{
bdbg("Not a relocatable file: e_type=%d\n", ehdr->e_type);
- return -EINVALID;
+ return -EINVAL;
}
/* Verify that this file works with the currently configured architecture */
diff --git a/nuttx/binfmt/libnxflat/Make.defs b/nuttx/binfmt/libnxflat/Make.defs
index 59c3ce334..4462e9a02 100644
--- a/nuttx/binfmt/libnxflat/Make.defs
+++ b/nuttx/binfmt/libnxflat/Make.defs
@@ -49,5 +49,6 @@ BINFMT_CSRCS = libnxflat_init.c libnxflat_uninit.c libnxflat_load.c \
VPATH += libnxflat
SUBDIRS += libnxflat
+DEPPATH += --dep-path libnxflat
endif