Modules: Add mod_setsymtab to set global symtol table once. Now we can remove symbol table parameters from the insmod call. This will make implementing an NSH insmod command much easier

This commit is contained in:
Gregory Nutt
2015-12-13 08:10:01 -06:00
parent 076f382f79
commit e8d0f85c8b
17 changed files with 437 additions and 239 deletions
+2 -2
View File
@@ -42,8 +42,8 @@ CSRCS += mod_insmod.c mod_rmmod.c
# loadable module library
CSRCS += mod_bind.c mod_init.c mod_iobuffer.c mod_load.c mod_read.c
CSRCS += mod_registry.c mod_sections.c mod_symbols.c mod_uninit.c
CSRCS += mod_unload.c mod_verify.c
CSRCS += mod_registry.c mod_sections.c mod_symbols.c mod_symtab.c
CSRCS += mod_uninit.c mod_unload.c mod_verify.c
# procfs support
+7 -10
View File
@@ -98,8 +98,7 @@ static inline int mod_readrel(FAR struct mod_loadinfo_s *loadinfo,
*
****************************************************************************/
static int mod_relocate(FAR struct mod_loadinfo_s *loadinfo, int relidx,
FAR const struct symtab_s *exports, int nexports)
static int mod_relocate(FAR struct mod_loadinfo_s *loadinfo, int relidx)
{
FAR Elf32_Shdr *relsec = &loadinfo->shdr[relidx];
@@ -149,7 +148,7 @@ static int mod_relocate(FAR struct mod_loadinfo_s *loadinfo, int relidx,
/* Get the value of the symbol (in sym.st_value) */
ret = mod_symvalue(loadinfo, &sym, exports, nexports);
ret = mod_symvalue(loadinfo, &sym);
if (ret < 0)
{
/* The special error -ESRCH is returned only in one condition: The
@@ -200,8 +199,7 @@ static int mod_relocate(FAR struct mod_loadinfo_s *loadinfo, int relidx,
return OK;
}
static int mod_relocateadd(FAR struct mod_loadinfo_s *loadinfo, int relidx,
FAR const struct symtab_s *exports, int nexports)
static int mod_relocateadd(FAR struct mod_loadinfo_s *loadinfo, int relidx)
{
sdbg("Not implemented\n");
return -ENOSYS;
@@ -216,7 +214,7 @@ static int mod_relocateadd(FAR struct mod_loadinfo_s *loadinfo, int relidx,
*
* Description:
* Bind the imported symbol names in the loaded module described by
* 'loadinfo' using the exported symbol values provided by 'symtab'.
* 'loadinfo' using the exported symbol values provided by mod_setsymtab().
*
* Returned Value:
* 0 (OK) is returned on success and a negated errno is returned on
@@ -224,8 +222,7 @@ static int mod_relocateadd(FAR struct mod_loadinfo_s *loadinfo, int relidx,
*
****************************************************************************/
int mod_bind(FAR struct mod_loadinfo_s *loadinfo,
FAR const struct symtab_s *exports, int nexports)
int mod_bind(FAR struct mod_loadinfo_s *loadinfo)
{
int ret;
int i;
@@ -274,11 +271,11 @@ int mod_bind(FAR struct mod_loadinfo_s *loadinfo,
if (loadinfo->shdr[i].sh_type == SHT_REL)
{
ret = mod_relocate(loadinfo, i, exports, nexports);
ret = mod_relocate(loadinfo, i);
}
else if (loadinfo->shdr[i].sh_type == SHT_RELA)
{
ret = mod_relocateadd(loadinfo, i, exports, nexports);
ret = mod_relocateadd(loadinfo, i);
}
if (ret < 0)
+8 -6
View File
@@ -166,13 +166,16 @@ static void mod_dumpinitializer(mod_initializer_t initializer,
* Verify that the file is an ELF module binary and, if so, load the
* module into kernel memory and initialize it for use.
*
* NOTE: mod_setsymtab had to have been called in board-specific OS logic
* prior to calling this function from application logic (perhaps via
* boardctl(BOARDIOC_OS_SYMTAB). Otherwise, insmod will be unable to
* resolve symbols in the OS module.
*
* Input Parameters:
*
* filename - Full path to the module binary to be loaded
* modulename - The name that can be used to refer to the module after
* it has been loaded.
* exports - Table of exported symbols
* nexports - The number of symbols in exports[]
*
* Returned Value:
* Zero (OK) on success. On any failure, -1 (ERROR) is returned the
@@ -180,8 +183,7 @@ static void mod_dumpinitializer(mod_initializer_t initializer,
*
****************************************************************************/
int insmod(FAR const char *filename, FAR const char *modulename,
FAR const struct symtab_s *exports, int nexports)
int insmod(FAR const char *filename, FAR const char *modulename)
{
struct mod_loadinfo_s loadinfo;
FAR struct module_s *modp;
@@ -237,9 +239,9 @@ int insmod(FAR const char *filename, FAR const char *modulename,
goto errout_with_registry_entry;
}
/* Bind the program to the exported symbol table */
/* Bind the program to the kernel symbol table */
ret = mod_bind(&loadinfo, exports, nexports);
ret = mod_bind(&loadinfo);
if (ret != 0)
{
sdbg("Failed to bind symbols program binary: %d\n", ret);
+7 -4
View File
@@ -261,8 +261,7 @@ int mod_readsym(FAR struct mod_loadinfo_s *loadinfo, int index,
*
****************************************************************************/
int mod_symvalue(FAR struct mod_loadinfo_s *loadinfo, FAR Elf32_Sym *sym,
FAR const struct symtab_s *exports, int nexports)
int mod_symvalue(FAR struct mod_loadinfo_s *loadinfo, FAR Elf32_Sym *sym)
{
FAR const struct symtab_s *symbol;
uintptr_t secbase;
@@ -306,9 +305,13 @@ int mod_symvalue(FAR struct mod_loadinfo_s *loadinfo, FAR Elf32_Sym *sym,
/* Check if the base code exports a symbol of this name */
#ifdef CONFIG_SYMTAB_ORDEREDBYNAME
symbol = symtab_findorderedbyname(exports, (FAR char *)loadinfo->iobuffer, nexports);
symbol = symtab_findorderedbyname(g_mod_symtab,
(FAR char *)loadinfo->iobuffer,
g_mod_nsymbols);
#else
symbol = symtab_findbyname(exports, (FAR char *)loadinfo->iobuffer, nexports);
symbol = symtab_findbyname(g_mod_symtab,
(FAR char *)loadinfo->iobuffer,
g_mod_nsymbols);
#endif
if (!symbol)
{
+110
View File
@@ -0,0 +1,110 @@
/****************************************************************************
* sched/module/mod_symtab.c
*
* 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
* 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 <assert.h>
#include <nuttx/symtab.h>
#include <nuttx/module.h>
#include "module.h"
/****************************************************************************
* Public Data
****************************************************************************/
FAR const struct symtab_s *g_mod_symtab;
FAR int g_mod_nsymbols;
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: mod_getsymtab
*
* Description:
* Get the current kernel symbol table selection as an atomic operation.
*
* Input Parameters:
* symtab - The location to store the symbol table.
* nsymbols - The location to store the number of symbols in the symbol table.
*
* Returned Value:
* None
*
****************************************************************************/
void mod_getsymtab(FAR const struct symtab_s **symtab, FAR int *nsymbols)
{
DEBUGASSERT(symtab != NULL && nsymbols != NULL);
/* Borrow the registry lock to assure atomic access */
mod_registry_lock();
*symtab = g_mod_symtab;
*nsymbols = g_mod_nsymbols;
mod_registry_lock();
}
/****************************************************************************
* Name: mod_setsymtab
*
* Description:
* Select a new kernel symbol table selection as an atomic operation.
*
* Input Parameters:
* symtab - The new symbol table.
* nsymbols - The number of symbols in the symbol table.
*
* Returned Value:
* None
*
****************************************************************************/
void mod_setsymtab(FAR const struct symtab_s *symtab, int nsymbols)
{
/* Borrow the registry lock to assure atomic access */
mod_registry_lock();
g_mod_symtab = symtab;
g_mod_nsymbols = nsymbols;
mod_registry_lock();
}
+10 -8
View File
@@ -99,6 +99,13 @@ struct mod_loadinfo_s
int filfd; /* Descriptor for the file being loaded */
};
/****************************************************************************
* Public Data
****************************************************************************/
FAR const struct symtab_s *g_mod_symtab;
FAR int g_mod_nsymbols;
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
@@ -154,7 +161,7 @@ int mod_load(FAR struct mod_loadinfo_s *loadinfo);
*
* Description:
* Bind the imported symbol names in the loaded module described by
* 'loadinfo' using the exported symbol values provided by 'symtab'.
* 'loadinfo' using the exported symbol values provided by mod_setsymtab().
*
* Returned Value:
* 0 (OK) is returned on success and a negated errno is returned on
@@ -162,9 +169,7 @@ int mod_load(FAR struct mod_loadinfo_s *loadinfo);
*
****************************************************************************/
struct symtab_s;
int mod_bind(FAR struct mod_loadinfo_s *loadinfo,
FAR const struct symtab_s *exports, int nexports);
int mod_bind(FAR struct mod_loadinfo_s *loadinfo);
/****************************************************************************
* Name: mod_unload
@@ -290,8 +295,6 @@ int mod_readsym(FAR struct mod_loadinfo_s *loadinfo, int index,
* Input Parameters:
* loadinfo - Load state information
* sym - Symbol table entry (value might be undefined)
* exports - The symbol table to use for resolving undefined symbols.
* nexports - Number of symbols in the symbol table.
*
* Returned Value:
* 0 (OK) is returned on success and a negated errno is returned on
@@ -305,8 +308,7 @@ int mod_readsym(FAR struct mod_loadinfo_s *loadinfo, int index,
*
****************************************************************************/
int mod_symvalue(FAR struct mod_loadinfo_s *loadinfo, FAR Elf32_Sym *sym,
FAR const struct symtab_s *exports, int nexports);
int mod_symvalue(FAR struct mod_loadinfo_s *loadinfo, FAR Elf32_Sym *sym);
/****************************************************************************
* Name: mod_freebuffers