summaryrefslogtreecommitdiff
path: root/nuttx/binfmt
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-10-29 20:43:35 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-10-29 20:43:35 +0000
commitb7c575a7ec2b15a37e888f94408680303ace71a7 (patch)
treeb7c28580644d845360274723b39b8367ed109bba /nuttx/binfmt
parent9e45144d3ad1420908cfdf84306c76f637829023 (diff)
downloadpx4-nuttx-b7c575a7ec2b15a37e888f94408680303ace71a7.tar.gz
px4-nuttx-b7c575a7ec2b15a37e888f94408680303ace71a7.tar.bz2
px4-nuttx-b7c575a7ec2b15a37e888f94408680303ace71a7.zip
C++ static destructors work with ELF load too now
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5274 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/binfmt')
-rw-r--r--nuttx/binfmt/binfmt_dumpmodule.c2
-rw-r--r--nuttx/binfmt/binfmt_execmodule.c2
-rw-r--r--nuttx/binfmt/binfmt_unloadmodule.c2
-rw-r--r--nuttx/binfmt/elf.c30
-rw-r--r--nuttx/binfmt/libelf/Make.defs2
-rw-r--r--nuttx/binfmt/libelf/libelf.h19
-rw-r--r--nuttx/binfmt/libelf/libelf_bind.c2
-rw-r--r--nuttx/binfmt/libelf/libelf_ctors.c35
-rw-r--r--nuttx/binfmt/libelf/libelf_dtors.c215
-rw-r--r--nuttx/binfmt/libelf/libelf_load.c31
-rw-r--r--nuttx/binfmt/libelf/libelf_unload.c39
11 files changed, 308 insertions, 71 deletions
diff --git a/nuttx/binfmt/binfmt_dumpmodule.c b/nuttx/binfmt/binfmt_dumpmodule.c
index e095c4a67..40cbe4b21 100644
--- a/nuttx/binfmt/binfmt_dumpmodule.c
+++ b/nuttx/binfmt/binfmt_dumpmodule.c
@@ -91,7 +91,7 @@ int dump_module(FAR const struct binary_s *bin)
bdbg(" argv: %p\n", bin->argv);
bdbg(" entrypt: %p\n", bin->entrypt);
bdbg(" mapped: %p size=%d\n", bin->mapped, bin->mapsize);
- bdbg(" alloc: %p %p\n", bin->alloc[0], bin->alloc[1]);
+ bdbg(" alloc: %p %p %p\n", bin->alloc[0], bin->alloc[1], bin->alloc[2]);
#ifdef CONFIG_BINFMT_CONSTRUCTORS
bdbg(" ctors: %p nctors=%d\n", bin->ctors, bin->nctors);
bdbg(" dtors: %p ndtors=%d\n", bin->dtors, bin->ndtors);
diff --git a/nuttx/binfmt/binfmt_execmodule.c b/nuttx/binfmt/binfmt_execmodule.c
index b00248183..37f445966 100644
--- a/nuttx/binfmt/binfmt_execmodule.c
+++ b/nuttx/binfmt/binfmt_execmodule.c
@@ -88,7 +88,7 @@
#ifdef CONFIG_BINFMT_CONSTRUCTORS
static inline void exec_ctors(FAR const struct binary_s *binp)
{
- elf_ctor_t *ctor = binp->ctors;
+ binfmt_ctor_t *ctor = binp->ctors;
int i;
/* Execute each constructor */
diff --git a/nuttx/binfmt/binfmt_unloadmodule.c b/nuttx/binfmt/binfmt_unloadmodule.c
index 15b238357..52243fcf7 100644
--- a/nuttx/binfmt/binfmt_unloadmodule.c
+++ b/nuttx/binfmt/binfmt_unloadmodule.c
@@ -85,7 +85,7 @@
#ifdef CONFIG_BINFMT_CONSTRUCTORS
static inline void exec_dtors(FAR const struct binary_s *binp)
{
- elf_dtor_t *dtor = binp->dtors;
+ binfmt_dtor_t *dtor = binp->dtors;
int i;
/* Execute each destructor */
diff --git a/nuttx/binfmt/elf.c b/nuttx/binfmt/elf.c
index 26057ffc1..ea1e7b0ca 100644
--- a/nuttx/binfmt/elf.c
+++ b/nuttx/binfmt/elf.c
@@ -111,12 +111,16 @@ static void elf_dumploadinfo(FAR struct elf_loadinfo_s *loadinfo)
int i;
bdbg("LOAD_INFO:\n");
- bdbg(" alloc: %08lx\n", (long)loadinfo->alloc);
- bdbg(" allocsize: %ld\n", (long)loadinfo->allocsize);
+ bdbg(" elfalloc: %08lx\n", (long)loadinfo->elfalloc);
+ bdbg(" elfsize: %ld\n", (long)loadinfo->elfsize);
bdbg(" filelen: %ld\n", (long)loadinfo->filelen);
#ifdef CONFIG_BINFMT_CONSTRUCTORS
+ bdbg(" ctoralloc: %08lx\n", (long)loadinfo->ctoralloc);
bdbg(" ctors: %08lx\n", (long)loadinfo->ctors);
bdbg(" nctors: %d\n", loadinfo->nctors);
+ bdbg(" dtoralloc: %08lx\n", (long)loadinfo->dtoralloc);
+ bdbg(" dtors: %08lx\n", (long)loadinfo->dtors);
+ bdbg(" ndtors: %d\n", loadinfo->ndtors);
#endif
bdbg(" filfd: %d\n", loadinfo->filfd);
bdbg(" symtabidx: %d\n", loadinfo->symtabidx);
@@ -210,8 +214,8 @@ static int elf_loadbinary(struct binary_s *binp)
/* Return the load information */
- binp->entrypt = (main_t)(loadinfo.alloc + loadinfo.ehdr.e_entry);
- binp->alloc[0] = (FAR void *)loadinfo.alloc;
+ binp->entrypt = (main_t)(loadinfo.elfalloc + loadinfo.ehdr.e_entry);
+ binp->alloc[0] = (FAR void *)loadinfo.elfalloc;
binp->stacksize = CONFIG_ELF_STACKSIZE;
#ifdef CONFIG_BINFMT_CONSTRUCTORS
@@ -219,19 +223,13 @@ static int elf_loadbinary(struct binary_s *binp)
* yet supported.
*/
- binp->ctors = loadinfo.ctors;
- binp->nctors = loadinfo.nctors;
+ binp->alloc[1] = loadinfo.ctoralloc;
+ binp->ctors = loadinfo.ctors;
+ binp->nctors = loadinfo.nctors;
- /* Was memory allocated for constructors? */
-
- if (!loadinfo.newabi)
- {
- /* Yes.. save the allocation address so that it can be freed by
- * unload module.
- */
-
- binp->alloc[1] = (FAR void *)loadinfo.ctors;
- }
+ binp->alloc[2] = loadinfo.dtoralloc;
+ binp->dtors = loadinfo.dtors;
+ binp->ndtors = loadinfo.ndtors;
#endif
elf_dumpbuffer("Entry code", (FAR const uint8_t*)binp->entrypt,
diff --git a/nuttx/binfmt/libelf/Make.defs b/nuttx/binfmt/libelf/Make.defs
index 26198ade2..c8857c3f7 100644
--- a/nuttx/binfmt/libelf/Make.defs
+++ b/nuttx/binfmt/libelf/Make.defs
@@ -46,7 +46,7 @@ BINFMT_CSRCS += libelf_bind.c libelf_init.c libelf_iobuffer.c libelf_load.c \
libelf_unload.c libelf_verify.c
ifeq ($(CONFIG_BINFMT_CONSTRUCTORS),y)
-BINFMT_CSRCS += libelf_ctors.c
+BINFMT_CSRCS += libelf_ctors.c libelf_dtors.c
endif
# Hook the libelf subdirectory into the build
diff --git a/nuttx/binfmt/libelf/libelf.h b/nuttx/binfmt/libelf/libelf.h
index bea92496a..5b0be9ab0 100644
--- a/nuttx/binfmt/libelf/libelf.h
+++ b/nuttx/binfmt/libelf/libelf.h
@@ -236,4 +236,23 @@ int elf_reallocbuffer(FAR struct elf_loadinfo_s *loadinfo, size_t increment);
int elf_loadctors(FAR struct elf_loadinfo_s *loadinfo);
#endif
+/****************************************************************************
+ * Name: elf_loaddtors
+ *
+ * Description:
+ * Load pointers to static destructors 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.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_BINFMT_CONSTRUCTORS
+int elf_loaddtors(FAR struct elf_loadinfo_s *loadinfo);
+#endif
+
#endif /* __BINFMT_LIBELF_LIBELF_H */
diff --git a/nuttx/binfmt/libelf/libelf_bind.c b/nuttx/binfmt/libelf/libelf_bind.c
index ef1b4fc8f..e35087b1d 100644
--- a/nuttx/binfmt/libelf/libelf_bind.c
+++ b/nuttx/binfmt/libelf/libelf_bind.c
@@ -298,7 +298,7 @@ int elf_bind(FAR struct elf_loadinfo_s *loadinfo,
/* Flush the instruction cache before starting the newly loaded module */
#ifdef CONFIG_ELF_ICACHE
- arch_flushicache((FAR void*)loadinfo->alloc, loadinfo->allocsize);
+ arch_flushicache((FAR void*)loadinfo->elfalloc, loadinfo->elfsize);
#endif
return ret;
diff --git a/nuttx/binfmt/libelf/libelf_ctors.c b/nuttx/binfmt/libelf/libelf_ctors.c
index a57fc37d9..20f1256e2 100644
--- a/nuttx/binfmt/libelf/libelf_ctors.c
+++ b/nuttx/binfmt/libelf/libelf_ctors.c
@@ -75,7 +75,7 @@
* Name: elf_loadctors
*
* Description:
- * Load points to static constructors into an in-memory array.
+ * Load pointers to static constructors into an in-memory array.
*
* Input Parameters:
* loadinfo - Load state information
@@ -96,8 +96,8 @@ int elf_loadctors(FAR struct elf_loadinfo_s *loadinfo)
DEBUGASSERT(loadinfo->ctors == NULL);
- /* Allocate an I/O buffer. This buffer is used by elf_sectname() to
- * accumulate the variable length symbol name.
+ /* Allocate an I/O buffer if necessary. This buffer is used by
+ * elf_sectname() to accumulate the variable length symbol name.
*/
ret = elf_allocbuffer(loadinfo);
@@ -110,7 +110,7 @@ int elf_loadctors(FAR struct elf_loadinfo_s *loadinfo)
/* Find the index to the section named ".ctors." NOTE: On old ABI system,
* .ctors is the name of the section containing the list of constructors;
* On newer systems, the similar section is called .init_array. It is
- * expected that the linker script will force the sectino name to be ".ctors"
+ * expected that the linker script will force the section name to be ".ctors"
* in either case.
*/
@@ -136,10 +136,10 @@ int elf_loadctors(FAR struct elf_loadinfo_s *loadinfo)
*/
ctorsize = shdr->sh_size;
- loadinfo->nctors = ctorsize / sizeof(elf_ctor_t);
+ loadinfo->nctors = ctorsize / sizeof(binfmt_ctor_t);
- bvdbg("ctoridx=%d ctorsize=%d sizeof(elf_ctor_t)=%d nctors=%d\n",
- ctoridx, ctorsize, sizeof(elf_ctor_t), loadinfo->nctors);
+ bvdbg("ctoridx=%d ctorsize=%d sizeof(binfmt_ctor_t)=%d nctors=%d\n",
+ ctoridx, ctorsize, sizeof(binfmt_ctor_t), loadinfo->nctors);
/* Check if there are any constructors. It is not an error if there
* are none.
@@ -149,7 +149,7 @@ int elf_loadctors(FAR struct elf_loadinfo_s *loadinfo)
{
/* Check an assumption that we made above */
- DEBUGASSERT(shdr->sh_size == loadinfo->nctors * sizeof(elf_ctor_t));
+ DEBUGASSERT(shdr->sh_size == loadinfo->nctors * sizeof(binfmt_ctor_t));
/* In the old ABI, the .ctors section is not allocated. In that case,
* we need to allocate memory to hold the .ctors and then copy the
@@ -161,19 +161,17 @@ int elf_loadctors(FAR struct elf_loadinfo_s *loadinfo)
if ((shdr->sh_flags & SHF_ALLOC) == 0)
{
- /* Not loaded -> Old ABI. */
-
- loadinfo->newabi = false;
-
/* Allocate memory to hold a copy of the .ctor section */
- loadinfo->ctors = (elf_ctor_t*)kmalloc(ctorsize);
- if (!loadinfo->ctors)
+ loadinfo->ctoralloc = (binfmt_ctor_t*)kmalloc(ctorsize);
+ if (!loadinfo->ctoralloc)
{
bdbg("Failed to allocate memory for .ctors\n");
return -ENOMEM;
}
+ loadinfo->ctors = (binfmt_ctor_t *)loadinfo->ctoralloc;
+
/* Read the section header table into memory */
ret = elf_read(loadinfo, (FAR uint8_t*)loadinfo->ctors, ctorsize,
@@ -194,23 +192,20 @@ int elf_loadctors(FAR struct elf_loadinfo_s *loadinfo)
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);
+ i, *ptr, loadinfo->elfalloc, *ptr + loadinfo->elfalloc);
- *ptr += loadinfo->alloc;
+ *ptr += loadinfo->elfalloc;
}
}
else
{
- /* Loaded -> New ABI. */
-
- loadinfo->newabi = true;
/* Save the address of the .ctors (actually, .init_array) where it was
* loaded into memory. Since the .ctors lie in allocated memory, they
* will be relocated via the normal mechanism.
*/
- loadinfo->ctors = (elf_ctor_t*)shdr->sh_addr;
+ loadinfo->ctors = (binfmt_ctor_t*)shdr->sh_addr;
}
}
diff --git a/nuttx/binfmt/libelf/libelf_dtors.c b/nuttx/binfmt/libelf/libelf_dtors.c
new file mode 100644
index 000000000..c0c73a337
--- /dev/null
+++ b/nuttx/binfmt/libelf/libelf_dtors.c
@@ -0,0 +1,215 @@
+/****************************************************************************
+ * binfmt/libelf/libelf_dtors.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 <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/binfmt/elf.h>
+
+#include "libelf.h"
+
+#ifdef CONFIG_BINFMT_CONSTRUCTORS
+
+/****************************************************************************
+ * Pre-Processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Constant Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: elf_loaddtors
+ *
+ * Description:
+ * Load pointers to static destructors 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_loaddtors(FAR struct elf_loadinfo_s *loadinfo)
+{
+ FAR Elf32_Shdr *shdr;
+ size_t dtorsize;
+ int dtoridx;
+ int ret;
+ int i;
+
+ DEBUGASSERT(loadinfo->dtors == NULL);
+
+ /* Allocate an I/O buffer if necessary. This buffer is used by
+ * elf_sectname() to accumulate the variable length symbol name.
+ */
+
+ ret = elf_allocbuffer(loadinfo);
+ if (ret < 0)
+ {
+ bdbg("elf_allocbuffer failed: %d\n", ret);
+ return -ENOMEM;
+ }
+
+ /* Find the index to the section named ".dtors." NOTE: On old ABI system,
+ * .dtors is the name of the section containing the list of destructors;
+ * On newer systems, the similar section is called .fini_array. It is
+ * expected that the linker script will force the section name to be ".dtors"
+ * in either case.
+ */
+
+ dtoridx = elf_findsection(loadinfo, ".dtors");
+ if (dtoridx < 0)
+ {
+ /* This may not be a failure. -ENOENT indicates that the file has no
+ * static destructor section.
+ */
+
+ bvdbg("elf_findsection .dtors section failed: %d\n", dtoridx);
+ return ret == -ENOENT ? OK : ret;
+ }
+
+ /* Now we can get a pointer to the .dtor section in the section header
+ * table.
+ */
+
+ shdr = &loadinfo->shdr[dtoridx];
+
+ /* Get the size of the .dtor section and the number of destructors that
+ * will need to be called.
+ */
+
+ dtorsize = shdr->sh_size;
+ loadinfo->ndtors = dtorsize / sizeof(binfmt_dtor_t);
+
+ bvdbg("dtoridx=%d dtorsize=%d sizeof(binfmt_dtor_t)=%d ndtors=%d\n",
+ dtoridx, dtorsize, sizeof(binfmt_dtor_t), loadinfo->ndtors);
+
+ /* Check if there are any destructors. It is not an error if there
+ * are none.
+ */
+
+ if (loadinfo->ndtors > 0)
+ {
+ /* Check an assumption that we made above */
+
+ DEBUGASSERT(shdr->sh_size == loadinfo->ndtors * sizeof(binfmt_dtor_t));
+
+ /* In the old ABI, the .dtors section is not allocated. In that case,
+ * we need to allocate memory to hold the .dtors and then copy the
+ * from the file into the allocated memory.
+ *
+ * SHF_ALLOC indicates that the section requires memory during
+ * execution.
+ */
+
+ if ((shdr->sh_flags & SHF_ALLOC) == 0)
+ {
+ /* Allocate memory to hold a copy of the .dtor section */
+
+ loadinfo->ctoralloc = (binfmt_dtor_t*)kmalloc(dtorsize);
+ if (!loadinfo->ctoralloc)
+ {
+ bdbg("Failed to allocate memory for .dtors\n");
+ return -ENOMEM;
+ }
+
+ loadinfo->dtors = (binfmt_dtor_t *)loadinfo->ctoralloc;
+
+ /* Read the section header table into memory */
+
+ ret = elf_read(loadinfo, (FAR uint8_t*)loadinfo->dtors, dtorsize,
+ shdr->sh_offset);
+ if (ret < 0)
+ {
+ bdbg("Failed to allocate .dtors: %d\n", ret);
+ return ret;
+ }
+
+ /* Fix up all of the .dtor addresses. Since the addresses
+ * do not lie in allocated memory, there will be no relocation
+ * section for them.
+ */
+
+ for (i = 0; i < loadinfo->ndtors; i++)
+ {
+ FAR uintptr_t *ptr = (uintptr_t *)((FAR void *)(&loadinfo->dtors)[i]);
+
+ bvdbg("dtor %d: %08lx + %08lx = %08lx\n",
+ i, *ptr, loadinfo->elfalloc, *ptr + loadinfo->elfalloc);
+
+ *ptr += loadinfo->elfalloc;
+ }
+ }
+ else
+ {
+
+ /* Save the address of the .dtors (actually, .init_array) where it was
+ * loaded into memory. Since the .dtors lie in allocated memory, they
+ * will be relocated via the normal mechanism.
+ */
+
+ loadinfo->dtors = (binfmt_dtor_t*)shdr->sh_addr;
+ }
+ }
+
+ return OK;
+}
+
+#endif /* CONFIG_BINFMT_CONSTRUCTORS */
diff --git a/nuttx/binfmt/libelf/libelf_load.c b/nuttx/binfmt/libelf/libelf_load.c
index 221ae8d43..b1ac44e21 100644
--- a/nuttx/binfmt/libelf/libelf_load.c
+++ b/nuttx/binfmt/libelf/libelf_load.c
@@ -76,7 +76,7 @@
****************************************************************************/
/****************************************************************************
- * Name: elf_allocsize
+ * Name: elf_elfsize
*
* Description:
* Calculate total memory allocation for the ELF file.
@@ -87,14 +87,14 @@
*
****************************************************************************/
-static void elf_allocsize(struct elf_loadinfo_s *loadinfo)
+static void elf_elfsize(struct elf_loadinfo_s *loadinfo)
{
- size_t allocsize;
+ size_t elfsize;
int i;
/* Accumulate the size each section into memory that is marked SHF_ALLOC */
- allocsize = 0;
+ elfsize = 0;
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
{
FAR Elf32_Shdr *shdr = &loadinfo->shdr[i];
@@ -105,13 +105,13 @@ static void elf_allocsize(struct elf_loadinfo_s *loadinfo)
if ((shdr->sh_flags & SHF_ALLOC) != 0)
{
- allocsize += ELF_ALIGNUP(shdr->sh_size);
+ elfsize += ELF_ALIGNUP(shdr->sh_size);
}
}
/* Save the allocation size */
- loadinfo->allocsize = allocsize;
+ loadinfo->elfsize = elfsize;
}
/****************************************************************************
@@ -136,8 +136,8 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
/* Allocate (and zero) memory for the ELF file. */
- loadinfo->alloc = (uintptr_t)kzalloc(loadinfo->allocsize);
- if (!loadinfo->alloc)
+ loadinfo->elfalloc = (uintptr_t)kzalloc(loadinfo->elfsize);
+ if (!loadinfo->elfalloc)
{
return -ENOMEM;
}
@@ -145,7 +145,7 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
/* Read each section into memory that is marked SHF_ALLOC + SHT_NOBITS */
bvdbg("Loaded sections:\n");
- dest = (FAR uint8_t*)loadinfo->alloc;
+ dest = (FAR uint8_t*)loadinfo->elfalloc;
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
{
@@ -223,7 +223,7 @@ int elf_load(FAR struct elf_loadinfo_s *loadinfo)
/* Determine total size to allocate */
- elf_allocsize(loadinfo);
+ elf_elfsize(loadinfo);
/* Allocate memory and load sections into memory */
@@ -234,7 +234,7 @@ int elf_load(FAR struct elf_loadinfo_s *loadinfo)
goto errout_with_buffers;
}
- /* Find static constructors. */
+ /* Load static constructors and destructors. */
#ifdef CONFIG_BINFMT_CONSTRUCTORS
ret = elf_loadctors(loadinfo);
@@ -243,6 +243,13 @@ int elf_load(FAR struct elf_loadinfo_s *loadinfo)
bdbg("elf_loadctors failed: %d\n", ret);
goto errout_with_buffers;
}
+
+ ret = elf_loaddtors(loadinfo);
+ if (ret < 0)
+ {
+ bdbg("elf_loaddtors failed: %d\n", ret);
+ goto errout_with_buffers;
+ }
#endif
return OK;
@@ -250,7 +257,7 @@ int elf_load(FAR struct elf_loadinfo_s *loadinfo)
/* Error exits */
errout_with_buffers:
- elf_freebuffers(loadinfo);
+ elf_unload(loadinfo);
return ret;
}
diff --git a/nuttx/binfmt/libelf/libelf_unload.c b/nuttx/binfmt/libelf/libelf_unload.c
index 8102f7bf2..532fc606f 100644
--- a/nuttx/binfmt/libelf/libelf_unload.c
+++ b/nuttx/binfmt/libelf/libelf_unload.c
@@ -84,31 +84,34 @@ int elf_unload(struct elf_loadinfo_s *loadinfo)
/* Release memory holding the relocated ELF image */
- if (loadinfo->alloc)
+ if (loadinfo->elfalloc != 0)
{
- kfree((FAR void *)loadinfo->alloc);
- loadinfo->alloc = 0;
- loadinfo->allocsize = 0;
+ kfree((FAR void *)loadinfo->elfalloc);
+ loadinfo->elfalloc = 0;
}
- /* Release any allocated constructor memory */
+ loadinfo->elfsize = 0;
+
+ /* Release memory used to hold static constructors and destructors */
#ifdef CONFIG_BINFMT_CONSTRUCTORS
- if (loadinfo->ctors)
+ if (loadinfo->ctoralloc != 0)
{
- /* In the old ABI, the .ctors section is not make for allocation. In
- * that case, we need to free the working buffer that was used to hold
- * the constructors.
- */
-
- if (!loadinfo->newabi)
- {
- kfree((FAR void *)loadinfo->ctors);
- }
-
- loadinfo->ctors = NULL;
- loadinfo->nctors = 0;
+ kfree(loadinfo->ctoralloc);
+ loadinfo->ctoralloc = NULL;
}
+
+ loadinfo->ctors = NULL;
+ loadinfo->nctors = 0;
+
+ if (loadinfo->dtoralloc != 0)
+ {
+ kfree(loadinfo->dtoralloc);
+ loadinfo->dtoralloc = NULL;
+ }
+
+ loadinfo->dtors = NULL;
+ loadinfo->ndtors = 0;
#endif
return OK;