mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 08:36:24 +08:00
Modules: Move next five of many C files from sched/module to libc/modlib
This commit is contained in:
@@ -41,7 +41,6 @@ CSRCS += mod_insmod.c mod_rmmod.c mod_modsym.c mod_symtab.c mod_modhandle.c
|
||||
|
||||
# Loadable module library
|
||||
|
||||
CSRCS += mod_iobuffer.c mod_load.c mod_read.c mod_sections.c mod_symbols.c
|
||||
CSRCS += mod_unload.c mod_verify.c
|
||||
|
||||
# procfs support
|
||||
|
||||
@@ -233,7 +233,7 @@ FAR void *insmod(FAR const char *filename, FAR const char *modulename)
|
||||
|
||||
/* Load the program binary */
|
||||
|
||||
ret = mod_load(&loadinfo);
|
||||
ret = modlib_load(&loadinfo);
|
||||
mod_dumploadinfo(&loadinfo);
|
||||
if (ret != 0)
|
||||
{
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
/****************************************************************************
|
||||
* sched/module/mod_iobuffer.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 <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/module.h>
|
||||
#include <nuttx/lib/modlib.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_allocbuffer
|
||||
*
|
||||
* Description:
|
||||
* Perform the initial allocation of the I/O buffer, if it has not already
|
||||
* been allocated.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mod_allocbuffer(FAR struct mod_loadinfo_s *loadinfo)
|
||||
{
|
||||
/* Has a buffer been allocated> */
|
||||
|
||||
if (!loadinfo->iobuffer)
|
||||
{
|
||||
/* No.. allocate one now */
|
||||
|
||||
loadinfo->iobuffer = (FAR uint8_t *)kmm_malloc(CONFIG_MODLIB_BUFFERSIZE);
|
||||
if (!loadinfo->iobuffer)
|
||||
{
|
||||
serr("ERROR: Failed to allocate an I/O buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
loadinfo->buflen = CONFIG_MODLIB_BUFFERSIZE;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_reallocbuffer
|
||||
*
|
||||
* Description:
|
||||
* Increase the size of I/O buffer by the specified buffer increment.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mod_reallocbuffer(FAR struct mod_loadinfo_s *loadinfo, size_t increment)
|
||||
{
|
||||
FAR void *buffer;
|
||||
size_t newsize;
|
||||
|
||||
/* Get the new size of the allocation */
|
||||
|
||||
newsize = loadinfo->buflen + increment;
|
||||
|
||||
/* And perform the reallocation */
|
||||
|
||||
buffer = kmm_realloc((FAR void *)loadinfo->iobuffer, newsize);
|
||||
if (!buffer)
|
||||
{
|
||||
serr("ERROR: Failed to reallocate the I/O buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Save the new buffer info */
|
||||
|
||||
loadinfo->iobuffer = buffer;
|
||||
loadinfo->buflen = newsize;
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -1,290 +0,0 @@
|
||||
/****************************************************************************
|
||||
* sched/module/mod_load.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 <sys/types.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <elf32.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/module.h>
|
||||
#include <nuttx/lib/modlib.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define ELF_ALIGN_MASK ((1 << CONFIG_MODLIB_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)
|
||||
|
||||
#ifndef MAX
|
||||
# define MAX(x,y) ((x) > (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
# define MIN(x,y) ((x) < (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_elfsize
|
||||
*
|
||||
* Description:
|
||||
* Calculate total memory allocation for the ELF file.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void mod_elfsize(struct mod_loadinfo_s *loadinfo)
|
||||
{
|
||||
size_t textsize;
|
||||
size_t datasize;
|
||||
int i;
|
||||
|
||||
/* Accumulate the size each section into memory that is marked SHF_ALLOC */
|
||||
|
||||
textsize = 0;
|
||||
datasize = 0;
|
||||
|
||||
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
||||
{
|
||||
FAR Elf32_Shdr *shdr = &loadinfo->shdr[i];
|
||||
|
||||
/* SHF_ALLOC indicates that the section requires memory during
|
||||
* execution.
|
||||
*/
|
||||
|
||||
if ((shdr->sh_flags & SHF_ALLOC) != 0)
|
||||
{
|
||||
/* SHF_WRITE indicates that the section address space is write-
|
||||
* able
|
||||
*/
|
||||
|
||||
if ((shdr->sh_flags & SHF_WRITE) != 0)
|
||||
{
|
||||
datasize += ELF_ALIGNUP(shdr->sh_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
textsize += ELF_ALIGNUP(shdr->sh_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Save the allocation size */
|
||||
|
||||
loadinfo->textsize = textsize;
|
||||
loadinfo->datasize = datasize;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_loadfile
|
||||
*
|
||||
* Description:
|
||||
* Read the section data into memory. Section addresses in the shdr[] are
|
||||
* updated to point to the corresponding position in the memory.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline int mod_loadfile(FAR struct mod_loadinfo_s *loadinfo)
|
||||
{
|
||||
FAR uint8_t *text;
|
||||
FAR uint8_t *data;
|
||||
FAR uint8_t **pptr;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* Read each section into memory that is marked SHF_ALLOC + SHT_NOBITS */
|
||||
|
||||
sinfo("Loaded sections:\n");
|
||||
text = (FAR uint8_t *)loadinfo->textalloc;
|
||||
data = (FAR uint8_t *)loadinfo->datastart;
|
||||
|
||||
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
||||
{
|
||||
FAR Elf32_Shdr *shdr = &loadinfo->shdr[i];
|
||||
|
||||
/* SHF_ALLOC indicates that the section requires memory during
|
||||
* execution */
|
||||
|
||||
if ((shdr->sh_flags & SHF_ALLOC) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* SHF_WRITE indicates that the section address space is write-
|
||||
* able
|
||||
*/
|
||||
|
||||
if ((shdr->sh_flags & SHF_WRITE) != 0)
|
||||
{
|
||||
pptr = &data;
|
||||
}
|
||||
else
|
||||
{
|
||||
pptr = &text;
|
||||
}
|
||||
|
||||
/* SHT_NOBITS indicates that there is no data in the file for the
|
||||
* section.
|
||||
*/
|
||||
|
||||
if (shdr->sh_type != SHT_NOBITS)
|
||||
{
|
||||
/* Read the section data from sh_offset to the memory region */
|
||||
|
||||
ret = mod_read(loadinfo, *pptr, shdr->sh_size, shdr->sh_offset);
|
||||
if (ret < 0)
|
||||
{
|
||||
serr("ERROR: Failed to read section %d: %d\n", i, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* If there is no data in an allocated section, then the allocated
|
||||
* section must be cleared.
|
||||
*/
|
||||
|
||||
else
|
||||
{
|
||||
memset(*pptr, 0, shdr->sh_size);
|
||||
}
|
||||
|
||||
/* Update sh_addr to point to copy in memory */
|
||||
|
||||
sinfo("%d. %08lx->%08lx\n", i,
|
||||
(unsigned long)shdr->sh_addr, (unsigned long)*pptr);
|
||||
|
||||
shdr->sh_addr = (uintptr_t)*pptr;
|
||||
|
||||
/* Setup the memory pointer for the next time through the loop */
|
||||
|
||||
*pptr += ELF_ALIGNUP(shdr->sh_size);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* 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)
|
||||
{
|
||||
int ret;
|
||||
|
||||
sinfo("loadinfo: %p\n", loadinfo);
|
||||
DEBUGASSERT(loadinfo && loadinfo->filfd >= 0);
|
||||
|
||||
/* Load section headers into memory */
|
||||
|
||||
ret = mod_loadshdrs(loadinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
serr("ERROR: mod_loadshdrs failed: %d\n", ret);
|
||||
goto errout_with_buffers;
|
||||
}
|
||||
|
||||
/* Determine total size to allocate */
|
||||
|
||||
mod_elfsize(loadinfo);
|
||||
|
||||
/* Allocate (and zero) memory for the ELF file. */
|
||||
|
||||
/* Allocate memory to hold the ELF image */
|
||||
|
||||
loadinfo->textalloc = (uintptr_t)kmm_zalloc(loadinfo->textsize + loadinfo->datasize);
|
||||
if (!loadinfo->textalloc)
|
||||
{
|
||||
serr("ERROR: Failed to allocate memory for the module\n");
|
||||
ret = -ENOMEM;
|
||||
goto errout_with_buffers;
|
||||
}
|
||||
|
||||
loadinfo->datastart = loadinfo->textalloc + loadinfo->textsize;
|
||||
|
||||
/* Load ELF section data into memory */
|
||||
|
||||
ret = mod_loadfile(loadinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
serr("ERROR: mod_loadfile failed: %d\n", ret);
|
||||
goto errout_with_buffers;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
/* Error exits */
|
||||
|
||||
errout_with_buffers:
|
||||
mod_unload(loadinfo);
|
||||
return ret;
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
/****************************************************************************
|
||||
* sched/module/mod_read.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 <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <elf32.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/module.h>
|
||||
#include <nuttx/lib/modlib.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#undef ELF_DUMP_READDATA /* Define to dump all file data read */
|
||||
|
||||
/****************************************************************************
|
||||
* Private Constant Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_dumpreaddata
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(ELF_DUMP_READDATA)
|
||||
static inline void mod_dumpreaddata(FAR char *buffer, int buflen)
|
||||
{
|
||||
FAR uint32_t *buf32 = (FAR uint32_t *)buffer;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
for (i = 0; i < buflen; i += 32)
|
||||
{
|
||||
syslog(LOG_DEBUG, "%04x:", i);
|
||||
for (j = 0; j < 32; j += sizeof(uint32_t))
|
||||
{
|
||||
syslog(LOG_DEBUG, " %08x", *buf32++);
|
||||
}
|
||||
|
||||
syslog(LOG_DEBUG, "\n");
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define mod_dumpreaddata(b,n)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_read
|
||||
*
|
||||
* Description:
|
||||
* Read 'readsize' bytes from the object file at 'offset'. The data is
|
||||
* read into 'buffer.'
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mod_read(FAR struct mod_loadinfo_s *loadinfo, FAR uint8_t *buffer,
|
||||
size_t readsize, off_t offset)
|
||||
{
|
||||
ssize_t nbytes; /* Number of bytes read */
|
||||
off_t rpos; /* Position returned by lseek */
|
||||
|
||||
sinfo("Read %ld bytes from offset %ld\n", (long)readsize, (long)offset);
|
||||
|
||||
/* Loop until all of the requested data has been read. */
|
||||
|
||||
while (readsize > 0)
|
||||
{
|
||||
/* Seek to the next read position */
|
||||
|
||||
rpos = lseek(loadinfo->filfd, offset, SEEK_SET);
|
||||
if (rpos != offset)
|
||||
{
|
||||
int errval = errno;
|
||||
serr("ERROR: Failed to seek to position %lu: %d\n",
|
||||
(unsigned long)offset, errval);
|
||||
return -errval;
|
||||
}
|
||||
|
||||
/* Read the file data at offset into the user buffer */
|
||||
|
||||
nbytes = read(loadinfo->filfd, buffer, readsize);
|
||||
if (nbytes < 0)
|
||||
{
|
||||
int errval = errno;
|
||||
|
||||
/* EINTR just means that we received a signal */
|
||||
|
||||
if (errval != EINTR)
|
||||
{
|
||||
serr("ERROR: Read from offset %lu failed: %d\n",
|
||||
(unsigned long)offset, errval);
|
||||
return -errval;
|
||||
}
|
||||
}
|
||||
else if (nbytes == 0)
|
||||
{
|
||||
serr("ERROR: Unexpected end of file\n");
|
||||
return -ENODATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
readsize -= nbytes;
|
||||
buffer += nbytes;
|
||||
offset += nbytes;
|
||||
}
|
||||
}
|
||||
|
||||
mod_dumpreaddata(buffer, readsize);
|
||||
return OK;
|
||||
}
|
||||
@@ -1,278 +0,0 @@
|
||||
/****************************************************************************
|
||||
* sched/module/mod_sections.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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/module.h>
|
||||
#include <nuttx/lib/modlib.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_sectname
|
||||
*
|
||||
* Description:
|
||||
* Get the symbol name in loadinfo->iobuffer[].
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline int mod_sectname(FAR struct mod_loadinfo_s *loadinfo,
|
||||
FAR const Elf32_Shdr *shdr)
|
||||
{
|
||||
FAR Elf32_Shdr *shstr;
|
||||
FAR uint8_t *buffer;
|
||||
off_t offset;
|
||||
size_t readlen;
|
||||
size_t bytesread;
|
||||
int shstrndx;
|
||||
int ret;
|
||||
|
||||
/* Get the section header table index of the entry associated with the
|
||||
* section name string table. If the file has no section name string table,
|
||||
* this member holds the value SH_UNDEF.
|
||||
*/
|
||||
|
||||
shstrndx = loadinfo->ehdr.e_shstrndx;
|
||||
if (shstrndx == SHN_UNDEF)
|
||||
{
|
||||
serr("ERROR: No section header string table\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Get the section name string table section header */
|
||||
|
||||
shstr = &loadinfo->shdr[shstrndx];
|
||||
|
||||
/* Get the file offset to the string that is the name of the section. This
|
||||
* is the sum of:
|
||||
*
|
||||
* shstr->sh_offset: The file offset to the first byte of the section
|
||||
* header string table data.
|
||||
* shdr->sh_name: The offset to the name of the section in the section
|
||||
* name table
|
||||
*/
|
||||
|
||||
offset = shstr->sh_offset + shdr->sh_name;
|
||||
|
||||
/* Loop until we get the entire section name into memory */
|
||||
|
||||
buffer = loadinfo->iobuffer;
|
||||
bytesread = 0;
|
||||
|
||||
for (; ; )
|
||||
{
|
||||
/* Get the number of bytes to read */
|
||||
|
||||
readlen = loadinfo->buflen - bytesread;
|
||||
if (offset + readlen > loadinfo->filelen)
|
||||
{
|
||||
if (loadinfo->filelen <= offset)
|
||||
{
|
||||
serr("ERROR: At end of file\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
readlen = loadinfo->filelen - offset;
|
||||
}
|
||||
|
||||
/* Read that number of bytes into the array */
|
||||
|
||||
buffer = &loadinfo->iobuffer[bytesread];
|
||||
ret = mod_read(loadinfo, buffer, readlen, offset);
|
||||
if (ret < 0)
|
||||
{
|
||||
serr("ERROR: Failed to read section name: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bytesread += readlen;
|
||||
|
||||
/* Did we read the NUL terminator? */
|
||||
|
||||
if (memchr(buffer, '\0', readlen) != NULL)
|
||||
{
|
||||
/* Yes, the buffer contains a NUL terminator. */
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* No.. then we have to read more */
|
||||
|
||||
ret = mod_reallocbuffer(loadinfo, CONFIG_MODLIB_BUFFERINCR);
|
||||
if (ret < 0)
|
||||
{
|
||||
serr("ERROR: mod_reallocbuffer failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* We will not get here */
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_loadshdrs
|
||||
*
|
||||
* Description:
|
||||
* Loads section headers into memory.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mod_loadshdrs(FAR struct mod_loadinfo_s *loadinfo)
|
||||
{
|
||||
size_t shdrsize;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(loadinfo->shdr == NULL);
|
||||
|
||||
/* Verify that there are sections */
|
||||
|
||||
if (loadinfo->ehdr.e_shnum < 1)
|
||||
{
|
||||
serr("ERROR: No sections(?)\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Get the total size of the section header table */
|
||||
|
||||
shdrsize = (size_t)loadinfo->ehdr.e_shentsize * (size_t)loadinfo->ehdr.e_shnum;
|
||||
if (loadinfo->ehdr.e_shoff + shdrsize > loadinfo->filelen)
|
||||
{
|
||||
serr("ERROR: Insufficent space in file for section header table\n");
|
||||
return -ESPIPE;
|
||||
}
|
||||
|
||||
/* Allocate memory to hold a working copy of the sector header table */
|
||||
|
||||
loadinfo->shdr = (FAR FAR Elf32_Shdr *)kmm_malloc(shdrsize);
|
||||
if (!loadinfo->shdr)
|
||||
{
|
||||
serr("ERROR: Failed to allocate the section header table. Size: %ld\n",
|
||||
(long)shdrsize);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Read the section header table into memory */
|
||||
|
||||
ret = mod_read(loadinfo, (FAR uint8_t *)loadinfo->shdr, shdrsize,
|
||||
loadinfo->ehdr.e_shoff);
|
||||
if (ret < 0)
|
||||
{
|
||||
serr("ERROR: Failed to read section header table: %d\n", ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_findsection
|
||||
*
|
||||
* Description:
|
||||
* A section by its name.
|
||||
*
|
||||
* Input Parameters:
|
||||
* loadinfo - Load state information
|
||||
* sectname - Name of the section to find
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, the index to the section is returned; A negated errno value
|
||||
* is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mod_findsection(FAR struct mod_loadinfo_s *loadinfo,
|
||||
FAR const char *sectname)
|
||||
{
|
||||
FAR const Elf32_Shdr *shdr;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* Search through the shdr[] array in loadinfo for a section named 'sectname' */
|
||||
|
||||
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
||||
{
|
||||
/* Get the name of this section */
|
||||
|
||||
shdr = &loadinfo->shdr[i];
|
||||
ret = mod_sectname(loadinfo, shdr);
|
||||
if (ret < 0)
|
||||
{
|
||||
serr("ERROR: mod_sectname failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Check if the name of this section is 'sectname' */
|
||||
|
||||
sinfo("%d. Comparing \"%s\" and .\"%s\"\n",
|
||||
i, loadinfo->iobuffer, sectname);
|
||||
|
||||
if (strcmp((FAR const char *)loadinfo->iobuffer, sectname) == 0)
|
||||
{
|
||||
/* We found it... return the index */
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
/* We failed to find a section with this name. */
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
@@ -1,441 +0,0 @@
|
||||
/****************************************************************************
|
||||
* sched/module/mod_symbols.c
|
||||
*
|
||||
* Copyright (C) 2015, 2017 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <elf32.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/module.h>
|
||||
#include <nuttx/lib/modlib.h>
|
||||
#include <nuttx/binfmt/symtab.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Amount to reallocate buffer when buffer is full */
|
||||
|
||||
#ifndef CONFIG_MODLIB_BUFFERINCR
|
||||
# define CONFIG_MODLIB_BUFFERINCR 32
|
||||
#endif
|
||||
|
||||
/* Return values search for exported modules */
|
||||
|
||||
#define SYM_NOT_FOUND 0
|
||||
#define SYM_FOUND 1
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct mod_exportinfo_s
|
||||
{
|
||||
FAR const char *name; /* Symbol name to find */
|
||||
FAR struct module_s *modp; /* The module that needs the symbol */
|
||||
FAR const struct symtab_s *symbol; /* Symbol info returned (if found) */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_symname
|
||||
*
|
||||
* Description:
|
||||
* Get the symbol name in loadinfo->iobuffer[].
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
* EINVAL - There is something inconsistent in the symbol table (should only
|
||||
* happen if the file is corrupted).
|
||||
* ESRCH - Symbol has no name
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int mod_symname(FAR struct mod_loadinfo_s *loadinfo,
|
||||
FAR const Elf32_Sym *sym)
|
||||
{
|
||||
FAR uint8_t *buffer;
|
||||
off_t offset;
|
||||
size_t readlen;
|
||||
size_t bytesread;
|
||||
int ret;
|
||||
|
||||
/* Get the file offset to the string that is the name of the symbol. The
|
||||
* st_name member holds an offset into the file's symbol string table.
|
||||
*/
|
||||
|
||||
if (sym->st_name == 0)
|
||||
{
|
||||
serr("ERROR: Symbol has no name\n");
|
||||
return -ESRCH;
|
||||
}
|
||||
|
||||
offset = loadinfo->shdr[loadinfo->strtabidx].sh_offset + sym->st_name;
|
||||
|
||||
/* Loop until we get the entire symbol name into memory */
|
||||
|
||||
bytesread = 0;
|
||||
|
||||
for (; ; )
|
||||
{
|
||||
/* Get the number of bytes to read */
|
||||
|
||||
readlen = loadinfo->buflen - bytesread;
|
||||
if (offset + readlen > loadinfo->filelen)
|
||||
{
|
||||
if (loadinfo->filelen <= offset)
|
||||
{
|
||||
serr("ERROR: At end of file\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
readlen = loadinfo->filelen - offset;
|
||||
}
|
||||
|
||||
/* Read that number of bytes into the array */
|
||||
|
||||
buffer = &loadinfo->iobuffer[bytesread];
|
||||
ret = mod_read(loadinfo, buffer, readlen, offset);
|
||||
if (ret < 0)
|
||||
{
|
||||
serr("ERROR: mod_read failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bytesread += readlen;
|
||||
|
||||
/* Did we read the NUL terminator? */
|
||||
|
||||
if (memchr(buffer, '\0', readlen) != NULL)
|
||||
{
|
||||
/* Yes, the buffer contains a NUL terminator. */
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* No.. then we have to read more */
|
||||
|
||||
ret = mod_reallocbuffer(loadinfo, CONFIG_MODLIB_BUFFERINCR);
|
||||
if (ret < 0)
|
||||
{
|
||||
serr("ERROR: mod_reallocbuffer failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* We will not get here */
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_symcallback
|
||||
*
|
||||
* Description:
|
||||
* modlib_registry_foreach() callback function. Test if the provided module,
|
||||
* modp, exports the symbol of interest. If so, return that symbol value
|
||||
* and setup the module dependency relationship.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int mod_symcallback(FAR struct module_s *modp, FAR void *arg)
|
||||
{
|
||||
FAR struct mod_exportinfo_s *exportinfo = (FAR struct mod_exportinfo_s *)arg;
|
||||
int ret;
|
||||
|
||||
/* Check if this module exports a symbol of that name */
|
||||
|
||||
#ifdef CONFIG_SYMTAB_ORDEREDBYNAME
|
||||
exportinfo->symbol = symtab_findorderedbyname(modp->modinfo.exports,
|
||||
exportinfo->name,
|
||||
modp->modinfo.nexports);
|
||||
#else
|
||||
exportinfo->symbol = symtab_findbyname(modp->modinfo.exports,
|
||||
exportinfo->name,
|
||||
modp->modinfo.nexports);
|
||||
#endif
|
||||
|
||||
if (exportinfo->symbol != NULL)
|
||||
{
|
||||
/* Yes.. save the dependency relationship and return SYM_FOUND to
|
||||
* stop the traversal.
|
||||
*/
|
||||
|
||||
ret = modlib_depend(exportinfo->modp, modp);
|
||||
if (ret < 0)
|
||||
{
|
||||
serr("ERROR: modlib_depend failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return SYM_FOUND;
|
||||
}
|
||||
|
||||
return SYM_NOT_FOUND;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_findsymtab
|
||||
*
|
||||
* Description:
|
||||
* Find the symbol table section.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mod_findsymtab(FAR struct mod_loadinfo_s *loadinfo)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Find the symbol table section header and its associated string table */
|
||||
|
||||
for (i = 1; i < loadinfo->ehdr.e_shnum; i++)
|
||||
{
|
||||
if (loadinfo->shdr[i].sh_type == SHT_SYMTAB)
|
||||
{
|
||||
loadinfo->symtabidx = i;
|
||||
loadinfo->strtabidx = loadinfo->shdr[i].sh_link;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Verify that there is a symbol and string table */
|
||||
|
||||
if (loadinfo->symtabidx == 0)
|
||||
{
|
||||
serr("ERROR: No symbols in ELF file\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_readsym
|
||||
*
|
||||
* Description:
|
||||
* Read the ELFT symbol structure at the specfied index into memory.
|
||||
*
|
||||
* Input Parameters:
|
||||
* loadinfo - Load state information
|
||||
* index - Symbol table index
|
||||
* sym - Location to return the table entry
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mod_readsym(FAR struct mod_loadinfo_s *loadinfo, int index,
|
||||
FAR Elf32_Sym *sym)
|
||||
{
|
||||
FAR Elf32_Shdr *symtab = &loadinfo->shdr[loadinfo->symtabidx];
|
||||
off_t offset;
|
||||
|
||||
/* Verify that the symbol table index lies within symbol table */
|
||||
|
||||
if (index < 0 || index > (symtab->sh_size / sizeof(Elf32_Sym)))
|
||||
{
|
||||
serr("ERROR: Bad relocation symbol index: %d\n", index);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Get the file offset to the symbol table entry */
|
||||
|
||||
offset = symtab->sh_offset + sizeof(Elf32_Sym) * index;
|
||||
|
||||
/* And, finally, read the symbol table entry into memory */
|
||||
|
||||
return mod_read(loadinfo, (FAR uint8_t *)sym, sizeof(Elf32_Sym), offset);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_symvalue
|
||||
*
|
||||
* Description:
|
||||
* Get the value of a symbol. The updated value of the symbol is returned
|
||||
* in the st_value field of the symbol table entry.
|
||||
*
|
||||
* Input Parameters:
|
||||
* modp - Module state information
|
||||
* loadinfo - Load state information
|
||||
* sym - Symbol table entry (value might be undefined)
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
* EINVAL - There is something inconsistent in the symbol table (should only
|
||||
* happen if the file is corrupted).
|
||||
* ENOSYS - Symbol lies in common
|
||||
* ESRCH - Symbol has no name
|
||||
* ENOENT - Symbol undefined and not provided via a symbol table
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mod_symvalue(FAR struct module_s *modp,
|
||||
FAR struct mod_loadinfo_s *loadinfo, FAR Elf32_Sym *sym)
|
||||
{
|
||||
FAR const struct symtab_s *symbol;
|
||||
struct mod_exportinfo_s exportinfo;
|
||||
uintptr_t secbase;
|
||||
int ret;
|
||||
|
||||
switch (sym->st_shndx)
|
||||
{
|
||||
case SHN_COMMON:
|
||||
{
|
||||
/* NuttX ELF modules should be compiled with -fno-common. */
|
||||
|
||||
serr("ERROR: SHN_COMMON: Re-compile with -fno-common\n");
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
case SHN_ABS:
|
||||
{
|
||||
/* st_value already holds the correct value */
|
||||
|
||||
sinfo("SHN_ABS: st_value=%08lx\n", (long)sym->st_value);
|
||||
return OK;
|
||||
}
|
||||
|
||||
case SHN_UNDEF:
|
||||
{
|
||||
/* Get the name of the undefined symbol */
|
||||
|
||||
ret = mod_symname(loadinfo, sym);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* There are a few relocations for a few architectures that do
|
||||
* no depend upon a named symbol. We don't know if that is the
|
||||
* case here, but return and special error to the caller to
|
||||
* indicate the nameless symbol.
|
||||
*/
|
||||
|
||||
serr("ERROR: SHN_UNDEF: Failed to get symbol name: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* First check if the symbol is exported by an installed module.
|
||||
* Newest modules are installed at the head of the list. Therefore,
|
||||
* if the symbol is exported by numerous modules, then the most
|
||||
* recently installed will take precedence.
|
||||
*/
|
||||
|
||||
exportinfo.name = (FAR const char *)loadinfo->iobuffer;
|
||||
exportinfo.modp = modp;
|
||||
exportinfo.symbol = NULL;
|
||||
|
||||
ret = modlib_registry_foreach(mod_symcallback, (FAR void *)&exportinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
serr("ERROR: mod_symcallback failed: \n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
symbol = exportinfo.symbol;
|
||||
|
||||
/* If the symbol is not exported by any module, then check if the
|
||||
* base code exports a symbol of this name.
|
||||
*/
|
||||
|
||||
if (symbol == NULL)
|
||||
{
|
||||
#ifdef CONFIG_SYMTAB_ORDEREDBYNAME
|
||||
symbol = symtab_findorderedbyname(g_mod_symtab, exportinfo.name,
|
||||
g_mod_nsymbols);
|
||||
#else
|
||||
symbol = symtab_findbyname(g_mod_symtab, exportinfo.name,
|
||||
g_mod_nsymbols);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Was the symbol found from any exporter? */
|
||||
|
||||
if (symbol == NULL)
|
||||
{
|
||||
serr("ERROR: SHN_UNDEF: Exported symbol \"%s\" not found\n",
|
||||
loadinfo->iobuffer);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* Yes... add the exported symbol value to the ELF symbol table entry */
|
||||
|
||||
sinfo("SHN_ABS: name=%s %08x+%08x=%08x\n",
|
||||
loadinfo->iobuffer, sym->st_value, symbol->sym_value,
|
||||
sym->st_value + symbol->sym_value);
|
||||
|
||||
sym->st_value += (Elf32_Word)((uintptr_t)symbol->sym_value);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
secbase = loadinfo->shdr[sym->st_shndx].sh_addr;
|
||||
|
||||
sinfo("Other: %08x+%08x=%08x\n",
|
||||
sym->st_value, secbase, sym->st_value + secbase);
|
||||
|
||||
sym->st_value += secbase;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
@@ -55,7 +55,7 @@
|
||||
*
|
||||
* Description:
|
||||
* This function unloads the object from memory. This essentially undoes
|
||||
* the actions of mod_load. It is called only under certain error
|
||||
* the actions of modlib_load(). It is called only under certain error
|
||||
* conditions after the module has been loaded but not yet started.
|
||||
*
|
||||
* Returned Value:
|
||||
|
||||
Reference in New Issue
Block a user