insmod is code complete and ready for test

This commit is contained in:
Gregory Nutt
2015-12-11 10:55:21 -06:00
parent 05cb7a9043
commit 44e45f0f91
19 changed files with 201 additions and 897 deletions
+1 -1
Submodule arch updated: c8448d662d...ca979759a7
+10
View File
@@ -12,6 +12,16 @@ config BINFMT_DISABLE
if !BINFMT_DISABLE if !BINFMT_DISABLE
config MODULE
bool "Enable loadable OS modules"
default n
---help---
Enable support for loadable OS modules. Default: n
if MODULE
source binfmt/libmodule/Kconfig
endif
config BINFMT_EXEPATH config BINFMT_EXEPATH
bool "Support PATH variable" bool "Support PATH variable"
default n default n
+1
View File
@@ -71,6 +71,7 @@ VPATH =
SUBDIRS = SUBDIRS =
DEPPATH = --dep-path . DEPPATH = --dep-path .
include libmodule$(DELIM)Make.defs
include libnxflat$(DELIM)Make.defs include libnxflat$(DELIM)Make.defs
include libelf$(DELIM)Make.defs include libelf$(DELIM)Make.defs
include libbuiltin$(DELIM)Make.defs include libbuiltin$(DELIM)Make.defs
+20 -123
View File
@@ -49,7 +49,6 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include <nuttx/binfmt/binfmt.h>
#include <nuttx/binfmt/module.h> #include <nuttx/binfmt/module.h>
#include "libmodule/libmodule.h" #include "libmodule/libmodule.h"
@@ -78,26 +77,6 @@
# define MIN(a,b) (a < b ? a : b) # define MIN(a,b) (a < b ? a : b)
#endif #endif
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
static int mod_loadbinary(FAR struct binary_s *binp);
#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_BINFMT)
static void mod_dumploadinfo(FAR struct mod_loadinfo_s *loadinfo);
#endif
/****************************************************************************
* Private Data
****************************************************************************/
static struct binfmt_s g_modbinfmt =
{
NULL, /* next */
mod_loadbinary, /* load */
NULL, /* unload */
};
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
@@ -107,24 +86,16 @@ static struct binfmt_s g_modbinfmt =
****************************************************************************/ ****************************************************************************/
#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_BINFMT) #if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_BINFMT)
static void mod_dumploadinfo(FAR struct mod_loadinfo_s *loadinfo) static void mod_dumploadinfo(FAR struct libmod_loadinfo_s *loadinfo)
{ {
int i; int i;
bdbg("LOAD_INFO:\n"); bdbg("LOAD_INFO:\n");
bdbg(" textalloc: %08lx\n", (long)loadinfo->textalloc); bdbg(" textalloc: %08lx\n", (long)loadinfo->textalloc);
bdbg(" dataalloc: %08lx\n", (long)loadinfo->dataalloc); bdbg(" datastart: %08lx\n", (long)loadinfo->datastart);
bdbg(" textsize: %ld\n", (long)loadinfo->textsize); bdbg(" textsize: %ld\n", (long)loadinfo->textsize);
bdbg(" datasize: %ld\n", (long)loadinfo->datasize); bdbg(" datasize: %ld\n", (long)loadinfo->datasize);
bdbg(" filelen: %ld\n", (long)loadinfo->filelen); 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(" filfd: %d\n", loadinfo->filfd);
bdbg(" symtabidx: %d\n", loadinfo->symtabidx); bdbg(" symtabidx: %d\n", loadinfo->symtabidx);
bdbg(" strtabidx: %d\n", loadinfo->strtabidx); bdbg(" strtabidx: %d\n", loadinfo->strtabidx);
@@ -186,25 +157,28 @@ static void mod_dumpinitializer(mod_initializer_t initializer,
#endif #endif
/**************************************************************************** /****************************************************************************
* Name: mod_loadbinary * Public Functions
****************************************************************************/
/****************************************************************************
* Name: insmod
* *
* Description: * Description:
* Verify that the file is an ELF binary and, if so, load the ELF * Verify that the file is an ELF module binary and, if so, load the
* binary into memory * module into kernel memory and initialize it for use.
* *
****************************************************************************/ ****************************************************************************/
static int mod_loadbinary(FAR struct binary_s *binp) int insmod(FAR struct module_s *modp)
{ {
struct mod_loadinfo_s loadinfo; /* Contains globals for libmodule */ struct libmod_loadinfo_s loadinfo; /* Contains globals for libmodule */
mod_initializer_t initializer; int ret;
int ret;
bvdbg("Loading file: %s\n", binp->filename); bvdbg("Loading file: %s\n", modp->filename);
/* Initialize the ELF library to load the program binary. */ /* Initialize the ELF library to load the program binary. */
ret = libmod_initialize(binp->filename, &loadinfo); ret = libmod_initialize(modp->filename, &loadinfo);
mod_dumploadinfo(&loadinfo); mod_dumploadinfo(&loadinfo);
if (ret != 0) if (ret != 0)
{ {
@@ -224,7 +198,7 @@ static int mod_loadbinary(FAR struct binary_s *binp)
/* Bind the program to the exported symbol table */ /* Bind the program to the exported symbol table */
ret = libmod_bind(&loadinfo, binp->exports, binp->nexports); ret = libmod_bind(&loadinfo, modp->exports, modp->nexports);
if (ret != 0) if (ret != 0)
{ {
bdbg("Failed to bind symbols program binary: %d\n", ret); bdbg("Failed to bind symbols program binary: %d\n", ret);
@@ -233,43 +207,18 @@ static int mod_loadbinary(FAR struct binary_s *binp)
/* Return the load information */ /* Return the load information */
binp->entrypt = NULL; modp->initializer = (mod_initializer_t)(loadinfo.textalloc + loadinfo.ehdr.e_entry);
binp->stacksize = 0; modp->alloc = (FAR void *)loadinfo.textalloc;
/* Add the ELF allocation to the alloc[] only if there is no address
* environment. If there is an address environment, it will automatically
* be freed when the function exits
*
* REVISIT: If the module is loaded then unloaded, wouldn't this cause
* a memory leak?
*/
binp->alloc[0] = (FAR void *)loadinfo.textalloc;
#ifdef CONFIG_BINFMT_CONSTRUCTORS
/* Save information about constructors. NOTE: destructors are not
* yet supported.
*/
binp->alloc[1] = loadinfo.ctoralloc;
binp->ctors = loadinfo.ctors;
binp->nctors = loadinfo.nctors;
binp->alloc[2] = loadinfo.dtoralloc;
binp->dtors = loadinfo.dtors;
binp->ndtors = loadinfo.ndtors;
#endif
/* Get the module initializer entry point */ /* Get the module initializer entry point */
initializer = (mod_initializer_t)(loadinfo.textalloc + loadinfo.ehdr.e_entry); if (modp->initializer)
if (initialize)
{ {
mod_dumpinitializer(initializer, &loadinfo); mod_dumpinitializer(modp->initializer, &loadinfo);
/* Call the module initializer */ /* Call the module initializer */
ret = initializer(); ret = modp->initializer();
if (ret < 0) if (ret < 0)
{ {
bdbg("Failed to initialize the module: %d\n", ret); bdbg("Failed to initialize the module: %d\n", ret);
@@ -288,56 +237,4 @@ errout:
return ret; return ret;
} }
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: mod_initialize
*
* Description:
* ELF support is built unconditionally. However, in order to
* use this binary format, this function must be called during system
* initialization in order to register the ELF binary format.
*
* Returned Value:
* This is a NuttX internal function so it follows the convention that
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
*
****************************************************************************/
int mod_initialize(void)
{
int ret;
/* Register ourselves as a binfmt loader */
bvdbg("Registering ELF\n");
ret = register_binfmt(&g_modbinfmt);
if (ret != 0)
{
bdbg("Failed to register binfmt: %d\n", ret);
}
return ret;
}
/****************************************************************************
* Name: mod_uninitialize
*
* Description:
* Unregister the ELF binary loader
*
* Returned Value:
* None
*
****************************************************************************/
void mod_uninitialize(void)
{
unregister_binfmt(&g_modbinfmt);
}
#endif /* CONFIG_MODULE */ #endif /* CONFIG_MODULE */
-10
View File
@@ -33,13 +33,3 @@ config MODULE_DUMPBUFFER
depends on DEBUG && DEBUG_VERBOSE depends on DEBUG && DEBUG_VERBOSE
---help--- ---help---
Dump various module buffers for debug purposes Dump various module buffers for debug purposes
config MODULE_EXIDX_SECTNAME
string "Module Section Name for Exception Index"
default ".ARM.exidx"
depends on UCLIBCXX_EXCEPTION
---help---
Set the name string for the exception index section on the modules to
be loaded by the module binary loader.
This is needed to support exception handling on loadable modules.
+4 -8
View File
@@ -33,23 +33,19 @@
# #
############################################################################ ############################################################################
ifeq ($(CONFIG_ELF),y) ifeq ($(CONFIG_MODULE),y)
# ELF application interfaces # OS module interfaces
BINFMT_CSRCS += module.c BINFMT_CSRCS += insmod.c
# ELF library # loadable module library
BINFMT_CSRCS += libmodule_bind.c libmodule_init.c libmodule_iobuffer.c BINFMT_CSRCS += libmodule_bind.c libmodule_init.c libmodule_iobuffer.c
BINFMT_CSRCS += libmodule_load.c libmodule_read.c libmodule_sections.c BINFMT_CSRCS += libmodule_load.c libmodule_read.c libmodule_sections.c
BINFMT_CSRCS += libmodule_symbols.c libmodule_uninit.c libmodule_unload.c BINFMT_CSRCS += libmodule_symbols.c libmodule_uninit.c libmodule_unload.c
BINFMT_CSRCS += libmodule_verify.c BINFMT_CSRCS += libmodule_verify.c
ifeq ($(CONFIG_BINFMT_CONSTRUCTORS),y)
BINFMT_CSRCS += libmodule_ctors.c libmodule_dtors.c
endif
# Hook the libmodule subdirectory into the build # Hook the libmodule subdirectory into the build
VPATH += libmodule VPATH += libmodule
-32
View File
@@ -45,14 +45,6 @@ SECTIONS
*(.glue_7) *(.glue_7)
*(.glue_7t) *(.glue_7t)
*(.jcr) *(.jcr)
/* C++ support: The .init and .fini sections contain specific logic
* to manage static constructors and destructors.
*/
*(.gnu.linkonce.t.*)
*(.init) /* Old ABI */
*(.fini) /* Old ABI */
_etext = . ; _etext = . ;
} }
@@ -76,30 +68,6 @@ SECTIONS
_edata = . ; _edata = . ;
} }
/* C++ support. For each global and static local C++ object,
* GCC creates a small subroutine to construct the object. Pointers
* to these routines (not the routines themselves) are stored as
* simple, linear arrays in the .ctors section of the object file.
* Similarly, pointers to global/static destructor routines are
* stored in .dtors.
*/
.ctors :
{
_sctors = . ;
*(.ctors) /* Old ABI: Unallocated */
*(.init_array) /* New ABI: Allocated */
_ectors = . ;
}
.dtors :
{
_sdtors = . ;
*(.dtors) /* Old ABI: Unallocated */
*(.fini_array) /* New ABI: Allocated */
_edtors = . ;
}
.bss : .bss :
{ {
_sbss = . ; _sbss = . ;
+112 -43
View File
@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* binfmt/libmodule/libmodule.h * binfmt/libmodule/libmodule.h
* *
* Copyright (C) 2012, 2014 Gregory Nutt. All rights reserved. * Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -48,18 +48,125 @@
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include <nuttx/binfmt/module.h> #include <nuttx/binfmt/module.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/**************************************************************************** /****************************************************************************
* Public Types * Public Types
****************************************************************************/ ****************************************************************************/
/* This struct provides a description of the currently loaded instantiation
* of the kernel module.
*/
struct libmod_loadinfo_s
{
/* elfalloc is the base address of the memory that is allocated to hold the
* module image.
*
* The alloc[] array in struct module_s will hold memory that persists after
* the module has been loaded.
*/
uintptr_t textalloc; /* .text memory allocated when module was loaded */
uintptr_t datastart; /* Start of.bss/.data memory in .text allocation */
size_t textsize; /* Size of the module .text memory allocation */
size_t datasize; /* Size of the module .bss/.data memory allocation */
off_t filelen; /* Length of the entire module file */
Elf32_Ehdr ehdr; /* Buffered module file header */
FAR Elf32_Shdr *shdr; /* Buffered module section headers */
uint8_t *iobuffer; /* File I/O buffer */
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 */
};
/**************************************************************************** /****************************************************************************
* Public Function Prototypes * Public Function Prototypes
****************************************************************************/ ****************************************************************************/
/****************************************************************************
* These are APIs exported by libmodule and used by insmod
****************************************************************************/
/****************************************************************************
* Name: libmod_initialize
*
* Description:
* This function is called to configure the library to process an kernel
* module.
*
* Returned Value:
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
*
****************************************************************************/
int libmod_initialize(FAR const char *filename,
FAR struct libmod_loadinfo_s *loadinfo);
/****************************************************************************
* Name: libmod_uninitialize
*
* Description:
* Releases any resources committed by mod_init(). This essentially
* undoes the actions of libmod_initialize.
*
* Returned Value:
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
*
****************************************************************************/
int libmod_uninitialize(FAR struct libmod_loadinfo_s *loadinfo);
/****************************************************************************
* Name: libmod_load
*
* Description:
* Loads the binary into memory, allocating memory, performing relocations
* and initializing the data and bss segments.
*
* Returned Value:
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
*
****************************************************************************/
int libmod_load(FAR struct libmod_loadinfo_s *loadinfo);
/****************************************************************************
* Name: libmod_bind
*
* Description:
* Bind the imported symbol names in the loaded module described by
* 'loadinfo' using the exported symbol values provided by 'symtab'.
*
* Returned Value:
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
*
****************************************************************************/
struct symtab_s;
int libmod_bind(FAR struct libmod_loadinfo_s *loadinfo,
FAR const struct symtab_s *exports, int nexports);
/****************************************************************************
* Name: libmod_unload
*
* Description:
* This function unloads the object from memory. This essentially undoes
* the actions of mod_load. It is called only under certain error
* conditions after the module has been loaded but not yet started.
*
* Returned Value:
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
*
****************************************************************************/
int libmod_unload(struct libmod_loadinfo_s *loadinfo);
/**************************************************************************** /****************************************************************************
* Name: libmod_verifyheader * Name: libmod_verifyheader
* *
@@ -229,42 +336,4 @@ int libmod_allocbuffer(FAR struct libmod_loadinfo_s *loadinfo);
int libmod_reallocbuffer(FAR struct libmod_loadinfo_s *loadinfo, size_t increment); int libmod_reallocbuffer(FAR struct libmod_loadinfo_s *loadinfo, size_t increment);
/****************************************************************************
* Name: libmod_findctors
*
* Description:
* Find C++ static constructors.
*
* 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 libmod_loadctors(FAR struct libmod_loadinfo_s *loadinfo);
#endif
/****************************************************************************
* Name: libmod_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 libmod_loaddtors(FAR struct libmod_loadinfo_s *loadinfo);
#endif
#endif /* __BINFMT_LIBELF_LIBELF_H */ #endif /* __BINFMT_LIBELF_LIBELF_H */
+5 -5
View File
@@ -56,18 +56,18 @@
****************************************************************************/ ****************************************************************************/
/* CONFIG_DEBUG, CONFIG_DEBUG_VERBOSE, and CONFIG_DEBUG_BINFMT have to be /* CONFIG_DEBUG, CONFIG_DEBUG_VERBOSE, and CONFIG_DEBUG_BINFMT have to be
* defined or CONFIG_ELF_DUMPBUFFER does nothing. * defined or CONFIG_MODULE_DUMPBUFFER does nothing.
*/ */
#if !defined(CONFIG_DEBUG_VERBOSE) || !defined (CONFIG_DEBUG_BINFMT) #if !defined(CONFIG_DEBUG_VERBOSE) || !defined (CONFIG_DEBUG_BINFMT)
# undef CONFIG_ELF_DUMPBUFFER # undef CONFIG_MODULE_DUMPBUFFER
#endif #endif
#ifndef CONFIG_ELF_BUFFERSIZE #ifndef CONFIG_MODULE_BUFFERSIZE
# define CONFIG_ELF_BUFFERSIZE 128 # define CONFIG_MODULE_BUFFERSIZE 128
#endif #endif
#ifdef CONFIG_ELF_DUMPBUFFER #ifdef CONFIG_MODULE_DUMPBUFFER
# define libmod_dumpbuffer(m,b,n) bvdbgdumpbuffer(m,b,n) # define libmod_dumpbuffer(m,b,n) bvdbgdumpbuffer(m,b,n)
#else #else
# define libmod_dumpbuffer(m,b,n) # define libmod_dumpbuffer(m,b,n)
-216
View File
@@ -1,216 +0,0 @@
/****************************************************************************
* binfmt/libmodule/libmodule_ctors.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/module.h>
#include "libmodule.h"
#ifdef CONFIG_BINFMT_CONSTRUCTORS
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Constant Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: libmod_loadctors
*
* Description:
* Load pointers 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 libmod_loadctors(FAR struct libmod_loadinfo_s *loadinfo)
{
FAR Elf32_Shdr *shdr;
size_t ctorsize;
int ctoridx;
int ret;
int i;
DEBUGASSERT(loadinfo->ctors == NULL);
/* Allocate an I/O buffer if necessary. This buffer is used by
* libmod_sectname() to accumulate the variable length symbol name.
*/
ret = libmod_allocbuffer(loadinfo);
if (ret < 0)
{
bdbg("libmod_allocbuffer failed: %d\n", ret);
return -ENOMEM;
}
/* 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 section name to be ".ctors"
* in either case.
*/
ctoridx = libmod_findsection(loadinfo, ".ctors");
if (ctoridx < 0)
{
/* This may not be a failure. -ENOENT indicates that the file has no
* static constructor section.
*/
bvdbg("libmod_findsection .ctors section 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];
/* Get the size of the .ctor section and the number of constructors that
* will need to be called.
*/
ctorsize = shdr->sh_size;
loadinfo->nctors = ctorsize / sizeof(binfmt_ctor_t);
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.
*/
if (loadinfo->nctors > 0)
{
/* Check an assumption that we made above */
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
* 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 .ctor section */
loadinfo->ctoralloc = (binfmt_ctor_t *)kmm_malloc(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 = libmod_read(loadinfo, (FAR uint8_t *)loadinfo->ctors, ctorsize,
shdr->sh_offset);
if (ret < 0)
{
bdbg("Failed to allocate .ctors: %d\n", ret);
return ret;
}
/* Fix up all of the .ctor addresses. Since the addresses
* do not lie in allocated memory, there will be no relocation
* section for them.
*/
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, (unsigned long)loadinfo->textalloc,
(unsigned long)(*ptr + loadinfo->textalloc));
*ptr += loadinfo->textalloc;
}
}
else
{
/* 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 = (binfmt_ctor_t *)shdr->sh_addr;
}
}
return OK;
}
#endif /* CONFIG_BINFMT_CONSTRUCTORS */
-216
View File
@@ -1,216 +0,0 @@
/****************************************************************************
* binfmt/libmodule/libmodule_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/module.h>
#include "libmodule.h"
#ifdef CONFIG_BINFMT_CONSTRUCTORS
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Constant Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: libmod_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 libmod_loaddtors(FAR struct libmod_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
* libmod_sectname() to accumulate the variable length symbol name.
*/
ret = libmod_allocbuffer(loadinfo);
if (ret < 0)
{
bdbg("libmod_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 = libmod_findsection(loadinfo, ".dtors");
if (dtoridx < 0)
{
/* This may not be a failure. -ENOENT indicates that the file has no
* static destructor section.
*/
bvdbg("libmod_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 *)kmm_malloc(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 = libmod_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, (unsigned long)loadinfo->textalloc,
(unsigned long)(*ptr + loadinfo->textalloc));
*ptr += loadinfo->textalloc;
}
}
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 */
+3 -3
View File
@@ -57,14 +57,14 @@
****************************************************************************/ ****************************************************************************/
/* CONFIG_DEBUG, CONFIG_DEBUG_VERBOSE, and CONFIG_DEBUG_BINFMT have to be /* CONFIG_DEBUG, CONFIG_DEBUG_VERBOSE, and CONFIG_DEBUG_BINFMT have to be
* defined or CONFIG_ELF_DUMPBUFFER does nothing. * defined or CONFIG_MODULE_DUMPBUFFER does nothing.
*/ */
#if !defined(CONFIG_DEBUG_VERBOSE) || !defined (CONFIG_DEBUG_BINFMT) #if !defined(CONFIG_DEBUG_VERBOSE) || !defined (CONFIG_DEBUG_BINFMT)
# undef CONFIG_ELF_DUMPBUFFER # undef CONFIG_MODULE_DUMPBUFFER
#endif #endif
#ifdef CONFIG_ELF_DUMPBUFFER #ifdef CONFIG_MODULE_DUMPBUFFER
# define libmod_dumpbuffer(m,b,n) bvdbgdumpbuffer(m,b,n) # define libmod_dumpbuffer(m,b,n) bvdbgdumpbuffer(m,b,n)
#else #else
# define libmod_dumpbuffer(m,b,n) # define libmod_dumpbuffer(m,b,n)
+2 -2
View File
@@ -84,14 +84,14 @@ int libmod_allocbuffer(FAR struct libmod_loadinfo_s *loadinfo)
{ {
/* No.. allocate one now */ /* No.. allocate one now */
loadinfo->iobuffer = (FAR uint8_t *)kmm_malloc(CONFIG_ELF_BUFFERSIZE); loadinfo->iobuffer = (FAR uint8_t *)kmm_malloc(CONFIG_MODULE_BUFFERSIZE);
if (!loadinfo->iobuffer) if (!loadinfo->iobuffer)
{ {
bdbg("Failed to allocate an I/O buffer\n"); bdbg("Failed to allocate an I/O buffer\n");
return -ENOMEM; return -ENOMEM;
} }
loadinfo->buflen = CONFIG_ELF_BUFFERSIZE; loadinfo->buflen = CONFIG_MODULE_BUFFERSIZE;
} }
return OK; return OK;
+5 -42
View File
@@ -50,6 +50,7 @@
#include <errno.h> #include <errno.h>
#include <debug.h> #include <debug.h>
#include <nuttx/kmalloc.h>
#include <nuttx/binfmt/module.h> #include <nuttx/binfmt/module.h>
#include "libmodule.h" #include "libmodule.h"
@@ -58,7 +59,7 @@
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
#define ELF_ALIGN_MASK ((1 << CONFIG_ELF_ALIGN_LOG2) - 1) #define ELF_ALIGN_MASK ((1 << CONFIG_MODULE_ALIGN_LOG2) - 1)
#define ELF_ALIGNUP(a) (((unsigned long)(a) + ELF_ALIGN_MASK) & ~ELF_ALIGN_MASK) #define ELF_ALIGNUP(a) (((unsigned long)(a) + ELF_ALIGN_MASK) & ~ELF_ALIGN_MASK)
#define ELF_ALIGNDOWN(a) ((unsigned long)(a) & ~ELF_ALIGN_MASK) #define ELF_ALIGNDOWN(a) ((unsigned long)(a) & ~ELF_ALIGN_MASK)
@@ -157,7 +158,7 @@ static inline int libmod_loadfile(FAR struct libmod_loadinfo_s *loadinfo)
bvdbg("Loaded sections:\n"); bvdbg("Loaded sections:\n");
text = (FAR uint8_t *)loadinfo->textalloc; text = (FAR uint8_t *)loadinfo->textalloc;
data = (FAR uint8_t *)loadinfo->dataalloc; data = (FAR uint8_t *)loadinfo->datastart;
for (i = 0; i < loadinfo->ehdr.e_shnum; i++) for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
{ {
@@ -243,10 +244,6 @@ static inline int libmod_loadfile(FAR struct libmod_loadinfo_s *loadinfo)
int libmod_load(FAR struct libmod_loadinfo_s *loadinfo) int libmod_load(FAR struct libmod_loadinfo_s *loadinfo)
{ {
size_t heapsize;
#ifdef CONFIG_UCLIBCXX_EXCEPTION
int exidx;
#endif
int ret; int ret;
bvdbg("loadinfo: %p\n", loadinfo); bvdbg("loadinfo: %p\n", loadinfo);
@@ -265,15 +262,11 @@ int libmod_load(FAR struct libmod_loadinfo_s *loadinfo)
libmod_elfsize(loadinfo); libmod_elfsize(loadinfo);
/* Determine the heapsize to allocate. */
heapsize = 0;
/* Allocate (and zero) memory for the ELF file. */ /* Allocate (and zero) memory for the ELF file. */
/* Allocate memory to hold the ELF image */ /* Allocate memory to hold the ELF image */
loadinfo->textalloc = (uintptr_t)kmm_zalloc(textsize + datasize); loadinfo->textalloc = (uintptr_t)kmm_zalloc(loadinfo->textsize + loadinfo->datasize);
if (!loadinfo->textalloc) if (!loadinfo->textalloc)
{ {
bdbg("ERROR: Failed to allocate memory for the module\n"); bdbg("ERROR: Failed to allocate memory for the module\n");
@@ -281,7 +274,7 @@ int libmod_load(FAR struct libmod_loadinfo_s *loadinfo)
goto errout_with_buffers; goto errout_with_buffers;
} }
loadinfo->dataalloc = loadinfo->textalloc + textsize; loadinfo->datastart = loadinfo->textalloc + loadinfo->textsize;
/* Load ELF section data into memory */ /* Load ELF section data into memory */
@@ -292,36 +285,6 @@ int libmod_load(FAR struct libmod_loadinfo_s *loadinfo)
goto errout_with_buffers; goto errout_with_buffers;
} }
/* Load static constructors and destructors. */
#ifdef CONFIG_BINFMT_CONSTRUCTORS
ret = libmod_loadctors(loadinfo);
if (ret < 0)
{
bdbg("ERROR: libmod_loadctors failed: %d\n", ret);
goto errout_with_buffers;
}
ret = libmod_loaddtors(loadinfo);
if (ret < 0)
{
bdbg("ERROR: libmod_loaddtors failed: %d\n", ret);
goto errout_with_buffers;
}
#endif
#ifdef CONFIG_UCLIBCXX_EXCEPTION
exidx = libmod_findsection(loadinfo, CONFIG_ELF_EXIDX_SECTNAME);
if (exidx < 0)
{
bvdbg("libmod_findsection: Exception Index section not found: %d\n", exidx);
}
else
{
up_init_exidx(loadinfo->shdr[exidx].sh_addr, loadinfo->shdr[exidx].sh_size);
}
#endif
return OK; return OK;
/* Error exits */ /* Error exits */
+2
View File
@@ -49,6 +49,8 @@
#include <nuttx/binfmt/module.h> #include <nuttx/binfmt/module.h>
#include "libmodule.h"
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
+1 -1
View File
@@ -156,7 +156,7 @@ static inline int libmod_sectname(FAR struct libmod_loadinfo_s *loadinfo,
/* No.. then we have to read more */ /* No.. then we have to read more */
ret = libmod_reallocbuffer(loadinfo, CONFIG_ELF_BUFFERINCR); ret = libmod_reallocbuffer(loadinfo, CONFIG_MODULE_BUFFERINCR);
if (ret < 0) if (ret < 0)
{ {
bdbg("libmod_reallocbuffer failed: %d\n", ret); bdbg("libmod_reallocbuffer failed: %d\n", ret);
+3 -3
View File
@@ -54,8 +54,8 @@
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
#ifndef CONFIG_ELF_BUFFERINCR #ifndef CONFIG_MODULE_BUFFERINCR
# define CONFIG_ELF_BUFFERINCR 32 # define CONFIG_MODULE_BUFFERINCR 32
#endif #endif
/**************************************************************************** /****************************************************************************
@@ -146,7 +146,7 @@ static int libmod_symname(FAR struct libmod_loadinfo_s *loadinfo,
/* No.. then we have to read more */ /* No.. then we have to read more */
ret = libmod_reallocbuffer(loadinfo, CONFIG_ELF_BUFFERINCR); ret = libmod_reallocbuffer(loadinfo, CONFIG_MODULE_BUFFERINCR);
if (ret < 0) if (ret < 0)
{ {
bdbg("libmod_reallocbuffer failed: %d\n", ret); bdbg("libmod_reallocbuffer failed: %d\n", ret);
+1 -23
View File
@@ -93,32 +93,10 @@ int libmod_unload(struct libmod_loadinfo_s *loadinfo)
/* Clear out all indications of the allocated address environment */ /* Clear out all indications of the allocated address environment */
loadinfo->textalloc = 0; loadinfo->textalloc = 0;
loadinfo->dataalloc = 0; loadinfo->datastart = 0;
loadinfo->textsize = 0; loadinfo->textsize = 0;
loadinfo->datasize = 0; loadinfo->datasize = 0;
#ifdef CONFIG_BINFMT_CONSTRUCTORS
/* Release memory used to hold static constructors and destructors */
if (loadinfo->ctoralloc != 0)
{
kmm_free(loadinfo->ctoralloc);
loadinfo->ctoralloc = NULL;
}
loadinfo->ctors = NULL;
loadinfo->nctors = 0;
if (loadinfo->dtoralloc != 0)
{
kmm_free(loadinfo->dtoralloc);
loadinfo->dtoralloc = NULL;
}
loadinfo->dtors = NULL;
loadinfo->ndtors = 0;
#endif
return OK; return OK;
} }
+31 -169
View File
@@ -86,45 +86,6 @@
* Public Types * Public Types
****************************************************************************/ ****************************************************************************/
/* This struct provides a description of the currently loaded instantiation
* of the kernel module.
*/
struct mod_loadinfo_s
{
/* elfalloc is the base address of the memory that is allocated to hold the
* module image.
*
* The alloc[] array in struct binary_s will hold memory that persists after
* the module has been loaded.
*/
uintptr_t textalloc; /* .text memory allocated when module was loaded */
uintptr_t dataalloc; /* .bss/.data memory allocated when module was loaded */
size_t textsize; /* Size of the module .text memory allocation */
size_t datasize; /* Size of the module .bss/.data memory allocation */
off_t filelen; /* Length of the entire module file */
Elf32_Ehdr ehdr; /* Buffered module file header */
FAR Elf32_Shdr *shdr; /* Buffered module section headers */
uint8_t *iobuffer; /* File I/O buffer */
/* Constructors and destructors */
#ifdef CONFIG_BINFMT_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 */
};
/* A NuttX module is expected to export a function called module_initialize() /* A NuttX module is expected to export a function called module_initialize()
* that has the following function prototype. This function should appear as * that has the following function prototype. This function should appear as
* the entry point in the ELF module file and will be called bythe binfmt * the entry point in the ELF module file and will be called bythe binfmt
@@ -145,8 +106,34 @@ struct mod_loadinfo_s
typedef CODE int (*mod_initializer_t)(void); typedef CODE int (*mod_initializer_t)(void);
/* This describes the file to be loaded.
*
* NOTE 1: The 'filename' must be the full, absolute path to the file to be
* executed unless CONFIG_BINFMT_EXEPATH is defined. In that case,
* 'filename' may be a relative path; a set of candidate absolute paths
* will be generated using the PATH environment variable and load_module()
* will attempt to load each file that is found at those absolute paths.
*/
struct symtab_s;
struct module_s
{
/* Information provided to insmod by the caller */
FAR const char *filename; /* Full path to the binary to be loaded (See NOTE 1 above) */
FAR const struct symtab_s *exports; /* Table of exported symbols */
int nexports; /* The number of symbols in exports[] */
/* Information provided from insmod (if successful) describing the
* resources used by the loaded module.
*/
mod_initializer_t initializer; /* Module initializer function */
FAR void *alloc; /* Allocated kernel memory */
};
/**************************************************************************** /****************************************************************************
* Public Functions * Public Function Prototypes
****************************************************************************/ ****************************************************************************/
#undef EXTERN #undef EXTERN
@@ -159,120 +146,15 @@ extern "C"
#endif #endif
/**************************************************************************** /****************************************************************************
* These are APIs exported by libelf (but are used only by the binfmt logic): * Name: insmod
****************************************************************************/
/****************************************************************************
* Name: libmod_initialize
* *
* Description: * Description:
* This function is called to configure the library to process an kernel * Verify that the file is an ELF module binary and, if so, load the
* module. * module into kernel memory and initialize it for use.
*
* Returned Value:
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
* *
****************************************************************************/ ****************************************************************************/
int libmod_initalize(FAR const char *filename, int insmod(FAR struct module_s *modp);
FAR struct mod_loadinfo_s *loadinfo);
/****************************************************************************
* Name: libmod_uninitialize
*
* Description:
* Releases any resources committed by mod_init(). This essentially
* undoes the actions of mod_init.
*
* Returned Value:
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
*
****************************************************************************/
int libmod_uninitialize(FAR struct mod_loadinfo_s *loadinfo);
/****************************************************************************
* Name: mod_load
*
* Description:
* Loads the binary into memory, allocating memory, performing relocations
* and initializing the data and bss segments.
*
* Returned Value:
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
*
****************************************************************************/
int mod_load(FAR struct mod_loadinfo_s *loadinfo);
/****************************************************************************
* Name: mod_bind
*
* Description:
* Bind the imported symbol names in the loaded module described by
* 'loadinfo' using the exported symbol values provided by 'symtab'.
*
* Returned Value:
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
*
****************************************************************************/
struct symtab_s;
int mod_bind(FAR struct mod_loadinfo_s *loadinfo,
FAR const struct symtab_s *exports, int nexports);
/****************************************************************************
* Name: mod_unload
*
* Description:
* This function unloads the object from memory. This essentially undoes
* the actions of mod_load. It is called only under certain error
* conditions after the module has been loaded but not yet started.
*
* Returned Value:
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
*
****************************************************************************/
int mod_unload(struct mod_loadinfo_s *loadinfo);
/****************************************************************************
* These are APIs used outside of binfmt by NuttX:
****************************************************************************/
/****************************************************************************
* Name: mod_initialize
*
* Description:
* Module support is built unconditionally. However, in order to
* use this binary format, this function must be called during system
* initialization in order to register the module binary format.
*
* Returned Value:
* This is a NuttX internal function so it follows the convention that
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
*
****************************************************************************/
int mod_initialize(void);
/****************************************************************************
* Name: mod_uninitialize
*
* Description:
* Unregister the module loader
*
* Returned Value:
* None
*
****************************************************************************/
void mod_uninitialize(void);
/**************************************************************************** /****************************************************************************
* These are APIs must be provided by architecture-specific logic. * These are APIs must be provided by architecture-specific logic.
@@ -323,26 +205,6 @@ int up_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym,
int up_relocateadd(FAR const Elf32_Rela *rel, int up_relocateadd(FAR const Elf32_Rela *rel,
FAR const Elf32_Sym *sym, uintptr_t addr); FAR const Elf32_Sym *sym, uintptr_t addr);
#ifdef CONFIG_UCLIBCXX_EXCEPTION
/****************************************************************************
* Name: up_init_exidx
*
* Description:
* Load the boundaries of the Exception Index ELF section in order to
* support exception handling for loaded modules.
*
* Input Parameters:
* address - The ELF section address for the Exception Index
* size - The size of the ELF section.
*
* Returned Value:
* Always returns Zero (OK).
*
****************************************************************************/
int up_init_exidx(Elf32_Addr address, Elf32_Word size);
#endif
/**************************************************************************** /****************************************************************************
* Name: up_coherent_dcache * Name: up_coherent_dcache
* *