mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 07:28:38 +08:00
insmod is code complete and ready for test
This commit is contained in:
parent
05cb7a9043
commit
44e45f0f91
19 changed files with 201 additions and 897 deletions
2
arch
2
arch
|
@ -1 +1 @@
|
|||
Subproject commit c8448d662d63fecbbd8c603ab54cfbe2de200fe1
|
||||
Subproject commit ca979759a701c3c5e7acb8fc8c604ee112c45601
|
|
@ -12,6 +12,16 @@ config 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
|
||||
bool "Support PATH variable"
|
||||
default n
|
||||
|
|
|
@ -71,6 +71,7 @@ VPATH =
|
|||
SUBDIRS =
|
||||
DEPPATH = --dep-path .
|
||||
|
||||
include libmodule$(DELIM)Make.defs
|
||||
include libnxflat$(DELIM)Make.defs
|
||||
include libelf$(DELIM)Make.defs
|
||||
include libbuiltin$(DELIM)Make.defs
|
||||
|
|
|
@ -49,7 +49,6 @@
|
|||
#include <arpa/inet.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/binfmt/binfmt.h>
|
||||
#include <nuttx/binfmt/module.h>
|
||||
|
||||
#include "libmodule/libmodule.h"
|
||||
|
@ -78,26 +77,6 @@
|
|||
# define MIN(a,b) (a < b ? a : b)
|
||||
#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
|
||||
****************************************************************************/
|
||||
|
@ -107,24 +86,16 @@ static struct binfmt_s g_modbinfmt =
|
|||
****************************************************************************/
|
||||
|
||||
#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;
|
||||
|
||||
bdbg("LOAD_INFO:\n");
|
||||
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(" datasize: %ld\n", (long)loadinfo->datasize);
|
||||
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);
|
||||
bdbg(" strtabidx: %d\n", loadinfo->strtabidx);
|
||||
|
@ -186,25 +157,28 @@ static void mod_dumpinitializer(mod_initializer_t initializer,
|
|||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_loadbinary
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: insmod
|
||||
*
|
||||
* Description:
|
||||
* Verify that the file is an ELF binary and, if so, load the ELF
|
||||
* binary into memory
|
||||
* Verify that the file is an ELF module binary and, if so, load the
|
||||
* 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 */
|
||||
mod_initializer_t initializer;
|
||||
int ret;
|
||||
struct libmod_loadinfo_s loadinfo; /* Contains globals for libmodule */
|
||||
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. */
|
||||
|
||||
ret = libmod_initialize(binp->filename, &loadinfo);
|
||||
ret = libmod_initialize(modp->filename, &loadinfo);
|
||||
mod_dumploadinfo(&loadinfo);
|
||||
if (ret != 0)
|
||||
{
|
||||
|
@ -224,7 +198,7 @@ static int mod_loadbinary(FAR struct binary_s *binp)
|
|||
|
||||
/* 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)
|
||||
{
|
||||
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 */
|
||||
|
||||
binp->entrypt = NULL;
|
||||
binp->stacksize = 0;
|
||||
|
||||
/* 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
|
||||
modp->initializer = (mod_initializer_t)(loadinfo.textalloc + loadinfo.ehdr.e_entry);
|
||||
modp->alloc = (FAR void *)loadinfo.textalloc;
|
||||
|
||||
/* Get the module initializer entry point */
|
||||
|
||||
initializer = (mod_initializer_t)(loadinfo.textalloc + loadinfo.ehdr.e_entry);
|
||||
if (initialize)
|
||||
if (modp->initializer)
|
||||
{
|
||||
mod_dumpinitializer(initializer, &loadinfo);
|
||||
mod_dumpinitializer(modp->initializer, &loadinfo);
|
||||
|
||||
/* Call the module initializer */
|
||||
|
||||
ret = initializer();
|
||||
ret = modp->initializer();
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("Failed to initialize the module: %d\n", ret);
|
||||
|
@ -288,56 +237,4 @@ errout:
|
|||
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 */
|
|
@ -33,13 +33,3 @@ config MODULE_DUMPBUFFER
|
|||
depends on DEBUG && DEBUG_VERBOSE
|
||||
---help---
|
||||
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.
|
||||
|
|
|
@ -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_load.c libmodule_read.c libmodule_sections.c
|
||||
BINFMT_CSRCS += libmodule_symbols.c libmodule_uninit.c libmodule_unload.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
|
||||
|
||||
VPATH += libmodule
|
||||
|
|
|
@ -45,14 +45,6 @@ SECTIONS
|
|||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.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 = . ;
|
||||
}
|
||||
|
||||
|
@ -76,30 +68,6 @@ SECTIONS
|
|||
_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 :
|
||||
{
|
||||
_sbss = . ;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* 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>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -48,18 +48,125 @@
|
|||
#include <nuttx/arch.h>
|
||||
#include <nuttx/binfmt/module.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* 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
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* 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
|
||||
*
|
||||
|
@ -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);
|
||||
|
||||
/****************************************************************************
|
||||
* 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 */
|
||||
|
|
|
@ -56,18 +56,18 @@
|
|||
****************************************************************************/
|
||||
|
||||
/* 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)
|
||||
# undef CONFIG_ELF_DUMPBUFFER
|
||||
# undef CONFIG_MODULE_DUMPBUFFER
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ELF_BUFFERSIZE
|
||||
# define CONFIG_ELF_BUFFERSIZE 128
|
||||
#ifndef CONFIG_MODULE_BUFFERSIZE
|
||||
# define CONFIG_MODULE_BUFFERSIZE 128
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ELF_DUMPBUFFER
|
||||
#ifdef CONFIG_MODULE_DUMPBUFFER
|
||||
# define libmod_dumpbuffer(m,b,n) bvdbgdumpbuffer(m,b,n)
|
||||
#else
|
||||
# define libmod_dumpbuffer(m,b,n)
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -57,14 +57,14 @@
|
|||
****************************************************************************/
|
||||
|
||||
/* 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)
|
||||
# undef CONFIG_ELF_DUMPBUFFER
|
||||
# undef CONFIG_MODULE_DUMPBUFFER
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ELF_DUMPBUFFER
|
||||
#ifdef CONFIG_MODULE_DUMPBUFFER
|
||||
# define libmod_dumpbuffer(m,b,n) bvdbgdumpbuffer(m,b,n)
|
||||
#else
|
||||
# define libmod_dumpbuffer(m,b,n)
|
||||
|
|
|
@ -84,14 +84,14 @@ int libmod_allocbuffer(FAR struct libmod_loadinfo_s *loadinfo)
|
|||
{
|
||||
/* 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)
|
||||
{
|
||||
bdbg("Failed to allocate an I/O buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
loadinfo->buflen = CONFIG_ELF_BUFFERSIZE;
|
||||
loadinfo->buflen = CONFIG_MODULE_BUFFERSIZE;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/binfmt/module.h>
|
||||
|
||||
#include "libmodule.h"
|
||||
|
@ -58,7 +59,7 @@
|
|||
* 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_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");
|
||||
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++)
|
||||
{
|
||||
|
@ -243,10 +244,6 @@ static inline int libmod_loadfile(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;
|
||||
|
||||
bvdbg("loadinfo: %p\n", loadinfo);
|
||||
|
@ -265,15 +262,11 @@ int libmod_load(FAR struct libmod_loadinfo_s *loadinfo)
|
|||
|
||||
libmod_elfsize(loadinfo);
|
||||
|
||||
/* Determine the heapsize to allocate. */
|
||||
|
||||
heapsize = 0;
|
||||
|
||||
/* Allocate (and zero) memory for the ELF file. */
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
loadinfo->dataalloc = loadinfo->textalloc + textsize;
|
||||
loadinfo->datastart = loadinfo->textalloc + loadinfo->textsize;
|
||||
|
||||
/* Load ELF section data into memory */
|
||||
|
||||
|
@ -292,36 +285,6 @@ int libmod_load(FAR struct libmod_loadinfo_s *loadinfo)
|
|||
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;
|
||||
|
||||
/* Error exits */
|
||||
|
|
|
@ -49,6 +49,8 @@
|
|||
|
||||
#include <nuttx/binfmt/module.h>
|
||||
|
||||
#include "libmodule.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
|
|
@ -156,7 +156,7 @@ static inline int libmod_sectname(FAR struct libmod_loadinfo_s *loadinfo,
|
|||
|
||||
/* No.. then we have to read more */
|
||||
|
||||
ret = libmod_reallocbuffer(loadinfo, CONFIG_ELF_BUFFERINCR);
|
||||
ret = libmod_reallocbuffer(loadinfo, CONFIG_MODULE_BUFFERINCR);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("libmod_reallocbuffer failed: %d\n", ret);
|
||||
|
|
|
@ -54,8 +54,8 @@
|
|||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_ELF_BUFFERINCR
|
||||
# define CONFIG_ELF_BUFFERINCR 32
|
||||
#ifndef CONFIG_MODULE_BUFFERINCR
|
||||
# define CONFIG_MODULE_BUFFERINCR 32
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -146,7 +146,7 @@ static int libmod_symname(FAR struct libmod_loadinfo_s *loadinfo,
|
|||
|
||||
/* No.. then we have to read more */
|
||||
|
||||
ret = libmod_reallocbuffer(loadinfo, CONFIG_ELF_BUFFERINCR);
|
||||
ret = libmod_reallocbuffer(loadinfo, CONFIG_MODULE_BUFFERINCR);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("libmod_reallocbuffer failed: %d\n", ret);
|
||||
|
|
|
@ -93,32 +93,10 @@ int libmod_unload(struct libmod_loadinfo_s *loadinfo)
|
|||
/* Clear out all indications of the allocated address environment */
|
||||
|
||||
loadinfo->textalloc = 0;
|
||||
loadinfo->dataalloc = 0;
|
||||
loadinfo->datastart = 0;
|
||||
loadinfo->textsize = 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -86,45 +86,6 @@
|
|||
* 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()
|
||||
* 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
|
||||
|
@ -145,8 +106,34 @@ struct mod_loadinfo_s
|
|||
|
||||
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
|
||||
|
@ -159,120 +146,15 @@ extern "C"
|
|||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* These are APIs exported by libelf (but are used only by the binfmt logic):
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: libmod_initialize
|
||||
* Name: insmod
|
||||
*
|
||||
* 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.
|
||||
* Verify that the file is an ELF module binary and, if so, load the
|
||||
* module into kernel memory and initialize it for use.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int libmod_initalize(FAR const char *filename,
|
||||
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);
|
||||
int insmod(FAR struct module_s *modp);
|
||||
|
||||
/****************************************************************************
|
||||
* 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,
|
||||
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
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue