mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-04-14 10:07:39 +08:00
Add back some (currently unused) files lost in an earlier NuttX merge
This commit is contained in:
parent
2f7a7ccf0a
commit
e7bbe685b4
40
nuttx/binfmt/libelf/Kconfig
Normal file
40
nuttx/binfmt/libelf/Kconfig
Normal file
@ -0,0 +1,40 @@
|
||||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see misc/tools/kconfig-language.txt.
|
||||
#
|
||||
|
||||
config ELF_ALIGN_LOG2
|
||||
int "Log2 Section Alignment"
|
||||
default 2
|
||||
---help---
|
||||
Align all sections to this Log2 value: 0->1, 1->2, 2->4, etc.
|
||||
|
||||
config ELF_STACKSIZE
|
||||
int "ELF Stack Size"
|
||||
default 2048
|
||||
---help---
|
||||
This is the default stack size that will will be used when starting ELF binaries.
|
||||
|
||||
config ELF_BUFFERSIZE
|
||||
int "ELF I/O Buffer Size"
|
||||
default 128
|
||||
---help---
|
||||
This is an I/O buffer that is used to access the ELF file. Variable length items
|
||||
will need to be read (such as symbol names). This is really just this initial
|
||||
size of the buffer; it will be reallocated as necessary to hold large symbol
|
||||
names). Default: 128
|
||||
|
||||
config ELF_BUFFERINCR
|
||||
int "ELF I/O Buffer Realloc Increment"
|
||||
default 32
|
||||
---help---
|
||||
This is an I/O buffer that is used to access the ELF file. Variable length items
|
||||
will need to be read (such as symbol names). This value specifies the size
|
||||
increment to use each time the buffer is reallocated. Default: 32
|
||||
|
||||
config ELF_DUMPBUFFER
|
||||
bool "Dump ELF buffers"
|
||||
default n
|
||||
depends on DEBUG && DEBUG_VERBOSE
|
||||
---help---
|
||||
Dump various ELF buffers for debug purposes
|
||||
129
nuttx/binfmt/libelf/gnu-elf.ld
Normal file
129
nuttx/binfmt/libelf/gnu-elf.ld
Normal file
@ -0,0 +1,129 @@
|
||||
/****************************************************************************
|
||||
* binfmt/libelf/gnu-elf.ld
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text 0x00000000 :
|
||||
{
|
||||
_stext = . ;
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.warning)
|
||||
*(.stub)
|
||||
*(.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 = . ;
|
||||
}
|
||||
|
||||
.rodata :
|
||||
{
|
||||
_srodata = . ;
|
||||
*(.rodata)
|
||||
*(.rodata1)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r*)
|
||||
_erodata = . ;
|
||||
}
|
||||
|
||||
.data :
|
||||
{
|
||||
_sdata = . ;
|
||||
*(.data)
|
||||
*(.data1)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d*)
|
||||
_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 */
|
||||
_edtors = . ;
|
||||
}
|
||||
|
||||
.dtors :
|
||||
{
|
||||
_sdtors = . ;
|
||||
*(.dtors) /* Old ABI: Unallocated */
|
||||
*(.fini_array) /* New ABI: Allocated */
|
||||
_edtors = . ;
|
||||
}
|
||||
|
||||
.bss :
|
||||
{
|
||||
_sbss = . ;
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.gnu.linkonce.b*)
|
||||
*(COMMON)
|
||||
_ebss = . ;
|
||||
}
|
||||
|
||||
/* Stabs debugging sections. */
|
||||
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
}
|
||||
215
nuttx/binfmt/libelf/libelf_ctors.c
Normal file
215
nuttx/binfmt/libelf/libelf_ctors.c
Normal file
@ -0,0 +1,215 @@
|
||||
/****************************************************************************
|
||||
* binfmt/libelf/libelf_ctors.c
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/binfmt/elf.h>
|
||||
|
||||
#include "libelf.h"
|
||||
|
||||
#ifdef CONFIG_BINFMT_CONSTRUCTORS
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-Processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Constant Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_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 elf_loadctors(FAR struct elf_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
|
||||
* elf_sectname() to accumulate the variable length symbol name.
|
||||
*/
|
||||
|
||||
ret = elf_allocbuffer(loadinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("elf_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 = elf_findsection(loadinfo, ".ctors");
|
||||
if (ctoridx < 0)
|
||||
{
|
||||
/* This may not be a failure. -ENOENT indicates that the file has no
|
||||
* static constructor section.
|
||||
*/
|
||||
|
||||
bvdbg("elf_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*)kmalloc(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 = elf_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, loadinfo->elfalloc, *ptr + loadinfo->elfalloc);
|
||||
|
||||
*ptr += loadinfo->elfalloc;
|
||||
}
|
||||
}
|
||||
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 */
|
||||
215
nuttx/binfmt/libelf/libelf_dtors.c
Normal file
215
nuttx/binfmt/libelf/libelf_dtors.c
Normal file
@ -0,0 +1,215 @@
|
||||
/****************************************************************************
|
||||
* binfmt/libelf/libelf_dtors.c
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/binfmt/elf.h>
|
||||
|
||||
#include "libelf.h"
|
||||
|
||||
#ifdef CONFIG_BINFMT_CONSTRUCTORS
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-Processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Constant Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_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 elf_loaddtors(FAR struct elf_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
|
||||
* elf_sectname() to accumulate the variable length symbol name.
|
||||
*/
|
||||
|
||||
ret = elf_allocbuffer(loadinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("elf_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 = elf_findsection(loadinfo, ".dtors");
|
||||
if (dtoridx < 0)
|
||||
{
|
||||
/* This may not be a failure. -ENOENT indicates that the file has no
|
||||
* static destructor section.
|
||||
*/
|
||||
|
||||
bvdbg("elf_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*)kmalloc(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 = elf_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, loadinfo->elfalloc, *ptr + loadinfo->elfalloc);
|
||||
|
||||
*ptr += loadinfo->elfalloc;
|
||||
}
|
||||
}
|
||||
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 */
|
||||
202
nuttx/binfmt/libelf/libelf_init.c
Normal file
202
nuttx/binfmt/libelf/libelf_init.c
Normal file
@ -0,0 +1,202 @@
|
||||
/****************************************************************************
|
||||
* binfmt/libelf/libelf_init.c
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <elf32.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/binfmt/elf.h>
|
||||
|
||||
#include "libelf.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-Processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* CONFIG_DEBUG, CONFIG_DEBUG_VERBOSE, and CONFIG_DEBUG_BINFMT have to be
|
||||
* defined or CONFIG_ELF_DUMPBUFFER does nothing.
|
||||
*/
|
||||
|
||||
#if !defined(CONFIG_DEBUG_VERBOSE) || !defined (CONFIG_DEBUG_BINFMT)
|
||||
# undef CONFIG_ELF_DUMPBUFFER
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ELF_DUMPBUFFER
|
||||
# define elf_dumpbuffer(m,b,n) bvdbgdumpbuffer(m,b,n)
|
||||
#else
|
||||
# define elf_dumpbuffer(m,b,n)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Constant Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_filelen
|
||||
*
|
||||
* Description:
|
||||
* Get the size of the ELF file
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline int elf_filelen(FAR struct elf_loadinfo_s *loadinfo,
|
||||
FAR const char *filename)
|
||||
{
|
||||
struct stat buf;
|
||||
int ret;
|
||||
|
||||
/* Get the file stats */
|
||||
|
||||
ret = stat(filename, &buf);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errval = errno;
|
||||
bdbg("Failed to fstat file: %d\n", errval);
|
||||
return -errval;
|
||||
}
|
||||
|
||||
/* Verify that it is a regular file */
|
||||
|
||||
if (!S_ISREG(buf.st_mode))
|
||||
{
|
||||
bdbg("Not a regular file. mode: %d\n", buf.st_mode);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* TODO: Verify that the file is readable. Not really important because
|
||||
* we will detect this when we try to open the file read-only.
|
||||
*/
|
||||
|
||||
/* Return the size of the file in the loadinfo structure */
|
||||
|
||||
loadinfo->filelen = buf.st_size;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_init
|
||||
*
|
||||
* Description:
|
||||
* This function is called to configure the library to process an ELF
|
||||
* program binary.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int elf_init(FAR const char *filename, FAR struct elf_loadinfo_s *loadinfo)
|
||||
{
|
||||
int ret;
|
||||
|
||||
bvdbg("filename: %s loadinfo: %p\n", filename, loadinfo);
|
||||
|
||||
/* Clear the load info structure */
|
||||
|
||||
memset(loadinfo, 0, sizeof(struct elf_loadinfo_s));
|
||||
|
||||
/* Get the length of the file. */
|
||||
|
||||
ret = elf_filelen(loadinfo, filename);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("elf_filelen failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Open the binary file for reading (only) */
|
||||
|
||||
loadinfo->filfd = open(filename, O_RDONLY);
|
||||
if (loadinfo->filfd < 0)
|
||||
{
|
||||
int errval = errno;
|
||||
bdbg("Failed to open ELF binary %s: %d\n", filename, errval);
|
||||
return -errval;
|
||||
}
|
||||
|
||||
/* Read the ELF ehdr from offset 0 */
|
||||
|
||||
ret = elf_read(loadinfo, (FAR uint8_t*)&loadinfo->ehdr, sizeof(Elf32_Ehdr), 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("Failed to read ELF header: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
elf_dumpbuffer("ELF header", (FAR const uint8_t*)&loadinfo->ehdr, sizeof(Elf32_Ehdr));
|
||||
|
||||
/* Verify the ELF header */
|
||||
|
||||
ret = elf_verifyheader(&loadinfo->ehdr);
|
||||
if (ret <0)
|
||||
{
|
||||
/* This may not be an error because we will be called to attempt loading
|
||||
* EVERY binary. If elf_verifyheader() does not recognize the ELF header,
|
||||
* it will -ENOEXEC whcih simply informs the system that the file is not an
|
||||
* ELF file. elf_verifyheader() will return other errors if the ELF header
|
||||
* is not correctly formed.
|
||||
*/
|
||||
|
||||
bdbg("Bad ELF header: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
136
nuttx/binfmt/libelf/libelf_iobuffer.c
Normal file
136
nuttx/binfmt/libelf/libelf_iobuffer.c
Normal file
@ -0,0 +1,136 @@
|
||||
/****************************************************************************
|
||||
* binfmt/libelf/elf_iobuffer.c
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/binfmt/elf.h>
|
||||
|
||||
#include "libelf.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Constant Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_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 elf_allocbuffer(FAR struct elf_loadinfo_s *loadinfo)
|
||||
{
|
||||
/* Has a buffer been allocated> */
|
||||
|
||||
if (!loadinfo->iobuffer)
|
||||
{
|
||||
/* No.. allocate one now */
|
||||
|
||||
loadinfo->iobuffer = (FAR uint8_t *)kmalloc(CONFIG_ELF_BUFFERSIZE);
|
||||
if (!loadinfo->iobuffer)
|
||||
{
|
||||
bdbg("Failed to allocate an I/O buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
loadinfo->buflen = CONFIG_ELF_BUFFERSIZE;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_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 elf_reallocbuffer(FAR struct elf_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 = krealloc((FAR void *)loadinfo->iobuffer, newsize);
|
||||
if (!buffer)
|
||||
{
|
||||
bdbg("Failed to reallocate the I/O buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Save the new buffer info */
|
||||
|
||||
loadinfo->iobuffer = buffer;
|
||||
loadinfo->buflen = newsize;
|
||||
return OK;
|
||||
}
|
||||
|
||||
284
nuttx/binfmt/libelf/libelf_sections.c
Normal file
284
nuttx/binfmt/libelf/libelf_sections.c
Normal file
@ -0,0 +1,284 @@
|
||||
/****************************************************************************
|
||||
* binfmt/libelf/libelf_sections.c
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/binfmt/elf.h>
|
||||
|
||||
#include "libelf.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-Processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Constant Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_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 elf_sectname(FAR struct elf_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)
|
||||
{
|
||||
bdbg("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)
|
||||
{
|
||||
readlen = loadinfo->filelen - offset;
|
||||
if (readlen <= 0)
|
||||
{
|
||||
bdbg("At end of file\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read that number of bytes into the array */
|
||||
|
||||
buffer = &loadinfo->iobuffer[bytesread];
|
||||
ret = elf_read(loadinfo, buffer, readlen, offset);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("Failed to read section name\n");
|
||||
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 = elf_reallocbuffer(loadinfo, CONFIG_ELF_BUFFERINCR);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("elf_reallocbuffer failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* We will not get here */
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_loadshdrs
|
||||
*
|
||||
* Description:
|
||||
* Loads section headers into memory.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int elf_loadshdrs(FAR struct elf_loadinfo_s *loadinfo)
|
||||
{
|
||||
size_t shdrsize;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(loadinfo->shdr == NULL);
|
||||
|
||||
/* Verify that there are sections */
|
||||
|
||||
if (loadinfo->ehdr.e_shnum < 1)
|
||||
{
|
||||
bdbg("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)
|
||||
{
|
||||
bdbg("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 Elf32_Shdr*)kmalloc(shdrsize);
|
||||
if (!loadinfo->shdr)
|
||||
{
|
||||
bdbg("Failed to allocate the section header table. Size: %ld\n", (long)shdrsize);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Read the section header table into memory */
|
||||
|
||||
ret = elf_read(loadinfo, (FAR uint8_t*)loadinfo->shdr, shdrsize, loadinfo->ehdr.e_shoff);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("Failed to read section header table: %d\n", ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_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 elf_findsection(FAR struct elf_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 = elf_sectname(loadinfo, shdr);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("elf_sectname failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Check if the name of this section is 'sectname' */
|
||||
|
||||
bvdbg("%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;
|
||||
}
|
||||
329
nuttx/binfmt/libelf/libelf_symbols.c
Normal file
329
nuttx/binfmt/libelf/libelf_symbols.c
Normal file
@ -0,0 +1,329 @@
|
||||
/****************************************************************************
|
||||
* binfmt/libelf/libelf_symbols.c
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <elf32.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/binfmt/elf.h>
|
||||
#include <nuttx/binfmt/symtab.h>
|
||||
|
||||
#include "libelf.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-Processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_ELF_BUFFERINCR
|
||||
# define CONFIG_ELF_BUFFERINCR 32
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Constant Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int elf_symname(FAR struct elf_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)
|
||||
{
|
||||
bdbg("Symbol has no name\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
readlen = loadinfo->filelen - offset;
|
||||
if (readlen <= 0)
|
||||
{
|
||||
bdbg("At end of file\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read that number of bytes into the array */
|
||||
|
||||
buffer = &loadinfo->iobuffer[bytesread];
|
||||
ret = elf_read(loadinfo, buffer, readlen, offset);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("elf_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 = elf_reallocbuffer(loadinfo, CONFIG_ELF_BUFFERINCR);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("elf_reallocbuffer failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* We will not get here */
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_findsymtab
|
||||
*
|
||||
* Description:
|
||||
* Find the symbol table section.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int elf_findsymtab(FAR struct elf_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)
|
||||
{
|
||||
bdbg("No symbols in ELF file\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_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 elf_readsym(FAR struct elf_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)))
|
||||
{
|
||||
bdbg("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 elf_read(loadinfo, (FAR uint8_t*)sym, sizeof(Elf32_Sym), offset);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_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:
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int elf_symvalue(FAR struct elf_loadinfo_s *loadinfo, FAR Elf32_Sym *sym,
|
||||
FAR const struct symtab_s *exports, int nexports)
|
||||
{
|
||||
FAR const struct symtab_s *symbol;
|
||||
uintptr_t secbase;
|
||||
int ret;
|
||||
|
||||
switch (sym->st_shndx)
|
||||
{
|
||||
case SHN_COMMON:
|
||||
{
|
||||
/* NuttX ELF modules should be compiled with -fno-common. */
|
||||
|
||||
bdbg("SHN_COMMON: Re-compile with -fno-common\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
case SHN_ABS:
|
||||
{
|
||||
/* st_value already holds the correct value */
|
||||
|
||||
bvdbg("SHN_ABS: st_value=%08lx\n", (long)sym->st_value);
|
||||
return OK;
|
||||
}
|
||||
|
||||
case SHN_UNDEF:
|
||||
{
|
||||
/* Get the name of the undefined symbol */
|
||||
|
||||
ret = elf_symname(loadinfo, sym);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("SHN_UNDEF: Failed to get symbol name: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Check if the base code exports a symbol of this name */
|
||||
|
||||
#ifdef CONFIG_SYMTAB_ORDEREDBYNAME
|
||||
symbol = symtab_findorderedbyname(exports, (FAR char *)loadinfo->iobuffer, nexports);
|
||||
#else
|
||||
symbol = symtab_findbyname(exports, (FAR char *)loadinfo->iobuffer, nexports);
|
||||
#endif
|
||||
if (!symbol)
|
||||
{
|
||||
bdbg("SHN_UNDEF: Exported symbol \"%s\" not found\n", loadinfo->iobuffer);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* Yes... add the exported symbol value to the ELF symbol table entry */
|
||||
|
||||
bvdbg("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;
|
||||
|
||||
bvdbg("Other: %08x+%08x=%08x\n",
|
||||
sym->st_value, secbase, sym->st_value + secbase);
|
||||
|
||||
sym->st_value += secbase;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
126
nuttx/binfmt/libelf/libelf_uninit.c
Normal file
126
nuttx/binfmt/libelf/libelf_uninit.c
Normal file
@ -0,0 +1,126 @@
|
||||
/****************************************************************************
|
||||
* binfmt/libelf/libelf_uninit.c
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/binfmt/elf.h>
|
||||
|
||||
#include "libelf.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-Processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Constant Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_uninit
|
||||
*
|
||||
* Description:
|
||||
* Releases any resources committed by elf_init(). This essentially
|
||||
* undoes the actions of elf_init.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int elf_uninit(struct elf_loadinfo_s *loadinfo)
|
||||
{
|
||||
/* Free all working buffers */
|
||||
|
||||
elf_freebuffers(loadinfo);
|
||||
|
||||
/* Close the ELF file */
|
||||
|
||||
if (loadinfo->filfd >= 0)
|
||||
{
|
||||
close(loadinfo->filfd);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_freebuffers
|
||||
*
|
||||
* Description:
|
||||
* Release all working buffers.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int elf_freebuffers(struct elf_loadinfo_s *loadinfo)
|
||||
{
|
||||
/* Release all working allocations */
|
||||
|
||||
if (loadinfo->shdr)
|
||||
{
|
||||
kfree((FAR void *)loadinfo->shdr);
|
||||
loadinfo->shdr = NULL;
|
||||
}
|
||||
|
||||
if (loadinfo->iobuffer)
|
||||
{
|
||||
kfree((FAR void *)loadinfo->iobuffer);
|
||||
loadinfo->iobuffer = NULL;
|
||||
loadinfo->buflen = 0;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
120
nuttx/binfmt/libelf/libelf_verify.c
Normal file
120
nuttx/binfmt/libelf/libelf_verify.c
Normal file
@ -0,0 +1,120 @@
|
||||
/****************************************************************************
|
||||
* binfmt/libelf/elf_verify.c
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/binfmt/elf.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Constant Data
|
||||
****************************************************************************/
|
||||
|
||||
static const char g_elfmagic[EI_MAGIC_SIZE] = { 0x7f, 'E', 'L', 'F' };
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_verifyheader
|
||||
*
|
||||
* Description:
|
||||
* Given the header from a possible ELF executable, verify that it
|
||||
* is an ELF executable.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
* -ENOEXEC : Not an ELF file
|
||||
* -EINVAL : Not a relocatable ELF file or not supported by the current,
|
||||
* configured architecture.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int elf_verifyheader(FAR const Elf32_Ehdr *ehdr)
|
||||
{
|
||||
if (!ehdr)
|
||||
{
|
||||
bdbg("NULL ELF header!");
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
/* Verify that the magic number indicates an ELF file */
|
||||
|
||||
if (memcmp(ehdr->e_ident, g_elfmagic, EI_MAGIC_SIZE) != 0)
|
||||
{
|
||||
bvdbg("Not ELF magic {%02x, %02x, %02x, %02x}\n",
|
||||
ehdr->e_ident[0], ehdr->e_ident[1], ehdr->e_ident[2], ehdr->e_ident[3]);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
/* Verify that this is a relocatable file */
|
||||
|
||||
if (ehdr->e_type != ET_REL)
|
||||
{
|
||||
bdbg("Not a relocatable file: e_type=%d\n", ehdr->e_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Verify that this file works with the currently configured architecture */
|
||||
|
||||
if (arch_checkarch(ehdr))
|
||||
{
|
||||
bdbg("Not a supported architecture\n");
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
/* Looks good so far... we still might find some problems later. */
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user