From b48508c844dbd558e728c5695136696b5dfea1fc Mon Sep 17 00:00:00 2001 From: patacongo Date: Mon, 29 Oct 2012 20:43:35 +0000 Subject: [PATCH] C++ static destructors work with ELF load too now git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5274 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/binfmt/binfmt_dumpmodule.c | 2 +- nuttx/binfmt/binfmt_execmodule.c | 2 +- nuttx/binfmt/binfmt_unloadmodule.c | 2 +- nuttx/binfmt/elf.c | 30 ++-- nuttx/binfmt/libelf/Make.defs | 2 +- nuttx/binfmt/libelf/libelf.h | 19 +++ nuttx/binfmt/libelf/libelf_bind.c | 2 +- nuttx/binfmt/libelf/libelf_ctors.c | 35 ++--- nuttx/binfmt/libelf/libelf_dtors.c | 215 ++++++++++++++++++++++++++++ nuttx/binfmt/libelf/libelf_load.c | 31 ++-- nuttx/binfmt/libelf/libelf_unload.c | 39 ++--- nuttx/include/nuttx/binfmt/binfmt.h | 10 +- nuttx/include/nuttx/binfmt/elf.h | 44 ++++-- 13 files changed, 344 insertions(+), 89 deletions(-) create mode 100644 nuttx/binfmt/libelf/libelf_dtors.c diff --git a/nuttx/binfmt/binfmt_dumpmodule.c b/nuttx/binfmt/binfmt_dumpmodule.c index e095c4a67a..40cbe4b213 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 b00248183b..37f4459660 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 15b2383570..52243fcf78 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 26057ffc10..ea1e7b0ca8 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 26198ade2a..c8857c3f74 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 bea92496ab..5b0be9ab02 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 ef1b4fc8fd..e35087b1de 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 a57fc37d93..20f1256e2e 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 0000000000..c0c73a3373 --- /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 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "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 221ae8d438..b1ac44e21f 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 8102f7bf2f..532fc606fb 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; diff --git a/nuttx/include/nuttx/binfmt/binfmt.h b/nuttx/include/nuttx/binfmt/binfmt.h index 0c18bfc49a..49ab37264f 100644 --- a/nuttx/include/nuttx/binfmt/binfmt.h +++ b/nuttx/include/nuttx/binfmt/binfmt.h @@ -49,15 +49,15 @@ * Pre-processor Definitions ****************************************************************************/ -#define BINFMT_NALLOC 2 +#define BINFMT_NALLOC 3 /**************************************************************************** * Public Types ****************************************************************************/ /* The type of one C++ constructor or destructor */ -typedef FAR void (*elf_ctor_t)(void); -typedef FAR void (*elf_dtor_t)(void); +typedef FAR void (*binfmt_ctor_t)(void); +typedef FAR void (*binfmt_dtor_t)(void); /* This describes the file to be loaded */ @@ -79,8 +79,8 @@ struct binary_s FAR void *mapped; /* Memory-mapped, address space */ FAR void *alloc[BINFMT_NALLOC]; /* Allocated address spaces */ #ifdef CONFIG_BINFMT_CONSTRUCTORS - elf_ctor_t *ctors; /* Pointer to a list of constructors */ - elf_dtor_t *dtors; /* Pointer to a list of destructors */ + FAR binfmt_ctor_t *ctors; /* Pointer to a list of constructors */ + FAR binfmt_dtor_t *dtors; /* Pointer to a list of destructors */ uint16_t nctors; /* Number of constructors in the list */ uint16_t ndtors; /* Number of destructors in the list */ #endif diff --git a/nuttx/include/nuttx/binfmt/elf.h b/nuttx/include/nuttx/binfmt/elf.h index 2e3cb86236..432e57f0f8 100644 --- a/nuttx/include/nuttx/binfmt/elf.h +++ b/nuttx/include/nuttx/binfmt/elf.h @@ -59,6 +59,17 @@ # define CONFIG_ELF_ALIGN_LOG2 2 #endif +/* Allocation array size and indices */ + +#define LIBELF_ELF_ALLOC 0 +#ifdef CONFIG_BINFMT_CONSTRUCTORS +# define LIBELF_CTORS_ALLOC 1 +# define LIBELF_CTPRS_ALLOC 2 +# define LIBELF_NALLOC 3 +#else +# define LIBELF_NALLOC 1 +#endif + /**************************************************************************** * Public Types ****************************************************************************/ @@ -69,21 +80,28 @@ struct elf_loadinfo_s { - uintptr_t alloc; /* Allocated memory with the ELF file is loaded */ - size_t allocsize; /* Size of the memory allocation */ - off_t filelen; /* Length of the entire ELF file */ - Elf32_Ehdr ehdr; /* Buffered ELF file header */ - FAR Elf32_Shdr *shdr; /* Buffered ELF section headers */ - uint8_t *iobuffer; /* File I/O buffer */ + /* The alloc[] array holds memory that persists after the ELF module has + * been loaded. + */ + + uintptr_t elfalloc; /* Memory allocated when ELF file was loaded */ + size_t elfsize; /* Size of the ELF memory allocation */ + off_t filelen; /* Length of the entire ELF file */ + Elf32_Ehdr ehdr; /* Buffered ELF file header */ + FAR Elf32_Shdr *shdr; /* Buffered ELF section headers */ + uint8_t *iobuffer; /* File I/O buffer */ #ifdef CONFIG_BINFMT_CONSTRUCTORS - elf_ctor_t *ctors; /* Pointer to a list of constructors */ - bool newabi; /* True: ctors in 'alloc' */ - uint16_t nctors; /* Number of constructors */ + FAR void *ctoralloc; /* Memory allocated for ctors */ + FAR void *dtoralloc; /* Memory allocated dtors */ + FAR binfmt_ctor_t *ctors; /* Pointer to a list of constructors */ + FAR binfmt_dtor_t *dtors; /* Pointer to a list of destructors */ + uint16_t nctors; /* Number of constructors */ + uint16_t ndtors; /* Number of destructors */ #endif - uint16_t symtabidx; /* Symbol table section index */ - uint16_t strtabidx; /* String table section index */ - uint16_t buflen; /* size of iobuffer[] */ - int filfd; /* Descriptor for the file being loaded */ + uint16_t symtabidx; /* Symbol table section index */ + uint16_t strtabidx; /* String table section index */ + uint16_t buflen; /* size of iobuffer[] */ + int filfd; /* Descriptor for the file being loaded */ }; /****************************************************************************