From 44e45f0f91fd13cc13409e00fe44275ce9de3251 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 11 Dec 2015 10:55:21 -0600 Subject: [PATCH] insmod is code complete and ready for test --- arch | 2 +- binfmt/Kconfig | 10 ++ binfmt/Makefile | 1 + binfmt/{module.c => insmod.c} | 143 +++-------------- binfmt/libmodule/Kconfig | 10 -- binfmt/libmodule/Make.defs | 12 +- binfmt/libmodule/gnu-elf.ld | 32 ---- binfmt/libmodule/libmodule.h | 155 +++++++++++++----- binfmt/libmodule/libmodule_bind.c | 10 +- binfmt/libmodule/libmodule_ctors.c | 216 -------------------------- binfmt/libmodule/libmodule_dtors.c | 216 -------------------------- binfmt/libmodule/libmodule_init.c | 6 +- binfmt/libmodule/libmodule_iobuffer.c | 4 +- binfmt/libmodule/libmodule_load.c | 47 +----- binfmt/libmodule/libmodule_read.c | 2 + binfmt/libmodule/libmodule_sections.c | 2 +- binfmt/libmodule/libmodule_symbols.c | 6 +- binfmt/libmodule/libmodule_unload.c | 24 +-- include/nuttx/binfmt/module.h | 200 ++++-------------------- 19 files changed, 201 insertions(+), 897 deletions(-) rename binfmt/{module.c => insmod.c} (66%) delete mode 100644 binfmt/libmodule/libmodule_ctors.c delete mode 100644 binfmt/libmodule/libmodule_dtors.c diff --git a/arch b/arch index c8448d662d..ca979759a7 160000 --- a/arch +++ b/arch @@ -1 +1 @@ -Subproject commit c8448d662d63fecbbd8c603ab54cfbe2de200fe1 +Subproject commit ca979759a701c3c5e7acb8fc8c604ee112c45601 diff --git a/binfmt/Kconfig b/binfmt/Kconfig index fc2b457f89..b9263becae 100644 --- a/binfmt/Kconfig +++ b/binfmt/Kconfig @@ -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 diff --git a/binfmt/Makefile b/binfmt/Makefile index 9da55ea973..ef329e6c38 100644 --- a/binfmt/Makefile +++ b/binfmt/Makefile @@ -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 diff --git a/binfmt/module.c b/binfmt/insmod.c similarity index 66% rename from binfmt/module.c rename to binfmt/insmod.c index cbc4941fc5..b2f5094d72 100644 --- a/binfmt/module.c +++ b/binfmt/insmod.c @@ -49,7 +49,6 @@ #include #include -#include #include #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 */ diff --git a/binfmt/libmodule/Kconfig b/binfmt/libmodule/Kconfig index dd91584ec8..0e8ab2efa3 100644 --- a/binfmt/libmodule/Kconfig +++ b/binfmt/libmodule/Kconfig @@ -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. diff --git a/binfmt/libmodule/Make.defs b/binfmt/libmodule/Make.defs index e610aec6a3..2de76e6eef 100644 --- a/binfmt/libmodule/Make.defs +++ b/binfmt/libmodule/Make.defs @@ -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 diff --git a/binfmt/libmodule/gnu-elf.ld b/binfmt/libmodule/gnu-elf.ld index a471c4f097..9addca41fb 100644 --- a/binfmt/libmodule/gnu-elf.ld +++ b/binfmt/libmodule/gnu-elf.ld @@ -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 = . ; diff --git a/binfmt/libmodule/libmodule.h b/binfmt/libmodule/libmodule.h index 7636f2ff07..427e5b13aa 100644 --- a/binfmt/libmodule/libmodule.h +++ b/binfmt/libmodule/libmodule.h @@ -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 * * Redistribution and use in source and binary forms, with or without @@ -48,18 +48,125 @@ #include #include -/**************************************************************************** - * 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 */ diff --git a/binfmt/libmodule/libmodule_bind.c b/binfmt/libmodule/libmodule_bind.c index 199be22faa..0f6a09e409 100644 --- a/binfmt/libmodule/libmodule_bind.c +++ b/binfmt/libmodule/libmodule_bind.c @@ -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) diff --git a/binfmt/libmodule/libmodule_ctors.c b/binfmt/libmodule/libmodule_ctors.c deleted file mode 100644 index ea79cac7ee..0000000000 --- a/binfmt/libmodule/libmodule_ctors.c +++ /dev/null @@ -1,216 +0,0 @@ -/**************************************************************************** - * binfmt/libmodule/libmodule_ctors.c - * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include - -#include -#include - -#include "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 */ diff --git a/binfmt/libmodule/libmodule_dtors.c b/binfmt/libmodule/libmodule_dtors.c deleted file mode 100644 index 9102ceaac0..0000000000 --- a/binfmt/libmodule/libmodule_dtors.c +++ /dev/null @@ -1,216 +0,0 @@ -/**************************************************************************** - * binfmt/libmodule/libmodule_dtors.c - * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include - -#include -#include - -#include "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 */ diff --git a/binfmt/libmodule/libmodule_init.c b/binfmt/libmodule/libmodule_init.c index c5f737e36f..0d3c75b6c7 100644 --- a/binfmt/libmodule/libmodule_init.c +++ b/binfmt/libmodule/libmodule_init.c @@ -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) diff --git a/binfmt/libmodule/libmodule_iobuffer.c b/binfmt/libmodule/libmodule_iobuffer.c index 296c8c2c94..cc3d16863c 100644 --- a/binfmt/libmodule/libmodule_iobuffer.c +++ b/binfmt/libmodule/libmodule_iobuffer.c @@ -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; diff --git a/binfmt/libmodule/libmodule_load.c b/binfmt/libmodule/libmodule_load.c index 6c55f853de..d1869d5901 100644 --- a/binfmt/libmodule/libmodule_load.c +++ b/binfmt/libmodule/libmodule_load.c @@ -50,6 +50,7 @@ #include #include +#include #include #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 */ diff --git a/binfmt/libmodule/libmodule_read.c b/binfmt/libmodule/libmodule_read.c index effa0510e0..13cfc7fc93 100644 --- a/binfmt/libmodule/libmodule_read.c +++ b/binfmt/libmodule/libmodule_read.c @@ -49,6 +49,8 @@ #include +#include "libmodule.h" + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ diff --git a/binfmt/libmodule/libmodule_sections.c b/binfmt/libmodule/libmodule_sections.c index 699b3e4f75..95bc414d84 100644 --- a/binfmt/libmodule/libmodule_sections.c +++ b/binfmt/libmodule/libmodule_sections.c @@ -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); diff --git a/binfmt/libmodule/libmodule_symbols.c b/binfmt/libmodule/libmodule_symbols.c index 6482e389e1..a9b3eb8d5c 100644 --- a/binfmt/libmodule/libmodule_symbols.c +++ b/binfmt/libmodule/libmodule_symbols.c @@ -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); diff --git a/binfmt/libmodule/libmodule_unload.c b/binfmt/libmodule/libmodule_unload.c index 73822b59c6..e524dbe197 100644 --- a/binfmt/libmodule/libmodule_unload.c +++ b/binfmt/libmodule/libmodule_unload.c @@ -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; } diff --git a/include/nuttx/binfmt/module.h b/include/nuttx/binfmt/module.h index 11931f20f2..bf3a8a5fe0 100644 --- a/include/nuttx/binfmt/module.h +++ b/include/nuttx/binfmt/module.h @@ -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 *