diff --git a/ChangeLog b/ChangeLog index c2c9a1413a..2006fcc216 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3513,4 +3513,6 @@ in is non-functional and is simply the framework for ELF support. * include/nuttx/binfmt.h, nxflat.h, elf.h, and symtab.h: Moved to include/nuttx/binfmt/. + * arch/sim/src/up_elf.c and arch/x86/src/common/up_elf.c: Add + for ELF modules. diff --git a/arch/sim/src/Makefile b/arch/sim/src/Makefile index d74e1c005b..43210e37b9 100644 --- a/arch/sim/src/Makefile +++ b/arch/sim/src/Makefile @@ -60,6 +60,10 @@ endif endif endif +ifeq ($(CONFIG_ELF),y) +CSRCS += up_elf.c +endif + ifeq ($(CONFIG_FS_FAT),y) CSRCS += up_blockdevice.c up_deviceimage.c endif diff --git a/arch/sim/src/up_elf.c b/arch/sim/src/up_elf.c new file mode 100644 index 0000000000..c6aabdcef7 --- /dev/null +++ b/arch/sim/src/up_elf.c @@ -0,0 +1,139 @@ +/**************************************************************************** + * arch/sim/src/up_elf.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define R_386_32 1 +#define R_386_PC32 2 + +#define ELF_BITS 32 +#define ELF_ARCH EM_386 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arch_checkarch + * + * Description: + * Given the ELF header in 'hdr', verify that the ELF file is appropriate + * for the current, configured architecture. Every architecture that uses + * the ELF loader must provide this function. + * + * Input Parameters: + * hdr - The ELF header read from the ELF file. + * + * Returned Value: + * True if the architecture supports this ELF file. + * + ****************************************************************************/ + +bool arch_checkarch(FAR const Elf32_Ehdr *hdr) +{ + return hdr->e_machine == EM_386 || hdr->e_machine == EM_486; +} + +/**************************************************************************** + * Name: arch_relocate and arch_relocateadd + * + * Description: + * Perform on architecture-specific ELF relocation. Every architecture + * that uses the ELF loader must provide this function. + * + * Input Parameters: + * rel - The relocation type + * sym - The ELF symbol structure containing the fully resolved value. + * addr - The address that requires the relocation. + * + * Returned Value: + * Zero (OK) if the relocation was successful. Otherwise, a negated errno + * value indicating the cause of the relocation failure. + * + ****************************************************************************/ + +int arch_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym, + uintptr_t addr) +{ + FAR uint32_t *ptr = (FAR uint32_t *)addr; + + switch (ELF_REL_TYPE(rel->r_info)) + { + case R_386_32: + *ptr += sym->st_value; + break; + + case R_386_PC32: + *ptr += sym->st_value - (uint32_t)ptr; + break; + + default: + return -EINVAL; + } + + return OK; +} + +int arch_relocateadd(FAR const Elf32_Rela *rel, FAR const Elf32_Sym *sym, + uintptr_t addr) +{ + bdbg("Not supported\n"); + return -ENOSYS; +} + diff --git a/arch/x86/src/common/up_elf.c b/arch/x86/src/common/up_elf.c new file mode 100644 index 0000000000..f159c8e518 --- /dev/null +++ b/arch/x86/src/common/up_elf.c @@ -0,0 +1,139 @@ +/**************************************************************************** + * arch/x86/src/up_elf.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define R_386_32 1 +#define R_386_PC32 2 + +#define ELF_BITS 32 +#define ELF_ARCH EM_386 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arch_checkarch + * + * Description: + * Given the ELF header in 'hdr', verify that the ELF file is appropriate + * for the current, configured architecture. Every architecture that uses + * the ELF loader must provide this function. + * + * Input Parameters: + * hdr - The ELF header read from the ELF file. + * + * Returned Value: + * True if the architecture supports this ELF file. + * + ****************************************************************************/ + +bool arch_checkarch(FAR const Elf32_Ehdr *hdr) +{ + return hdr->e_machine == EM_386 || hdr->e_machine == EM_486; +} + +/**************************************************************************** + * Name: arch_relocate and arch_relocateadd + * + * Description: + * Perform on architecture-specific ELF relocation. Every architecture + * that uses the ELF loader must provide this function. + * + * Input Parameters: + * rel - The relocation type + * sym - The ELF symbol structure containing the fully resolved value. + * addr - The address that requires the relocation. + * + * Returned Value: + * Zero (OK) if the relocation was successful. Otherwise, a negated errno + * value indicating the cause of the relocation failure. + * + ****************************************************************************/ + +int arch_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym, + uintptr_t addr) +{ + FAR uint32_t *ptr = (FAR uint32_t *)addr; + + switch (ELF_REL_TYPE(rel->r_info)) + { + case R_386_32: + *ptr += sym->st_value; + break; + + case R_386_PC32: + *ptr += sym->st_value - (uint32_t)ptr; + break; + + default: + return -EINVAL; + } + + return OK; +} + +int arch_relocateadd(FAR const Elf32_Rela *rel, FAR const Elf32_Sym *sym, + uintptr_t addr) +{ + bdbg("Not supported\n"); + return -ENOSYS; +} + diff --git a/binfmt/libelf/libelf_bind.c b/binfmt/libelf/libelf_bind.c index dd75809ec3..e9491af0e4 100644 --- a/binfmt/libelf/libelf_bind.c +++ b/binfmt/libelf/libelf_bind.c @@ -266,7 +266,9 @@ int elf_bind(FAR struct elf_loadinfo_s *loadinfo, /* Flush the instruction cache before starting the newly loaded module */ +#ifdef CONFIG_ELF_ICACHE arch_flushicache((FAR void*)loadinfo->alloc, loadinfo->allocsize); +#endif return ret; } diff --git a/include/elf.h b/include/elf.h index ec7aecf637..1b36701fda 100644 --- a/include/elf.h +++ b/include/elf.h @@ -73,10 +73,28 @@ #define EM_386 3 /* Intel 80386 */ #define EM_68K 4 /* Motorola 68000 */ #define EM_88K 5 /* Motorola 88000 */ +#define EM_486 6 /* Intel 486+ */ #define EM_860 7 /* Intel 80860 */ -#define EM_MIPS 8 /* MIPS RS3000 Big-Endian */ -#define EM_MIPS_RS4_BE 10 /* MIPS RS4000 Big-Endian */ - /* 11-16 Reserved for future use */ +#define EM_MIPS 8 /* MIPS R3000 Big-Endian */ +#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */ +#define EM_PARISC 15 /* HPPA */ +#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ +#define EM_PPC 20 /* PowerPC */ +#define EM_PPC64 21 /* PowerPC64 */ +#define EM_SH 42 /* SuperH */ +#define EM_SPARCV9 43 /* SPARC v9 64-bit */ +#define EM_IA_64 50 /* HP/Intel IA-64 */ +#define EM_X86_64 62 /* AMD x86-64 */ +#define EM_S390 22 /* IBM S/390 */ +#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ +#define EM_V850 87 /* NEC v850 */ +#define EM_M32R 88 /* Renesas M32R */ +#define EM_H8_300 46 +#define EM_ALPHA 0x9026 +#define EM_CYGNUS_V850 0x9080 +#define EM_CYGNUS_M32R 0x9041 +#define EM_S390_OLD 0xa390 +#define EM_FRV 0x5441 /* Values for Elf32_Ehdr::e_version */ diff --git a/include/nuttx/binfmt/elf.h b/include/nuttx/binfmt/elf.h index dc28c5c6a1..8a12c5019f 100644 --- a/include/nuttx/binfmt/elf.h +++ b/include/nuttx/binfmt/elf.h @@ -174,7 +174,7 @@ EXTERN int elf_bind(FAR struct elf_loadinfo_s *loadinfo, EXTERN int elf_unload(struct elf_loadinfo_s *loadinfo); /**************************************************************************** - * These are APIs used internally only by NuttX: + * These are APIs used outside of binfmt by NuttX: ****************************************************************************/ /**************************************************************************** * Name: elf_initialize @@ -206,6 +206,9 @@ EXTERN int elf_initialize(void); EXTERN void elf_uninitialize(void); +/**************************************************************************** + * These are APIs must be provided by architecture-specific logic: + ****************************************************************************/ /**************************************************************************** * Name: arch_checkarch * @@ -262,7 +265,9 @@ EXTERN int arch_relocateadd(FAR const Elf32_Rela *rel, * ****************************************************************************/ +#ifdef CONFIG_ELF_ICACHE EXTERN bool arch_flushicache(FAR void *addr, size_t len); +#endif #undef EXTERN #if defined(__cplusplus)