From 2bb91343c2e88ddab9efd864f4b2006cdf4c7c94 Mon Sep 17 00:00:00 2001 From: anjiahao Date: Wed, 26 Jun 2024 16:55:42 +0800 Subject: [PATCH 01/20] modlib:Modify modlib loading DYN elf file conditions Signed-off-by: anjiahao --- libs/libc/modlib/modlib_load.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/libc/modlib/modlib_load.c b/libs/libc/modlib/modlib_load.c index 0d36f97ccf8a5..c34f258471bd3 100644 --- a/libs/libc/modlib/modlib_load.c +++ b/libs/libc/modlib/modlib_load.c @@ -140,7 +140,7 @@ static void modlib_elfsize(FAR struct mod_loadinfo_s *loadinfo) * (and zero) memory for the each section. */ - if (loadinfo->ehdr.e_phnum > 0) + if (loadinfo->ehdr.e_type == ET_DYN) { for (i = 0; i < loadinfo->ehdr.e_phnum; i++) { @@ -251,7 +251,7 @@ static inline int modlib_loadfile(FAR struct mod_loadinfo_s *loadinfo) binfo("Loading sections - text: %p.%zx data: %p.%zx\n", text, loadinfo->textsize, data, loadinfo->datasize); - if (loadinfo->ehdr.e_phnum > 0) + if (loadinfo->ehdr.e_type == ET_DYN) { for (i = 0; i < loadinfo->ehdr.e_phnum; i++) { From 0eaed0e73ebe4bea86bce24608bdbafb6015efa6 Mon Sep 17 00:00:00 2001 From: anjiahao Date: Sun, 30 Jun 2024 17:11:23 +0800 Subject: [PATCH 02/20] modlib:move elf LMA logic to modlib Signed-off-by: anjiahao --- libs/libc/modlib/Kconfig | 8 ++++++ libs/libc/modlib/modlib_load.c | 46 ++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/libs/libc/modlib/Kconfig b/libs/libc/modlib/Kconfig index 70462486e436c..f225bb3544b9d 100644 --- a/libs/libc/modlib/Kconfig +++ b/libs/libc/modlib/Kconfig @@ -98,4 +98,12 @@ config MODLIB_SYSTEM_SYMTAB endif # MODLIB_HAVE_SYMTAB +config MODLIB_LOADTO_LMA + bool "modlib load sections to LMA" + default n + ---help--- + Load all section to LMA not VMA, so the startup code(e.g. start.S) need + relocate .data section to the final address(VMA) and zero .bss section + by self. + endmenu # Module library configuration diff --git a/libs/libc/modlib/modlib_load.c b/libs/libc/modlib/modlib_load.c index c34f258471bd3..fa58513c515b0 100644 --- a/libs/libc/modlib/modlib_load.c +++ b/libs/libc/modlib/modlib_load.c @@ -226,6 +226,43 @@ static void modlib_elfsize(FAR struct mod_loadinfo_s *loadinfo) loadinfo->datasize = datasize; } +#ifdef CONFIG_MODLIB_LOADTO_LMA +/**************************************************************************** + * Name: modlib_vma2lma + * + * Description: + * Convert section`s VMA to LMA according to PhysAddr(p_paddr) of + * Program Header. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +static int modlib_vma2lma(FAR struct mod_loadinfo_s *loadinfo, + FAR Elf_Shdr *shdr, FAR Elf_Addr *lma) +{ + int i; + + for (i = 0; i < loadinfo->ehdr.e_phnum; i++) + { + FAR Elf_Phdr *phdr = &loadinfo->phdr[i]; + + if (shdr->sh_addr >= phdr->p_vaddr && + shdr->sh_addr + shdr->sh_size <= phdr->p_vaddr + phdr->p_memsz && + shdr->sh_offset >= phdr->p_offset && + shdr->sh_offset <= phdr->p_offset + phdr->p_filesz) + { + *lma = phdr->p_paddr + shdr->sh_addr - phdr->p_vaddr; + return 0; + } + } + + return -ENOENT; +} +#endif + /**************************************************************************** * Name: modlib_loadfile * @@ -332,6 +369,15 @@ static inline int modlib_loadfile(FAR struct mod_loadinfo_s *loadinfo) if (shdr->sh_type != SHT_NOBITS) { +#ifdef CONFIG_MODLIB_LOADTO_LMA + ret = modlib_vma2lma(loadinfo, shdr, *pptr); + if (ret < 0) + { + berr("ERROR: Failed to convert addr %d: %d\n", i, ret); + return ret; + } +#endif + /* Read the section data from sh_offset to the memory region */ ret = modlib_read(loadinfo, *pptr, shdr->sh_size, From 9a11c61ca05a46c4acf2f61ebef2d9dd65453bfa Mon Sep 17 00:00:00 2001 From: anjiahao Date: Tue, 2 Jul 2024 12:07:07 +0800 Subject: [PATCH 03/20] modlib:move get file info logic to modlib Signed-off-by: anjiahao --- include/nuttx/lib/modlib.h | 3 +++ libs/libc/modlib/modlib_init.c | 19 +++++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/include/nuttx/lib/modlib.h b/include/nuttx/lib/modlib.h index a18a224ba24f5..2a9c24b5b5479 100644 --- a/include/nuttx/lib/modlib.h +++ b/include/nuttx/lib/modlib.h @@ -205,6 +205,9 @@ struct mod_loadinfo_s size_t textalign; /* Necessary alignment of .text */ size_t dataalign; /* Necessary alignment of .bss/.text */ off_t filelen; /* Length of the entire module file */ + uid_t fileuid; /* Uid of the file system */ + gid_t filegid; /* Gid of the file system */ + int filemode; /* Mode of the file system */ Elf_Ehdr ehdr; /* Buffered module file header */ FAR Elf_Phdr *phdr; /* Buffered module program headers */ FAR Elf_Shdr *shdr; /* Buffered module section headers */ diff --git a/libs/libc/modlib/modlib_init.c b/libs/libc/modlib/modlib_init.c index 6f1c709cdb3e3..9b092fc5835fd 100644 --- a/libs/libc/modlib/modlib_init.c +++ b/libs/libc/modlib/modlib_init.c @@ -44,10 +44,10 @@ ****************************************************************************/ /**************************************************************************** - * Name: modlib_filelen + * Name: modlib_fileinfo * * Description: - * Get the size of the ELF file + * Get the info of the ELF file * * Returned Value: * 0 (OK) is returned on success and a negated errno is returned on @@ -55,7 +55,7 @@ * ****************************************************************************/ -static inline int modlib_filelen(FAR struct mod_loadinfo_s *loadinfo) +static inline int modlib_fileinfo(FAR struct mod_loadinfo_s *loadinfo) { struct stat buf; int ret; @@ -78,9 +78,12 @@ static inline int modlib_filelen(FAR struct mod_loadinfo_s *loadinfo) return -ENOENT; } - /* Return the size of the file in the loadinfo structure */ + /* Return some stats info of the file in the loadinfo structure */ - loadinfo->filelen = buf.st_size; + loadinfo->filelen = buf.st_size; + loadinfo->fileuid = buf.st_uid; + loadinfo->filegid = buf.st_gid; + loadinfo->filemode = buf.st_mode; return OK; } @@ -122,12 +125,12 @@ int modlib_initialize(FAR const char *filename, return -errval; } - /* Get the length of the file. */ + /* Get some stats info of the file. */ - ret = modlib_filelen(loadinfo); + ret = modlib_fileinfo(loadinfo); if (ret < 0) { - berr("ERROR: modlib_filelen failed: %d\n", ret); + berr("ERROR: modlib_fileinfo failed: %d\n", ret); return ret; } From c8e99ae1e937b725cca488d6f0bf0ab3da74a4f5 Mon Sep 17 00:00:00 2001 From: anjiahao Date: Tue, 2 Jul 2024 15:18:04 +0800 Subject: [PATCH 04/20] modlib:fix bug when read modlib sections name Signed-off-by: anjiahao --- libs/libc/modlib/modlib_sections.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/libc/modlib/modlib_sections.c b/libs/libc/modlib/modlib_sections.c index 25f99736f25b9..cae9db2bfe1a8 100644 --- a/libs/libc/modlib/modlib_sections.c +++ b/libs/libc/modlib/modlib_sections.c @@ -119,7 +119,7 @@ static inline int modlib_sectname(FAR struct mod_loadinfo_s *loadinfo, /* Read that number of bytes into the array */ - ret = modlib_read(loadinfo, buffer, readlen, offset); + ret = modlib_read(loadinfo, buffer, readlen, offset + bytesread); if (ret < 0) { berr("ERROR: Failed to read section name: %d\n", ret); From 3d107f2bd6e524184ed162100728625994235c94 Mon Sep 17 00:00:00 2001 From: anjiahao Date: Tue, 9 Jul 2024 23:01:57 +0800 Subject: [PATCH 05/20] coredump:Move private functions to internal header files Signed-off-by: anjiahao --- include/nuttx/coredump.h | 24 ----------------- sched/init/nx_bringup.c | 2 +- sched/misc/assert.c | 2 ++ sched/misc/coredump.c | 4 +-- sched/misc/coredump.h | 58 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 63 insertions(+), 27 deletions(-) create mode 100644 sched/misc/coredump.h diff --git a/include/nuttx/coredump.h b/include/nuttx/coredump.h index 1c1df1b6d366e..46f1fa0975023 100644 --- a/include/nuttx/coredump.h +++ b/include/nuttx/coredump.h @@ -54,28 +54,4 @@ int coredump_set_memory_region(FAR const struct memory_region_s *region); int coredump_add_memory_region(FAR const void *ptr, size_t size); -/**************************************************************************** - * Name: coredump_initialize - * - * Description: - * Initialize the coredump facility. Called once and only from - * nx_start_application. - * - ****************************************************************************/ - -int coredump_initialize(void); - -/**************************************************************************** - * Name: coredump_dump - * - * Description: - * Do coredump of the task specified by pid. - * - * Input Parameters: - * pid - The task/thread ID of the thread to dump - * - ****************************************************************************/ - -void coredump_dump(pid_t pid); - #endif /* __INCLUDE_NUTTX_COREDUMP_H */ diff --git a/sched/init/nx_bringup.c b/sched/init/nx_bringup.c index e3601c472ca41..e3da041d996ca 100644 --- a/sched/init/nx_bringup.c +++ b/sched/init/nx_bringup.c @@ -34,7 +34,6 @@ #include #include -#include #include #include #include @@ -52,6 +51,7 @@ #include "sched/sched.h" #include "wqueue/wqueue.h" #include "init/init.h" +#include "misc/coredump.h" #ifdef CONFIG_ETC_ROMFS # include diff --git a/sched/misc/assert.c b/sched/misc/assert.c index c52f23df9019b..7fb6dd9fb089b 100644 --- a/sched/misc/assert.c +++ b/sched/misc/assert.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -58,6 +59,7 @@ #include "irq/irq.h" #include "sched/sched.h" #include "group/group.h" +#include "coredump.h" /**************************************************************************** * Pre-processor Definitions diff --git a/sched/misc/coredump.c b/sched/misc/coredump.c index 46bf7ca5e8866..16c6867b5880e 100644 --- a/sched/misc/coredump.c +++ b/sched/misc/coredump.c @@ -24,11 +24,11 @@ * Included Files ****************************************************************************/ -#include -#include #include #include +#include "coredump.h" + /**************************************************************************** * Private Data ****************************************************************************/ diff --git a/sched/misc/coredump.h b/sched/misc/coredump.h new file mode 100644 index 0000000000000..28adb83d4c409 --- /dev/null +++ b/sched/misc/coredump.h @@ -0,0 +1,58 @@ +/**************************************************************************** + * sched/misc/coredump.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __SCHED_MISC_COREDUMP_H +#define __SCHED_MISC_COREDUMP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: coredump_initialize + * + * Description: + * Initialize the coredump facility. Called once and only from + * nx_start_application. + * + ****************************************************************************/ + +int coredump_initialize(void); + +/**************************************************************************** + * Name: coredump_dump + * + * Description: + * Do coredump of the task specified by pid. + * + * Input Parameters: + * pid - The task/thread ID of the thread to dump + * + ****************************************************************************/ + +void coredump_dump(pid_t pid); + +#endif /* __SCHED_MISC_COREDUMP_H */ From 5b4d54473938d829360bbb5b7320ae32013f26bc Mon Sep 17 00:00:00 2001 From: anjiahao Date: Sat, 6 Jul 2024 15:22:51 +0800 Subject: [PATCH 06/20] coredump:Move coredump to sched/misc 1. move coredump form libelf to sched/misc 2. rename core_dump to coredump Signed-off-by: anjiahao --- Documentation/guides/coredump.rst | 4 +- binfmt/CMakeLists.txt | 3 +- binfmt/Makefile | 1 - binfmt/binfmt_coredump.c | 72 -- binfmt/elf.c | 34 - binfmt/libelf/CMakeLists.txt | 5 - binfmt/libelf/Kconfig | 11 - binfmt/libelf/Make.defs | 6 - binfmt/libelf/libelf_coredump.c | 666 ------------------ binfmt/nxflat.c | 1 - boards/Kconfig | 4 +- .../sabre-6quad/configs/coredump/defconfig | 3 +- include/nuttx/binfmt/binfmt.h | 37 - include/nuttx/binfmt/elf.h | 31 - include/nuttx/coredump.h | 37 +- include/nuttx/elf.h | 2 +- sched/Kconfig | 12 + sched/misc/CMakeLists.txt | 2 +- sched/misc/Make.defs | 2 +- sched/misc/coredump.c | 643 ++++++++++++++++- 20 files changed, 697 insertions(+), 879 deletions(-) delete mode 100644 binfmt/binfmt_coredump.c delete mode 100644 binfmt/libelf/libelf_coredump.c diff --git a/Documentation/guides/coredump.rst b/Documentation/guides/coredump.rst index 94dfa7fc30701..9b68c755cc088 100644 --- a/Documentation/guides/coredump.rst +++ b/Documentation/guides/coredump.rst @@ -16,9 +16,7 @@ Enable Kconfig .. code-block:: console - CONFIG_ELF=y /* Enable ELF */ - - CONFIG_ELF_COREDUMP=y /* Enable ELF Coredump */ + CONFIG_COREDUMP=y /* Enable Coredump */ CONFIG_BOARD_COREDUMP_SYSLOG=y /* Enable Board Coredump, if exceptions and assertions occur, */ diff --git a/binfmt/CMakeLists.txt b/binfmt/CMakeLists.txt index 35f8f9cdb3277..0f0578ebce3d7 100644 --- a/binfmt/CMakeLists.txt +++ b/binfmt/CMakeLists.txt @@ -39,8 +39,7 @@ list( binfmt_exec.c binfmt_copyargv.c binfmt_copyactions.c - binfmt_dumpmodule.c - binfmt_coredump.c) + binfmt_dumpmodule.c) if(CONFIG_BINFMT_LOADABLE) list(APPEND SRCS binfmt_exit.c) diff --git a/binfmt/Makefile b/binfmt/Makefile index 89168659900d6..02b48c2b1301c 100644 --- a/binfmt/Makefile +++ b/binfmt/Makefile @@ -27,7 +27,6 @@ include $(TOPDIR)/Make.defs CSRCS = binfmt_globals.c binfmt_initialize.c binfmt_register.c binfmt_unregister.c CSRCS += binfmt_loadmodule.c binfmt_unloadmodule.c binfmt_execmodule.c CSRCS += binfmt_exec.c binfmt_copyargv.c binfmt_copyactions.c binfmt_dumpmodule.c -CSRCS += binfmt_coredump.c ifeq ($(CONFIG_BINFMT_LOADABLE),y) CSRCS += binfmt_exit.c diff --git a/binfmt/binfmt_coredump.c b/binfmt/binfmt_coredump.c deleted file mode 100644 index a4fd7eea59981..0000000000000 --- a/binfmt/binfmt_coredump.c +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** - * binfmt/binfmt_coredump.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include - -#include "binfmt.h" - -#ifndef CONFIG_BINFMT_DISABLE - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: core_dump - * - * Description: - * This function for generating core dump stream. - * - ****************************************************************************/ - -int core_dump(FAR const struct memory_region_s *regions, - FAR struct lib_outstream_s *stream, - pid_t pid) -{ - FAR struct binfmt_s *binfmt; - int ret = -ENOENT; - - for (binfmt = g_binfmts; binfmt; binfmt = binfmt->next) - { - /* Use this handler to try to load the format */ - - if (binfmt->coredump) - { - ret = binfmt->coredump(regions, stream, pid); - if (ret == OK) - { - break; - } - } - } - - return ret; -} - -#endif /* CONFIG_BINFMT_DISABLE */ diff --git a/binfmt/elf.c b/binfmt/elf.c index 42fbaca0c49cc..2ae29db77bea2 100644 --- a/binfmt/elf.c +++ b/binfmt/elf.c @@ -69,11 +69,6 @@ static int elf_loadbinary(FAR struct binary_s *binp, FAR const char *filename, FAR const struct symtab_s *exports, int nexports); -#ifdef CONFIG_ELF_COREDUMP -static int elf_dumpbinary(FAR const struct memory_region_s *regions, - FAR struct lib_outstream_s *stream, - pid_t pid); -#endif #if defined(CONFIG_DEBUG_FEATURES) && defined(CONFIG_DEBUG_BINFMT) static void elf_dumploadinfo(FAR struct elf_loadinfo_s *loadinfo); #endif @@ -87,9 +82,6 @@ static struct binfmt_s g_elfbinfmt = NULL, /* next */ elf_loadbinary, /* load */ NULL, /* unload */ -#ifdef CONFIG_ELF_COREDUMP - elf_dumpbinary, /* coredump */ -#endif }; /**************************************************************************** @@ -370,32 +362,6 @@ static int elf_loadbinary(FAR struct binary_s *binp, return ret; } -/**************************************************************************** - * Name: elf_dumpbinary - * - * Description: - * Generat the core dump stream as ELF structure. - * - * Returned Value: - * Zero (OK) on success; a negated errno value on failure. - * - ****************************************************************************/ - -#ifdef CONFIG_ELF_COREDUMP -static int elf_dumpbinary(FAR const struct memory_region_s *regions, - FAR struct lib_outstream_s *stream, - pid_t pid) -{ - struct elf_dumpinfo_s dumpinfo; - - dumpinfo.regions = regions; - dumpinfo.stream = stream; - dumpinfo.pid = pid; - - return elf_coredump(&dumpinfo); -} -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/binfmt/libelf/CMakeLists.txt b/binfmt/libelf/CMakeLists.txt index aa6fedd582960..8df1a0bd525b8 100644 --- a/binfmt/libelf/CMakeLists.txt +++ b/binfmt/libelf/CMakeLists.txt @@ -40,11 +40,6 @@ if(CONFIG_ELF) libelf_unload.c libelf_verify.c) - if(CONFIG_ELF_COREDUMP) - list(APPEND SRCS libelf_coredump.c) - target_include_directories(binfmt PRIVATE ${NUTTX_DIR}/sched) - endif() - if(CONFIG_BINFMT_CONSTRUCTORS) list(APPEND SRCS libelf_ctors.c libelf_dtors.c) endif() diff --git a/binfmt/libelf/Kconfig b/binfmt/libelf/Kconfig index dbba7921e4003..f33d737021e26 100644 --- a/binfmt/libelf/Kconfig +++ b/binfmt/libelf/Kconfig @@ -63,17 +63,6 @@ config ELF_SYMBOL_CACHECOUNT This is a cache that is used to store elf symbol table to reduce access fs. Default: 256 -config ELF_COREDUMP - bool "ELF Coredump" - depends on ARCH_HAVE_TCBINFO - default n - ---help--- - Generate ELF core dump to provide information about the CPU state and the - memory state of program. - The memory state embeds a snapshot of all segments mapped in the - memory space of the program. The CPU state contains register values - when the core dump has been generated. - config ELF_LOADTO_LMA bool "ELF load sections to LMA" default n diff --git a/binfmt/libelf/Make.defs b/binfmt/libelf/Make.defs index ee138761bc7e2..8c1a53182d648 100644 --- a/binfmt/libelf/Make.defs +++ b/binfmt/libelf/Make.defs @@ -28,12 +28,6 @@ CSRCS += libelf_bind.c libelf_init.c libelf_addrenv.c libelf_iobuffer.c CSRCS += libelf_load.c libelf_read.c libelf_sections.c libelf_symbols.c CSRCS += libelf_uninit.c libelf_unload.c libelf_verify.c -ifeq ($(CONFIG_ELF_COREDUMP),y) -CSRCS += libelf_coredump.c - -CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)sched -endif - ifeq ($(CONFIG_BINFMT_CONSTRUCTORS),y) CSRCS += libelf_ctors.c libelf_dtors.c endif diff --git a/binfmt/libelf/libelf_coredump.c b/binfmt/libelf/libelf_coredump.c deleted file mode 100644 index a37bbdeada00c..0000000000000 --- a/binfmt/libelf/libelf_coredump.c +++ /dev/null @@ -1,666 +0,0 @@ -/**************************************************************************** - * binfmt/libelf/libelf_coredump.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#ifdef PAGESIZE -# define ELF_PAGESIZE PAGESIZE -#else -# define ELF_PAGESIZE 1024 -#endif - -#define PROGRAM_ALIGNMENT 64 - -#define ROUNDUP(x, y) ((x + (y - 1)) / (y)) * (y) -#define ROUNDDOWN(x ,y) (((x) / (y)) * (y)) - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static uint8_t g_running_regs[XCPTCONTEXT_SIZE] aligned_data(16); - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: elf_flush - * - * Description: - * Flush the out stream - * - ****************************************************************************/ - -static int elf_flush(FAR struct elf_dumpinfo_s *cinfo) -{ - return lib_stream_flush(cinfo->stream); -} - -/**************************************************************************** - * Name: elf_emit - * - * Description: - * Send the dump data to binfmt_outstream_s - * - ****************************************************************************/ - -static int elf_emit(FAR struct elf_dumpinfo_s *cinfo, - FAR const void *buf, size_t len) -{ - FAR const uint8_t *ptr = buf; - size_t total = len; - int ret = 0; - - while (total > 0) - { - ret = lib_stream_puts(cinfo->stream, ptr, total); - if (ret < 0) - { - break; - } - - total -= ret; - ptr += ret; - } - - return ret < 0 ? ret : len - total; -} - -/**************************************************************************** - * Name: elf_emit_align - * - * Description: - * Align the filled data according to the current offset - * - ****************************************************************************/ - -static int elf_emit_align(FAR struct elf_dumpinfo_s *cinfo) -{ - off_t align = ROUNDUP(cinfo->stream->nput, - ELF_PAGESIZE) - cinfo->stream->nput; - unsigned char null[256]; - off_t total = align; - off_t ret = 0; - - memset(null, 0, sizeof(null)); - - while (total > 0) - { - ret = elf_emit(cinfo, null, total > sizeof(null) ? - sizeof(null) : total); - if (ret <= 0) - { - break; - } - - total -= ret; - } - - return ret < 0 ? ret : align; -} - -/**************************************************************************** - * Name: elf_emit_hdr - * - * Description: - * Fill the elf header - * - ****************************************************************************/ - -static int elf_emit_hdr(FAR struct elf_dumpinfo_s *cinfo, - int segs) -{ - Elf_Ehdr ehdr; - - memset(&ehdr, 0, sizeof(ehdr)); - memcpy(ehdr.e_ident, ELFMAG, EI_MAGIC_SIZE); - - ehdr.e_ident[EI_CLASS] = ELF_CLASS; - ehdr.e_ident[EI_DATA] = ELF_DATA; - ehdr.e_ident[EI_VERSION] = EV_CURRENT; - ehdr.e_ident[EI_OSABI] = ELF_OSABI; - - ehdr.e_type = ET_CORE; - ehdr.e_machine = EM_ARCH; - ehdr.e_version = EV_CURRENT; - ehdr.e_phoff = sizeof(Elf_Ehdr); - ehdr.e_flags = EF_FLAG; - ehdr.e_ehsize = sizeof(Elf_Ehdr); - ehdr.e_phentsize = sizeof(Elf_Phdr); - ehdr.e_phnum = segs; - - return elf_emit(cinfo, &ehdr, sizeof(ehdr)); -} - -/**************************************************************************** - * Name: elf_get_ntcb - * - * Description: - * Calculate the note segment size - * - ****************************************************************************/ - -static int elf_get_ntcb(void) -{ - int count = 0; - int i; - - for (i = 0; i < g_npidhash; i++) - { - if (g_pidhash[i] != NULL) - { - count++; - } - } - - return count; -} - -/**************************************************************************** - * Name: elf_get_note_size - * - * Description: - * Calculate the note segment size - * - ****************************************************************************/ - -static int elf_get_note_size(int stksegs) -{ - int total; - - total = stksegs * (sizeof(Elf_Nhdr) + ROUNDUP(CONFIG_TASK_NAME_SIZE, 8) + - sizeof(elf_prstatus_t)); - total += stksegs * (sizeof(Elf_Nhdr) + ROUNDUP(CONFIG_TASK_NAME_SIZE, 8) + - sizeof(elf_prpsinfo_t)); - return total; -} - -/**************************************************************************** - * Name: elf_emit_tcb_note - * - * Description: - * Fill the note segment information from tcb - * - ****************************************************************************/ - -static void elf_emit_tcb_note(FAR struct elf_dumpinfo_s *cinfo, - FAR struct tcb_s *tcb) -{ - char name[ROUNDUP(CONFIG_TASK_NAME_SIZE, 8)]; - elf_prstatus_t status; - elf_prpsinfo_t info; - FAR uintptr_t *regs; - Elf_Nhdr nhdr; - int i; - - memset(&info, 0x0, sizeof(info)); - memset(&status, 0x0, sizeof(status)); - - /* Fill Process info */ - - nhdr.n_namesz = sizeof(name); - nhdr.n_descsz = sizeof(info); - nhdr.n_type = NT_PRPSINFO; - - elf_emit(cinfo, &nhdr, sizeof(nhdr)); - - strlcpy(name, get_task_name(tcb), sizeof(name)); - elf_emit(cinfo, name, sizeof(name)); - - info.pr_pid = tcb->pid; - strlcpy(info.pr_fname, get_task_name(tcb), sizeof(info.pr_fname)); - elf_emit(cinfo, &info, sizeof(info)); - - /* Fill Process status */ - - nhdr.n_descsz = sizeof(status); - nhdr.n_type = NT_PRSTATUS; - - elf_emit(cinfo, &nhdr, sizeof(nhdr)); - elf_emit(cinfo, name, sizeof(name)); - - status.pr_pid = tcb->pid; - - if (running_task() == tcb) - { - if (up_interrupt_context()) - { - regs = (FAR uintptr_t *)up_current_regs(); - } - else - { - up_saveusercontext(g_running_regs); - regs = (FAR uintptr_t *)g_running_regs; - } - } - else - { - regs = (FAR uintptr_t *)tcb->xcp.regs; - } - - if (regs != NULL) - { - for (i = 0; i < nitems(status.pr_regs); i++) - { - if (g_tcbinfo.reg_off.p[i] == UINT16_MAX) - { - continue; - } - else - { - status.pr_regs[i] = *(FAR uintptr_t *) - ((FAR uint8_t *)regs + g_tcbinfo.reg_off.p[i]); - } - } - } - - elf_emit(cinfo, &status, sizeof(status)); -} - -/**************************************************************************** - * Name: elf_emit_note - * - * Description: - * Fill the note segment information - * - ****************************************************************************/ - -static void elf_emit_note(FAR struct elf_dumpinfo_s *cinfo) -{ - int i; - - if (cinfo->pid == INVALID_PROCESS_ID) - { - for (i = 0; i < g_npidhash; i++) - { - if (g_pidhash[i] != NULL) - { - elf_emit_tcb_note(cinfo, g_pidhash[i]); - } - } - } - else - { - elf_emit_tcb_note(cinfo, nxsched_get_tcb(cinfo->pid)); - } -} - -/**************************************************************************** - * Name: elf_emit_tcb_stack - * - * Description: - * Fill the task stack information from tcb - * - ****************************************************************************/ - -static void elf_emit_tcb_stack(FAR struct elf_dumpinfo_s *cinfo, - FAR struct tcb_s *tcb) -{ - uintptr_t buf = 0; - uintptr_t sp; - size_t len; - - if (running_task() != tcb) - { - sp = up_getusrsp(tcb->xcp.regs); - - if (sp > (uintptr_t)tcb->stack_base_ptr && - sp < (uintptr_t)tcb->stack_base_ptr + tcb->adj_stack_size) - { - len = ((uintptr_t)tcb->stack_base_ptr + - tcb->adj_stack_size) - sp; - buf = sp; - } -#ifdef CONFIG_STACK_COLORATION - else - { - len = up_check_tcbstack(tcb); - buf = (uintptr_t)tcb->stack_base_ptr + - (tcb->adj_stack_size - len); - } -#endif - } - - if (buf == 0) - { - buf = (uintptr_t)tcb->stack_alloc_ptr; - len = tcb->adj_stack_size + - (tcb->stack_base_ptr - tcb->stack_alloc_ptr); - } - - sp = ROUNDDOWN(buf, PROGRAM_ALIGNMENT); - len = ROUNDUP(len + (buf - sp), PROGRAM_ALIGNMENT); - buf = sp; - - elf_emit(cinfo, (FAR void *)buf, len); - - /* Align to page */ - - elf_emit_align(cinfo); -} - -/**************************************************************************** - * Name: elf_emit_stack - * - * Description: - * Fill the task stack information - * - ****************************************************************************/ - -static void elf_emit_stack(FAR struct elf_dumpinfo_s *cinfo) -{ - int i; - - if (cinfo->pid == INVALID_PROCESS_ID) - { - for (i = 0; i < g_npidhash; i++) - { - if (g_pidhash[i] != NULL) - { - elf_emit_tcb_stack(cinfo, g_pidhash[i]); - } - } - } - else - { - elf_emit_tcb_stack(cinfo, nxsched_get_tcb(cinfo->pid)); - } -} - -/**************************************************************************** - * Name: elf_emit_memory - * - * Description: - * Fill the note segment information - * - ****************************************************************************/ - -static void elf_emit_memory(FAR struct elf_dumpinfo_s *cinfo, int memsegs) -{ - int i; - - for (i = 0; i < memsegs; i++) - { - if (cinfo->regions[i].flags & PF_REGISTER) - { - FAR uintptr_t *start = (FAR uintptr_t *)cinfo->regions[i].start; - FAR uintptr_t *end = (FAR uintptr_t *)cinfo->regions[i].end; - uintptr_t buf[64]; - size_t offset = 0; - - while (start < end) - { - buf[offset++] = *start++; - - if (offset % (sizeof(buf) / sizeof(uintptr_t)) == 0) - { - elf_emit(cinfo, buf, sizeof(buf)); - offset = 0; - } - } - - if (offset != 0) - { - elf_emit(cinfo, buf, offset * sizeof(uintptr_t)); - } - } - else - { - elf_emit(cinfo, (FAR void *)cinfo->regions[i].start, - cinfo->regions[i].end - cinfo->regions[i].start); - } - - /* Align to page */ - - elf_emit_align(cinfo); - } -} - -/**************************************************************************** - * Name: elf_emit_tcb_phdr - * - * Description: - * Fill the program segment header from tcb - * - ****************************************************************************/ - -static void elf_emit_tcb_phdr(FAR struct elf_dumpinfo_s *cinfo, - FAR struct tcb_s *tcb, - FAR Elf_Phdr *phdr, FAR off_t *offset) -{ - uintptr_t sp; - - phdr->p_vaddr = 0; - - if (running_task() != tcb) - { - sp = up_getusrsp(tcb->xcp.regs); - - if (sp > (uintptr_t)tcb->stack_base_ptr && - sp < (uintptr_t)tcb->stack_base_ptr + tcb->adj_stack_size) - { - phdr->p_filesz = ((uintptr_t)tcb->stack_base_ptr + - tcb->adj_stack_size) - sp; - phdr->p_vaddr = sp; - } -#ifdef CONFIG_STACK_COLORATION - else - { - phdr->p_filesz = up_check_tcbstack(tcb); - phdr->p_vaddr = (uintptr_t)tcb->stack_base_ptr + - (tcb->adj_stack_size - phdr->p_filesz); - } -#endif - } - - if (phdr->p_vaddr == 0) - { - phdr->p_vaddr = (uintptr_t)tcb->stack_alloc_ptr; - phdr->p_filesz = tcb->adj_stack_size + - (tcb->stack_base_ptr - tcb->stack_alloc_ptr); - } - - sp = ROUNDDOWN(phdr->p_vaddr, PROGRAM_ALIGNMENT); - phdr->p_filesz = ROUNDUP(phdr->p_filesz + - (phdr->p_vaddr - sp), PROGRAM_ALIGNMENT); - phdr->p_vaddr = sp; - - phdr->p_type = PT_LOAD; - phdr->p_offset = ROUNDUP(*offset, ELF_PAGESIZE); - phdr->p_paddr = phdr->p_vaddr; - phdr->p_memsz = phdr->p_filesz; - phdr->p_flags = PF_X | PF_W | PF_R; - phdr->p_align = ELF_PAGESIZE; - *offset += ROUNDUP(phdr->p_memsz, ELF_PAGESIZE); - - elf_emit(cinfo, phdr, sizeof(*phdr)); -} - -/**************************************************************************** - * Name: elf_emit_phdr - * - * Description: - * Fill the program segment header - * - ****************************************************************************/ - -static void elf_emit_phdr(FAR struct elf_dumpinfo_s *cinfo, - int stksegs, int memsegs) -{ - off_t offset = cinfo->stream->nput + - (stksegs + memsegs + 1) * sizeof(Elf_Phdr); - Elf_Phdr phdr; - int i; - - memset(&phdr, 0, sizeof(Elf_Phdr)); - - phdr.p_type = PT_NOTE; - phdr.p_offset = offset; - phdr.p_filesz = elf_get_note_size(stksegs); - offset += phdr.p_filesz; - - elf_emit(cinfo, &phdr, sizeof(phdr)); - - if (cinfo->pid == INVALID_PROCESS_ID) - { - for (i = 0; i < g_npidhash; i++) - { - if (g_pidhash[i] != NULL) - { - elf_emit_tcb_phdr(cinfo, g_pidhash[i], &phdr, &offset); - } - } - } - else - { - elf_emit_tcb_phdr(cinfo, nxsched_get_tcb(cinfo->pid), - &phdr, &offset); - } - - /* Write program headers for segments dump */ - - for (i = 0; i < memsegs; i++) - { - phdr.p_type = PT_LOAD; - phdr.p_offset = ROUNDUP(offset, ELF_PAGESIZE); - phdr.p_vaddr = cinfo->regions[i].start; - phdr.p_paddr = phdr.p_vaddr; - phdr.p_filesz = cinfo->regions[i].end - cinfo->regions[i].start; - phdr.p_memsz = phdr.p_filesz; - phdr.p_flags = cinfo->regions[i].flags; - phdr.p_align = ELF_PAGESIZE; - offset += ROUNDUP(phdr.p_memsz, ELF_PAGESIZE); - elf_emit(cinfo, &phdr, sizeof(phdr)); - } -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: elf_coredump - * - * Description: - * Generat the core dump stream as ELF structure. - * - * Input Parameters: - * dumpinfo - elf coredump informations - * - * Returned Value: - * Zero (OK) on success; a negated errno value on failure. - * - ****************************************************************************/ - -int elf_coredump(FAR struct elf_dumpinfo_s *cinfo) -{ - irqstate_t flags; - int memsegs = 0; - int stksegs; - - flags = enter_critical_section(); - - if (cinfo->pid != INVALID_PROCESS_ID) - { - if (nxsched_get_tcb(cinfo->pid) == NULL) - { - leave_critical_section(flags); - return -EINVAL; - } - - stksegs = 1; - } - else - { - stksegs = elf_get_ntcb(); - } - - /* Check the memory region */ - - if (cinfo->regions != NULL) - { - for (; cinfo->regions[memsegs].start < - cinfo->regions[memsegs].end; memsegs++); - } - - /* Fill notes section */ - - elf_emit_hdr(cinfo, stksegs + memsegs + 1); - - /* Fill all the program information about the process for the - * notes. This also sets up the file header. - */ - - elf_emit_phdr(cinfo, stksegs, memsegs); - - /* Fill note information */ - - elf_emit_note(cinfo); - - /* Align to page */ - - elf_emit_align(cinfo); - - /* Dump stack */ - - elf_emit_stack(cinfo); - - /* Dump memory segments */ - - if (memsegs > 0) - { - elf_emit_memory(cinfo, memsegs); - } - - /* Flush the dump */ - - elf_flush(cinfo); - - leave_critical_section(flags); - - return OK; -} diff --git a/binfmt/nxflat.c b/binfmt/nxflat.c index b1ec250e63d9f..175c3eb5ddbbe 100644 --- a/binfmt/nxflat.c +++ b/binfmt/nxflat.c @@ -81,7 +81,6 @@ static struct binfmt_s g_nxflatbinfmt = NULL, /* next */ nxflat_loadbinary, /* load */ nxflat_unloadbinary, /* unload */ - NULL, /* coredump */ }; /**************************************************************************** diff --git a/boards/Kconfig b/boards/Kconfig index e98058c9e6a65..44d2ec5cd0632 100644 --- a/boards/Kconfig +++ b/boards/Kconfig @@ -4634,14 +4634,14 @@ config BOARD_CRASHDUMP config BOARD_COREDUMP_SYSLOG bool "Enable Core dump to syslog" default n - depends on ELF_COREDUMP + depends on COREDUMP ---help--- Enable put coredump to syslog when crash. config BOARD_COREDUMP_BLKDEV bool "Enable Core Dump to block device" default n - depends on ELF_COREDUMP + depends on COREDUMP ---help--- Enable save coredump at block device when crash. diff --git a/boards/arm/imx6/sabre-6quad/configs/coredump/defconfig b/boards/arm/imx6/sabre-6quad/configs/coredump/defconfig index da7f72396b10c..e8112e8b25f57 100644 --- a/boards/arm/imx6/sabre-6quad/configs/coredump/defconfig +++ b/boards/arm/imx6/sabre-6quad/configs/coredump/defconfig @@ -21,13 +21,12 @@ CONFIG_BOARD_COREDUMP_SYSLOG=y CONFIG_BOARD_LOOPSPERMSEC=99369 CONFIG_BOOT_RUNFROMSDRAM=y CONFIG_BUILTIN=y +CONFIG_COREDUMP=y CONFIG_DEBUG_ASSERTIONS=y CONFIG_DEBUG_FEATURES=y CONFIG_DEBUG_FULLOPT=y CONFIG_DEBUG_SYMBOLS=y CONFIG_DEV_ZERO=y -CONFIG_ELF=y -CONFIG_ELF_COREDUMP=y CONFIG_EXAMPLES_HELLO=y CONFIG_EXPERIMENTAL=y CONFIG_FS_PROCFS=y diff --git a/include/nuttx/binfmt/binfmt.h b/include/nuttx/binfmt/binfmt.h index 044719692f58a..9582ee1ac4f47 100644 --- a/include/nuttx/binfmt/binfmt.h +++ b/include/nuttx/binfmt/binfmt.h @@ -31,18 +31,14 @@ #include #include -#include #include -#include -#include /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ #define BINFMT_NALLOC 4 -#define COREDUMP_MAGIC 0x434f5245 /**************************************************************************** * Public Types @@ -138,22 +134,6 @@ struct binfmt_s /* Unload module callback */ CODE int (*unload)(FAR struct binary_s *bin); - - /* Coredump callback */ - - CODE int (*coredump)(FAR const struct memory_region_s *regions, - FAR struct lib_outstream_s *stream, - pid_t pid); -}; - -/* Coredump information for block header */ - -struct coredump_info_s -{ - uint32_t magic; - struct utsname name; - time_t time; - size_t size; }; /**************************************************************************** @@ -209,23 +189,6 @@ int register_binfmt(FAR struct binfmt_s *binfmt); int unregister_binfmt(FAR struct binfmt_s *binfmt); -/**************************************************************************** - * Name: core_dump - * - * Description: - * This function for generating core dump stream. - * - * Returned Value: - * This is a NuttX internal function so it follows the convention that - * 0 (OK) is returned on success and a negated errno is returned on - * failure. - * - ****************************************************************************/ - -int core_dump(FAR const struct memory_region_s *regions, - FAR struct lib_outstream_s *stream, - pid_t pid); - /**************************************************************************** * Name: load_module * diff --git a/include/nuttx/binfmt/elf.h b/include/nuttx/binfmt/elf.h index 854c0106883ad..60793dabc8ad6 100644 --- a/include/nuttx/binfmt/elf.h +++ b/include/nuttx/binfmt/elf.h @@ -129,19 +129,6 @@ struct elf_loadinfo_s struct file file; /* Descriptor for the file being loaded */ }; -/* This struct provides a description of the dump information of - * memory regions. - */ - -#ifdef CONFIG_ELF_COREDUMP -struct elf_dumpinfo_s -{ - FAR const struct memory_region_s *regions; - FAR struct lib_outstream_s *stream; - pid_t pid; -}; -#endif - /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -233,24 +220,6 @@ int elf_bind(FAR struct elf_loadinfo_s *loadinfo, int elf_unload(FAR struct elf_loadinfo_s *loadinfo); -/**************************************************************************** - * Name: elf_coredump - * - * Description: - * Generat the core dump stream as ELF structure. - * - * Input Parameters: - * dumpinfo - elf coredump informations - * - * Returned Value: - * Zero (OK) on success; a negated errno value on failure. - * - ****************************************************************************/ - -#ifdef CONFIG_ELF_COREDUMP -int elf_coredump(FAR struct elf_dumpinfo_s *dumpinfo); -#endif - #undef EXTERN #if defined(__cplusplus) } diff --git a/include/nuttx/coredump.h b/include/nuttx/coredump.h index 46f1fa0975023..ee798223a0150 100644 --- a/include/nuttx/coredump.h +++ b/include/nuttx/coredump.h @@ -27,9 +27,32 @@ * Included Files ****************************************************************************/ -#include +#include #include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define COREDUMP_MAGIC 0x434f5245 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* Coredump information for block header */ + +struct coredump_info_s +{ + uint32_t magic; + struct utsname name; + time_t time; + size_t size; +}; + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -54,4 +77,16 @@ int coredump_set_memory_region(FAR const struct memory_region_s *region); int coredump_add_memory_region(FAR const void *ptr, size_t size); +/**************************************************************************** + * Name: coredump + * + * Description: + * This function for generating core dump stream. + * + ****************************************************************************/ + +int coredump(FAR const struct memory_region_s *regions, + FAR struct lib_outstream_s *stream, + pid_t pid); + #endif /* __INCLUDE_NUTTX_COREDUMP_H */ diff --git a/include/nuttx/elf.h b/include/nuttx/elf.h index 522795de78aaa..0737f5b61523f 100644 --- a/include/nuttx/elf.h +++ b/include/nuttx/elf.h @@ -40,7 +40,7 @@ * Public Types ****************************************************************************/ -#ifdef CONFIG_ELF_COREDUMP +#ifdef CONFIG_COREDUMP typedef struct elf_prpsinfo_s { char pr_state; /* Numeric process state */ diff --git a/sched/Kconfig b/sched/Kconfig index fe7cd0008af4b..8b09ca1f02571 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -2047,3 +2047,15 @@ config ASSERT_PAUSE_CPU_TIMEOUT ---help--- Timeout in milisecond to pause another CPU when assert. Only available when SMP is enabled. + Enable to support perf events. + +config COREDUMP + bool "Coredump support" + depends on ARCH_HAVE_TCBINFO + default n + ---help--- + Generate ELF core dump to provide information about the CPU state and the + memory state of program. + The memory state embeds a snapshot of all segments mapped in the + memory space of the program. The CPU state contains register values + when the core dump has been generated. diff --git a/sched/misc/CMakeLists.txt b/sched/misc/CMakeLists.txt index d9afdf25ed9fb..43003dee4851c 100644 --- a/sched/misc/CMakeLists.txt +++ b/sched/misc/CMakeLists.txt @@ -26,7 +26,7 @@ if(CONFIG_ARCH_DEADLOCKDUMP) list(APPEND SRCS deadlock.c) endif() -if(CONFIG_BOARD_COREDUMP_SYSLOG OR CONFIG_BOARD_COREDUMP_BLKDEV) +if(CONFIG_COREDUMP) list(APPEND SRCS coredump.c) endif() diff --git a/sched/misc/Make.defs b/sched/misc/Make.defs index c105d79f96d9d..9a40bec31ce4b 100644 --- a/sched/misc/Make.defs +++ b/sched/misc/Make.defs @@ -26,7 +26,7 @@ ifeq ($(CONFIG_ARCH_DEADLOCKDUMP),y) CSRCS += deadlock.c endif -ifneq ($(CONFIG_BOARD_COREDUMP_SYSLOG)$(CONFIG_BOARD_COREDUMP_BLKDEV),) +ifeq ($(CONFIG_COREDUMP),y) CSRCS += coredump.c endif diff --git a/sched/misc/coredump.c b/sched/misc/coredump.c index 16c6867b5880e..76d048251cb64 100644 --- a/sched/misc/coredump.c +++ b/sched/misc/coredump.c @@ -24,15 +24,55 @@ * Included Files ****************************************************************************/ +#include +#include + #include #include +#include +#include +#include + +#include "sched/sched.h" #include "coredump.h" /**************************************************************************** * Private Data ****************************************************************************/ +#ifdef PAGESIZE +# define ELF_PAGESIZE PAGESIZE +#else +# define ELF_PAGESIZE 1024 +#endif + +#define PROGRAM_ALIGNMENT 64 + +#define ROUNDUP(x, y) ((x + (y - 1)) / (y)) * (y) +#define ROUNDDOWN(x ,y) (((x) / (y)) * (y)) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This struct provides a description of the dump information of + * memory regions. + */ + +struct elf_dumpinfo_s +{ + FAR const struct memory_region_s *regions; + FAR struct lib_outstream_s *stream; + pid_t pid; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint8_t g_running_regs[XCPTCONTEXT_SIZE] aligned_data(16); + #ifdef CONFIG_BOARD_COREDUMP_COMPRESSION static struct lib_lzfoutstream_s g_lzfstream; #endif @@ -63,6 +103,521 @@ static const struct memory_region_s *g_regions; * Private Functions ****************************************************************************/ +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: elf_flush + * + * Description: + * Flush the out stream + * + ****************************************************************************/ + +static int elf_flush(FAR struct elf_dumpinfo_s *cinfo) +{ + return lib_stream_flush(cinfo->stream); +} + +/**************************************************************************** + * Name: elf_emit + * + * Description: + * Send the dump data to binfmt_outstream_s + * + ****************************************************************************/ + +static int elf_emit(FAR struct elf_dumpinfo_s *cinfo, + FAR const void *buf, size_t len) +{ + FAR const uint8_t *ptr = buf; + size_t total = len; + int ret; + + while (total > 0) + { + ret = lib_stream_puts(cinfo->stream, ptr, total); + if (ret < 0) + { + break; + } + + total -= ret; + ptr += ret; + } + + return ret < 0 ? ret : len - total; +} + +/**************************************************************************** + * Name: elf_emit_align + * + * Description: + * Align the filled data according to the current offset + * + ****************************************************************************/ + +static int elf_emit_align(FAR struct elf_dumpinfo_s *cinfo) +{ + off_t align = ROUNDUP(cinfo->stream->nput, + ELF_PAGESIZE) - cinfo->stream->nput; + unsigned char null[256]; + off_t total = align; + off_t ret; + + memset(null, 0, sizeof(null)); + + while (total > 0) + { + ret = elf_emit(cinfo, null, total > sizeof(null) ? + sizeof(null) : total); + if (ret <= 0) + { + break; + } + + total -= ret; + } + + return ret < 0 ? ret : align; +} + +/**************************************************************************** + * Name: elf_emit_hdr + * + * Description: + * Fill the elf header + * + ****************************************************************************/ + +static int elf_emit_hdr(FAR struct elf_dumpinfo_s *cinfo, + int segs) +{ + Elf_Ehdr ehdr; + + memset(&ehdr, 0, sizeof(ehdr)); + memcpy(ehdr.e_ident, ELFMAG, EI_MAGIC_SIZE); + + ehdr.e_ident[EI_CLASS] = ELF_CLASS; + ehdr.e_ident[EI_DATA] = ELF_DATA; + ehdr.e_ident[EI_VERSION] = EV_CURRENT; + ehdr.e_ident[EI_OSABI] = ELF_OSABI; + + ehdr.e_type = ET_CORE; + ehdr.e_machine = EM_ARCH; + ehdr.e_version = EV_CURRENT; + ehdr.e_phoff = sizeof(Elf_Ehdr); + ehdr.e_flags = EF_FLAG; + ehdr.e_ehsize = sizeof(Elf_Ehdr); + ehdr.e_phentsize = sizeof(Elf_Phdr); + ehdr.e_phnum = segs; + + return elf_emit(cinfo, &ehdr, sizeof(ehdr)); +} + +/**************************************************************************** + * Name: elf_get_ntcb + * + * Description: + * Calculate the note segment size + * + ****************************************************************************/ + +static int elf_get_ntcb(void) +{ + int count = 0; + int i; + + for (i = 0; i < g_npidhash; i++) + { + if (g_pidhash[i] != NULL) + { + count++; + } + } + + return count; +} + +/**************************************************************************** + * Name: elf_get_note_size + * + * Description: + * Calculate the note segment size + * + ****************************************************************************/ + +static int elf_get_note_size(int stksegs) +{ + int total; + + total = stksegs * (sizeof(Elf_Nhdr) + ROUNDUP(CONFIG_TASK_NAME_SIZE, 8) + + sizeof(elf_prstatus_t)); + total += stksegs * (sizeof(Elf_Nhdr) + ROUNDUP(CONFIG_TASK_NAME_SIZE, 8) + + sizeof(elf_prpsinfo_t)); + return total; +} + +/**************************************************************************** + * Name: elf_emit_tcb_note + * + * Description: + * Fill the note segment information from tcb + * + ****************************************************************************/ + +static void elf_emit_tcb_note(FAR struct elf_dumpinfo_s *cinfo, + FAR struct tcb_s *tcb) +{ + char name[ROUNDUP(CONFIG_TASK_NAME_SIZE, 8)]; + elf_prstatus_t status; + elf_prpsinfo_t info; + FAR uintptr_t *regs; + Elf_Nhdr nhdr; + int i; + + memset(&info, 0x0, sizeof(info)); + memset(&status, 0x0, sizeof(status)); + + /* Fill Process info */ + + nhdr.n_namesz = sizeof(name); + nhdr.n_descsz = sizeof(info); + nhdr.n_type = NT_PRPSINFO; + + elf_emit(cinfo, &nhdr, sizeof(nhdr)); + + strlcpy(name, tcb->name, sizeof(name)); + elf_emit(cinfo, name, sizeof(name)); + + info.pr_pid = tcb->pid; + strlcpy(info.pr_fname, tcb->name, sizeof(info.pr_fname)); + elf_emit(cinfo, &info, sizeof(info)); + + /* Fill Process status */ + + nhdr.n_descsz = sizeof(status); + nhdr.n_type = NT_PRSTATUS; + + elf_emit(cinfo, &nhdr, sizeof(nhdr)); + elf_emit(cinfo, name, sizeof(name)); + + status.pr_pid = tcb->pid; + + if (running_task() == tcb) + { + if (up_interrupt_context()) + { + regs = (FAR uintptr_t *)up_current_regs(); + } + else + { + up_saveusercontext(g_running_regs); + regs = (FAR uintptr_t *)g_running_regs; + } + } + else + { + regs = (FAR uintptr_t *)tcb->xcp.regs; + } + + if (regs != NULL) + { + for (i = 0; i < nitems(status.pr_regs); i++) + { + if (g_tcbinfo.reg_off.p[i] == UINT16_MAX) + { + continue; + } + else + { + status.pr_regs[i] = + *(uintptr_t *)((uint8_t *)regs + g_tcbinfo.reg_off.p[i]); + } + } + } + + elf_emit(cinfo, &status, sizeof(status)); +} + +/**************************************************************************** + * Name: elf_emit_note + * + * Description: + * Fill the note segment information + * + ****************************************************************************/ + +static void elf_emit_note(FAR struct elf_dumpinfo_s *cinfo) +{ + int i; + + if (cinfo->pid == INVALID_PROCESS_ID) + { + for (i = 0; i < g_npidhash; i++) + { + if (g_pidhash[i] != NULL) + { + elf_emit_tcb_note(cinfo, g_pidhash[i]); + } + } + } + else + { + elf_emit_tcb_note(cinfo, nxsched_get_tcb(cinfo->pid)); + } +} + +/**************************************************************************** + * Name: elf_emit_tcb_stack + * + * Description: + * Fill the task stack information from tcb + * + ****************************************************************************/ + +static void elf_emit_tcb_stack(FAR struct elf_dumpinfo_s *cinfo, + FAR struct tcb_s *tcb) +{ + uintptr_t buf = 0; + uintptr_t sp; + size_t len; + + if (running_task() != tcb) + { + sp = up_getusrsp(tcb->xcp.regs); + + if (sp > (uintptr_t)tcb->stack_base_ptr && + sp < (uintptr_t)tcb->stack_base_ptr + tcb->adj_stack_size) + { + len = ((uintptr_t)tcb->stack_base_ptr + + tcb->adj_stack_size) - sp; + buf = sp; + } +#ifdef CONFIG_STACK_COLORATION + else + { + len = up_check_tcbstack(tcb); + buf = (uintptr_t)tcb->stack_base_ptr + + (tcb->adj_stack_size - len); + } +#endif + } + + if (buf == 0) + { + buf = (uintptr_t)tcb->stack_alloc_ptr; + len = tcb->adj_stack_size + + (tcb->stack_base_ptr - tcb->stack_alloc_ptr); + } + + sp = ROUNDDOWN(buf, PROGRAM_ALIGNMENT); + len = ROUNDUP(len + (buf - sp), PROGRAM_ALIGNMENT); + buf = sp; + + elf_emit(cinfo, (FAR void *)buf, len); + + /* Align to page */ + + elf_emit_align(cinfo); +} + +/**************************************************************************** + * Name: elf_emit_stack + * + * Description: + * Fill the task stack information + * + ****************************************************************************/ + +static void elf_emit_stack(FAR struct elf_dumpinfo_s *cinfo) +{ + int i; + + if (cinfo->pid == INVALID_PROCESS_ID) + { + for (i = 0; i < g_npidhash; i++) + { + if (g_pidhash[i] != NULL) + { + elf_emit_tcb_stack(cinfo, g_pidhash[i]); + } + } + } + else + { + elf_emit_tcb_stack(cinfo, nxsched_get_tcb(cinfo->pid)); + } +} + +/**************************************************************************** + * Name: elf_emit_memory + * + * Description: + * Fill the note segment information + * + ****************************************************************************/ + +static void elf_emit_memory(FAR struct elf_dumpinfo_s *cinfo, int memsegs) +{ + int i; + + for (i = 0; i < memsegs; i++) + { + if (cinfo->regions[i].flags & PF_REGISTER) + { + FAR uintptr_t *start = (FAR uintptr_t *)cinfo->regions[i].start; + FAR uintptr_t *end = (FAR uintptr_t *)cinfo->regions[i].end; + uintptr_t buf[64]; + size_t offset = 0; + + while (start < end) + { + buf[offset++] = *start++; + + if (offset % (sizeof(buf) / sizeof(uintptr_t)) == 0) + { + elf_emit(cinfo, buf, sizeof(buf)); + offset = 0; + } + } + + if (offset != 0) + { + elf_emit(cinfo, buf, offset * sizeof(uintptr_t)); + } + } + else + { + elf_emit(cinfo, (FAR void *)cinfo->regions[i].start, + cinfo->regions[i].end - cinfo->regions[i].start); + } + + /* Align to page */ + + elf_emit_align(cinfo); + } +} + +/**************************************************************************** + * Name: elf_emit_tcb_phdr + * + * Description: + * Fill the program segment header from tcb + * + ****************************************************************************/ + +static void elf_emit_tcb_phdr(FAR struct elf_dumpinfo_s *cinfo, + FAR struct tcb_s *tcb, + FAR Elf_Phdr *phdr, off_t *offset) +{ + uintptr_t sp; + + phdr->p_vaddr = 0; + + if (running_task() != tcb) + { + sp = up_getusrsp(tcb->xcp.regs); + + if (sp > (uintptr_t)tcb->stack_base_ptr && + sp < (uintptr_t)tcb->stack_base_ptr + tcb->adj_stack_size) + { + phdr->p_filesz = ((uintptr_t)tcb->stack_base_ptr + + tcb->adj_stack_size) - sp; + phdr->p_vaddr = sp; + } +#ifdef CONFIG_STACK_COLORATION + else + { + phdr->p_filesz = up_check_tcbstack(tcb); + phdr->p_vaddr = (uintptr_t)tcb->stack_base_ptr + + (tcb->adj_stack_size - phdr->p_filesz); + } +#endif + } + + if (phdr->p_vaddr == 0) + { + phdr->p_vaddr = (uintptr_t)tcb->stack_alloc_ptr; + phdr->p_filesz = tcb->adj_stack_size + + (tcb->stack_base_ptr - tcb->stack_alloc_ptr); + } + + sp = ROUNDDOWN(phdr->p_vaddr, PROGRAM_ALIGNMENT); + phdr->p_filesz = ROUNDUP(phdr->p_filesz + + (phdr->p_vaddr - sp), PROGRAM_ALIGNMENT); + phdr->p_vaddr = sp; + + phdr->p_type = PT_LOAD; + phdr->p_offset = ROUNDUP(*offset, ELF_PAGESIZE); + phdr->p_paddr = phdr->p_vaddr; + phdr->p_memsz = phdr->p_filesz; + phdr->p_flags = PF_X | PF_W | PF_R; + phdr->p_align = ELF_PAGESIZE; + *offset += ROUNDUP(phdr->p_memsz, ELF_PAGESIZE); + + elf_emit(cinfo, phdr, sizeof(*phdr)); +} + +/**************************************************************************** + * Name: elf_emit_phdr + * + * Description: + * Fill the program segment header + * + ****************************************************************************/ + +static void elf_emit_phdr(FAR struct elf_dumpinfo_s *cinfo, + int stksegs, int memsegs) +{ + off_t offset = cinfo->stream->nput + + (stksegs + memsegs + 1) * sizeof(Elf_Phdr); + Elf_Phdr phdr; + int i; + + memset(&phdr, 0, sizeof(Elf_Phdr)); + + phdr.p_type = PT_NOTE; + phdr.p_offset = offset; + phdr.p_filesz = elf_get_note_size(stksegs); + offset += phdr.p_filesz; + + elf_emit(cinfo, &phdr, sizeof(phdr)); + + if (cinfo->pid == INVALID_PROCESS_ID) + { + for (i = 0; i < g_npidhash; i++) + { + if (g_pidhash[i] != NULL) + { + elf_emit_tcb_phdr(cinfo, g_pidhash[i], &phdr, &offset); + } + } + } + else + { + elf_emit_tcb_phdr(cinfo, nxsched_get_tcb(cinfo->pid), + &phdr, &offset); + } + + /* Write program headers for segments dump */ + + for (i = 0; i < memsegs; i++) + { + phdr.p_type = PT_LOAD; + phdr.p_offset = ROUNDUP(offset, ELF_PAGESIZE); + phdr.p_vaddr = cinfo->regions[i].start; + phdr.p_paddr = phdr.p_vaddr; + phdr.p_filesz = cinfo->regions[i].end - cinfo->regions[i].start; + phdr.p_memsz = phdr.p_filesz; + phdr.p_flags = cinfo->regions[i].flags; + phdr.p_align = ELF_PAGESIZE; + offset += ROUNDUP(phdr.p_memsz, ELF_PAGESIZE); + elf_emit(cinfo, &phdr, sizeof(phdr)); + } +} + /**************************************************************************** * Name: coredump_dump_syslog * @@ -106,7 +661,7 @@ static void coredump_dump_syslog(pid_t pid) /* Do core dump */ - core_dump(g_regions, stream, pid); + coredump(g_regions, stream, pid); # ifdef CONFIG_BOARD_COREDUMP_COMPRESSION _alert("Finish coredump (Compression Enabled). %s formatted\n", @@ -161,7 +716,7 @@ static void coredump_dump_blkdev(pid_t pid) stream = &g_lzfstream; #endif - ret = core_dump(g_regions, stream, pid); + ret = coredump(g_regions, stream, pid); if (ret < 0) { _alert("Coredump fail\n"); @@ -352,3 +907,87 @@ void coredump_dump(pid_t pid) coredump_dump_blkdev(pid); #endif } + +/**************************************************************************** + * Name: coredump + * + * Description: + * This function for generating core dump stream. + * + ****************************************************************************/ + +int coredump(FAR const struct memory_region_s *regions, + FAR struct lib_outstream_s *stream, + pid_t pid) +{ + struct elf_dumpinfo_s cinfo; + irqstate_t flags; + int memsegs = 0; + int stksegs; + + cinfo.regions = regions; + cinfo.stream = stream; + cinfo.pid = pid; + + flags = enter_critical_section(); + + if (cinfo.pid != INVALID_PROCESS_ID) + { + if (nxsched_get_tcb(cinfo.pid) == NULL) + { + leave_critical_section(flags); + return -EINVAL; + } + + stksegs = 1; + } + else + { + stksegs = elf_get_ntcb(); + } + + /* Check the memory region */ + + if (cinfo.regions != NULL) + { + for (; cinfo.regions[memsegs].start < + cinfo.regions[memsegs].end; memsegs++); + } + + /* Fill notes section */ + + elf_emit_hdr(&cinfo, stksegs + memsegs + 1); + + /* Fill all the program information about the process for the + * notes. This also sets up the file header. + */ + + elf_emit_phdr(&cinfo, stksegs, memsegs); + + /* Fill note information */ + + elf_emit_note(&cinfo); + + /* Align to page */ + + elf_emit_align(&cinfo); + + /* Dump stack */ + + elf_emit_stack(&cinfo); + + /* Dump memory segments */ + + if (memsegs > 0) + { + elf_emit_memory(&cinfo, memsegs); + } + + /* Flush the dump */ + + elf_flush(&cinfo); + + leave_critical_section(flags); + + return OK; +} From 2c73735f0eaeb2a05673ef08d7c20ede34efaff9 Mon Sep 17 00:00:00 2001 From: anjiahao Date: Sun, 30 Jun 2024 16:49:13 +0800 Subject: [PATCH 07/20] modlib:Move addrenv logic to modlib Signed-off-by: anjiahao --- include/nuttx/lib/modlib.h | 32 ++++ libs/libc/modlib/CMakeLists.txt | 1 + libs/libc/modlib/Make.defs | 4 +- libs/libc/modlib/modlib.h | 84 ++++++++++ libs/libc/modlib/modlib_addrenv.c | 251 ++++++++++++++++++++++++++++++ libs/libc/modlib/modlib_bind.c | 32 ++++ libs/libc/modlib/modlib_load.c | 89 ++++++++++- libs/libc/modlib/modlib_unload.c | 7 + 8 files changed, 494 insertions(+), 6 deletions(-) create mode 100644 libs/libc/modlib/modlib_addrenv.c diff --git a/include/nuttx/lib/modlib.h b/include/nuttx/lib/modlib.h index 2a9c24b5b5479..f55521e07fa67 100644 --- a/include/nuttx/lib/modlib.h +++ b/include/nuttx/lib/modlib.h @@ -32,6 +32,8 @@ #include #include +#include + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -227,6 +229,17 @@ struct mod_loadinfo_s uint16_t buflen; /* size of iobuffer[] */ int filfd; /* Descriptor for the file being loaded */ int nexports; /* ET_DYN - Number of symbols exported */ + + /* Address environment. + * + * addrenv - This is the handle created by addrenv_allocate() that can be + * used to manage the tasks address space. + */ + +#ifdef CONFIG_ARCH_ADDRENV + FAR addrenv_t *addrenv; /* Address environment */ + FAR addrenv_t *oldenv; /* Saved address environment */ +#endif }; /**************************************************************************** @@ -318,6 +331,25 @@ void modlib_setsymtab(FAR const struct symtab_s *symtab, int nsymbols); int modlib_load(FAR struct mod_loadinfo_s *loadinfo); +/**************************************************************************** + * Name: modlib_load_with_addrenv + * + * Description: + * Loads the binary into memory, use the address environment to load the + * binary. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_ADDRENV +int modlib_load_with_addrenv(FAR struct mod_loadinfo_s *loadinfo); +#else +# define modlib_load_with_addrenv(l) modlib_load(l) +#endif + /**************************************************************************** * Name: modlib_bind * diff --git a/libs/libc/modlib/CMakeLists.txt b/libs/libc/modlib/CMakeLists.txt index 7372cad4fea39..fde06db98e38c 100644 --- a/libs/libc/modlib/CMakeLists.txt +++ b/libs/libc/modlib/CMakeLists.txt @@ -25,6 +25,7 @@ if(CONFIG_LIBC_MODLIB) list( APPEND SRCS + modlib_addrenv.c modlib_bind.c modlib_depend.c modlib_init.c diff --git a/libs/libc/modlib/Make.defs b/libs/libc/modlib/Make.defs index c9f5c222cfc34..4d727470d87af 100644 --- a/libs/libc/modlib/Make.defs +++ b/libs/libc/modlib/Make.defs @@ -24,8 +24,8 @@ ifeq ($(CONFIG_LIBC_MODLIB),y) # Add the nuttx/lib/modlib.h files to the build -CSRCS += modlib_bind.c modlib_depend.c modlib_init.c modlib_iobuffer.c -CSRCS += modlib_load.c modlib_loadhdrs.c modlib_verify.c +CSRCS += modlib_addrenv.c modlib_bind.c modlib_depend.c modlib_init.c +CSRCS += modlib_iobuffer.c modlib_load.c modlib_loadhdrs.c modlib_verify.c CSRCS += modlib_read.c modlib_registry.c modlib_sections.c CSRCS += modlib_symbols.c modlib_symtab.c modlib_uninit.c modlib_unload.c CSRCS += modlib_gethandle.c modlib_getsymbol.c modlib_insert.c diff --git a/libs/libc/modlib/modlib.h b/libs/libc/modlib/modlib.h index 74043cc5a4275..4e004521d37b6 100644 --- a/libs/libc/modlib/modlib.h +++ b/libs/libc/modlib/modlib.h @@ -27,6 +27,7 @@ * Included Files ****************************************************************************/ +#include #include /**************************************************************************** @@ -237,4 +238,87 @@ int modlib_reallocbuffer(FAR struct mod_loadinfo_s *loadinfo, int modlib_freebuffers(FAR struct mod_loadinfo_s *loadinfo); +#ifdef CONFIG_ARCH_ADDRENV + +/**************************************************************************** + * Name: modlib_addrenv_alloc + * + * Description: + * Allocate memory for the ELF image (textalloc and datastart). If + * CONFIG_ARCH_ADDRENV=n, textalloc will be allocated using kmm_zalloc() + * and datastart will be a offset from textalloc. If + * CONFIG_ARCH_ADDRENV=y, then textalloc and datastart will be allocated + * using up_addrenv_create(). In either case, there will be a unique + * instance of textalloc and datastart (and stack) for each instance of a + * process. + * + * Input Parameters: + * loadinfo - Load state information + * textsize - The size (in bytes) of the .text address environment needed + * for the ELF image (read/execute). + * datasize - The size (in bytes) of the .bss/.data address environment + * needed for the ELF image (read/write). + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int modlib_addrenv_alloc(FAR struct mod_loadinfo_s *loadinfo, + size_t textsize, size_t datasize); + +/**************************************************************************** + * Name: modlib_addrenv_select + * + * Description: + * Temporarily select the task's address environment. + * + * Input Parameters: + * loadinfo - Load state information + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int modlib_addrenv_select(FAR struct mod_loadinfo_s *loadinfo); + +/**************************************************************************** + * Name: modlib_addrenv_restore + * + * Description: + * Restore the address environment before modlib_addrenv_select() was + * called. + * + * Input Parameters: + * loadinfo - Load state information + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int modlib_addrenv_restore(FAR struct mod_loadinfo_s *loadinfo); + +/**************************************************************************** + * Name: modlib_addrenv_free + * + * Description: + * Release the address environment previously created by + * modlib_addrenv_alloc(). This function is called only under certain + * error conditions after the module has been loaded but not yet started. + * After the module has been started, the address environment will + * automatically be freed when the module exits. + * + * Input Parameters: + * loadinfo - Load state information + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void modlib_addrenv_free(FAR struct mod_loadinfo_s *loadinfo); + +#endif /* CONFIG_ARCH_ADDRENV */ #endif /* __LIBS_LIBC_MODLIB_MODLIB_H */ diff --git a/libs/libc/modlib/modlib_addrenv.c b/libs/libc/modlib/modlib_addrenv.c new file mode 100644 index 0000000000000..6d140ff341feb --- /dev/null +++ b/libs/libc/modlib/modlib_addrenv.c @@ -0,0 +1,251 @@ +/**************************************************************************** + * libs/libc/modlib/modlib_addrenv.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include +#include + +#include "modlib.h" + +#ifdef CONFIG_ARCH_ADDRENV + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ELF_TEXT_WRE (PROT_READ | PROT_WRITE | PROT_EXEC) +#define ELF_TEXT_RE (PROT_READ | PROT_EXEC) + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: modlib_addrenv_alloc + * + * Description: + * Allocate memory for the ELF image (textalloc and datastart). If + * CONFIG_ARCH_ADDRENV=n, textalloc will be allocated using kmm_zalloc() + * and datastart will be a offset from textalloc. If + * CONFIG_ARCH_ADDRENV=y, then textalloc and datastart will be allocated + * using up_addrenv_create(). In either case, there will be a unique + * instance of textalloc and datastart (and stack) for each instance of a + * process. + * + * Input Parameters: + * loadinfo - Load state information + * textsize - The size (in bytes) of the .text address environment needed + * for the ELF image (read/execute). + * datasize - The size (in bytes) of the .bss/.data address environment + * needed for the ELF image (read/write). + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int modlib_addrenv_alloc(FAR struct mod_loadinfo_s *loadinfo, + size_t textsize, size_t datasize) +{ +#if defined(CONFIG_ARCH_STACK_DYNAMIC) + size_t heapsize = ARCH_HEAP_SIZE; +#else + size_t heapsize = MAX(ARCH_HEAP_SIZE, CONFIG_ELF_STACKSIZE); +#endif + FAR struct arch_addrenv_s *addrenv; + FAR void *vtext; + FAR void *vdata; + int ret; + + /* Create an address environment for the new ELF task */ + + loadinfo->addrenv = addrenv_allocate(); + if (!loadinfo->addrenv) + { + return -ENOMEM; + } + + /* Start creating the address environment sections */ + + addrenv = &loadinfo->addrenv->addrenv; + + ret = up_addrenv_create(textsize, datasize, heapsize, addrenv); + if (ret < 0) + { + berr("ERROR: up_addrenv_create failed: %d\n", ret); + goto errout_with_addrenv; + } + + /* Get the virtual address associated with the start of the address + * environment. This is the base address that we will need to use to + * access the ELF image (but only if the address environment has been + * selected. + */ + + ret = up_addrenv_vtext(addrenv, &vtext); + if (ret < 0) + { + berr("ERROR: up_addrenv_vtext failed: %d\n", ret); + goto errout_with_addrenv; + } + + ret = up_addrenv_vdata(addrenv, textsize, &vdata); + if (ret < 0) + { + berr("ERROR: up_addrenv_vdata failed: %d\n", ret); + goto errout_with_addrenv; + } + + loadinfo->textalloc = (uintptr_t)vtext; + loadinfo->datastart = (uintptr_t)vdata; + + return OK; + +errout_with_addrenv: + addrenv_drop(loadinfo->addrenv, false); + return ret; +} + +/**************************************************************************** + * Name: modlib_addrenv_select + * + * Description: + * Temporarily select the task's address environment. + * + * Input Parameters: + * loadinfo - Load state information + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int modlib_addrenv_select(FAR struct mod_loadinfo_s *loadinfo) +{ + int ret; + + /* Instantiate the new address environment */ + + ret = addrenv_select(loadinfo->addrenv, &loadinfo->oldenv); + if (ret < 0) + { + berr("ERROR: addrenv_select failed: %d\n", ret); + return ret; + } + + /* Allow write access to .text */ + + ret = up_addrenv_mprot(&loadinfo->addrenv->addrenv, loadinfo->textalloc, + loadinfo->textsize, ELF_TEXT_WRE); + if (ret < 0) + { + berr("ERROR: up_addrenv_text_enable_write failed: %d\n", ret); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Name: modlib_addrenv_restore + * + * Description: + * Restore the address environment before modlib_addrenv_select() was + * called. + * + * Input Parameters: + * loadinfo - Load state information + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int modlib_addrenv_restore(FAR struct mod_loadinfo_s *loadinfo) +{ + int ret; + + /* Remove write access to .text */ + + ret = up_addrenv_mprot(&loadinfo->addrenv->addrenv, loadinfo->textalloc, + loadinfo->textsize, ELF_TEXT_RE); + if (ret < 0) + { + berr("ERROR: up_addrenv_text_disable_write failed: %d\n", ret); + return ret; + } + + /* Restore the old address environment */ + + ret = addrenv_restore(loadinfo->oldenv); + if (ret < 0) + { + berr("ERROR: addrenv_restore failed: %d\n", ret); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Name: modlib_addrenv_free + * + * Description: + * Release the address environment previously created by + * modlib_addrenv_alloc(). This function is called only under certain + * error conditions after the module has been loaded but not yet started. + * After the module has been started, the address environment will + * automatically be freed when the module exits. + * + * Input Parameters: + * loadinfo - Load state information + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void modlib_addrenv_free(FAR struct mod_loadinfo_s *loadinfo) +{ + /* Free the address environment */ + + addrenv_drop(loadinfo->addrenv, false); +} + +#endif diff --git a/libs/libc/modlib/modlib_bind.c b/libs/libc/modlib/modlib_bind.c index 2e9ef7ac5e2b0..d8679d28545d7 100644 --- a/libs/libc/modlib/modlib_bind.c +++ b/libs/libc/modlib/modlib_bind.c @@ -851,6 +851,23 @@ int modlib_bind(FAR struct module_s *modp, int ret; int i; +#ifdef CONFIG_ARCH_ADDRENV + /* If CONFIG_ARCH_ADDRENV=y, then the loaded ELF lies in a virtual address + * space that may not be in place now. modlib_addrenv_select() will + * temporarily instantiate that address space. + */ + + if (loadinfo->addrenv != NULL) + { + ret = modlib_addrenv_select(loadinfo); + if (ret < 0) + { + berr("ERROR: modlib_addrenv_select() failed: %d\n", ret); + return ret; + } + } +#endif + /* Find the symbol and string tables */ ret = modlib_findsymtab(loadinfo); @@ -1007,5 +1024,20 @@ int modlib_bind(FAR struct module_s *modp, } #endif +#ifdef CONFIG_ARCH_ADDRENV + if (loadinfo->addrenv != NULL) + { + int status = modlib_addrenv_restore(loadinfo); + if (status < 0) + { + berr("ERROR: modlib_addrenv_restore() failed: %d\n", status); + if (ret == OK) + { + ret = status; + } + } + } +#endif + return ret; } diff --git a/libs/libc/modlib/modlib_load.c b/libs/libc/modlib/modlib_load.c index fa58513c515b0..865df005a1fd1 100644 --- a/libs/libc/modlib/modlib_load.c +++ b/libs/libc/modlib/modlib_load.c @@ -129,7 +129,7 @@ static int modlib_section_alloc(FAR struct mod_loadinfo_s *loadinfo, * ****************************************************************************/ -static void modlib_elfsize(FAR struct mod_loadinfo_s *loadinfo) +static void modlib_elfsize(FAR struct mod_loadinfo_s *loadinfo, bool alloc) { size_t textsize = 0; size_t datasize = 0; @@ -187,7 +187,7 @@ static void modlib_elfsize(FAR struct mod_loadinfo_s *loadinfo) ) { #ifdef CONFIG_ARCH_USE_SEPARATED_SECTION - if (modlib_section_alloc(loadinfo, shdr, i) >= 0) + if (alloc && modlib_section_alloc(loadinfo, shdr, i) >= 0) { continue; } @@ -203,7 +203,7 @@ static void modlib_elfsize(FAR struct mod_loadinfo_s *loadinfo) else { #ifdef CONFIG_ARCH_USE_SEPARATED_SECTION - if (modlib_section_alloc(loadinfo, shdr, i) >= 0) + if (alloc && modlib_section_alloc(loadinfo, shdr, i) >= 0) { continue; } @@ -456,7 +456,7 @@ int modlib_load(FAR struct mod_loadinfo_s *loadinfo) /* Determine total size to allocate */ - modlib_elfsize(loadinfo); + modlib_elfsize(loadinfo, true); /* Allocate (and zero) memory for the ELF file. */ @@ -545,3 +545,84 @@ int modlib_load(FAR struct mod_loadinfo_s *loadinfo) modlib_unload(loadinfo); return ret; } + +/**************************************************************************** + * Name: modlib_load_with_addrenv + * + * Description: + * Loads the binary into memory, use the address environment to load the + * binary. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_ADDRENV +int modlib_load_with_addrenv(FAR struct mod_loadinfo_s *loadinfo) +{ + int ret; + + binfo("loadinfo: %p\n", loadinfo); + DEBUGASSERT(loadinfo && loadinfo->filfd >= 0); + + /* Load section and program headers into memory */ + + ret = modlib_loadhdrs(loadinfo); + if (ret < 0) + { + berr("ERROR: modlib_loadhdrs failed: %d\n", ret); + goto errout_with_buffers; + } + + /* Determine total size to allocate */ + + modlib_elfsize(loadinfo, false); + + ret = modlib_addrenv_alloc(loadinfo, loadinfo->textsize, + loadinfo->datasize); + if (ret < 0) + { + berr("ERROR: Failed to create address environment: %d\n", ret); + goto errout_with_buffers; + } + + /* If CONFIG_ARCH_ADDRENV=y, then the loaded ELF lies in a virtual address + * space that may not be in place now. elf_addrenv_select() will + * temporarily instantiate that address space. + */ + + ret = modlib_addrenv_select(loadinfo); + if (ret < 0) + { + berr("ERROR: elf_addrenv_select() failed: %d\n", ret); + goto errout_with_buffers; + } + + ret = modlib_loadfile(loadinfo); + if (ret < 0) + { + berr("ERROR: modlib_loadfile failed: %d\n", ret); + goto errout_with_addrenv; + } + + /* Restore the original address environment */ + + ret = modlib_addrenv_restore(loadinfo); + if (ret < 0) + { + berr("ERROR: modlib_addrenv_restore() failed: %d\n", ret); + goto errout_with_buffers; + } + + return OK; + +errout_with_addrenv: + modlib_addrenv_restore(loadinfo); + +errout_with_buffers: + modlib_unload(loadinfo); + return ret; +} +#endif diff --git a/libs/libc/modlib/modlib_unload.c b/libs/libc/modlib/modlib_unload.c index 9d36cc79d0966..5fde605d2b0a8 100644 --- a/libs/libc/modlib/modlib_unload.c +++ b/libs/libc/modlib/modlib_unload.c @@ -58,6 +58,13 @@ int modlib_unload(FAR struct mod_loadinfo_s *loadinfo) modlib_freebuffers(loadinfo); +#ifdef CONFIG_ARCH_ADDRENV + if (loadinfo->addrenv != NULL) + { + modlib_addrenv_free(loadinfo); + } + else +#endif /* Release memory holding the relocated ELF image */ /* ET_DYN has a single allocation so we only free textalloc */ From 05b5428a4788caca2a8481b66261d50fd2b4451b Mon Sep 17 00:00:00 2001 From: anjiahao Date: Tue, 9 Jul 2024 15:17:11 +0800 Subject: [PATCH 08/20] modlib:move Exception section logic to modlib Signed-off-by: anjiahao --- libs/libc/modlib/Kconfig | 10 ++++++++++ libs/libc/modlib/modlib_load.c | 14 ++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/libs/libc/modlib/Kconfig b/libs/libc/modlib/Kconfig index f225bb3544b9d..f1667180ad17b 100644 --- a/libs/libc/modlib/Kconfig +++ b/libs/libc/modlib/Kconfig @@ -106,4 +106,14 @@ config MODLIB_LOADTO_LMA relocate .data section to the final address(VMA) and zero .bss section by self. +config MODLIB_EXIDX_SECTNAME + string "ELF Section Name for Exception Index" + default ".ARM.exidx" + depends on CXX_EXCEPTION && ARCH_ARM + ---help--- + Set the name string for the exception index section on the ELF modules to + be loaded by the ELF binary loader. + + This is needed to support exception handling on loadable ELF modules. + endmenu # Module library configuration diff --git a/libs/libc/modlib/modlib_load.c b/libs/libc/modlib/modlib_load.c index 865df005a1fd1..152f477100e68 100644 --- a/libs/libc/modlib/modlib_load.c +++ b/libs/libc/modlib/modlib_load.c @@ -537,6 +537,20 @@ int modlib_load(FAR struct mod_loadinfo_s *loadinfo) goto errout_with_buffers; } +#ifdef CONFIG_MODLIB_EXIDX_SECTNAME + ret = modlib_findsection(loadinfo, CONFIG_MODLIB_EXIDX_SECTNAME); + if (ret < 0) + { + binfo("modlib_findsection: Exception Index section not found: %d\n", + ret); + } + else + { + up_init_exidx(loadinfo->shdr[ret].sh_addr, + loadinfo->shdr[ret].sh_size); + } +#endif + return OK; /* Error exits */ From 5b9caa5fe96aa79ecd74219708e19a2870462d65 Mon Sep 17 00:00:00 2001 From: anjiahao Date: Wed, 10 Jul 2024 20:49:28 +0800 Subject: [PATCH 09/20] modlib:add new api to uninitialize modp Signed-off-by: anjiahao --- include/nuttx/lib/modlib.h | 10 ++++ libs/libc/modlib/modlib_remove.c | 95 +++++++++++++++++++------------- 2 files changed, 68 insertions(+), 37 deletions(-) diff --git a/include/nuttx/lib/modlib.h b/include/nuttx/lib/modlib.h index f55521e07fa67..f70491406a499 100644 --- a/include/nuttx/lib/modlib.h +++ b/include/nuttx/lib/modlib.h @@ -691,6 +691,16 @@ FAR void *modlib_insert(FAR const char *filename, FAR const char *modname); FAR const void *modlib_getsymbol(FAR void *handle, FAR const char *name); +/**************************************************************************** + * Name: modlib_uninit + * + * Description: + * Uninitialize module resources. + * + ****************************************************************************/ + +int modlib_uninit(FAR struct module_s *modp); + /**************************************************************************** * Name: modlib_remove * diff --git a/libs/libc/modlib/modlib_remove.c b/libs/libc/modlib/modlib_remove.c index 765b85ee31b8f..1f6c864fe2e13 100644 --- a/libs/libc/modlib/modlib_remove.c +++ b/libs/libc/modlib/modlib_remove.c @@ -36,50 +36,26 @@ ****************************************************************************/ /**************************************************************************** - * Name: modlib_remove + * Name: modlib_uninit * * Description: - * Remove a previously installed module from memory. - * - * Input Parameters: - * handle - The module handler previously returned by modlib_insert(). - * - * Returned Value: - * Zero (OK) on success. On any failure, -1 (ERROR) is returned the - * errno value is set appropriately. + * Uninitialize module resources. * ****************************************************************************/ -int modlib_remove(FAR void *handle) +int modlib_uninit(FAR struct module_s *modp) { - FAR struct module_s *modp = (FAR struct module_s *)handle; FAR void (**array)(void); - int ret; + int ret = OK; int i; - DEBUGASSERT(modp != NULL); - - /* Get exclusive access to the module registry */ - - modlib_registry_lock(); - - /* Verify that the module is in the registry */ - - ret = modlib_registry_verify(modp); - if (ret < 0) - { - berr("ERROR: Failed to verify module: %d\n", ret); - goto errout_with_lock; - } - #if CONFIG_MODLIB_MAXDEPEND > 0 /* Refuse to remove any module that other modules may depend upon. */ if (modp->dependents > 0) { berr("ERROR: Module has dependents: %d\n", modp->dependents); - ret = -EBUSY; - goto errout_with_lock; + return -EBUSY; } #endif @@ -102,7 +78,7 @@ int modlib_remove(FAR void *handle) if (ret < 0) { berr("ERROR: Failed to uninitialize the module: %d\n", ret); - goto errout_with_lock; + return ret; } modlib_freesymtab(modp); @@ -183,6 +159,57 @@ int modlib_remove(FAR void *handle) #endif } +#if CONFIG_MODLIB_MAXDEPEND > 0 + /* Eliminate any dependencies that this module has on other modules */ + + modlib_undepend(modp); +#endif + + return ret; +} + +/**************************************************************************** + * Name: modlib_remove + * + * Description: + * Remove a previously installed module from memory. + * + * Input Parameters: + * handle - The module handler previously returned by modlib_insert(). + * + * Returned Value: + * Zero (OK) on success. On any failure, -1 (ERROR) is returned the + * errno value is set appropriately. + * + ****************************************************************************/ + +int modlib_remove(FAR void *handle) +{ + FAR struct module_s *modp = (FAR struct module_s *)handle; + int ret; + + DEBUGASSERT(modp != NULL); + + /* Get exclusive access to the module registry */ + + modlib_registry_lock(); + + /* Verify that the module is in the registry */ + + ret = modlib_registry_verify(modp); + if (ret < 0) + { + berr("ERROR: Failed to verify module: %d\n", ret); + goto errout_with_lock; + } + + ret = modlib_uninit(modp); + if (ret < 0) + { + berr("ERROR: Failed to uninitialize module %d\n", ret); + goto errout_with_lock; + } + /* Remove the module from the registry */ ret = modlib_registry_del(modp); @@ -193,17 +220,11 @@ int modlib_remove(FAR void *handle) goto errout_with_lock; } -#if CONFIG_MODLIB_MAXDEPEND > 0 - /* Eliminate any dependencies that this module has on other modules */ - - modlib_undepend(modp); -#endif modlib_registry_unlock(); /* And free the registry entry */ - lib_free(modp); - return OK; + return ret; errout_with_lock: modlib_registry_unlock(); From 35af627173ec425a1b57c4176220efd487ef3cc0 Mon Sep 17 00:00:00 2001 From: anjiahao Date: Wed, 10 Jul 2024 22:49:47 +0800 Subject: [PATCH 10/20] modilib:add new args to modp record init arry Signed-off-by: anjiahao --- include/nuttx/lib/modlib.h | 2 ++ libs/libc/modlib/modlib_insert.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/include/nuttx/lib/modlib.h b/include/nuttx/lib/modlib.h index f70491406a499..f29fd550f7fc4 100644 --- a/include/nuttx/lib/modlib.h +++ b/include/nuttx/lib/modlib.h @@ -179,6 +179,8 @@ struct module_s FAR struct module_s *dependencies[CONFIG_MODLIB_MAXDEPEND]; #endif + uintptr_t initarr; /* .init_array */ + uint16_t ninit; /* Number of entries in .init_array */ uintptr_t finiarr; /* .fini_array */ uint16_t nfini; /* Number of entries in .fini_array */ }; diff --git a/libs/libc/modlib/modlib_insert.c b/libs/libc/modlib/modlib_insert.c index bfaaca3e305e6..8debdeb5edf0c 100644 --- a/libs/libc/modlib/modlib_insert.c +++ b/libs/libc/modlib/modlib_insert.c @@ -332,6 +332,8 @@ FAR void *modlib_insert(FAR const char *filename, FAR const char *modname) array[i](); } + modp->initarr = loadinfo.initarr; + modp->ninit = loadinfo.ninit; modp->finiarr = loadinfo.finiarr; modp->nfini = loadinfo.nfini; break; From a3e73d0975a4a9fbc1b8d55035297ab966ffdbc6 Mon Sep 17 00:00:00 2001 From: anjiahao Date: Tue, 16 Jul 2024 11:31:07 +0800 Subject: [PATCH 11/20] modlib:support modlib can load exec Signed-off-by: anjiahao --- libs/libc/modlib/modlib_load.c | 13 +++++++++---- libs/libc/modlib/modlib_verify.c | 3 ++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/libs/libc/modlib/modlib_load.c b/libs/libc/modlib/modlib_load.c index 152f477100e68..8c9a962114919 100644 --- a/libs/libc/modlib/modlib_load.c +++ b/libs/libc/modlib/modlib_load.c @@ -328,6 +328,11 @@ static inline int modlib_loadfile(FAR struct mod_loadinfo_s *loadinfo) * execution */ + if (shdr->sh_size == 0) + { + continue; + } + if ((shdr->sh_flags & SHF_ALLOC) == 0) { continue; @@ -360,7 +365,7 @@ static inline int modlib_loadfile(FAR struct mod_loadinfo_s *loadinfo) } *pptr = (FAR uint8_t *)_ALIGN_UP((uintptr_t)*pptr, - shdr->sh_addralign); + shdr->sh_addralign); } /* SHT_NOBITS indicates that there is no data in the file for the @@ -370,7 +375,7 @@ static inline int modlib_loadfile(FAR struct mod_loadinfo_s *loadinfo) if (shdr->sh_type != SHT_NOBITS) { #ifdef CONFIG_MODLIB_LOADTO_LMA - ret = modlib_vma2lma(loadinfo, shdr, *pptr); + ret = modlib_vma2lma(loadinfo, shdr, (FAR Elf_Addr *)pptr); if (ret < 0) { berr("ERROR: Failed to convert addr %d: %d\n", i, ret); @@ -393,7 +398,7 @@ static inline int modlib_loadfile(FAR struct mod_loadinfo_s *loadinfo) * section must be cleared. */ - else + else if (*pptr != NULL) { memset(*pptr, 0, shdr->sh_size); } @@ -509,7 +514,7 @@ int modlib_load(FAR struct mod_loadinfo_s *loadinfo) } #endif } - else + else if (loadinfo->ehdr.e_type == ET_DYN) { loadinfo->textalloc = (uintptr_t)lib_memalign(loadinfo->textalign, loadinfo->textsize + diff --git a/libs/libc/modlib/modlib_verify.c b/libs/libc/modlib/modlib_verify.c index 4f59c438a8f28..efd947bf3e947 100644 --- a/libs/libc/modlib/modlib_verify.c +++ b/libs/libc/modlib/modlib_verify.c @@ -81,7 +81,8 @@ int modlib_verifyheader(FAR const Elf_Ehdr *ehdr) /* Verify that this is a relocatable file */ - if (ehdr->e_type != ET_REL && ehdr->e_type != ET_DYN) + if (ehdr->e_type != ET_REL && ehdr->e_type != ET_DYN && + ehdr->e_type != ET_EXEC) { berr("ERROR: Not a relocatable file: e_type=%d\n", ehdr->e_type); return -EINVAL; From d0c995e7ba76bb1fa4fac82d861e411c1a092246 Mon Sep 17 00:00:00 2001 From: anjiahao Date: Tue, 9 Jul 2024 23:30:04 +0800 Subject: [PATCH 12/20] binfmt:use modlib api inside of elf api [1/2] Signed-off-by: anjiahao --- binfmt/Kconfig | 7 +- binfmt/Makefile | 1 - binfmt/binfmt_dumpmodule.c | 7 - binfmt/binfmt_execmodule.c | 8 +- binfmt/binfmt_unloadmodule.c | 121 ---------- binfmt/elf.c | 214 ++++-------------- binfmt/nxflat.c | 8 +- .../lc823450-xgevk/configs/usb/defconfig | 2 +- .../lpc17xx_40xx/lx_cpu/configs/nsh/defconfig | 5 +- .../configs/qemu-protected/defconfig | 4 +- .../c906/smartl-c906/configs/module/defconfig | 2 +- .../c906/smartl-c906/configs/sotest/defconfig | 2 +- .../k210/maix-bit/configs/elf/defconfig | 2 +- .../k210/maix-bit/configs/module/defconfig | 2 +- .../sparc/bm3803/xx3803/configs/nsh/defconfig | 5 +- .../s698pm/s698pm-dkit/configs/nsh/defconfig | 5 +- .../s698pm/s698pm-dkit/configs/smp/defconfig | 5 +- include/nuttx/binfmt/binfmt.h | 17 +- libs/libc/modlib/modlib_insert.c | 5 + libs/libc/modlib/modlib_remove.c | 2 - 20 files changed, 81 insertions(+), 343 deletions(-) diff --git a/binfmt/Kconfig b/binfmt/Kconfig index 95d50b130f364..1e7c5a91a2f65 100644 --- a/binfmt/Kconfig +++ b/binfmt/Kconfig @@ -51,12 +51,17 @@ config ELF default n select BINFMT_LOADABLE select LIBC_ARCH_ELF + select LIBC_MODLIB select ARCH_USE_TEXT_HEAP if ARCH_HAVE_TEXT_HEAP ---help--- Enable support for the ELF binary format. Default: n if ELF -source "binfmt/libelf/Kconfig" +config ELF_STACKSIZE + int "ELF Stack Size" + default DEFAULT_TASK_STACKSIZE + ---help--- + This is the default stack size that will be used when starting ELF binaries. endif endif diff --git a/binfmt/Makefile b/binfmt/Makefile index 02b48c2b1301c..30863b285ec3a 100644 --- a/binfmt/Makefile +++ b/binfmt/Makefile @@ -57,7 +57,6 @@ endif # Add configured binary modules include libnxflat/Make.defs -include libelf/Make.defs CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)sched diff --git a/binfmt/binfmt_dumpmodule.c b/binfmt/binfmt_dumpmodule.c index 147a925d2db0f..d55dc2686e6c4 100644 --- a/binfmt/binfmt_dumpmodule.c +++ b/binfmt/binfmt_dumpmodule.c @@ -61,13 +61,6 @@ int binfmt_dumpmodule(FAR const struct binary_s *bin) binfo("Module:\n"); binfo(" entrypt: %p\n", bin->entrypt); binfo(" mapped: %p size=%zd\n", bin->mapped, bin->mapsize); - binfo(" alloc: %p %p %p\n", bin->alloc[0], - bin->alloc[1], - bin->alloc[2]); -#ifdef CONFIG_BINFMT_CONSTRUCTORS - binfo(" ctors: %p nctors=%d\n", bin->ctors, bin->nctors); - binfo(" dtors: %p ndtors=%d\n", bin->dtors, bin->ndtors); -#endif #ifdef CONFIG_ARCH_ADDRENV binfo(" addrenv: %p\n", bin->addrenv); #endif diff --git a/binfmt/binfmt_execmodule.c b/binfmt/binfmt_execmodule.c index d333a8d4466b5..65ca7c18f6de1 100644 --- a/binfmt/binfmt_execmodule.c +++ b/binfmt/binfmt_execmodule.c @@ -86,12 +86,12 @@ static void exec_ctors(FAR void *arg) { FAR const struct binary_s *binp = (FAR const struct binary_s *)arg; - binfmt_ctor_t *ctor = binp->ctors; + binfmt_ctor_t *ctor = (CODE binfmt_ctor_t *)binp->mod.initarr; int i; /* Execute each constructor */ - for (i = 0; i < binp->nctors; i++) + for (i = 0; i < binp->mod.ninit; i++) { binfo("Calling ctor %d at %p\n", i, ctor); @@ -338,7 +338,7 @@ int exec_module(FAR struct binary_s *binp, * must be the first allocated address space. */ - tcb->cmn.dspace = binp->alloc[0]; + tcb->cmn.dspace = binp->picbase; /* Re-initialize the task's initial state to account for the new PIC base */ @@ -362,7 +362,7 @@ int exec_module(FAR struct binary_s *binp, * until the new task has been started. */ - if (binp->nctors > 0) + if (binp->mod.ninit > 0) { nxtask_starthook(tcb, exec_ctors, binp); } diff --git a/binfmt/binfmt_unloadmodule.c b/binfmt/binfmt_unloadmodule.c index 0f0b246deebc4..c8e51adb9435e 100644 --- a/binfmt/binfmt_unloadmodule.c +++ b/binfmt/binfmt_unloadmodule.c @@ -44,61 +44,6 @@ * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: exec_dtors - * - * Description: - * Execute C++ static destructors. - * - * Input Parameters: - * binp - Load state information - * - * Returned Value: - * 0 (OK) is returned on success and a negated errno is returned on - * failure. - * - ****************************************************************************/ - -#ifdef CONFIG_BINFMT_CONSTRUCTORS -static inline int exec_dtors(FAR struct binary_s *binp) -{ - binfmt_dtor_t *dtor = binp->dtors; -#ifdef CONFIG_ARCH_ADDRENV - int ret; -#endif - int i; - - /* Instantiate the address environment containing the destructors */ - -#ifdef CONFIG_ARCH_ADDRENV - ret = addrenv_select(binp->addrenv, &binp->oldenv); - if (ret < 0) - { - berr("ERROR: addrenv_select() failed: %d\n", ret); - return ret; - } -#endif - - /* Execute each destructor */ - - for (i = 0; i < binp->ndtors; i++) - { - binfo("Calling dtor %d at %p\n", i, dtor); - - (*dtor)(); - dtor++; - } - - /* Restore the address environment */ - -#ifdef CONFIG_ARCH_ADDRENV - return addrenv_restore(binp->oldenv); -#else - return OK; -#endif -} -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -125,7 +70,6 @@ static inline int exec_dtors(FAR struct binary_s *binp) int unload_module(FAR struct binary_s *binp) { int ret; - int i; if (binp) { @@ -141,17 +85,6 @@ int unload_module(FAR struct binary_s *binp) } } -#ifdef CONFIG_BINFMT_CONSTRUCTORS - /* Execute C++ destructors */ - - ret = exec_dtors(binp); - if (ret < 0) - { - berr("exec_ctors() failed: %d\n", ret); - return ret; - } -#endif - /* Unmap mapped address spaces */ if (binp->mapped) @@ -161,60 +94,6 @@ int unload_module(FAR struct binary_s *binp) file_munmap(binp->mapped, binp->mapsize); } -#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION - for (i = 0; binp->sectalloc[i] != NULL && i < binp->nsect; i++) - { -# ifdef CONFIG_ARCH_USE_TEXT_HEAP - if (up_textheap_heapmember(binp->sectalloc[i])) - { - up_textheap_free(binp->sectalloc[i]); - } - else -# endif - -# ifdef CONFIG_ARCH_USE_DATA_HEAP - if (up_dataheap_heapmember(binp->sectalloc[i])) - { - up_dataheap_free(binp->sectalloc[i]); - } - else -# endif - { - kumm_free(binp->sectalloc[i]); - } - } - - binp->alloc[0] = NULL; - binp->alloc[1] = NULL; -#endif - - /* Free allocated address spaces */ - - for (i = 0; i < BINFMT_NALLOC; i++) - { - if (binp->alloc[i]) - { - binfo("Freeing alloc[%d]: %p\n", i, binp->alloc[i]); -#if defined(CONFIG_ARCH_USE_TEXT_HEAP) - if (i == 0) - { - up_textheap_free(binp->alloc[i]); - } - else -#endif -#if defined(CONFIG_ARCH_USE_DATA_HEAP) - if (i == 1) - { - up_dataheap_free(binp->alloc[i]); - } - else -#endif - { - kumm_free(binp->alloc[i]); - } - } - } - /* Notice that the address environment is not destroyed. This should * happen automatically when the task exits. */ diff --git a/binfmt/elf.c b/binfmt/elf.c index 2ae29db77bea2..1d531bfb66794 100644 --- a/binfmt/elf.c +++ b/binfmt/elf.c @@ -44,23 +44,17 @@ ****************************************************************************/ /* CONFIG_DEBUG_FEATURES, CONFIG_DEBUG_INFO, and CONFIG_DEBUG_BINFMT - * have to be defined or CONFIG_ELF_DUMPBUFFER does nothing. + * have to be defined or CONFIG_MODLIB_DUMPBUFFER does nothing. */ #if !defined(CONFIG_DEBUG_INFO) || !defined(CONFIG_DEBUG_BINFMT) -# undef CONFIG_ELF_DUMPBUFFER +# undef CONFIG_MODLIB_DUMPBUFFER #endif #ifndef CONFIG_ELF_STACKSIZE # define CONFIG_ELF_STACKSIZE 2048 #endif -#ifdef CONFIG_ELF_DUMPBUFFER -# define elf_dumpbuffer(m,b,n) binfodumpbuffer(m,b,n) -#else -# define elf_dumpbuffer(m,b,n) -#endif - /**************************************************************************** * Private Function Prototypes ****************************************************************************/ @@ -69,9 +63,8 @@ static int elf_loadbinary(FAR struct binary_s *binp, FAR const char *filename, FAR const struct symtab_s *exports, int nexports); -#if defined(CONFIG_DEBUG_FEATURES) && defined(CONFIG_DEBUG_BINFMT) -static void elf_dumploadinfo(FAR struct elf_loadinfo_s *loadinfo); -#endif + +static int elf_unloadbinary(FAR struct binary_s *binp); /**************************************************************************** * Private Data @@ -81,148 +74,13 @@ static struct binfmt_s g_elfbinfmt = { NULL, /* next */ elf_loadbinary, /* load */ - NULL, /* unload */ + elf_unloadbinary, /* unload */ }; /**************************************************************************** * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: elf_dumploadinfo - ****************************************************************************/ - -#if defined(CONFIG_DEBUG_FEATURES) && defined(CONFIG_DEBUG_BINFMT) -static void elf_dumploadinfo(FAR struct elf_loadinfo_s *loadinfo) -{ - int i; - - binfo("LOAD_INFO:\n"); - binfo(" textalloc: %08lx\n", (long)loadinfo->textalloc); - binfo(" dataalloc: %08lx\n", (long)loadinfo->dataalloc); - binfo(" textsize: %ld\n", (long)loadinfo->textsize); - binfo(" datasize: %ld\n", (long)loadinfo->datasize); - binfo(" textalign: %zu\n", loadinfo->textalign); - binfo(" dataalign: %zu\n", loadinfo->dataalign); - binfo(" filelen: %ld\n", (long)loadinfo->filelen); -#ifdef CONFIG_BINFMT_CONSTRUCTORS - binfo(" ctoralloc: %08lx\n", (long)loadinfo->ctoralloc); - binfo(" ctors: %08lx\n", (long)loadinfo->ctors); - binfo(" nctors: %d\n", loadinfo->nctors); - binfo(" dtoralloc: %08lx\n", (long)loadinfo->dtoralloc); - binfo(" dtors: %08lx\n", (long)loadinfo->dtors); - binfo(" ndtors: %d\n", loadinfo->ndtors); -#endif - binfo(" symtabidx: %d\n", loadinfo->symtabidx); - binfo(" strtabidx: %d\n", loadinfo->strtabidx); - - binfo("ELF Header:\n"); - binfo(" e_ident: %02x %02x %02x %02x\n", - loadinfo->ehdr.e_ident[0], loadinfo->ehdr.e_ident[1], - loadinfo->ehdr.e_ident[2], loadinfo->ehdr.e_ident[3]); - binfo(" e_type: %04x\n", loadinfo->ehdr.e_type); - binfo(" e_machine: %04x\n", loadinfo->ehdr.e_machine); - binfo(" e_version: %08x\n", loadinfo->ehdr.e_version); - binfo(" e_entry: %08lx\n", (long)loadinfo->ehdr.e_entry); - binfo(" e_phoff: %ju\n", (uintmax_t)loadinfo->ehdr.e_phoff); - binfo(" e_shoff: %ju\n", (uintmax_t)loadinfo->ehdr.e_shoff); - binfo(" e_flags: %08x\n" , loadinfo->ehdr.e_flags); - binfo(" e_ehsize: %d\n", loadinfo->ehdr.e_ehsize); - binfo(" e_phentsize: %d\n", loadinfo->ehdr.e_phentsize); - binfo(" e_phnum: %d\n", loadinfo->ehdr.e_phnum); - binfo(" e_shentsize: %d\n", loadinfo->ehdr.e_shentsize); - binfo(" e_shnum: %d\n", loadinfo->ehdr.e_shnum); - binfo(" e_shstrndx: %d\n", loadinfo->ehdr.e_shstrndx); - - if (loadinfo->phdr && loadinfo->ehdr.e_phnum > 0) - { - for (i = 0; i < loadinfo->ehdr.e_phnum; i++) - { - FAR Elf_Phdr *phdr = &loadinfo->phdr[i]; - binfo("Programs %d:\n", i); - binfo(" p_type: %08jx\n", (uintmax_t)phdr->p_type); - binfo(" p_offset: %08jx\n", (uintmax_t)phdr->p_offset); - binfo(" p_vaddr: %08jx\n", (uintmax_t)phdr->p_vaddr); - binfo(" p_paddr: %08jx\n", (uintmax_t)phdr->p_paddr); - binfo(" p_filesz: %08jx\n", (uintmax_t)phdr->p_filesz); - binfo(" p_memsz: %08jx\n", (uintmax_t)phdr->p_memsz); - binfo(" p_flags: %08jx\n", (uintmax_t)phdr->p_flags); - binfo(" p_align: %08x\n", phdr->p_align); - } - } - - if (loadinfo->shdr && loadinfo->ehdr.e_shnum > 0) - { - for (i = 0; i < loadinfo->ehdr.e_shnum; i++) - { - FAR Elf_Shdr *shdr = &loadinfo->shdr[i]; -# ifdef CONFIG_ARCH_USE_SEPARATED_SECTION - if (loadinfo->ehdr.e_type == ET_REL) - { - binfo(" sh_alloc: %08jx\n", - (uintmax_t)loadinfo->sectalloc[i]); - } -# endif - - binfo("Sections %d:\n", i); - binfo(" sh_name: %08x\n", shdr->sh_name); - binfo(" sh_type: %08x\n", shdr->sh_type); - binfo(" sh_flags: %08jx\n", (uintmax_t)shdr->sh_flags); - binfo(" sh_addr: %08jx\n", (uintmax_t)shdr->sh_addr); - binfo(" sh_offset: %ju\n", (uintmax_t)shdr->sh_offset); - binfo(" sh_size: %ju\n", (uintmax_t)shdr->sh_size); - binfo(" sh_link: %d\n", shdr->sh_link); - binfo(" sh_info: %d\n", shdr->sh_info); - binfo(" sh_addralign: %ju\n", (uintmax_t)shdr->sh_addralign); - binfo(" sh_entsize: %ju\n", (uintmax_t)shdr->sh_entsize); - } - } -} -#else -# define elf_dumploadinfo(i) -#endif - -/**************************************************************************** - * Name: elf_dumpentrypt - ****************************************************************************/ - -#ifdef CONFIG_ELF_DUMPBUFFER -static void elf_dumpentrypt(FAR struct binary_s *binp, - FAR struct elf_loadinfo_s *loadinfo) -{ -#ifdef CONFIG_ARCH_ADDRENV - int ret; - - /* If CONFIG_ARCH_ADDRENV=y, then the loaded ELF lies in a virtual address - * space that may not be in place now. elf_addrenv_select() will - * temporarily instantiate that address space. - */ - - ret = elf_addrenv_select(loadinfo); - if (ret < 0) - { - berr("ERROR: elf_addrenv_select() failed: %d\n", ret); - return; - } -#endif - - elf_dumpbuffer("Entry code", (FAR const uint8_t *)binp->entrypt, - MIN(loadinfo->textsize - loadinfo->ehdr.e_entry, 512)); - -#ifdef CONFIG_ARCH_ADDRENV - /* Restore the original address environment */ - - ret = elf_addrenv_restore(loadinfo); - if (ret < 0) - { - berr("ERROR: elf_addrenv_restore() failed: %d\n", ret); - } -#endif -} -#else -# define elf_dumpentrypt(b,l) -#endif - /**************************************************************************** * Name: elf_loadbinary * @@ -237,25 +95,25 @@ static int elf_loadbinary(FAR struct binary_s *binp, FAR const struct symtab_s *exports, int nexports) { - struct elf_loadinfo_s loadinfo; /* Contains globals for libelf */ - int ret; + struct mod_loadinfo_s loadinfo; + int ret; binfo("Loading file: %s\n", filename); /* Initialize the ELF library to load the program binary. */ - ret = elf_init(filename, &loadinfo); - elf_dumploadinfo(&loadinfo); + ret = modlib_initialize(filename, &loadinfo); + modlib_dumploadinfo(&loadinfo); if (ret != 0) { - berr("Failed to initialize for load of ELF program: %d\n", ret); - goto errout_with_init; + berr("Failed to initialize to load ELF program binary: %d\n", ret); + return ret; } /* Load the program binary */ - ret = elf_load(&loadinfo); - elf_dumploadinfo(&loadinfo); + ret = modlib_load_with_addrenv(&loadinfo); + modlib_dumploadinfo(&loadinfo); if (ret != 0) { berr("Failed to load ELF program binary: %d\n", ret); @@ -266,7 +124,7 @@ static int elf_loadbinary(FAR struct binary_s *binp, if (loadinfo.ehdr.e_type == ET_REL) { - ret = elf_bind(&loadinfo, exports, nexports); + ret = modlib_bind(&binp->mod, &loadinfo, exports, nexports); if (ret != 0) { berr("Failed to bind symbols program binary: %d\n", ret); @@ -320,27 +178,27 @@ static int elf_loadbinary(FAR struct binary_s *binp, # ifdef CONFIG_ARCH_USE_SEPARATED_SECTION if (loadinfo.ehdr.e_type == ET_REL) { - binp->sectalloc = (FAR void *)loadinfo.sectalloc; - binp->nsect = loadinfo.ehdr.e_shnum; + binp->mod.sectalloc = (FAR void *)loadinfo.sectalloc; + binp->mod.nsect = loadinfo.ehdr.e_shnum; } # endif - binp->alloc[0] = (FAR void *)loadinfo.textalloc; - binp->alloc[1] = (FAR void *)loadinfo.dataalloc; + binp->mod.textalloc = (FAR void *)loadinfo.textalloc; + binp->mod.dataalloc = (FAR void *)loadinfo.datastart; # ifdef CONFIG_BINFMT_CONSTRUCTORS - binp->alloc[2] = loadinfo.ctoralloc; - binp->alloc[3] = loadinfo.dtoralloc; + binp->mod.initarr = loadinfo.initarr; + binp->mod.finiarr = loadinfo.finiarr; # endif #endif #ifdef CONFIG_BINFMT_CONSTRUCTORS /* Save information about constructors and destructors. */ - binp->ctors = loadinfo.ctors; - binp->nctors = loadinfo.nctors; + binp->mod.initarr = loadinfo.initarr; + binp->mod.ninit = loadinfo.ninit; - binp->dtors = loadinfo.dtors; - binp->ndtors = loadinfo.ndtors; + binp->mod.finiarr = loadinfo.finiarr; + binp->mod.nfini = loadinfo.nfini; #endif #ifdef CONFIG_SCHED_USER_IDENTITY @@ -351,17 +209,33 @@ static int elf_loadbinary(FAR struct binary_s *binp, binp->mode = loadinfo.filemode; #endif - elf_dumpentrypt(binp, &loadinfo); - elf_uninit(&loadinfo); + modlib_dumpentrypt(&loadinfo); + modlib_uninitialize(&loadinfo); return OK; errout_with_load: - elf_unload(&loadinfo); + modlib_unload(&loadinfo); errout_with_init: - elf_uninit(&loadinfo); + modlib_uninitialize(&loadinfo); return ret; } +/**************************************************************************** + * Name: elf_unloadbinary + * + * Description: + * Unload the ELF binary that was loaded into memory by elf_loadbinary. + * + ****************************************************************************/ + +static int elf_unloadbinary(FAR struct binary_s *binp) +{ + binfo("Unloading %p\n", binp); + modlib_uninit(&binp->mod); + + return OK; +} + /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/binfmt/nxflat.c b/binfmt/nxflat.c index 175c3eb5ddbbe..5e520b848cd3f 100644 --- a/binfmt/nxflat.c +++ b/binfmt/nxflat.c @@ -193,7 +193,7 @@ static int nxflat_loadbinary(FAR struct binary_s *binp, #ifdef CONFIG_ARCH_ADDRENV # warning "REVISIT" #else - binp->alloc[0] = (FAR void *)loadinfo.dspace; + binp->picbase = (FAR void *)loadinfo.dspace; #endif #ifdef CONFIG_ARCH_ADDRENV @@ -229,7 +229,7 @@ static int nxflat_loadbinary(FAR struct binary_s *binp, static int nxflat_unloadbinary(FAR struct binary_s *binp) { - FAR struct dspace_s *dspace = (FAR struct dspace_s *)binp->alloc[0]; + FAR struct dspace_s *dspace = (FAR struct dspace_s *)binp->picbase; /* Check if this is the last reference to dspace. It may still be needed * by other threads. In that case, it must persist after this thread @@ -243,9 +243,9 @@ static int nxflat_unloadbinary(FAR struct binary_s *binp) kumm_free(dspace->region); dspace->region = NULL; - /* Mark alloc[0] (dspace) as freed */ + /* Mark picbase (dspace) as freed */ - binp->alloc[0] = NULL; + binp->picbase = NULL; /* The reference count will be decremented to zero and the dspace * container will be freed in sched/nxsched_release_tcb.c diff --git a/boards/arm/lc823450/lc823450-xgevk/configs/usb/defconfig b/boards/arm/lc823450/lc823450-xgevk/configs/usb/defconfig index 3cb17561ee0c6..3a9542154325e 100644 --- a/boards/arm/lc823450/lc823450-xgevk/configs/usb/defconfig +++ b/boards/arm/lc823450/lc823450-xgevk/configs/usb/defconfig @@ -27,7 +27,6 @@ CONFIG_DEBUG_SYMBOLS=y CONFIG_DEV_ZERO=y CONFIG_DISABLE_POSIX_TIMERS=y CONFIG_ELF=y -CONFIG_ELF_BUFFERSIZE=512 CONFIG_EXAMPLES_ADC=y CONFIG_EXAMPLES_ADC_GROUPSIZE=6 CONFIG_EXAMPLES_ADC_SWTRIG=y @@ -63,6 +62,7 @@ CONFIG_LIBC_KBDCODEC=y CONFIG_LIBC_MAX_EXITFUNS=32 CONFIG_LIBM=y CONFIG_MEMSET_OPTSPEED=y +CONFIG_MODLIB_BUFFERSIZE=512 CONFIG_MQ_MAXMSGSIZE=64 CONFIG_MTD=y CONFIG_NAME_MAX=255 diff --git a/boards/arm/lpc17xx_40xx/lx_cpu/configs/nsh/defconfig b/boards/arm/lpc17xx_40xx/lx_cpu/configs/nsh/defconfig index af2de216ee90a..5e0ba47b8a807 100644 --- a/boards/arm/lpc17xx_40xx/lx_cpu/configs/nsh/defconfig +++ b/boards/arm/lpc17xx_40xx/lx_cpu/configs/nsh/defconfig @@ -37,8 +37,6 @@ CONFIG_DEV_LOOP=y CONFIG_DEV_ZERO=y CONFIG_DFU=y CONFIG_ELF=y -CONFIG_ELF_ALIGN_LOG2=3 -CONFIG_ELF_BUFFERSIZE=128 CONFIG_ETH0_PHY_DP83848C=y CONFIG_ETH1_PHY_DP83848C=y CONFIG_EXAMPLES_CAN=y @@ -48,7 +46,6 @@ CONFIG_EXAMPLES_HELLO=y CONFIG_EXAMPLES_MODULE=y CONFIG_EXAMPLES_MODULE_DEVMINOR=1 CONFIG_EXAMPLES_MODULE_DEVPATH="/dev/ram1" -CONFIG_EXAMPLES_ROMFS=y CONFIG_EXECFUNCS_HAVE_SYMTAB=y CONFIG_EXECFUNCS_SYSTEM_SYMTAB=y CONFIG_FAT_LCNAMES=y @@ -95,6 +92,8 @@ CONFIG_M25P_SUBSECTOR_ERASE=y CONFIG_MMCSD=y CONFIG_MMCSD_SDIO=y CONFIG_MM_REGIONS=3 +CONFIG_MODLIB_ALIGN_LOG2=3 +CONFIG_MODLIB_BUFFERSIZE=128 CONFIG_MTD=y CONFIG_MTD_M25P=y CONFIG_NETDB_DNSCLIENT=y diff --git a/boards/arm/tiva/lm3s6965-ek/configs/qemu-protected/defconfig b/boards/arm/tiva/lm3s6965-ek/configs/qemu-protected/defconfig index 32ca54f0ccfcb..50afa89ae4c49 100644 --- a/boards/arm/tiva/lm3s6965-ek/configs/qemu-protected/defconfig +++ b/boards/arm/tiva/lm3s6965-ek/configs/qemu-protected/defconfig @@ -24,8 +24,6 @@ CONFIG_DEBUG_FEATURES=y CONFIG_DEBUG_FULLOPT=y CONFIG_DEBUG_SYMBOLS=y CONFIG_ELF=y -CONFIG_ELF_RELOCATION_BUFFERCOUNT=64 -CONFIG_ELF_SYMBOL_CACHECOUNT=64 CONFIG_EXAMPLES_ELF=y CONFIG_EXAMPLES_ELF_DEVPATH="/dev/ram5" CONFIG_EXAMPLES_HELLO=m @@ -42,6 +40,8 @@ CONFIG_LIBC_DLFCN=y CONFIG_LIBC_ENVPATH=y CONFIG_MMCSD=y CONFIG_MMCSD_SPICLOCK=12500000 +CONFIG_MODLIB_RELOCATION_BUFFERCOUNT=64 +CONFIG_MODLIB_SYMBOL_CACHECOUNT=64 CONFIG_MODULE=y CONFIG_NET=y CONFIG_NETDB_DNSCLIENT=y diff --git a/boards/risc-v/c906/smartl-c906/configs/module/defconfig b/boards/risc-v/c906/smartl-c906/configs/module/defconfig index 556d5133ee66d..2a9f5939c75ab 100644 --- a/boards/risc-v/c906/smartl-c906/configs/module/defconfig +++ b/boards/risc-v/c906/smartl-c906/configs/module/defconfig @@ -24,7 +24,6 @@ CONFIG_DEBUG_FULLOPT=y CONFIG_DEBUG_SYMBOLS=y CONFIG_DEV_ZERO=y CONFIG_ELF=y -CONFIG_ELF_ALIGN_LOG2=3 CONFIG_EXAMPLES_HELLO=y CONFIG_EXAMPLES_MODULE=y CONFIG_FS_PROCFS=y @@ -36,6 +35,7 @@ CONFIG_INTELHEX_BINARY=y CONFIG_LIBC_EXECFUNCS=y CONFIG_LIBC_PERROR_STDOUT=y CONFIG_LIBC_STRERROR=y +CONFIG_MODLIB_ALIGN_LOG2=3 CONFIG_MODULE=y CONFIG_NSH_ARCHINIT=y CONFIG_NSH_BUILTIN_APPS=y diff --git a/boards/risc-v/c906/smartl-c906/configs/sotest/defconfig b/boards/risc-v/c906/smartl-c906/configs/sotest/defconfig index fb24a30245b28..fe9da7c394677 100644 --- a/boards/risc-v/c906/smartl-c906/configs/sotest/defconfig +++ b/boards/risc-v/c906/smartl-c906/configs/sotest/defconfig @@ -24,7 +24,6 @@ CONFIG_DEBUG_FULLOPT=y CONFIG_DEBUG_SYMBOLS=y CONFIG_DEV_ZERO=y CONFIG_ELF=y -CONFIG_ELF_ALIGN_LOG2=3 CONFIG_EXAMPLES_HELLO=y CONFIG_EXAMPLES_SOTEST=y CONFIG_FS_PROCFS=y @@ -37,6 +36,7 @@ CONFIG_LIBC_DLFCN=y CONFIG_LIBC_EXECFUNCS=y CONFIG_LIBC_PERROR_STDOUT=y CONFIG_LIBC_STRERROR=y +CONFIG_MODLIB_ALIGN_LOG2=3 CONFIG_NSH_ARCHINIT=y CONFIG_NSH_BUILTIN_APPS=y CONFIG_NSH_DISABLE_IFUPDOWN=y diff --git a/boards/risc-v/k210/maix-bit/configs/elf/defconfig b/boards/risc-v/k210/maix-bit/configs/elf/defconfig index a5a07c2a65e07..6618106d2429c 100644 --- a/boards/risc-v/k210/maix-bit/configs/elf/defconfig +++ b/boards/risc-v/k210/maix-bit/configs/elf/defconfig @@ -23,7 +23,6 @@ CONFIG_DEBUG_FULLOPT=y CONFIG_DEBUG_SYMBOLS=y CONFIG_DEV_ZERO=y CONFIG_ELF=y -CONFIG_ELF_ALIGN_LOG2=3 CONFIG_EXAMPLES_ELF=y CONFIG_FS_PROCFS=y CONFIG_FS_ROMFS=y @@ -35,6 +34,7 @@ CONFIG_INTELHEX_BINARY=y CONFIG_LIBC_ENVPATH=y CONFIG_LIBC_PERROR_STDOUT=y CONFIG_LIBC_STRERROR=y +CONFIG_MODLIB_ALIGN_LOG2=3 CONFIG_PATH_INITIAL="/mnt/romfs" CONFIG_PIPES=y CONFIG_PREALLOC_TIMERS=4 diff --git a/boards/risc-v/k210/maix-bit/configs/module/defconfig b/boards/risc-v/k210/maix-bit/configs/module/defconfig index 63cd1cb2c379c..ffcf089f695e5 100644 --- a/boards/risc-v/k210/maix-bit/configs/module/defconfig +++ b/boards/risc-v/k210/maix-bit/configs/module/defconfig @@ -23,7 +23,6 @@ CONFIG_DEBUG_FULLOPT=y CONFIG_DEBUG_SYMBOLS=y CONFIG_DEV_ZERO=y CONFIG_ELF=y -CONFIG_ELF_ALIGN_LOG2=3 CONFIG_EXAMPLES_MODULE=y CONFIG_FS_PROCFS=y CONFIG_FS_ROMFS=y @@ -36,6 +35,7 @@ CONFIG_LIBC_ENVPATH=y CONFIG_LIBC_EXECFUNCS=y CONFIG_LIBC_PERROR_STDOUT=y CONFIG_LIBC_STRERROR=y +CONFIG_MODLIB_ALIGN_LOG2=3 CONFIG_MODULE=y CONFIG_PATH_INITIAL="/mnt/romfs" CONFIG_PIPES=y diff --git a/boards/sparc/bm3803/xx3803/configs/nsh/defconfig b/boards/sparc/bm3803/xx3803/configs/nsh/defconfig index d8d7892e3f4ed..2460046b949d8 100644 --- a/boards/sparc/bm3803/xx3803/configs/nsh/defconfig +++ b/boards/sparc/bm3803/xx3803/configs/nsh/defconfig @@ -39,9 +39,6 @@ CONFIG_DEFAULT_TASK_STACKSIZE=4096 CONFIG_DISABLE_MQUEUE=y CONFIG_DISABLE_POSIX_TIMERS=y CONFIG_ELF=y -CONFIG_ELF_ALIGN_LOG2=3 -CONFIG_ELF_BUFFERINCR=64 -CONFIG_ELF_BUFFERSIZE=64 CONFIG_ELF_STACKSIZE=8192 CONFIG_ENDIAN_BIG=y CONFIG_EXAMPLES_HELLO=y @@ -55,6 +52,8 @@ CONFIG_INTELHEX_BINARY=y CONFIG_LIBM=y CONFIG_MEMSET_64BIT=y CONFIG_MEMSET_OPTSPEED=y +CONFIG_MODLIB_ALIGN_LOG2=3 +CONFIG_MODLIB_BUFFERSIZE=64 CONFIG_NSH_ARCHINIT=y CONFIG_NSH_BUILTIN_APPS=y CONFIG_NSH_DISABLEBG=y diff --git a/boards/sparc/s698pm/s698pm-dkit/configs/nsh/defconfig b/boards/sparc/s698pm/s698pm-dkit/configs/nsh/defconfig index d87e13f1dad22..4ea6d657ad55e 100644 --- a/boards/sparc/s698pm/s698pm-dkit/configs/nsh/defconfig +++ b/boards/sparc/s698pm/s698pm-dkit/configs/nsh/defconfig @@ -29,9 +29,6 @@ CONFIG_DEFAULT_TASK_STACKSIZE=8192 CONFIG_DISABLE_MQUEUE=y CONFIG_DISABLE_POSIX_TIMERS=y CONFIG_ELF=y -CONFIG_ELF_ALIGN_LOG2=3 -CONFIG_ELF_BUFFERINCR=64 -CONFIG_ELF_BUFFERSIZE=64 CONFIG_ENDIAN_BIG=y CONFIG_EXAMPLES_HELLO=y CONFIG_EXAMPLES_HELLO_STACKSIZE=4096 @@ -45,6 +42,8 @@ CONFIG_INTELHEX_BINARY=y CONFIG_LIBM=y CONFIG_MEMSET_64BIT=y CONFIG_MEMSET_OPTSPEED=y +CONFIG_MODLIB_ALIGN_LOG2=3 +CONFIG_MODLIB_BUFFERSIZE=64 CONFIG_NSH_ARCHINIT=y CONFIG_NSH_BUILTIN_APPS=y CONFIG_NSH_DISABLEBG=y diff --git a/boards/sparc/s698pm/s698pm-dkit/configs/smp/defconfig b/boards/sparc/s698pm/s698pm-dkit/configs/smp/defconfig index 60074215665b6..7f2efae0bfa04 100644 --- a/boards/sparc/s698pm/s698pm-dkit/configs/smp/defconfig +++ b/boards/sparc/s698pm/s698pm-dkit/configs/smp/defconfig @@ -30,9 +30,6 @@ CONFIG_DEFAULT_TASK_STACKSIZE=8192 CONFIG_DISABLE_MQUEUE=y CONFIG_DISABLE_POSIX_TIMERS=y CONFIG_ELF=y -CONFIG_ELF_ALIGN_LOG2=3 -CONFIG_ELF_BUFFERINCR=64 -CONFIG_ELF_BUFFERSIZE=64 CONFIG_ENDIAN_BIG=y CONFIG_EXAMPLES_HELLO=y CONFIG_EXAMPLES_HELLO_STACKSIZE=4096 @@ -46,6 +43,8 @@ CONFIG_INTELHEX_BINARY=y CONFIG_LIBM=y CONFIG_MEMSET_64BIT=y CONFIG_MEMSET_OPTSPEED=y +CONFIG_MODLIB_ALIGN_LOG2=3 +CONFIG_MODLIB_BUFFERSIZE=64 CONFIG_NSH_ARCHINIT=y CONFIG_NSH_BUILTIN_APPS=y CONFIG_NSH_DISABLEBG=y diff --git a/include/nuttx/binfmt/binfmt.h b/include/nuttx/binfmt/binfmt.h index 9582ee1ac4f47..bd39cd2703b47 100644 --- a/include/nuttx/binfmt/binfmt.h +++ b/include/nuttx/binfmt/binfmt.h @@ -33,6 +33,7 @@ #include #include +#include /**************************************************************************** * Pre-processor Definitions @@ -67,20 +68,8 @@ struct binary_s main_t entrypt; /* Entry point into a program module */ FAR void *mapped; /* Memory-mapped, address space */ -#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION - FAR void **sectalloc; /* All sections memory allocated */ - uint16_t nsect; /* Number of sections */ -#endif - FAR void *alloc[BINFMT_NALLOC]; /* Allocated address spaces */ - -#ifdef CONFIG_BINFMT_CONSTRUCTORS - /* Constructors/destructors */ - - FAR binfmt_ctor_t *ctors; /* Pointer to a list of constructors */ - FAR binfmt_dtor_t *dtors; /* Pointer to a list of destructors */ - uint16_t nctors; /* Number of constructors in the list */ - uint16_t ndtors; /* Number of destructors in the list */ -#endif + struct module_s mod; /* Module context */ + FAR void *picbase; /* Position-independent */ #ifdef CONFIG_ARCH_ADDRENV /* Address environment. diff --git a/libs/libc/modlib/modlib_insert.c b/libs/libc/modlib/modlib_insert.c index 8debdeb5edf0c..3516e675e9de1 100644 --- a/libs/libc/modlib/modlib_insert.c +++ b/libs/libc/modlib/modlib_insert.c @@ -304,6 +304,11 @@ FAR void *modlib_insert(FAR const char *filename, FAR const char *modname) modp->textalloc = (FAR void *)loadinfo.textalloc; modp->dataalloc = (FAR void *)loadinfo.datastart; +#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION + modp->sectalloc = (FAR void **)loadinfo.sectalloc; + modp->nsect = loadinfo.ehdr.e_shnum; +#endif + #if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) modp->textsize = loadinfo.textsize; modp->datasize = loadinfo.datasize; diff --git a/libs/libc/modlib/modlib_remove.c b/libs/libc/modlib/modlib_remove.c index 1f6c864fe2e13..844f031d5ff43 100644 --- a/libs/libc/modlib/modlib_remove.c +++ b/libs/libc/modlib/modlib_remove.c @@ -107,8 +107,6 @@ int modlib_uninit(FAR struct module_s *modp) if (!modp->dynamic) { #ifdef CONFIG_ARCH_USE_SEPARATED_SECTION - int i; - for (i = 0; i < modp->nsect && modp->sectalloc[i] != NULL; i++) { # ifdef CONFIG_ARCH_USE_TEXT_HEAP From 60dbfbb65628704407f10b4942251ef8d5aa057a Mon Sep 17 00:00:00 2001 From: anjiahao Date: Wed, 10 Jul 2024 12:08:27 +0800 Subject: [PATCH 13/20] binfmt/libelf:Remove libelf implementation [2/2] this commit is part two, all logic move to modlib, so we can remove it. and change all use defconfig Signed-off-by: anjiahao --- arch/arm/src/common/Toolchain.defs | 2 +- arch/arm64/src/Toolchain.defs | 2 +- arch/avr/src/avr/Toolchain.defs | 2 +- arch/avr/src/avr32/Toolchain.defs | 2 +- arch/ceva/src/xc5/Toolchain.defs | 2 +- arch/ceva/src/xm6/Toolchain.defs | 2 +- arch/mips/src/mips32/Toolchain.defs | 2 +- arch/misoc/src/lm32/Toolchain.defs | 2 +- arch/misoc/src/minerva/Toolchain.defs | 2 +- arch/or1k/src/mor1kx/Toolchain.defs | 2 +- arch/risc-v/src/common/Toolchain.defs | 2 +- arch/sparc/src/sparc_v8/Toolchain.defs | 2 +- arch/x86/src/common/Toolchain.defs | 71 ++ arch/x86_64/src/common/Toolchain.defs | 2 +- arch/xtensa/src/lx6/Toolchain.defs | 2 +- arch/xtensa/src/lx7/Toolchain.defs | 2 +- arch/z16/src/z16f/Toolchain.defs | 2 +- arch/z80/src/ez80/Toolchain.defs | 2 +- arch/z80/src/z180/Toolchain.defs | 2 +- arch/z80/src/z8/Toolchain.defs | 2 +- arch/z80/src/z80/Toolchain.defs | 2 +- binfmt/elf.c | 3 - binfmt/libelf/CMakeLists.txt | 48 -- binfmt/libelf/Kconfig | 72 -- binfmt/libelf/Make.defs | 41 - binfmt/libelf/gnu-elf.ld | 118 --- binfmt/libelf/libelf.h | 345 --------- binfmt/libelf/libelf_addrenv.c | 354 --------- binfmt/libelf/libelf_bind.c | 703 ------------------ binfmt/libelf/libelf_ctors.c | 193 ----- binfmt/libelf/libelf_dtors.c | 194 ----- binfmt/libelf/libelf_init.c | 178 ----- binfmt/libelf/libelf_iobuffer.c | 122 --- binfmt/libelf/libelf_load.c | 552 -------------- binfmt/libelf/libelf_read.c | 188 ----- binfmt/libelf/libelf_sections.c | 342 --------- binfmt/libelf/libelf_symbols.c | 340 --------- binfmt/libelf/libelf_uninit.c | 119 --- binfmt/libelf/libelf_unload.c | 102 --- binfmt/libelf/libelf_verify.c | 109 --- boards/arm/mps/mps2-an500/scripts/Make.defs | 2 +- boards/arm/mps/mps3-an547/scripts/Make.defs | 2 +- .../sama5/sama5d3-xplained/scripts/Make.defs | 2 +- boards/sim/sim/sim/scripts/Make.defs | 2 +- tools/mkexport.sh | 2 +- 45 files changed, 96 insertions(+), 4148 deletions(-) create mode 100644 arch/x86/src/common/Toolchain.defs delete mode 100644 binfmt/libelf/CMakeLists.txt delete mode 100644 binfmt/libelf/Kconfig delete mode 100644 binfmt/libelf/Make.defs delete mode 100644 binfmt/libelf/gnu-elf.ld delete mode 100644 binfmt/libelf/libelf.h delete mode 100644 binfmt/libelf/libelf_addrenv.c delete mode 100644 binfmt/libelf/libelf_bind.c delete mode 100644 binfmt/libelf/libelf_ctors.c delete mode 100644 binfmt/libelf/libelf_dtors.c delete mode 100644 binfmt/libelf/libelf_init.c delete mode 100644 binfmt/libelf/libelf_iobuffer.c delete mode 100644 binfmt/libelf/libelf_load.c delete mode 100644 binfmt/libelf/libelf_read.c delete mode 100644 binfmt/libelf/libelf_sections.c delete mode 100644 binfmt/libelf/libelf_symbols.c delete mode 100644 binfmt/libelf/libelf_uninit.c delete mode 100644 binfmt/libelf/libelf_unload.c delete mode 100644 binfmt/libelf/libelf_verify.c diff --git a/arch/arm/src/common/Toolchain.defs b/arch/arm/src/common/Toolchain.defs index dc1a2b2ccc133..22a35be0ec0da 100644 --- a/arch/arm/src/common/Toolchain.defs +++ b/arch/arm/src/common/Toolchain.defs @@ -510,7 +510,7 @@ CELFFLAGS = $(CFLAGS) -fvisibility=hidden -mlong-calls # --target1-abs CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden LDELFFLAGS = -r -e main -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)binfmt$(DELIM)libelf$(DELIM)gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)modlib$(DELIM)gnu-elf.ld) # Zig toolchain diff --git a/arch/arm64/src/Toolchain.defs b/arch/arm64/src/Toolchain.defs index 58970f4fa58d0..3cfc20ab5d252 100644 --- a/arch/arm64/src/Toolchain.defs +++ b/arch/arm64/src/Toolchain.defs @@ -211,4 +211,4 @@ CELFFLAGS = $(CFLAGS) -fvisibility=hidden -mlong-calls # --target1-abs CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden -mlong-calls # --target1-abs LDELFFLAGS = -r -e main -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)binfmt$(DELIM)libelf$(DELIM)gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)modlib$(DELIM)gnu-elf.ld) diff --git a/arch/avr/src/avr/Toolchain.defs b/arch/avr/src/avr/Toolchain.defs index bf18342c7e650..76e236cc3b060 100644 --- a/arch/avr/src/avr/Toolchain.defs +++ b/arch/avr/src/avr/Toolchain.defs @@ -179,4 +179,4 @@ CELFFLAGS = $(CFLAGS) -fvisibility=hidden CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden LDELFFLAGS = -r -e main -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)binfmt$(DELIM)libelf$(DELIM)gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)modlib$(DELIM)gnu-elf.ld) diff --git a/arch/avr/src/avr32/Toolchain.defs b/arch/avr/src/avr32/Toolchain.defs index eb45a46bc9e46..b2e785ac08d63 100644 --- a/arch/avr/src/avr32/Toolchain.defs +++ b/arch/avr/src/avr32/Toolchain.defs @@ -109,4 +109,4 @@ CELFFLAGS = $(CFLAGS) -fvisibility=hidden CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden LDELFFLAGS = -r -e main -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)binfmt$(DELIM)libelf$(DELIM)gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)modlib$(DELIM)gnu-elf.ld) diff --git a/arch/ceva/src/xc5/Toolchain.defs b/arch/ceva/src/xc5/Toolchain.defs index a9fe9f0338ba3..e299f400e87e3 100644 --- a/arch/ceva/src/xc5/Toolchain.defs +++ b/arch/ceva/src/xc5/Toolchain.defs @@ -98,4 +98,4 @@ CELFFLAGS = $(CFLAGS) -fvisibility=hidden CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden LDELFFLAGS = -r -e main -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)binfmt$(DELIM)libelf$(DELIM)gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)modlib$(DELIM)gnu-elf.ld) diff --git a/arch/ceva/src/xm6/Toolchain.defs b/arch/ceva/src/xm6/Toolchain.defs index 96ac99dfe58db..b43708da128a8 100644 --- a/arch/ceva/src/xm6/Toolchain.defs +++ b/arch/ceva/src/xm6/Toolchain.defs @@ -103,4 +103,4 @@ CELFFLAGS = $(CFLAGS) -fvisibility=hidden CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden LDELFFLAGS = -r -e main -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)binfmt$(DELIM)libelf$(DELIM)gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)modlib$(DELIM)gnu-elf.ld) diff --git a/arch/mips/src/mips32/Toolchain.defs b/arch/mips/src/mips32/Toolchain.defs index 5d725f99ae7c3..819cb1ad1fceb 100644 --- a/arch/mips/src/mips32/Toolchain.defs +++ b/arch/mips/src/mips32/Toolchain.defs @@ -324,4 +324,4 @@ CELFFLAGS = $(CFLAGS) -fvisibility=hidden CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden LDELFFLAGS = -r -e main -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)binfmt$(DELIM)libelf$(DELIM)gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)modlib$(DELIM)gnu-elf.ld) diff --git a/arch/misoc/src/lm32/Toolchain.defs b/arch/misoc/src/lm32/Toolchain.defs index 678ca17f87d91..01a926d326d32 100644 --- a/arch/misoc/src/lm32/Toolchain.defs +++ b/arch/misoc/src/lm32/Toolchain.defs @@ -140,4 +140,4 @@ CELFFLAGS = $(CFLAGS) -fvisibility=hidden CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden LDELFFLAGS = -r -e main -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)binfmt$(DELIM)libelf$(DELIM)gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)modlib$(DELIM)gnu-elf.ld) diff --git a/arch/misoc/src/minerva/Toolchain.defs b/arch/misoc/src/minerva/Toolchain.defs index 09cf8875e2450..efbf92a3d91f3 100644 --- a/arch/misoc/src/minerva/Toolchain.defs +++ b/arch/misoc/src/minerva/Toolchain.defs @@ -88,4 +88,4 @@ CELFFLAGS = $(CFLAGS) -fvisibility=hidden CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden LDELFFLAGS = -r -e main -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)binfmt$(DELIM)libelf$(DELIM)gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)modlib$(DELIM)gnu-elf.ld) diff --git a/arch/or1k/src/mor1kx/Toolchain.defs b/arch/or1k/src/mor1kx/Toolchain.defs index 151932c9c962e..346c6b7147426 100644 --- a/arch/or1k/src/mor1kx/Toolchain.defs +++ b/arch/or1k/src/mor1kx/Toolchain.defs @@ -126,4 +126,4 @@ CELFFLAGS = $(CFLAGS) -fvisibility=hidden CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden LDELFFLAGS = -r -e main -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)binfmt$(DELIM)libelf$(DELIM)gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)modlib$(DELIM)gnu-elf.ld) diff --git a/arch/risc-v/src/common/Toolchain.defs b/arch/risc-v/src/common/Toolchain.defs index a6fddffd8e28a..4de10db89c97b 100644 --- a/arch/risc-v/src/common/Toolchain.defs +++ b/arch/risc-v/src/common/Toolchain.defs @@ -417,7 +417,7 @@ else LDELFFLAGS += --oformat elf64-littleriscv endif -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)binfmt$(DELIM)libelf$(DELIM)gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/modlib/gnu-elf.ld) # Zig toolchain diff --git a/arch/sparc/src/sparc_v8/Toolchain.defs b/arch/sparc/src/sparc_v8/Toolchain.defs index a97af2fb47ea1..60d0f9a39cf13 100644 --- a/arch/sparc/src/sparc_v8/Toolchain.defs +++ b/arch/sparc/src/sparc_v8/Toolchain.defs @@ -135,4 +135,4 @@ CELFFLAGS = $(CFLAGS) -fvisibility=hidden CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden LDELFFLAGS = -r -e main -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)binfmt$(DELIM)libelf$(DELIM)gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)modlib$(DELIM)gnu-elf.ld) diff --git a/arch/x86/src/common/Toolchain.defs b/arch/x86/src/common/Toolchain.defs new file mode 100644 index 0000000000000..2c7a1ce9c97c7 --- /dev/null +++ b/arch/x86/src/common/Toolchain.defs @@ -0,0 +1,71 @@ +############################################################################ +# arch/x86/src/common/Toolchain.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifeq ($(CONFIG_DEBUG_SYMBOLS),y) + ARCHOPTIMIZATION = -g3 +endif + +ifneq ($(CONFIG_DEBUG_NOOPT),y) + ARCHOPTIMIZATION += -O2 +endif + +ARCHCPUFLAGS = -march=i486 -mtune=i486 -fno-stack-protector +ARCHPICFLAGS = -fpic +ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef + +# Check if building a 32-bit target with a 64-bit toolchain + +ifeq ($(CONFIG_ARCH_X86_M32),y) +ARCHCPUFLAGS += -m32 +LDFLAGS += -m elf_i386 +endif + +# We have to use a cross-development toolchain under Cygwin because the native +# Cygwin toolchains don't generate ELF binaries. + +ifeq ($(CONFIG_WINDOWS_CYGWIN),y) +CROSSDEV = i486-nuttx-elf- +endif + +CC = $(CROSSDEV)gcc +CPP = $(CROSSDEV)gcc -E -x c +LD = $(CROSSDEV)ld +STRIP = $(CROSSDEV)strip --strip-unneeded +AR = $(CROSSDEV)ar rcs +NM = $(CROSSDEV)nm +OBJCOPY = $(CROSSDEV)objcopy +OBJDUMP = $(CROSSDEV)objdump + +CFLAGS := $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe +CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) +AFLAGS := $(CFLAGS) -D__ASSEMBLY__ + +# Loadable module definitions + +CMODULEFLAGS = $(CFLAGS) -fvisibility=hidden +LDMODULEFLAGS = -r -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/modlib/gnu-elf.ld) + +# ELF module definitions + +CELFFLAGS = $(CFLAGS) -fvisibility=hidden +CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden + +LDELFFLAGS = -r -e main +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)modlib$(DELIM)gnu-elf.ld) diff --git a/arch/x86_64/src/common/Toolchain.defs b/arch/x86_64/src/common/Toolchain.defs index e8613edf04712..b7bc53b35290f 100644 --- a/arch/x86_64/src/common/Toolchain.defs +++ b/arch/x86_64/src/common/Toolchain.defs @@ -195,7 +195,7 @@ CELFFLAGS = $(CFLAGS) -fvisibility=hidden CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden LDELFFLAGS = -r -e main --gc-sections -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)binfmt$(DELIM)libelf$(DELIM)gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)modlib$(DELIM)gnu-elf.ld) # -fno-pic to avoid GOT relocations # -mcmodel=large to avoid out-of-range 32-bit relocations diff --git a/arch/xtensa/src/lx6/Toolchain.defs b/arch/xtensa/src/lx6/Toolchain.defs index 9f8eb9620e7f2..c70eeb8edcb08 100644 --- a/arch/xtensa/src/lx6/Toolchain.defs +++ b/arch/xtensa/src/lx6/Toolchain.defs @@ -206,4 +206,4 @@ CELFFLAGS = $(CFLAGS) -fvisibility=hidden -mtext-section-literals CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden -mtext-section-literals LDELFFLAGS = -r -e main -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)binfmt$(DELIM)libelf$(DELIM)gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)modlib$(DELIM)gnu-elf.ld) diff --git a/arch/xtensa/src/lx7/Toolchain.defs b/arch/xtensa/src/lx7/Toolchain.defs index 071ccd9d057b2..5ad3e768a2f11 100644 --- a/arch/xtensa/src/lx7/Toolchain.defs +++ b/arch/xtensa/src/lx7/Toolchain.defs @@ -210,4 +210,4 @@ CELFFLAGS = $(CFLAGS) -fvisibility=hidden -mtext-section-literals CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden -mtext-section-literals LDELFFLAGS = -r -e main -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)binfmt$(DELIM)libelf$(DELIM)gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)modlib$(DELIM)gnu-elf.ld) diff --git a/arch/z16/src/z16f/Toolchain.defs b/arch/z16/src/z16f/Toolchain.defs index 262c59bb56ea1..9da2fb7869d46 100644 --- a/arch/z16/src/z16f/Toolchain.defs +++ b/arch/z16/src/z16f/Toolchain.defs @@ -117,4 +117,4 @@ CELFFLAGS = $(CFLAGS) -fvisibility=hidden CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden LDELFFLAGS = -r -e main -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)binfmt$(DELIM)libelf$(DELIM)gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)modlib$(DELIM)gnu-elf.ld) diff --git a/arch/z80/src/ez80/Toolchain.defs b/arch/z80/src/ez80/Toolchain.defs index 75812bcdb2999..930066db7e6ba 100644 --- a/arch/z80/src/ez80/Toolchain.defs +++ b/arch/z80/src/ez80/Toolchain.defs @@ -221,4 +221,4 @@ CELFFLAGS = $(CFLAGS) -fvisibility=hidden CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden LDELFFLAGS = -r -e main -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)binfmt$(DELIM)libelf$(DELIM)gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)modlib$(DELIM)gnu-elf.ld) diff --git a/arch/z80/src/z180/Toolchain.defs b/arch/z80/src/z180/Toolchain.defs index 3e82d73c3cc93..8ecbdeaae5efe 100644 --- a/arch/z80/src/z180/Toolchain.defs +++ b/arch/z80/src/z180/Toolchain.defs @@ -119,4 +119,4 @@ CELFFLAGS = $(CFLAGS) -fvisibility=hidden CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden LDELFFLAGS = -r -e main -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)binfmt$(DELIM)libelf$(DELIM)gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)modlib$(DELIM)gnu-elf.ld) diff --git a/arch/z80/src/z8/Toolchain.defs b/arch/z80/src/z8/Toolchain.defs index 571dca9fa58a0..bf12ac950ddd0 100644 --- a/arch/z80/src/z8/Toolchain.defs +++ b/arch/z80/src/z8/Toolchain.defs @@ -144,4 +144,4 @@ CELFFLAGS = $(CFLAGS) -fvisibility=hidden CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden LDELFFLAGS = -r -e main -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)binfmt$(DELIM)libelf$(DELIM)gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)modlib$(DELIM)gnu-elf.ld) diff --git a/arch/z80/src/z80/Toolchain.defs b/arch/z80/src/z80/Toolchain.defs index 09ab0e4763c3c..3d2cecc1ff145 100644 --- a/arch/z80/src/z80/Toolchain.defs +++ b/arch/z80/src/z80/Toolchain.defs @@ -119,4 +119,4 @@ CELFFLAGS = $(CFLAGS) -fvisibility=hidden CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden LDELFFLAGS = -r -e main -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)binfmt$(DELIM)libelf$(DELIM)gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)modlib$(DELIM)gnu-elf.ld) diff --git a/binfmt/elf.c b/binfmt/elf.c index 1d531bfb66794..d95557ef367ef 100644 --- a/binfmt/elf.c +++ b/binfmt/elf.c @@ -33,9 +33,6 @@ #include #include -#include - -#include "libelf/libelf.h" #ifdef CONFIG_ELF diff --git a/binfmt/libelf/CMakeLists.txt b/binfmt/libelf/CMakeLists.txt deleted file mode 100644 index 8df1a0bd525b8..0000000000000 --- a/binfmt/libelf/CMakeLists.txt +++ /dev/null @@ -1,48 +0,0 @@ -# ############################################################################## -# binfmt/libelf/CMakeLists.txt -# -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed to the Apache Software Foundation (ASF) under one or more contributor -# license agreements. See the NOTICE file distributed with this work for -# additional information regarding copyright ownership. The ASF licenses this -# file to you under the Apache License, Version 2.0 (the "License"); you may not -# use this file except in compliance with the License. You may obtain a copy of -# the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations under -# the License. -# -# ############################################################################## - -if(CONFIG_ELF) - set(SRCS) - - # ELF library - - list( - APPEND - SRCS - libelf_bind.c - libelf_init.c - libelf_addrenv.c - libelf_iobuffer.c - libelf_load.c - libelf_read.c - libelf_sections.c - libelf_symbols.c - libelf_uninit.c - libelf_unload.c - libelf_verify.c) - - if(CONFIG_BINFMT_CONSTRUCTORS) - list(APPEND SRCS libelf_ctors.c libelf_dtors.c) - endif() - - target_sources(binfmt PRIVATE ${SRCS}) -endif() diff --git a/binfmt/libelf/Kconfig b/binfmt/libelf/Kconfig deleted file mode 100644 index f33d737021e26..0000000000000 --- a/binfmt/libelf/Kconfig +++ /dev/null @@ -1,72 +0,0 @@ -# -# For a description of the syntax of this configuration file, -# see the file kconfig-language.txt in the NuttX tools repository. -# - -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 DEFAULT_TASK_STACKSIZE - ---help--- - This is the default stack size that will be used when starting ELF binaries. - -config ELF_BUFFERSIZE - int "ELF I/O Buffer Size" - 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 is really just this initial - size of the buffer; it will be reallocated as necessary to hold large symbol - names. Default: 32 - -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_INFO - ---help--- - Dump various ELF buffers for debug purposes - -config ELF_EXIDX_SECTNAME - string "ELF Section Name for Exception Index" - default ".ARM.exidx" - depends on CXX_EXCEPTION && ARCH_ARM - ---help--- - Set the name string for the exception index section on the ELF modules to - be loaded by the ELF binary loader. - - This is needed to support exception handling on loadable ELF modules. - -config ELF_RELOCATION_BUFFERCOUNT - int "ELF Relocation Table Buffer Count" - default 256 - ---help--- - This is a relocation buffer that is used to store elf relocation table to - reduce access fs. Default: 256 - -config ELF_SYMBOL_CACHECOUNT - int "ELF SYMBOL Table Cache Count" - default 256 - ---help--- - This is a cache that is used to store elf symbol table to - reduce access fs. Default: 256 - -config ELF_LOADTO_LMA - bool "ELF load sections to LMA" - default n - ---help--- - Load all section to LMA not VMA, so the startup code(e.g. start.S) need - relocate .data section to the final address(VMA) and zero .bss section - by self. diff --git a/binfmt/libelf/Make.defs b/binfmt/libelf/Make.defs deleted file mode 100644 index 8c1a53182d648..0000000000000 --- a/binfmt/libelf/Make.defs +++ /dev/null @@ -1,41 +0,0 @@ -############################################################################ -# binfmt/libelf/Make.defs -# -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. The -# ASF licenses this file to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance with the -# License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# -############################################################################ - -ifeq ($(CONFIG_ELF),y) - -# ELF library - -CSRCS += libelf_bind.c libelf_init.c libelf_addrenv.c libelf_iobuffer.c -CSRCS += libelf_load.c libelf_read.c libelf_sections.c libelf_symbols.c -CSRCS += libelf_uninit.c libelf_unload.c libelf_verify.c - -ifeq ($(CONFIG_BINFMT_CONSTRUCTORS),y) -CSRCS += libelf_ctors.c libelf_dtors.c -endif - -# Hook the libelf subdirectory into the build - -VPATH += libelf -SUBDIRS += libelf -DEPPATH += --dep-path libelf - -endif diff --git a/binfmt/libelf/gnu-elf.ld b/binfmt/libelf/gnu-elf.ld deleted file mode 100644 index 55e689e9fe2b4..0000000000000 --- a/binfmt/libelf/gnu-elf.ld +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** - * binfmt/libelf/gnu-elf.ld - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -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*) - . = ALIGN(4); - _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 = . ; - KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) - KEEP(*(.init_array EXCLUDE_FILE(*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o) .ctors)) - _ectors = . ; - } - - .dtors : - { - _sdtors = . ; - *(.dtors) /* Old ABI: Unallocated */ - *(.fini_array) /* New ABI: Allocated */ - *(SORT(.fini_array.*)) - _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) } -} diff --git a/binfmt/libelf/libelf.h b/binfmt/libelf/libelf.h deleted file mode 100644 index 57d3b525b80db..0000000000000 --- a/binfmt/libelf/libelf.h +++ /dev/null @@ -1,345 +0,0 @@ -/**************************************************************************** - * binfmt/libelf/libelf.h - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -#ifndef __BINFMT_LIBELF_LIBELF_H -#define __BINFMT_LIBELF_LIBELF_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * 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. - * - ****************************************************************************/ - -int elf_verifyheader(FAR const Elf_Ehdr *header); - -/**************************************************************************** - * Name: elf_read - * - * Description: - * Read 'readsize' bytes from the object file at 'offset'. The data is - * read into 'buffer.' If 'buffer' is part of the ELF address environment, - * then the caller is responsible for assuring that that address - * environment is in place before calling this function (i.e., that - * elf_addrenv_select() has been called if CONFIG_ARCH_ADDRENV=y). - * - * Returned Value: - * 0 (OK) is returned on success and a negated errno is returned on - * failure. - * - ****************************************************************************/ - -int elf_read(FAR struct elf_loadinfo_s *loadinfo, FAR uint8_t *buffer, - size_t readsize, off_t offset); - -/**************************************************************************** - * Name: elf_loadphdrs - * - * Description: - * Loads program headers into memory. - * - * Returned Value: - * 0 (OK) is returned on success and a negated errno is returned on - * failure. - * - ****************************************************************************/ - -int elf_loadphdrs(FAR struct elf_loadinfo_s *loadinfo); - -/**************************************************************************** - * 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); - -/**************************************************************************** - * 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); - -/**************************************************************************** - * 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); - -/**************************************************************************** - * Name: elf_readsym - * - * Description: - * Read the ELF symbol structure at the specified 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 Elf_Sym *sym); - -/**************************************************************************** - * 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) - * exports - The symbol table to use for resolving undefined symbols. - * nexports - Number of symbols in the symbol table. - * - * Returned Value: - * 0 (OK) is returned on success and a negated errno is returned on - * 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 elf_symvalue(FAR struct elf_loadinfo_s *loadinfo, FAR Elf_Sym *sym, - FAR const struct symtab_s *exports, int nexports); - -/**************************************************************************** - * 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(FAR struct elf_loadinfo_s *loadinfo); - -/**************************************************************************** - * 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); - -/**************************************************************************** - * 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); - -/**************************************************************************** - * Name: elf_findctors - * - * Description: - * Find C++ static constructors. - * - * Input Parameters: - * loadinfo - Load state information - * - * Returned Value: - * 0 (OK) is returned on success and a negated errno is returned on - * failure. - * - ****************************************************************************/ - -#ifdef CONFIG_BINFMT_CONSTRUCTORS -int elf_loadctors(FAR struct elf_loadinfo_s *loadinfo); -#endif - -/**************************************************************************** - * 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. - * - ****************************************************************************/ - -#ifdef CONFIG_BINFMT_CONSTRUCTORS -int elf_loaddtors(FAR struct elf_loadinfo_s *loadinfo); -#endif - -/**************************************************************************** - * Name: elf_addrenv_alloc - * - * Description: - * Allocate memory for the ELF image (textalloc and dataalloc). - * If CONFIG_ARCH_ADDRENV=n, textalloc will be allocated using kmm_zalloc() - * and dataalloc will be a offset from textalloc. - * If CONFIG_ARCH_ADDRENV=y, then textalloc and dataalloc will be allocated - * using up_addrenv_create(). - * In either case, there will be a unique instance of textalloc and - * dataalloc (and stack) for each instance of a process. - * - * Input Parameters: - * loadinfo - Load state information - * textsize - The size (in bytes) of the .text address environment needed - * for the ELF image (read/execute). - * datasize - The size (in bytes) of the .bss/.data address environment - * needed for the ELF image (read/write). - * heapsize - The initial size (in bytes) of the heap address environment - * needed by the task. This region may be read/write only. - * - * Returned Value: - * Zero (OK) on success; a negated errno value on failure. - * - ****************************************************************************/ - -int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t textsize, - size_t datasize, size_t heapsize); - -/**************************************************************************** - * Name: elf_addrenv_select - * - * Description: - * Temporarily select the task's address environment. - * - * Input Parameters: - * loadinfo - Load state information - * - * Returned Value: - * Zero (OK) on success; a negated errno value on failure. - * - ****************************************************************************/ - -#ifdef CONFIG_ARCH_ADDRENV -int elf_addrenv_select(FAR struct elf_loadinfo_s *loadinfo); -#endif - -/**************************************************************************** - * Name: elf_addrenv_restore - * - * Description: - * Restore the address environment before elf_addrenv_select() was called.. - * - * Input Parameters: - * loadinfo - Load state information - * - * Returned Value: - * Zero (OK) on success; a negated errno value on failure. - * - ****************************************************************************/ - -#ifdef CONFIG_ARCH_ADDRENV -int elf_addrenv_restore(FAR struct elf_loadinfo_s *loadinfo); -#endif - -/**************************************************************************** - * Name: elf_addrenv_free - * - * Description: - * Release the address environment previously created by - * elf_addrenv_alloc(). This function is called only under certain error - * conditions after the module has been loaded but not yet started. - * After the module has been started, the address environment will - * automatically be freed when the module exits. - * - * Input Parameters: - * loadinfo - Load state information - * - * Returned Value: - * None. - * - ****************************************************************************/ - -void elf_addrenv_free(FAR struct elf_loadinfo_s *loadinfo); - -#endif /* __BINFMT_LIBELF_LIBELF_H */ diff --git a/binfmt/libelf/libelf_addrenv.c b/binfmt/libelf/libelf_addrenv.c deleted file mode 100644 index 3f2ebe3b66bd0..0000000000000 --- a/binfmt/libelf/libelf_addrenv.c +++ /dev/null @@ -1,354 +0,0 @@ -/**************************************************************************** - * binfmt/libelf/libelf_addrenv.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include - -#include -#include -#include - -#include - -#include "libelf.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define ELF_TEXT_WRE (PROT_READ | PROT_WRITE | PROT_EXEC) -#define ELF_TEXT_RE (PROT_READ | PROT_EXEC) - -/**************************************************************************** - * Private Constant Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: elf_addrenv_alloc - * - * Description: - * Allocate memory for the ELF image (textalloc and dataalloc). If - * CONFIG_ARCH_ADDRENV=n, textalloc will be allocated using kmm_zalloc() - * and dataalloc will be a offset from textalloc. If - * CONFIG_ARCH_ADDRENV=y, then textalloc and dataalloc will be allocated - * using up_addrenv_create(). In either case, there will be a unique - * instance of textalloc and dataalloc (and stack) for each instance of a - * process. - * - * Input Parameters: - * loadinfo - Load state information - * textsize - The size (in bytes) of the .text address environment needed - * for the ELF image (read/execute). - * datasize - The size (in bytes) of the .bss/.data address environment - * needed for the ELF image (read/write). - * heapsize - The initial size (in bytes) of the heap address environment - * needed by the task. This region may be read/write only. - * - * Returned Value: - * Zero (OK) on success; a negated errno value on failure. - * - ****************************************************************************/ - -int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t textsize, - size_t datasize, size_t heapsize) -{ -#ifdef CONFIG_ARCH_ADDRENV - FAR struct arch_addrenv_s *addrenv; - FAR void *vtext; - FAR void *vdata; - int ret; - - /* Create an address environment for the new ELF task */ - - loadinfo->addrenv = addrenv_allocate(); - if (!loadinfo->addrenv) - { - return -ENOMEM; - } - - /* Start creating the address environment sections */ - - addrenv = &loadinfo->addrenv->addrenv; - - ret = up_addrenv_create(textsize, datasize, heapsize, addrenv); - if (ret < 0) - { - berr("ERROR: up_addrenv_create failed: %d\n", ret); - goto errout_with_addrenv; - } - - /* Get the virtual address associated with the start of the address - * environment. This is the base address that we will need to use to - * access the ELF image (but only if the address environment has been - * selected. - */ - - ret = up_addrenv_vtext(addrenv, &vtext); - if (ret < 0) - { - berr("ERROR: up_addrenv_vtext failed: %d\n", ret); - goto errout_with_addrenv; - } - - ret = up_addrenv_vdata(addrenv, textsize, &vdata); - if (ret < 0) - { - berr("ERROR: up_addrenv_vdata failed: %d\n", ret); - goto errout_with_addrenv; - } - - loadinfo->textalloc = (uintptr_t)vtext; - loadinfo->dataalloc = (uintptr_t)vdata; - - return OK; - -errout_with_addrenv: - addrenv_drop(loadinfo->addrenv, false); - return ret; -#else - if (loadinfo->ehdr.e_type == ET_EXEC) - { - return OK; - } - - /* Allocate memory to hold the ELF image */ - -# ifndef CONFIG_ARCH_USE_SEPARATED_SECTION -# if defined(CONFIG_ARCH_USE_TEXT_HEAP) - loadinfo->textalloc = (uintptr_t) - up_textheap_memalign(loadinfo->textalign, - textsize); -# else - loadinfo->textalloc = (uintptr_t) - kumm_memalign(loadinfo->textalign, textsize); -# endif - - if (!loadinfo->textalloc) - { - return -ENOMEM; - } - - if (loadinfo->datasize > 0) - { -# ifdef CONFIG_ARCH_USE_DATA_HEAP - loadinfo->dataalloc = (uintptr_t) - up_dataheap_memalign(loadinfo->dataalign, - datasize); -# else - loadinfo->dataalloc = (uintptr_t) - kumm_memalign(loadinfo->dataalign, datasize); -# endif - if (!loadinfo->dataalloc) - { - return -ENOMEM; - } - } -# endif - - return OK; -#endif -} - -/**************************************************************************** - * Name: elf_addrenv_select - * - * Description: - * Temporarily select the task's address environment. - * - * Input Parameters: - * loadinfo - Load state information - * - * Returned Value: - * Zero (OK) on success; a negated errno value on failure. - * - ****************************************************************************/ - -#ifdef CONFIG_ARCH_ADDRENV -int elf_addrenv_select(FAR struct elf_loadinfo_s *loadinfo) -{ - int ret; - - /* Instantiate the new address environment */ - - ret = addrenv_select(loadinfo->addrenv, &loadinfo->oldenv); - if (ret < 0) - { - berr("ERROR: addrenv_select failed: %d\n", ret); - return ret; - } - - /* Allow write access to .text */ - - ret = up_addrenv_mprot(&loadinfo->addrenv->addrenv, loadinfo->textalloc, - loadinfo->textsize, ELF_TEXT_WRE); - if (ret < 0) - { - berr("ERROR: up_addrenv_text_enable_write failed: %d\n", ret); - return ret; - } - - return OK; -} -#endif - -/**************************************************************************** - * Name: elf_addrenv_restore - * - * Description: - * Restore the address environment before elf_addrenv_select() was called.. - * - * Input Parameters: - * loadinfo - Load state information - * - * Returned Value: - * Zero (OK) on success; a negated errno value on failure. - * - ****************************************************************************/ - -#ifdef CONFIG_ARCH_ADDRENV -int elf_addrenv_restore(FAR struct elf_loadinfo_s *loadinfo) -{ - int ret; - - /* Remove write access to .text */ - - ret = up_addrenv_mprot(&loadinfo->addrenv->addrenv, loadinfo->textalloc, - loadinfo->textsize, ELF_TEXT_RE); - if (ret < 0) - { - berr("ERROR: up_addrenv_text_disable_write failed: %d\n", ret); - return ret; - } - - /* Restore the old address environment */ - - ret = addrenv_restore(loadinfo->oldenv); - if (ret < 0) - { - berr("ERROR: addrenv_restore failed: %d\n", ret); - return ret; - } - - return OK; -} -#endif - -/**************************************************************************** - * Name: elf_addrenv_free - * - * Description: - * Release the address environment previously created by - * elf_addrenv_alloc(). This function is called only under certain error - * conditions after the module has been loaded but not yet started. - * After the module has been started, the address environment will - * automatically be freed when the module exits. - * - * Input Parameters: - * loadinfo - Load state information - * - * Returned Value: - * None. - * - ****************************************************************************/ - -void elf_addrenv_free(FAR struct elf_loadinfo_s *loadinfo) -{ -#ifdef CONFIG_ARCH_ADDRENV - - /* Free the address environment */ - - addrenv_drop(loadinfo->addrenv, false); -#else - -# ifndef CONFIG_ARCH_USE_SEPARATED_SECTION - if (loadinfo->textalloc != 0) - { -# if defined(CONFIG_ARCH_USE_TEXT_HEAP) - up_textheap_free((FAR void *)loadinfo->textalloc); -# else - kumm_free((FAR void *)loadinfo->textalloc); -# endif - } - - if (loadinfo->dataalloc != 0) - { -# if defined(CONFIG_ARCH_USE_DATA_HEAP) - up_dataheap_free((FAR void *)loadinfo->dataalloc); -# else - kumm_free((FAR void *)loadinfo->dataalloc); -# endif - } -# else - int i; - - for (i = 0; loadinfo->ehdr.e_type == ET_REL && i < loadinfo->ehdr.e_shnum; - i++) - { - if (loadinfo->sectalloc[i] == 0) - { - continue; - } - - if ((loadinfo->shdr[i].sh_flags & SHF_WRITE) != 0) - { -# if defined(CONFIG_ARCH_USE_DATA_HEAP) - up_dataheap_free((FAR void *)loadinfo->sectalloc[i]); -# else - kumm_free((FAR void *)loadinfo->sectalloc[i]); -# endif - } - else - { -# if defined(CONFIG_ARCH_USE_TEXT_HEAP) - up_textheap_free((FAR void *)loadinfo->sectalloc[i]); -# else - kumm_free((FAR void *)loadinfo->sectalloc[i]); -# endif - } - } - - kmm_free(loadinfo->sectalloc); - loadinfo->sectalloc = 0; -# endif -#endif - - /* Clear out all indications of the allocated address environment */ - - loadinfo->textalloc = 0; - loadinfo->dataalloc = 0; - loadinfo->textsize = 0; - loadinfo->datasize = 0; -} diff --git a/binfmt/libelf/libelf_bind.c b/binfmt/libelf/libelf_bind.c deleted file mode 100644 index 57ec52dcb2895..0000000000000 --- a/binfmt/libelf/libelf_bind.c +++ /dev/null @@ -1,703 +0,0 @@ -/**************************************************************************** - * binfmt/libelf/libelf_bind.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "libelf.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* CONFIG_DEBUG_FEATURES, CONFIG_DEBUG_INFO, and CONFIG_DEBUG_BINFMT have to - * be defined or CONFIG_ELF_DUMPBUFFER does nothing. - */ - -#if !defined(CONFIG_DEBUG_INFO) || !defined (CONFIG_DEBUG_BINFMT) -# undef CONFIG_ELF_DUMPBUFFER -#endif - -#ifdef CONFIG_ELF_DUMPBUFFER -# define elf_dumpbuffer(m,b,n) binfodumpbuffer(m,b,n) -#else -# define elf_dumpbuffer(m,b,n) -#endif - -#ifdef ARCH_ELFDATA -# define ARCH_ELFDATA_DEF arch_elfdata_t arch_data; \ - memset(&arch_data, 0, sizeof(arch_elfdata_t)) -# define ARCH_ELFDATA_PARM &arch_data -#else -# define ARCH_ELFDATA_DEF -# define ARCH_ELFDATA_PARM NULL -#endif - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -struct elf_symcache_s -{ - dq_entry_t entry; - Elf_Sym sym; - int idx; -}; - -typedef struct elf_symcache_s elf_symcache_t; - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: elf_readrels - * - * Description: - * Read the (ELF_Rel structure * buffer count) into memory. - * - ****************************************************************************/ - -static inline int elf_readrels(FAR struct elf_loadinfo_s *loadinfo, - FAR const Elf_Shdr *relsec, - int index, FAR Elf_Rel *rels, - int count) -{ - off_t offset; - int size; - - /* Verify that the symbol table index lies within symbol table */ - - if (index < 0 || index > (relsec->sh_size / sizeof(Elf_Rel))) - { - berr("Bad relocation symbol index: %d\n", index); - return -EINVAL; - } - - /* Get the file offset to the symbol table entry */ - - offset = sizeof(Elf_Rel) * index; - size = sizeof(Elf_Rel) * count; - - if (offset + size > relsec->sh_size) - { - size = relsec->sh_size - offset; - } - - /* And, finally, read the symbol table entry into memory */ - - return elf_read(loadinfo, (FAR uint8_t *)rels, size, - relsec->sh_offset + offset); -} - -/**************************************************************************** - * Name: elf_readrelas - * - * Description: - * Read the (ELF_Rela structure * buffer count) into memory. - * - ****************************************************************************/ - -static inline int elf_readrelas(FAR struct elf_loadinfo_s *loadinfo, - FAR const Elf_Shdr *relsec, - int index, FAR Elf_Rela *relas, - int count) -{ - off_t offset; - int size; - - /* Verify that the symbol table index lies within symbol table */ - - if (index < 0 || index > (relsec->sh_size / sizeof(Elf_Rela))) - { - berr("Bad relocation symbol index: %d\n", index); - return -EINVAL; - } - - /* Get the file offset to the symbol table entry */ - - offset = sizeof(Elf_Rela) * index; - size = sizeof(Elf_Rela) * count; - - if (offset + size > relsec->sh_size) - { - size = relsec->sh_size - offset; - } - - /* And, finally, read the symbol table entry into memory */ - - return elf_read(loadinfo, (FAR uint8_t *)relas, size, - relsec->sh_offset + offset); -} - -/**************************************************************************** - * Name: elf_relocate and elf_relocateadd - * - * Description: - * Perform all relocations associated with a section. - * - * Returned Value: - * 0 (OK) is returned on success and a negated errno is returned on - * failure. - * - ****************************************************************************/ - -static int elf_relocate(FAR struct elf_loadinfo_s *loadinfo, int relidx, - FAR const struct symtab_s *exports, int nexports) -{ - FAR Elf_Shdr *relsec = &loadinfo->shdr[relidx]; - FAR Elf_Shdr *dstsec = &loadinfo->shdr[relsec->sh_info]; - FAR Elf_Rel *rels; - FAR Elf_Rel *rel; - FAR elf_symcache_t *cache; - FAR Elf_Sym *sym; - FAR dq_entry_t *e; - dq_queue_t q; - uintptr_t addr; - int symidx; - int ret; - int i; - int j; - - /* Define potential architecture specific elf data container */ - - ARCH_ELFDATA_DEF; - - rels = kmm_malloc(CONFIG_ELF_RELOCATION_BUFFERCOUNT * sizeof(Elf_Rel)); - if (rels == NULL) - { - berr("Failed to allocate memory for elf relocation\n"); - return -ENOMEM; - } - - dq_init(&q); - - /* Examine each relocation in the section. 'relsec' is the section - * containing the relations. 'dstsec' is the section containing the data - * to be relocated. - */ - - ret = OK; - - for (i = j = 0; i < relsec->sh_size / sizeof(Elf_Rel); i++) - { - /* Read the relocation entry into memory */ - - rel = &rels[i % CONFIG_ELF_RELOCATION_BUFFERCOUNT]; - - if (!(i % CONFIG_ELF_RELOCATION_BUFFERCOUNT)) - { - ret = elf_readrels(loadinfo, relsec, i, rels, - CONFIG_ELF_RELOCATION_BUFFERCOUNT); - if (ret < 0) - { - berr("Section %d reloc %d: " - "Failed to read relocation entry: %d\n", - relidx, i, ret); - break; - } - } - - /* Get the symbol table index for the relocation. This is contained - * in a bit-field within the r_info element. - */ - - symidx = ELF_R_SYM(rel->r_info); - - /* First try the cache */ - - sym = NULL; - for (e = dq_peek(&q); e; e = dq_next(e)) - { - cache = (FAR elf_symcache_t *)e; - if (cache->idx == symidx) - { - dq_rem(&cache->entry, &q); - dq_addfirst(&cache->entry, &q); - sym = &cache->sym; - break; - } - } - - /* If the symbol was not found in the cache, we will need to read the - * symbol from the file. - */ - - if (sym == NULL) - { - if (j < CONFIG_ELF_SYMBOL_CACHECOUNT) - { - cache = kmm_malloc(sizeof(elf_symcache_t)); - if (!cache) - { - berr("Failed to allocate memory for elf symbols\n"); - ret = -ENOMEM; - break; - } - - j++; - } - else - { - cache = (FAR elf_symcache_t *)dq_remlast(&q); - } - - sym = &cache->sym; - - /* Read the symbol table entry into memory */ - - ret = elf_readsym(loadinfo, symidx, sym); - if (ret < 0) - { - berr("Section %d reloc %d: Failed to read symbol[%d]: %d\n", - relidx, i, symidx, ret); - kmm_free(cache); - break; - } - - /* Get the value of the symbol (in sym.st_value) */ - - ret = elf_symvalue(loadinfo, sym, exports, nexports); - if (ret < 0) - { - /* The special error -ESRCH is returned only in one condition: - * The symbol has no name. - * - * 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 we will use a NULL symbol pointer to indicate - * that case to up_relocate(). That function can then do what - * is best. - */ - - if (ret == -ESRCH) - { - berr("Section %d reloc %d: " - "Undefined symbol[%d] has no name: %d\n", - relidx, i, symidx, ret); - } - else - { - berr("Section %d reloc %d: " - "Failed to get value of symbol[%d]: %d\n", - relidx, i, symidx, ret); - kmm_free(cache); - break; - } - } - - cache->idx = symidx; - dq_addfirst(&cache->entry, &q); - } - - if (sym->st_shndx == SHN_UNDEF && sym->st_name == 0) - { - sym = NULL; - } - - /* Calculate the relocation address. */ - - if (rel->r_offset < 0 || - rel->r_offset > dstsec->sh_size - sizeof(uint32_t)) - { - berr("Section %d reloc %d: Relocation address out of range, " - "offset %" PRIdPTR " size %jd\n", - relidx, i, (uintptr_t)rel->r_offset, - (uintmax_t)dstsec->sh_size); - ret = -EINVAL; - break; - } - - addr = dstsec->sh_addr + rel->r_offset; - - /* Now perform the architecture-specific relocation */ - - ret = up_relocate(rel, sym, addr, ARCH_ELFDATA_PARM); - if (ret < 0) - { - berr("ERROR: Section %d reloc %d: Relocation failed: %d\n", - relidx, i, ret); - break; - } - } - - kmm_free(rels); - while ((e = dq_peek(&q))) - { - dq_rem(e, &q); - kmm_free(e); - } - - return ret; -} - -static int elf_relocateadd(FAR struct elf_loadinfo_s *loadinfo, int relidx, - FAR const struct symtab_s *exports, int nexports) -{ - FAR Elf_Shdr *relsec = &loadinfo->shdr[relidx]; - FAR Elf_Shdr *dstsec = &loadinfo->shdr[relsec->sh_info]; - FAR Elf_Rela *relas; - FAR Elf_Rela *rela; - FAR elf_symcache_t *cache; - FAR Elf_Sym *sym; - FAR dq_entry_t *e; - dq_queue_t q; - uintptr_t addr; - int symidx; - int ret; - int i; - int j; - - /* Define potential architecture specific elf data container */ - - ARCH_ELFDATA_DEF; - - relas = kmm_malloc(CONFIG_ELF_RELOCATION_BUFFERCOUNT * sizeof(Elf_Rela)); - if (relas == NULL) - { - berr("Failed to allocate memory for elf relocation\n"); - return -ENOMEM; - } - - dq_init(&q); - - /* Examine each relocation in the section. 'relsec' is the section - * containing the relations. 'dstsec' is the section containing the data - * to be relocated. - */ - - ret = OK; - - for (i = j = 0; i < relsec->sh_size / sizeof(Elf_Rela); i++) - { - /* Read the relocation entry into memory */ - - rela = &relas[i % CONFIG_ELF_RELOCATION_BUFFERCOUNT]; - - if (!(i % CONFIG_ELF_RELOCATION_BUFFERCOUNT)) - { - ret = elf_readrelas(loadinfo, relsec, i, relas, - CONFIG_ELF_RELOCATION_BUFFERCOUNT); - if (ret < 0) - { - berr("Section %d reloc %d: " - "Failed to read relocation entry: %d\n", - relidx, i, ret); - break; - } - } - - /* Get the symbol table index for the relocation. This is contained - * in a bit-field within the r_info element. - */ - - symidx = ELF_R_SYM(rela->r_info); - - /* First try the cache */ - - sym = NULL; - for (e = dq_peek(&q); e; e = dq_next(e)) - { - cache = (FAR elf_symcache_t *)e; - if (cache->idx == symidx) - { - dq_rem(&cache->entry, &q); - dq_addfirst(&cache->entry, &q); - sym = &cache->sym; - break; - } - } - - /* If the symbol was not found in the cache, we will need to read the - * symbol from the file. - */ - - if (sym == NULL) - { - if (j < CONFIG_ELF_SYMBOL_CACHECOUNT) - { - cache = kmm_malloc(sizeof(elf_symcache_t)); - if (!cache) - { - berr("Failed to allocate memory for elf symbols\n"); - ret = -ENOMEM; - break; - } - - j++; - } - else - { - cache = (FAR elf_symcache_t *)dq_remlast(&q); - } - - sym = &cache->sym; - - /* Read the symbol table entry into memory */ - - ret = elf_readsym(loadinfo, symidx, sym); - if (ret < 0) - { - berr("Section %d reloc %d: Failed to read symbol[%d]: %d\n", - relidx, i, symidx, ret); - kmm_free(cache); - break; - } - - /* Get the value of the symbol (in sym.st_value) */ - - ret = elf_symvalue(loadinfo, sym, exports, nexports); - if (ret < 0) - { - /* The special error -ESRCH is returned only in one condition: - * The symbol has no name. - * - * 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 we will use a NULL symbol pointer to indicate - * that case to up_relocate(). That function can then do what - * is best. - */ - - if (ret == -ESRCH) - { - bwarn("Section %d reloc %d: " - "Undefined symbol[%d] has no name: %d\n", - relidx, i, symidx, ret); - } - else - { - berr("Section %d reloc %d: " - "Failed to get value of symbol[%d]: %d\n", - relidx, i, symidx, ret); - kmm_free(cache); - break; - } - } - - cache->idx = symidx; - dq_addfirst(&cache->entry, &q); - } - - if (sym->st_shndx == SHN_UNDEF && sym->st_name == 0) - { - sym = NULL; - } - - /* Calculate the relocation address. */ - - if (rela->r_offset < 0 || - rela->r_offset > dstsec->sh_size) - { - berr("Section %d reloc %d: Relocation address out of range, " - "offset %" PRIdPTR " size %jd\n", - relidx, i, (uintptr_t)rela->r_offset, - (uintmax_t)dstsec->sh_size); - ret = -EINVAL; - break; - } - - addr = dstsec->sh_addr + rela->r_offset; - - /* Now perform the architecture-specific relocation */ - - ret = up_relocateadd(rela, sym, addr, ARCH_ELFDATA_PARM); - if (ret < 0) - { - berr("ERROR: Section %d reloc %d: Relocation failed: %d\n", - relidx, i, ret); - break; - } - } - - kmm_free(relas); - while ((e = dq_peek(&q))) - { - dq_rem(e, &q); - kmm_free(e); - } - - return ret; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: elf_bind - * - * Description: - * Bind the imported symbol names in the loaded module described by - * 'loadinfo' using the exported symbol values provided by 'symtab'. - * - * Returned Value: - * 0 (OK) is returned on success and a negated errno is returned on - * failure. - * - ****************************************************************************/ - -int elf_bind(FAR struct elf_loadinfo_s *loadinfo, - FAR const struct symtab_s *exports, int nexports) -{ -#ifdef CONFIG_ARCH_ADDRENV - int status; -#endif - int ret; - int i; - - /* Find the symbol and string tables */ - - ret = elf_findsymtab(loadinfo); - if (ret < 0) - { - return ret; - } - -#ifdef CONFIG_ARCH_ADDRENV - /* If CONFIG_ARCH_ADDRENV=y, then the loaded ELF lies in a virtual address - * space that may not be in place now. elf_addrenv_select() will - * temporarily instantiate that address space. - */ - - ret = elf_addrenv_select(loadinfo); - if (ret < 0) - { - berr("ERROR: elf_addrenv_select() failed: %d\n", ret); - return ret; - } -#endif - - /* Process relocations in every allocated section */ - - for (i = 1; i < loadinfo->ehdr.e_shnum; i++) - { - /* Get the index to the relocation section */ - - int infosec = loadinfo->shdr[i].sh_info; - if (infosec >= loadinfo->ehdr.e_shnum) - { - continue; - } - - /* Make sure that the section is allocated. We can't relocated - * sections that were not loaded into memory. - */ - - if ((loadinfo->shdr[infosec].sh_flags & SHF_ALLOC) == 0) - { - continue; - } - - /* Process the relocations by type */ - - if (loadinfo->shdr[i].sh_type == SHT_REL) - { - ret = elf_relocate(loadinfo, i, exports, nexports); - } - else if (loadinfo->shdr[i].sh_type == SHT_RELA) - { - ret = elf_relocateadd(loadinfo, i, exports, nexports); - } - - if (ret < 0) - { - break; - } - } - -#if defined(CONFIG_ARCH_ADDRENV) - /* Ensure that the I and D caches are coherent before starting the newly - * loaded module by cleaning the D cache (i.e., flushing the D cache - * contents to memory and invalidating the I cache). - */ - -#if 0 /* REVISIT... has some problems */ - up_addrenv_coherent(&loadinfo->addrenv.addrenv); -#else - up_coherent_dcache(loadinfo->textalloc, loadinfo->textsize); - up_coherent_dcache(loadinfo->dataalloc, loadinfo->datasize); -#endif - - /* Restore the original address environment */ - - status = elf_addrenv_restore(loadinfo); - if (status < 0) - { - berr("ERROR: elf_addrenv_restore() failed: %d\n", status); - if (ret == OK) - { - ret = status; - } - } - -#else - /* Ensure that the I and D caches are coherent before starting the newly - * loaded module by cleaning the D cache (i.e., flushing the D cache - * contents to memory and invalidating the I cache). - */ - - if (loadinfo->textsize > 0) - { - up_coherent_dcache(loadinfo->textalloc, loadinfo->textsize); - } - - if (loadinfo->datasize > 0) - { - up_coherent_dcache(loadinfo->dataalloc, loadinfo->datasize); - } - -# ifdef CONFIG_ARCH_USE_SEPARATED_SECTION - for (i = 0; loadinfo->ehdr.e_type == ET_REL && i < loadinfo->ehdr.e_shnum; - i++) - { - if (loadinfo->sectalloc[i] == 0) - { - continue; - } - - up_coherent_dcache(loadinfo->sectalloc[i], loadinfo->shdr[i].sh_size); - } -# endif - -#endif - - return ret; -} diff --git a/binfmt/libelf/libelf_ctors.c b/binfmt/libelf/libelf_ctors.c deleted file mode 100644 index 129f61cd99d26..0000000000000 --- a/binfmt/libelf/libelf_ctors.c +++ /dev/null @@ -1,193 +0,0 @@ -/**************************************************************************** - * binfmt/libelf/libelf_ctors.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include -#include - -#include -#include - -#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 Elf_Shdr *shdr; - size_t ctorsize; - int ctoridx; - int ret; - int i; - - DEBUGASSERT(loadinfo->ctors == NULL); - - /* 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. - */ - - binfo("elf_findsection .ctors section failed: %d\n", ctoridx); - return ctoridx == -ENOENT ? OK : ctoridx; - } - - /* 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); - - binfo("ctoridx=%d ctorsize=%zd sizeof(binfmt_ctor_t)=%zd 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 = kumm_malloc(ctorsize); - if (!loadinfo->ctoralloc) - { - berr("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) - { - berr("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 = (FAR uintptr_t *) - ((FAR void *)(&loadinfo->ctors)[i]); - - binfo("ctor %d: " - "%08" PRIxPTR " + %08" PRIxPTR " = %08" PRIxPTR "\n", i, - *ptr, loadinfo->textalloc, (*ptr + loadinfo->textalloc)); - - *ptr += loadinfo->textalloc; - } - } - else - { - /* Save the address of the .ctors (actually, .init_array) where - * it was loaded into memory. Since the .ctors lie in allocated - * memory, they will be relocated via the normal mechanism. - */ - - loadinfo->ctors = (binfmt_ctor_t *)shdr->sh_addr; - } - } - - return OK; -} - -#endif /* CONFIG_BINFMT_CONSTRUCTORS */ diff --git a/binfmt/libelf/libelf_dtors.c b/binfmt/libelf/libelf_dtors.c deleted file mode 100644 index 8ec86982ff2d7..0000000000000 --- a/binfmt/libelf/libelf_dtors.c +++ /dev/null @@ -1,194 +0,0 @@ -/**************************************************************************** - * binfmt/libelf/libelf_dtors.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#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 Elf_Shdr *shdr; - size_t dtorsize; - int dtoridx; - int ret; - int i; - - DEBUGASSERT(loadinfo->dtors == NULL); - - /* 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. - */ - - binfo("elf_findsection .dtors section failed: %d\n", dtoridx); - return dtoridx == -ENOENT ? OK : dtoridx; - } - - /* 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); - - binfo("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->dtoralloc = kumm_malloc(dtorsize); - if (!loadinfo->dtoralloc) - { - berr("Failed to allocate memory for .dtors\n"); - return -ENOMEM; - } - - loadinfo->dtors = (binfmt_dtor_t *)loadinfo->dtoralloc; - - /* Read the section header table into memory */ - - ret = elf_read(loadinfo, (FAR uint8_t *)loadinfo->dtors, dtorsize, - shdr->sh_offset); - if (ret < 0) - { - berr("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 = (FAR uintptr_t *) - ((FAR void *)(&loadinfo->dtors)[i]); - - binfo("dtor %d: " - "%08" PRIxPTR " + %08" PRIxPTR " = %08" PRIxPTR "\n", i, - *ptr, loadinfo->textalloc, (*ptr + loadinfo->textalloc)); - - *ptr += loadinfo->textalloc; - } - } - else - { - /* Save the address of the .dtors (actually, .init_array) where - * it was loaded into memory. Since the .dtors lie in allocated - * memory, they will be relocated via the normal mechanism. - */ - - loadinfo->dtors = (binfmt_dtor_t *)shdr->sh_addr; - } - } - - return OK; -} - -#endif /* CONFIG_BINFMT_CONSTRUCTORS */ diff --git a/binfmt/libelf/libelf_init.c b/binfmt/libelf/libelf_init.c deleted file mode 100644 index d6e0e05d41dd7..0000000000000 --- a/binfmt/libelf/libelf_init.c +++ /dev/null @@ -1,178 +0,0 @@ -/**************************************************************************** - * binfmt/libelf/libelf_init.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include "libelf.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* CONFIG_DEBUG_FEATURES, CONFIG_DEBUG_INFO, and CONFIG_DEBUG_BINFMT have to - * be defined or CONFIG_ELF_DUMPBUFFER does nothing. - */ - -#if !defined(CONFIG_DEBUG_INFO) || !defined(CONFIG_DEBUG_BINFMT) -# undef CONFIG_ELF_DUMPBUFFER -#endif - -#ifdef CONFIG_ELF_DUMPBUFFER -# define elf_dumpbuffer(m,b,n) binfodumpbuffer(m,b,n) -#else -# define elf_dumpbuffer(m,b,n) -#endif - -/**************************************************************************** - * Private Constant Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: elf_fileinfo - * - * Description: - * Get some stats info of the ELF file - * - * Returned Value: - * 0 (OK) is returned on success and a negated errno is returned on - * failure. - * - ****************************************************************************/ - -static inline int elf_fileinfo(FAR struct elf_loadinfo_s *loadinfo) -{ - struct stat buf; - int ret; - - /* Get the file stats */ - - ret = file_fstat(&loadinfo->file, &buf); - if (ret < 0) - { - berr("Failed to stat file: %d\n", ret); - return ret; - } - - /* Return some stats info of the file in the loadinfo structure */ - - loadinfo->filelen = buf.st_size; - loadinfo->fileuid = buf.st_uid; - loadinfo->filegid = buf.st_gid; - loadinfo->filemode = buf.st_mode; - 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; - - binfo("filename: %s loadinfo: %p\n", filename, loadinfo); - - /* Clear the load info structure */ - - memset(loadinfo, 0, sizeof(struct elf_loadinfo_s)); - - /* Open the binary file for reading (only) */ - - ret = file_open(&loadinfo->file, filename, O_RDONLY | O_CLOEXEC); - if (ret < 0) - { - berr("Failed to open ELF binary %s: %d\n", filename, ret); - return ret; - } - - /* Get some stats info of the file. */ - - ret = elf_fileinfo(loadinfo); - if (ret < 0) - { - berr("elf_fileinfo failed: %d\n", ret); - return ret; - } - - /* Read the ELF ehdr from offset 0 */ - - ret = elf_read(loadinfo, (FAR uint8_t *)&loadinfo->ehdr, - sizeof(Elf_Ehdr), 0); - if (ret < 0) - { - berr("Failed to read ELF header: %d\n", ret); - return ret; - } - - elf_dumpbuffer("ELF header", (FAR const uint8_t *)&loadinfo->ehdr, - sizeof(Elf_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 which 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. - */ - - berr("Bad ELF header: %d\n", ret); - return ret; - } - - return OK; -} diff --git a/binfmt/libelf/libelf_iobuffer.c b/binfmt/libelf/libelf_iobuffer.c deleted file mode 100644 index fbdf8b89dd07f..0000000000000 --- a/binfmt/libelf/libelf_iobuffer.c +++ /dev/null @@ -1,122 +0,0 @@ -/**************************************************************************** - * binfmt/libelf/libelf_iobuffer.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include - -#include -#include - -#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 = kmm_malloc(CONFIG_ELF_BUFFERSIZE); - if (!loadinfo->iobuffer) - { - berr("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 = kmm_realloc(loadinfo->iobuffer, newsize); - if (!buffer) - { - berr("Failed to reallocate the I/O buffer\n"); - return -ENOMEM; - } - - /* Save the new buffer info */ - - loadinfo->iobuffer = buffer; - loadinfo->buflen = newsize; - return OK; -} diff --git a/binfmt/libelf/libelf_load.c b/binfmt/libelf/libelf_load.c deleted file mode 100644 index 1ffade84e27ad..0000000000000 --- a/binfmt/libelf/libelf_load.c +++ /dev/null @@ -1,552 +0,0 @@ -/**************************************************************************** - * binfmt/libelf/libelf_load.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "libelf.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define ELF_ALIGN_MASK ((1 << CONFIG_ELF_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) - -/* _ALIGN_UP: 'a' is assumed to be a power of two */ - -#define _ALIGN_UP(v, a) (((v) + ((a) - 1)) & ~((a) - 1)) - -/**************************************************************************** - * Private Constant Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -#if defined(CONFIG_ARCH_USE_SEPARATED_SECTION) && !defined(CONFIG_ARCH_ADDRENV) -static int elf_section_alloc(FAR struct elf_loadinfo_s *loadinfo, - FAR Elf_Shdr *shdr, uint8_t idx) -{ - if (loadinfo->ehdr.e_type != ET_REL) - { - return -EINVAL; - } - - if (loadinfo->sectalloc == NULL) - { - /* Allocate memory info for all sections */ - - loadinfo->sectalloc = kmm_zalloc(sizeof(uintptr_t) * - loadinfo->ehdr.e_shnum); - if (loadinfo->sectalloc == NULL) - { - return -ENOMEM; - } - } - - elf_sectname(loadinfo, shdr); - if ((shdr->sh_flags & SHF_WRITE) != 0) - { -# ifdef CONFIG_ARCH_USE_DATA_HEAP - loadinfo->sectalloc[idx] = (uintptr_t) - up_dataheap_memalign( - (FAR const char *)loadinfo->iobuffer, - shdr->sh_addralign, - shdr->sh_size); -# else - loadinfo->sectalloc[idx] = (uintptr_t)kumm_memalign(shdr->sh_addralign, - shdr->sh_size); -# endif - - if (loadinfo->dataalloc == 0) - { - loadinfo->dataalloc = loadinfo->sectalloc[idx]; - } - } - else - { -# ifdef CONFIG_ARCH_USE_TEXT_HEAP - loadinfo->sectalloc[idx] = (uintptr_t) - up_textheap_memalign( - (FAR const char *)loadinfo->iobuffer, - shdr->sh_addralign, - shdr->sh_size); -# else - loadinfo->sectalloc[idx] = (uintptr_t)kumm_memalign(shdr->sh_addralign, - shdr->sh_size); -# endif - - if (loadinfo->textalloc == 0) - { - loadinfo->textalloc = loadinfo->sectalloc[idx]; - } - } - - return OK; -} -#endif - -/**************************************************************************** - * Name: elf_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 elf_elfsize(FAR struct elf_loadinfo_s *loadinfo) -{ - size_t textsize = 0; - size_t datasize = 0; - int i; - - /* Accumulate the size each section into memory that is marked SHF_ALLOC */ - - for (i = 0; i < loadinfo->ehdr.e_shnum; i++) - { - FAR Elf_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 -#ifdef CONFIG_ARCH_HAVE_TEXT_HEAP_WORD_ALIGNED_READ - || (shdr->sh_flags & SHF_EXECINSTR) == 0 -#endif - ) - { -#if defined(CONFIG_ARCH_USE_SEPARATED_SECTION) && !defined(CONFIG_ARCH_ADDRENV) - if (elf_section_alloc(loadinfo, shdr, i) >= 0) - { - continue; - } -#endif - - datasize = _ALIGN_UP(datasize, shdr->sh_addralign); - datasize += ELF_ALIGNUP(shdr->sh_size); - if (loadinfo->dataalign < shdr->sh_addralign) - { - loadinfo->dataalign = shdr->sh_addralign; - } - } - else - { -#if defined(CONFIG_ARCH_USE_SEPARATED_SECTION) && !defined(CONFIG_ARCH_ADDRENV) - if (elf_section_alloc(loadinfo, shdr, i) >= 0) - { - continue; - } -#endif - - textsize = _ALIGN_UP(textsize, shdr->sh_addralign); - textsize += ELF_ALIGNUP(shdr->sh_size); - if (loadinfo->textalign < shdr->sh_addralign) - { - loadinfo->textalign = shdr->sh_addralign; - } - } - } - } - - /* Save the allocation size */ - - loadinfo->textsize = textsize; - loadinfo->datasize = datasize; -} - -#ifdef CONFIG_ELF_LOADTO_LMA -/**************************************************************************** - * Name: elf_vma2lma - * - * Description: - * Convert section`s VMA to LMA according to PhysAddr(p_paddr) of - * Program Header. - * - * Returned Value: - * 0 (OK) is returned on success and a negated errno is returned on - * failure. - * - ****************************************************************************/ - -static int elf_vma2lma(FAR struct elf_loadinfo_s *loadinfo, - FAR Elf_Shdr *shdr, FAR Elf_Addr *lma) -{ - int i; - - for (i = 0; i < loadinfo->ehdr.e_phnum; i++) - { - FAR Elf_Phdr *phdr = &loadinfo->phdr[i]; - - if (shdr->sh_addr >= phdr->p_vaddr && - shdr->sh_addr < phdr->p_vaddr + phdr->p_memsz) - { - *lma = phdr->p_paddr + shdr->sh_addr - phdr->p_vaddr; - return 0; - } - } - - return -ENOENT; -} -#endif - -/**************************************************************************** - * Name: elf_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 elf_loadfile(FAR struct elf_loadinfo_s *loadinfo) -{ - FAR uint8_t *text = (FAR uint8_t *)loadinfo->textalloc; - FAR uint8_t *data = (FAR uint8_t *)loadinfo->dataalloc; - FAR uint8_t **pptr = NULL; - int ret; - int i; - - /* Read each section into memory that is marked SHF_ALLOC + SHT_NOBITS */ - - binfo("Loaded sections:\n"); - - for (i = 0; i < loadinfo->ehdr.e_shnum; i++) - { - FAR Elf_Shdr *shdr = &loadinfo->shdr[i]; - -#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION - if (loadinfo->ehdr.e_type == ET_REL) - { - pptr = (FAR uint8_t **)&loadinfo->sectalloc[i]; - } - else -#endif - - /* SHF_WRITE indicates that the section address space is write- - * able - */ - - if ((shdr->sh_flags & SHF_WRITE) != 0 -#ifdef CONFIG_ARCH_HAVE_TEXT_HEAP_WORD_ALIGNED_READ - || (shdr->sh_flags & SHF_EXECINSTR) == 0 -#endif - ) - { - pptr = &data; - } - else - { - pptr = &text; - } - - /* SHF_ALLOC indicates that the section requires memory during - * execution. - */ - - if ((shdr->sh_flags & SHF_ALLOC) == 0) - { - /* Set the VMA regardless, some relocations might depend on this */ - - shdr->sh_addr = (uintptr_t)*pptr; - continue; - } - - if (*pptr == NULL) - { - if (shdr->sh_type != SHT_NOBITS) - { - Elf_Addr addr = shdr->sh_addr; - -#ifdef CONFIG_ELF_LOADTO_LMA - ret = elf_vma2lma(loadinfo, shdr, &addr); - if (ret < 0) - { - berr("ERROR: Failed to convert addr %d: %d\n", i, ret); - return ret; - } -#endif - - /* Read the section data from sh_offset to specified region */ - - ret = elf_read(loadinfo, (FAR uint8_t *)addr, - shdr->sh_size, shdr->sh_offset); - if (ret < 0) - { - berr("ERROR: Failed to read section %d: %d\n", i, ret); - return ret; - } - } - -#ifndef CONFIG_ELF_LOADTO_LMA - /* If there is no data in an allocated section, then the - * allocated section must be cleared. - */ - - else - { - memset((FAR uint8_t *)shdr->sh_addr, 0, shdr->sh_size); - } -#endif - - continue; - } - -#ifndef CONFIG_ARCH_USE_SEPARATED_SECTION - *pptr = (FAR uint8_t *)_ALIGN_UP((uintptr_t)*pptr, shdr->sh_addralign); -#endif - - /* 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 = elf_read(loadinfo, *pptr, shdr->sh_size, shdr->sh_offset); - if (ret < 0) - { - berr("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 */ - - binfo("%d. %08lx->%08lx\n", i, - (unsigned long)shdr->sh_addr, (unsigned long)*pptr); - - shdr->sh_addr = (uintptr_t)*pptr; - -#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION - if (loadinfo->ehdr.e_type != ET_REL) - { - *pptr += ELF_ALIGNUP(shdr->sh_size); - } -#else - /* Setup the memory pointer for the next time through the loop */ - - *pptr += ELF_ALIGNUP(shdr->sh_size); -#endif - } - - return OK; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: elf_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 elf_load(FAR struct elf_loadinfo_s *loadinfo) -{ - /* Determine the heapsize to allocate. heapsize is ignored if there is - * no address environment because the heap is a shared resource in that - * case. If there is no dynamic stack then heapsize must at least as big - * as the fixed stack size since the stack will be allocated from the heap - * in that case. - */ - -#if !defined(CONFIG_ARCH_ADDRENV) - size_t heapsize = 0; -#elif defined(CONFIG_ARCH_STACK_DYNAMIC) - size_t heapsize = ARCH_HEAP_SIZE; -#else - size_t heapsize = MAX(ARCH_HEAP_SIZE, CONFIG_ELF_STACKSIZE); -#endif -#ifdef CONFIG_ELF_EXIDX_SECTNAME - int exidx; -#endif - int ret; - - binfo("loadinfo: %p\n", loadinfo); - DEBUGASSERT(loadinfo && loadinfo->file.f_inode); - - /* Load program headers into memory */ - - ret = elf_loadphdrs(loadinfo); - if (ret < 0) - { - berr("ERROR: elf_loadphdrs failed: %d\n", ret); - goto errout_with_buffers; - } - - /* Load section headers into memory */ - - ret = elf_loadshdrs(loadinfo); - if (ret < 0) - { - berr("ERROR: elf_loadshdrs failed: %d\n", ret); - goto errout_with_buffers; - } - - /* Determine total size to allocate */ - - elf_elfsize(loadinfo); - - /* Allocate (and zero) memory for the ELF file. */ - - ret = elf_addrenv_alloc(loadinfo, loadinfo->textsize, loadinfo->datasize, - heapsize); - if (ret < 0) - { - berr("ERROR: elf_addrenv_alloc() failed: %d\n", ret); - goto errout_with_buffers; - } - -#ifdef CONFIG_ARCH_ADDRENV - /* If CONFIG_ARCH_ADDRENV=y, then the loaded ELF lies in a virtual address - * space that may not be in place now. elf_addrenv_select() will - * temporarily instantiate that address space. - */ - - ret = elf_addrenv_select(loadinfo); - if (ret < 0) - { - berr("ERROR: elf_addrenv_select() failed: %d\n", ret); - goto errout_with_buffers; - } -#endif - - /* Load ELF section data into memory */ - - ret = elf_loadfile(loadinfo); - if (ret < 0) - { - berr("ERROR: elf_loadfile failed: %d\n", ret); - goto errout_with_addrenv; - } - - /* Load static constructors and destructors. */ - -#ifdef CONFIG_BINFMT_CONSTRUCTORS - ret = elf_loadctors(loadinfo); - if (ret < 0) - { - berr("ERROR: elf_loadctors failed: %d\n", ret); - goto errout_with_addrenv; - } - - ret = elf_loaddtors(loadinfo); - if (ret < 0) - { - berr("ERROR: elf_loaddtors failed: %d\n", ret); - goto errout_with_addrenv; - } -#endif - -#ifdef CONFIG_ELF_EXIDX_SECTNAME - exidx = elf_findsection(loadinfo, CONFIG_ELF_EXIDX_SECTNAME); - if (exidx < 0) - { - binfo("elf_findsection: Exception Index section not found: %d\n", - exidx); - } - else - { - up_init_exidx(loadinfo->shdr[exidx].sh_addr, - loadinfo->shdr[exidx].sh_size); - } -#endif - -#ifdef CONFIG_ARCH_ADDRENV - /* Restore the original address environment */ - - ret = elf_addrenv_restore(loadinfo); - if (ret < 0) - { - berr("ERROR: elf_addrenv_restore() failed: %d\n", ret); - goto errout_with_buffers; - } -#endif - - return OK; - - /* Error exits */ - -errout_with_addrenv: -#ifdef CONFIG_ARCH_ADDRENV - elf_addrenv_restore(loadinfo); -#endif - -errout_with_buffers: - elf_unload(loadinfo); - return ret; -} diff --git a/binfmt/libelf/libelf_read.c b/binfmt/libelf/libelf_read.c deleted file mode 100644 index 1ada63465066a..0000000000000 --- a/binfmt/libelf/libelf_read.c +++ /dev/null @@ -1,188 +0,0 @@ -/**************************************************************************** - * binfmt/libelf/libelf_read.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#undef ELF_DUMP_READDATA /* Define to dump all file data read */ - -/**************************************************************************** - * Private Constant Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: elf_dumpreaddata - ****************************************************************************/ - -#ifdef ELF_DUMP_READDATA -static inline void elf_dumpreaddata(FAR char *buffer, size_t buflen) -{ - FAR uint32_t *buf32 = (FAR uint32_t *)buffer; - size_t i; - size_t j; - - for (i = 0; i < buflen; i += 32) - { - syslog(LOG_DEBUG, "%04zx:", i); - for (j = 0; j < 32; j += sizeof(uint32_t)) - { - syslog(LOG_DEBUG, " %08" PRIx32, *buf32++); - } - - syslog(LOG_DEBUG, "\n"); - } -} -#else -# define elf_dumpreaddata(b,n) -#endif - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: elf_read - * - * Description: - * Read 'readsize' bytes from the object file at 'offset'. The data is - * read into 'buffer.' If 'buffer' is part of the ELF address environment, - * then the caller is responsible for assuring that that address - * environment is in place before calling this function (i.e., that - * elf_addrenv_select() has been called if CONFIG_ARCH_ADDRENV=y). - * - * Returned Value: - * 0 (OK) is returned on success and a negated errno is returned on - * failure. - * - ****************************************************************************/ - -int elf_read(FAR struct elf_loadinfo_s *loadinfo, FAR uint8_t *buffer, - size_t readsize, off_t offset) -{ - size_t nsize = readsize; /* Bytes to read from the object file */ - ssize_t nbytes; /* Number of bytes read */ - off_t rpos; /* Position returned by lseek */ - int ret = OK; /* Return value */ - -#ifdef CONFIG_ARCH_USE_COPY_SECTION - FAR uint8_t *dest = buffer; /* Destination address - `buffer` */ - - /* Redirect `buffer` to temporary allocated memory */ - - buffer = kmm_malloc(readsize); - if (buffer == NULL) - { - berr("ERROR: Failed to allocate memory\n"); - return -ENOMEM; - } -#endif - - binfo("Read %zu bytes from offset %" PRIdOFF "\n", readsize, offset); - - /* Loop until all of the requested data has been read. */ - - while (readsize > 0) - { - /* Seek to the next read position */ - - rpos = file_seek(&loadinfo->file, offset, SEEK_SET); - if (rpos != offset) - { - berr("Failed to seek to position %" PRIdOFF ": %" PRIdOFF "\n", - offset, rpos); - ret = rpos; - goto errout; - } - - /* Read the file data at offset into the user buffer */ - - nbytes = file_read(&loadinfo->file, - buffer + nsize - readsize, readsize); - if (nbytes < 0) - { - /* EINTR just means that we received a signal */ - - if (nbytes != -EINTR) - { - berr("Read from offset %" PRIdOFF " failed: %zd\n", - offset, nbytes); - ret = nbytes; - goto errout; - } - } - else if (nbytes == 0) - { - berr("Unexpected end of file\n"); - ret = -ENODATA; - goto errout; - } - else - { - readsize -= nbytes; - offset += nbytes; - } - } - -#ifdef CONFIG_ARCH_USE_COPY_SECTION - /* Copy the requested data from temporary memory to destination */ - - ret = up_copy_section(dest, buffer, nsize); - if (ret < 0) - { - berr("ERROR: Failed to copy section at offset %"PRIdOFF"\n", offset); - goto errout; - } -#endif - - elf_dumpreaddata(buffer, nsize); - -errout: -#ifdef CONFIG_ARCH_USE_COPY_SECTION - /* Free the temporary memory */ - - kmm_free(buffer); -#endif - - return ret; -} diff --git a/binfmt/libelf/libelf_sections.c b/binfmt/libelf/libelf_sections.c deleted file mode 100644 index d7d5ff16e08bd..0000000000000 --- a/binfmt/libelf/libelf_sections.c +++ /dev/null @@ -1,342 +0,0 @@ -/**************************************************************************** - * binfmt/libelf/libelf_sections.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include -#include - -#include -#include - -#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 Elf_Shdr *shdr) -{ - FAR Elf_Shdr *shstr; - off_t offset; - size_t bytesread = 0; - 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) - { - berr("No section header string table\n"); - return -EINVAL; - } - - /* 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) - { - berr("elf_allocbuffer failed: %d\n", ret); - return ret; - } - - /* 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 */ - - for (; ; ) - { - FAR uint8_t *buffer = &loadinfo->iobuffer[bytesread]; - size_t readlen = loadinfo->buflen - bytesread; - - /* Get the number of bytes to read */ - - if (offset + readlen > loadinfo->filelen) - { - if (loadinfo->filelen <= offset) - { - berr("At end of file\n"); - return -EINVAL; - } - - readlen = loadinfo->filelen - offset; - } - - /* Read that number of bytes into the array */ - - ret = elf_read(loadinfo, buffer, readlen, offset + bytesread); - if (ret < 0) - { - berr("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) - { - berr("elf_reallocbuffer failed: %d\n", ret); - return ret; - } - } - - /* We will not get here */ - - return OK; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: elf_loadphdrs - * - * Description: - * Loads program headers into memory. - * - * Returned Value: - * 0 (OK) is returned on success and a negated errno is returned on - * failure. - * - ****************************************************************************/ - -int elf_loadphdrs(FAR struct elf_loadinfo_s *loadinfo) -{ - size_t phdrsize; - int ret; - - DEBUGASSERT(loadinfo->phdr == NULL); - - /* Verify that there are programs */ - - if (loadinfo->ehdr.e_phnum < 1) - { - binfo("No programs(?)\n"); - return 0; - } - - /* Get the total size of the program header table */ - - phdrsize = (size_t)loadinfo->ehdr.e_phentsize * - (size_t)loadinfo->ehdr.e_phnum; - if (loadinfo->ehdr.e_phoff + phdrsize > loadinfo->filelen) - { - berr("Insufficient space in file for program header table\n"); - return -ESPIPE; - } - - /* Allocate memory to hold a working copy of the program header table */ - - loadinfo->phdr = (FAR Elf_Phdr *)kmm_malloc(phdrsize); - if (!loadinfo->phdr) - { - berr("Failed to allocate the program header table. Size: %ld\n", - (long)phdrsize); - return -ENOMEM; - } - - /* Read the program header table into memory */ - - ret = elf_read(loadinfo, (FAR uint8_t *)loadinfo->phdr, phdrsize, - loadinfo->ehdr.e_phoff); - if (ret < 0) - { - berr("Failed to read program header table: %d\n", ret); - } - - return ret; -} - -/**************************************************************************** - * 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) - { - berr("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) - { - berr("Insufficient space in file for section header table\n"); - return -ESPIPE; - } - - /* Allocate memory to hold a working copy of the sector header table */ - - loadinfo->shdr = kmm_malloc(shdrsize); - if (!loadinfo->shdr) - { - berr("Failed to allocate the section header table. Size: %zu\n", - 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) - { - berr("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) -{ - int i; - - /* Search through the shdr[] array in loadinfo for a section named - * 'sectname' - */ - - for (i = 0; i < loadinfo->ehdr.e_shnum; i++) - { - FAR const Elf_Shdr *shdr = &loadinfo->shdr[i]; - - /* Get the name of this section */ - - int ret = elf_sectname(loadinfo, shdr); - if (ret < 0) - { - berr("elf_sectname failed: %d\n", ret); - return ret; - } - - /* Check if the name of this section is 'sectname' */ - - binfo("%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; -} diff --git a/binfmt/libelf/libelf_symbols.c b/binfmt/libelf/libelf_symbols.c deleted file mode 100644 index bc865c61d8653..0000000000000 --- a/binfmt/libelf/libelf_symbols.c +++ /dev/null @@ -1,340 +0,0 @@ -/**************************************************************************** - * binfmt/libelf/libelf_symbols.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include "libelf.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * 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. - * - * EINVAL - There is something inconsistent in the symbol table (should - * only happen if the file is corrupted). - * ESRCH - Symbol has no name - * - ****************************************************************************/ - -static int elf_symname(FAR struct elf_loadinfo_s *loadinfo, - FAR const Elf_Sym *sym) -{ - off_t offset; - size_t bytesread = 0; - 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) - { - bwarn("Symbol has no name\n"); - return -ESRCH; - } - - /* Allocate an I/O buffer. This buffer is used by elf_symname() to - * accumulate the variable length symbol name. - */ - - ret = elf_allocbuffer(loadinfo); - if (ret < 0) - { - berr("elf_allocbuffer failed: %d\n", ret); - return ret; - } - - offset = loadinfo->shdr[loadinfo->strtabidx].sh_offset + sym->st_name; - - /* Loop until we get the entire symbol name into memory */ - - for (; ; ) - { - FAR uint8_t *buffer = &loadinfo->iobuffer[bytesread]; - size_t readlen = loadinfo->buflen - bytesread; - - /* Get the number of bytes to read */ - - if (offset + readlen > loadinfo->filelen) - { - if (loadinfo->filelen <= offset) - { - berr("At end of file\n"); - return -EINVAL; - } - - readlen = loadinfo->filelen - offset; - } - - /* Read that number of bytes into the array */ - - ret = elf_read(loadinfo, buffer, readlen, offset + bytesread); - if (ret < 0) - { - berr("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) - { - berr("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) - { - berr("No symbols in ELF file\n"); - return -EINVAL; - } - - return OK; -} - -/**************************************************************************** - * Name: elf_readsym - * - * Description: - * Read the ELF symbol structure at the specified 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 Elf_Sym *sym) -{ - FAR Elf_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(Elf_Sym))) - { - berr("Bad relocation symbol index: %d\n", index); - return -EINVAL; - } - - /* Get the file offset to the symbol table entry */ - - offset = symtab->sh_offset + sizeof(Elf_Sym) * index; - - /* And, finally, read the symbol table entry into memory */ - - return elf_read(loadinfo, (FAR uint8_t *)sym, sizeof(Elf_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. - * - * 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 elf_symvalue(FAR struct elf_loadinfo_s *loadinfo, FAR Elf_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. */ - - berr("SHN_COMMON: Re-compile with -fno-common\n"); - return -ENOSYS; - } - - case SHN_ABS: - { - /* st_value already holds the correct value */ - - binfo("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) - { - /* 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. - */ - - bwarn("SHN_UNDEF: Failed to get symbol name: %d\n", ret); - return ret; - } - - /* Check if the base code exports a symbol of this name */ - - symbol = symtab_findbyname(exports, (FAR char *)loadinfo->iobuffer, - nexports); - if (!symbol) - { - berr("SHN_UNDEF: Exported symbol \"%s\" not found\n", - loadinfo->iobuffer); - return -ENOENT; - } - - /* Yes... add the exported symbol value to the ELF symbol table - * entry - */ - - binfo("SHN_UNDEF: name=%s " - "%08" PRIxPTR "+%08" PRIxPTR "=%08" PRIxPTR "\n", - loadinfo->iobuffer, (uintptr_t)sym->st_value, - (uintptr_t)symbol->sym_value, - (uintptr_t)(sym->st_value + (uintptr_t)symbol->sym_value)); - - sym->st_value += (uintptr_t)symbol->sym_value; - } - break; - - default: - { - secbase = loadinfo->shdr[sym->st_shndx].sh_addr; - - binfo("Other: %08" PRIxPTR "+%08" PRIxPTR "=%08" PRIxPTR "\n", - (uintptr_t)sym->st_value, secbase, - (uintptr_t)(sym->st_value + secbase)); - - sym->st_value += secbase; - } - break; - } - - return OK; -} diff --git a/binfmt/libelf/libelf_uninit.c b/binfmt/libelf/libelf_uninit.c deleted file mode 100644 index 29de1d61f65b2..0000000000000 --- a/binfmt/libelf/libelf_uninit.c +++ /dev/null @@ -1,119 +0,0 @@ -/**************************************************************************** - * binfmt/libelf/libelf_uninit.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include - -#include -#include - -#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->file.f_inode) - { - file_close(&loadinfo->file); - } - - 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(FAR struct elf_loadinfo_s *loadinfo) -{ - /* Release all working allocations */ - - if (loadinfo->phdr) - { - kmm_free((FAR void *)loadinfo->phdr); - loadinfo->phdr = NULL; - } - - if (loadinfo->shdr) - { - kmm_free(loadinfo->shdr); - loadinfo->shdr = NULL; - } - - if (loadinfo->iobuffer) - { - kmm_free(loadinfo->iobuffer); - loadinfo->iobuffer = NULL; - loadinfo->buflen = 0; - } - - return OK; -} diff --git a/binfmt/libelf/libelf_unload.c b/binfmt/libelf/libelf_unload.c deleted file mode 100644 index 06bbebd36583f..0000000000000 --- a/binfmt/libelf/libelf_unload.c +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** - * binfmt/libelf/libelf_unload.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include - -#include -#include - -#include "libelf.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Constant Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: elf_unload - * - * Description: - * This function unloads the object from memory. This essentially undoes - * the actions of elf_load. It is called only under certain error - * conditions after the module has been loaded but not yet started. - * - * Returned Value: - * 0 (OK) is returned on success and a negated errno is returned on - * failure. - * - ****************************************************************************/ - -int elf_unload(FAR struct elf_loadinfo_s *loadinfo) -{ - /* Free all working buffers */ - - elf_freebuffers(loadinfo); - - /* Release memory holding the relocated ELF image */ - - elf_addrenv_free(loadinfo); - - /* Release memory used to hold static constructors and destructors */ - -#ifdef CONFIG_BINFMT_CONSTRUCTORS -# ifndef CONFIG_ARCH_ADDRENV - if (loadinfo->ctoralloc != 0) - { - kumm_free(loadinfo->ctoralloc); - } - - if (loadinfo->dtoralloc != 0) - { - kumm_free(loadinfo->dtoralloc); - } -# endif - - loadinfo->ctoralloc = NULL; - loadinfo->ctors = NULL; - loadinfo->nctors = 0; - - loadinfo->dtoralloc = NULL; - loadinfo->dtors = NULL; - loadinfo->ndtors = 0; -#endif - - return OK; -} diff --git a/binfmt/libelf/libelf_verify.c b/binfmt/libelf/libelf_verify.c deleted file mode 100644 index 2e005d516f09d..0000000000000 --- a/binfmt/libelf/libelf_verify.c +++ /dev/null @@ -1,109 +0,0 @@ -/**************************************************************************** - * binfmt/libelf/libelf_verify.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include - -#include -#include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Constant Data - ****************************************************************************/ - -static const char g_elfmagic[EI_MAGIC_SIZE] = EI_MAGIC; - -/**************************************************************************** - * 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 Elf_Ehdr *ehdr) -{ - if (!ehdr) - { - berr("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) - { - binfo("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 && ehdr->e_type != ET_EXEC) - { - berr("Not a relocatable or executable file: e_type=%d\n", - ehdr->e_type); - return -EINVAL; - } - - /* Verify that this file works with the currently configured architecture */ - - if (!up_checkarch(ehdr)) - { - berr("Not a supported architecture\n"); - return -ENOEXEC; - } - - /* Looks good so far... we still might find some problems later. */ - - return OK; -} diff --git a/boards/arm/mps/mps2-an500/scripts/Make.defs b/boards/arm/mps/mps2-an500/scripts/Make.defs index 45e22c1e2be3b..84f445475f196 100644 --- a/boards/arm/mps/mps2-an500/scripts/Make.defs +++ b/boards/arm/mps/mps2-an500/scripts/Make.defs @@ -54,4 +54,4 @@ LDNXFLATFLAGS = -e main -s 2048 # ELF module definitions LDELFFLAGS = -r -e main -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/binfmt/libelf/gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/modlib/gnu-elf.ld) diff --git a/boards/arm/mps/mps3-an547/scripts/Make.defs b/boards/arm/mps/mps3-an547/scripts/Make.defs index 585f443c1896c..d31709d88f67a 100644 --- a/boards/arm/mps/mps3-an547/scripts/Make.defs +++ b/boards/arm/mps/mps3-an547/scripts/Make.defs @@ -42,4 +42,4 @@ LDNXFLATFLAGS = -e main -s 2048 # ELF module definitions LDELFFLAGS = -r -e main -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/binfmt/libelf/gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/modlib/gnu-elf.ld) diff --git a/boards/arm/sama5/sama5d3-xplained/scripts/Make.defs b/boards/arm/sama5/sama5d3-xplained/scripts/Make.defs index da2ce0355f0da..dc2238c853b23 100644 --- a/boards/arm/sama5/sama5d3-xplained/scripts/Make.defs +++ b/boards/arm/sama5/sama5d3-xplained/scripts/Make.defs @@ -53,4 +53,4 @@ CELFFLAGS = $(CFLAGS) -mlong-calls # --target1-abs CXXELFFLAGS = $(CXXFLAGS) -mlong-calls # --target1-abs LDELFFLAGS = -r -e main -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/binfmt/libelf/gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/modlib/gnu-elf.ld) diff --git a/boards/sim/sim/sim/scripts/Make.defs b/boards/sim/sim/sim/scripts/Make.defs index bb4f0f0a97990..729c957f15769 100644 --- a/boards/sim/sim/sim/scripts/Make.defs +++ b/boards/sim/sim/sim/scripts/Make.defs @@ -280,7 +280,7 @@ ifeq ($(CONFIG_LIBC_ARCH_ELF_64BIT),y) endif LDELFFLAGS = -r -e main --gc-sections -LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/binfmt/libelf/gnu-elf.ld) +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/modlib/gnu-elf.ld) ifeq ($(CONFIG_HOST_MACOS),y) LDFLAGS += -Wl,-dead_strip diff --git a/tools/mkexport.sh b/tools/mkexport.sh index bf1d3f98a25df..8c434b220fee4 100755 --- a/tools/mkexport.sh +++ b/tools/mkexport.sh @@ -188,7 +188,7 @@ APPLD=gnu-elf.ld if [ -f "${BOARDDIR}/scripts/${APPLD}" ]; then cp -f "${BOARDDIR}/scripts/${APPLD}" "${EXPORTDIR}/scripts/." else - cp -f "${TOPDIR}/binfmt/libelf/${APPLD}" "${EXPORTDIR}/scripts/." + cp -f "${TOPDIR}/libs/libc/modlib/${APPLD}" "${EXPORTDIR}/scripts/." fi if [ "${NUTTX_BUILD}" = "kernel" ]; then From b471c0e9f0b9889314efb0ef1dd4de03d4b92ea2 Mon Sep 17 00:00:00 2001 From: anjiahao Date: Tue, 9 Jul 2024 23:27:59 +0800 Subject: [PATCH 14/20] modlib_bind:add new args export and nexport to modlib_bind if modp is NULL, we can use export and nexport load externl symbol Signed-off-by: anjiahao --- include/nuttx/lib/modlib.h | 9 ++++++- libs/libc/modlib/modlib.h | 12 ++++++---- libs/libc/modlib/modlib_bind.c | 40 ++++++++++++++++++++++++------- libs/libc/modlib/modlib_insert.c | 8 ++++++- libs/libc/modlib/modlib_symbols.c | 11 +++++---- 5 files changed, 61 insertions(+), 19 deletions(-) diff --git a/include/nuttx/lib/modlib.h b/include/nuttx/lib/modlib.h index f29fd550f7fc4..a41730094f415 100644 --- a/include/nuttx/lib/modlib.h +++ b/include/nuttx/lib/modlib.h @@ -360,6 +360,12 @@ int modlib_load_with_addrenv(FAR struct mod_loadinfo_s *loadinfo); * 'loadinfo' using the exported symbol values provided by * modlib_setsymtab(). * + * Input Parameters: + * modp - Module state information + * loadinfo - Load state information + * exports - The table of exported symbols + * nexports - The number of symbols in the exports table + * * Returned Value: * 0 (OK) is returned on success and a negated errno is returned on * failure. @@ -367,7 +373,8 @@ int modlib_load_with_addrenv(FAR struct mod_loadinfo_s *loadinfo); ****************************************************************************/ int modlib_bind(FAR struct module_s *modp, - FAR struct mod_loadinfo_s *loadinfo); + FAR struct mod_loadinfo_s *loadinfo, + FAR const struct symtab_s *exports, int nexports); /**************************************************************************** * Name: modlib_unload diff --git a/libs/libc/modlib/modlib.h b/libs/libc/modlib/modlib.h index 4e004521d37b6..a3d2c0ed0ee50 100644 --- a/libs/libc/modlib/modlib.h +++ b/libs/libc/modlib/modlib.h @@ -91,9 +91,12 @@ int modlib_readsym(FAR struct mod_loadinfo_s *loadinfo, int index, * 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) + * modp - Module state information + * loadinfo - Load state information + * sym - Symbol table entry (value might be undefined) + * sh_offset - Offset of strtab + * exports - Pointer to the symbol table + * nexports - Number of symbols in the symbol table* * * Returned Value: * 0 (OK) is returned on success and a negated errno is returned on @@ -109,7 +112,8 @@ int modlib_readsym(FAR struct mod_loadinfo_s *loadinfo, int index, int modlib_symvalue(FAR struct module_s *modp, FAR struct mod_loadinfo_s *loadinfo, FAR Elf_Sym *sym, - Elf_Off offset); + Elf_Off sh_offset, + FAR const struct symtab_s *exports, int nexports); /**************************************************************************** * Name: modlib_insertsymtab diff --git a/libs/libc/modlib/modlib_bind.c b/libs/libc/modlib/modlib_bind.c index d8679d28545d7..af1e09366a41d 100644 --- a/libs/libc/modlib/modlib_bind.c +++ b/libs/libc/modlib/modlib_bind.c @@ -176,7 +176,8 @@ static inline int modlib_readrelas(FAR struct mod_loadinfo_s *loadinfo, ****************************************************************************/ static int modlib_relocate(FAR struct module_s *modp, - FAR struct mod_loadinfo_s *loadinfo, int relidx) + FAR struct mod_loadinfo_s *loadinfo, int relidx, + FAR const struct symtab_s *exports, int nexports) { FAR Elf_Shdr *relsec = &loadinfo->shdr[relidx]; FAR Elf_Shdr *dstsec = &loadinfo->shdr[relsec->sh_info]; @@ -291,7 +292,8 @@ static int modlib_relocate(FAR struct module_s *modp, /* Get the value of the symbol (in sym.st_value) */ ret = modlib_symvalue(modp, loadinfo, sym, - loadinfo->shdr[loadinfo->strtabidx].sh_offset); + loadinfo->shdr[loadinfo->strtabidx].sh_offset, + exports, nexports); if (ret < 0) { /* The special error -ESRCH is returned only in one condition: @@ -367,7 +369,9 @@ static int modlib_relocate(FAR struct module_s *modp, static int modlib_relocateadd(FAR struct module_s *modp, FAR struct mod_loadinfo_s *loadinfo, - int relidx) + int relidx, + FAR const struct symtab_s *exports, + int nexports) { FAR Elf_Shdr *relsec = &loadinfo->shdr[relidx]; FAR Elf_Shdr *dstsec = &loadinfo->shdr[relsec->sh_info]; @@ -483,7 +487,8 @@ static int modlib_relocateadd(FAR struct module_s *modp, /* Get the value of the symbol (in sym.st_value) */ ret = modlib_symvalue(modp, loadinfo, sym, - loadinfo->shdr[loadinfo->strtabidx].sh_offset); + loadinfo->shdr[loadinfo->strtabidx].sh_offset, + exports, nexports); if (ret < 0) { /* The special error -ESRCH is returned only in one condition: @@ -836,6 +841,8 @@ static int modlib_relocatedyn(FAR struct module_s *modp, * Input Parameters: * modp - Module state information * loadinfo - Load state information + * exports - The table of exported symbols + * nexports - The number of symbols in the exports table * * Returned Value: * 0 (OK) is returned on success and a negated errno is returned on @@ -844,7 +851,8 @@ static int modlib_relocatedyn(FAR struct module_s *modp, ****************************************************************************/ int modlib_bind(FAR struct module_s *modp, - FAR struct mod_loadinfo_s *loadinfo) + FAR struct mod_loadinfo_s *loadinfo, + FAR const struct symtab_s *exports, int nexports) { FAR Elf_Shdr *symhdr; FAR Elf_Sym *sym; @@ -921,6 +929,11 @@ int modlib_bind(FAR struct module_s *modp, sizeof(uintptr_t); break; } + + if (ret < 0) + { + return ret; + } } else { @@ -941,10 +954,21 @@ int modlib_bind(FAR struct module_s *modp, switch (loadinfo->shdr[i].sh_type) { case SHT_REL: - ret = modlib_relocate(modp, loadinfo, i); + if ((loadinfo->shdr[infosec].sh_flags & SHF_ALLOC) == 0) + { + continue; + } + + ret = modlib_relocate(modp, loadinfo, i, exports, nexports); break; case SHT_RELA: - ret = modlib_relocateadd(modp, loadinfo, i); + if ((loadinfo->shdr[infosec].sh_flags & SHF_ALLOC) == 0) + { + continue; + } + + ret = modlib_relocateadd(modp, loadinfo, i, exports, + nexports); break; case SHT_INIT_ARRAY: loadinfo->initarr = loadinfo->shdr[i].sh_addr; @@ -961,7 +985,7 @@ int modlib_bind(FAR struct module_s *modp, if (ret < 0) { - break; + return ret; } } diff --git a/libs/libc/modlib/modlib_insert.c b/libs/libc/modlib/modlib_insert.c index 3516e675e9de1..92c58ce5d43af 100644 --- a/libs/libc/modlib/modlib_insert.c +++ b/libs/libc/modlib/modlib_insert.c @@ -231,9 +231,11 @@ void modlib_dumpentrypt(FAR struct mod_loadinfo_s *loadinfo) FAR void *modlib_insert(FAR const char *filename, FAR const char *modname) { + FAR const struct symtab_s *exports; struct mod_loadinfo_s loadinfo; FAR struct module_s *modp; FAR void (**array)(void); + int nexports; int ret; int i; @@ -291,9 +293,13 @@ FAR void *modlib_insert(FAR const char *filename, FAR const char *modname) goto errout_with_registry_entry; } + /* Get the symbol table */ + + modlib_getsymtab(&exports, &nexports); + /* Bind the program to the kernel symbol table */ - ret = modlib_bind(modp, &loadinfo); + ret = modlib_bind(modp, &loadinfo, exports, nexports); if (ret != 0) { binfo("Failed to bind symbols program binary: %d\n", ret); diff --git a/libs/libc/modlib/modlib_symbols.c b/libs/libc/modlib/modlib_symbols.c index 5412daf3c041a..f27a8dbb49c42 100644 --- a/libs/libc/modlib/modlib_symbols.c +++ b/libs/libc/modlib/modlib_symbols.c @@ -322,6 +322,8 @@ int modlib_readsym(FAR struct mod_loadinfo_s *loadinfo, int index, * loadinfo - Load state information * sym - Symbol table entry (value might be undefined) * sh_offset - Offset of strtab + * exports - Pointer to the symbol table + * nexports - Number of symbols in the symbol table* * * Returned Value: * 0 (OK) is returned on success and a negated errno is returned on @@ -337,12 +339,12 @@ int modlib_readsym(FAR struct mod_loadinfo_s *loadinfo, int index, int modlib_symvalue(FAR struct module_s *modp, FAR struct mod_loadinfo_s *loadinfo, FAR Elf_Sym *sym, - Elf_Off sh_offset) + Elf_Off sh_offset, + FAR const struct symtab_s *exports, int nexports) { FAR const struct symtab_s *symbol; struct mod_exportinfo_s exportinfo; uintptr_t secbase; - int nsymbols; int ret; switch (sym->st_shndx) @@ -406,9 +408,8 @@ int modlib_symvalue(FAR struct module_s *modp, if (symbol == NULL) { - modlib_getsymtab(&symbol, &nsymbols); - symbol = symtab_findbyname(symbol, exportinfo.name, - nsymbols); + symbol = symtab_findbyname(exports, exportinfo.name, + nexports); } /* Was the symbol found from any exporter? */ From 98b6739ff4d0586d9dfb05ff715b87d4cbbcbe62 Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Fri, 10 Nov 2023 21:19:44 +0800 Subject: [PATCH 15/20] binfmt/modlib: move modlib_sectname to public Signed-off-by: dongjiuzhu1 --- libs/libc/modlib/modlib.h | 15 +++++++++++++++ libs/libc/modlib/modlib_sections.c | 10 +++------- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/libs/libc/modlib/modlib.h b/libs/libc/modlib/modlib.h index a3d2c0ed0ee50..7405042f93c4d 100644 --- a/libs/libc/modlib/modlib.h +++ b/libs/libc/modlib/modlib.h @@ -179,6 +179,21 @@ void *modlib_findglobal(FAR struct module_s *modp, int modlib_loadhdrs(FAR struct mod_loadinfo_s *loadinfo); +/**************************************************************************** + * Name: modlib_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. + * + ****************************************************************************/ + +int modlib_sectname(FAR struct mod_loadinfo_s *loadinfo, + FAR const Elf_Shdr *shdr); + /**************************************************************************** * Name: modlib_findsection * diff --git a/libs/libc/modlib/modlib_sections.c b/libs/libc/modlib/modlib_sections.c index cae9db2bfe1a8..7e8ac1553ca71 100644 --- a/libs/libc/modlib/modlib_sections.c +++ b/libs/libc/modlib/modlib_sections.c @@ -35,7 +35,7 @@ #include "modlib/modlib.h" /**************************************************************************** - * Private Functions + * Public Functions ****************************************************************************/ /**************************************************************************** @@ -50,8 +50,8 @@ * ****************************************************************************/ -static inline int modlib_sectname(FAR struct mod_loadinfo_s *loadinfo, - FAR const Elf_Shdr *shdr) +int modlib_sectname(FAR struct mod_loadinfo_s *loadinfo, + FAR const Elf_Shdr *shdr) { FAR Elf_Shdr *shstr; off_t offset; @@ -152,10 +152,6 @@ static inline int modlib_sectname(FAR struct mod_loadinfo_s *loadinfo, return OK; } -/**************************************************************************** - * Public Functions - ****************************************************************************/ - /**************************************************************************** * Name: modlib_findsection * From 5533ac8b0dbc4358dc8f25a563bc34856aa5a6c6 Mon Sep 17 00:00:00 2001 From: anjiahao Date: Thu, 18 Jul 2024 16:36:39 +0800 Subject: [PATCH 16/20] modlib:move modlib_findsection to common headfile Signed-off-by: anjiahao --- include/nuttx/lib/modlib.h | 19 +++++++++++++++++++ libs/libc/modlib/modlib.h | 19 ------------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/include/nuttx/lib/modlib.h b/include/nuttx/lib/modlib.h index a41730094f415..228a24e88070c 100644 --- a/include/nuttx/lib/modlib.h +++ b/include/nuttx/lib/modlib.h @@ -455,6 +455,25 @@ int modlib_undepend(FAR struct module_s *importer); int modlib_read(FAR struct mod_loadinfo_s *loadinfo, FAR uint8_t *buffer, size_t readsize, off_t offset); +/**************************************************************************** + * Name: modlib_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 modlib_findsection(FAR struct mod_loadinfo_s *loadinfo, + FAR const char *sectname); + /**************************************************************************** * Name: modlib_registry_lock * diff --git a/libs/libc/modlib/modlib.h b/libs/libc/modlib/modlib.h index 7405042f93c4d..43bb58eda8f44 100644 --- a/libs/libc/modlib/modlib.h +++ b/libs/libc/modlib/modlib.h @@ -194,25 +194,6 @@ int modlib_loadhdrs(FAR struct mod_loadinfo_s *loadinfo); int modlib_sectname(FAR struct mod_loadinfo_s *loadinfo, FAR const Elf_Shdr *shdr); -/**************************************************************************** - * Name: modlib_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 modlib_findsection(FAR struct mod_loadinfo_s *loadinfo, - FAR const char *sectname); - /**************************************************************************** * Name: modlib_allocbuffer * From b0f198cd6f24b39e06fc1439826832f56b6f0cdc Mon Sep 17 00:00:00 2001 From: anjiahao Date: Thu, 18 Jul 2024 17:04:53 +0800 Subject: [PATCH 17/20] modlib:Allow loading elf from block devices Signed-off-by: anjiahao --- libs/libc/modlib/modlib_init.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/libs/libc/modlib/modlib_init.c b/libs/libc/modlib/modlib_init.c index 9b092fc5835fd..d7162d38fb106 100644 --- a/libs/libc/modlib/modlib_init.c +++ b/libs/libc/modlib/modlib_init.c @@ -70,14 +70,6 @@ static inline int modlib_fileinfo(FAR struct mod_loadinfo_s *loadinfo) return -errval; } - /* Verify that it is a regular file */ - - if (!S_ISREG(buf.st_mode)) - { - berr("ERROR: Not a regular file. mode: %d\n", buf.st_mode); - return -ENOENT; - } - /* Return some stats info of the file in the loadinfo structure */ loadinfo->filelen = buf.st_size; From 66f9a681135f8754363c1724607b955d4b548767 Mon Sep 17 00:00:00 2001 From: anjiahao Date: Mon, 29 Jul 2024 12:28:48 +0800 Subject: [PATCH 18/20] modlib:if use LMA, not set bss Signed-off-by: anjiahao --- libs/libc/modlib/modlib_load.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/libc/modlib/modlib_load.c b/libs/libc/modlib/modlib_load.c index 8c9a962114919..63e12ab382a76 100644 --- a/libs/libc/modlib/modlib_load.c +++ b/libs/libc/modlib/modlib_load.c @@ -398,10 +398,12 @@ static inline int modlib_loadfile(FAR struct mod_loadinfo_s *loadinfo) * section must be cleared. */ +#ifndef CONFIG_MODLIB_LOADTO_LMA else if (*pptr != NULL) { memset(*pptr, 0, shdr->sh_size); } +#endif /* Update sh_addr to point to copy in memory */ From c56e86e342bd0e841f6fdbac7ed040f399673504 Mon Sep 17 00:00:00 2001 From: anjiahao Date: Fri, 11 Oct 2024 15:18:49 +0800 Subject: [PATCH 19/20] binfmt_loadmodule.c:fix build break undefine lib_free Signed-off-by: anjiahao --- binfmt/binfmt_loadmodule.c | 1 + 1 file changed, 1 insertion(+) diff --git a/binfmt/binfmt_loadmodule.c b/binfmt/binfmt_loadmodule.c index 78fe70bd7f6d2..95daa44c8ec8a 100644 --- a/binfmt/binfmt_loadmodule.c +++ b/binfmt/binfmt_loadmodule.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include From b33718b06fdc251b84b1886ef4fb51b08869f8bf Mon Sep 17 00:00:00 2001 From: anjiahao Date: Fri, 11 Oct 2024 22:31:48 +0800 Subject: [PATCH 20/20] sabre-6quad:by pass coredump ci ci Signed-off-by: anjiahao --- boards/arm/imx6/sabre-6quad/configs/coredump/defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/boards/arm/imx6/sabre-6quad/configs/coredump/defconfig b/boards/arm/imx6/sabre-6quad/configs/coredump/defconfig index e8112e8b25f57..c66a1cc3024ef 100644 --- a/boards/arm/imx6/sabre-6quad/configs/coredump/defconfig +++ b/boards/arm/imx6/sabre-6quad/configs/coredump/defconfig @@ -58,7 +58,6 @@ CONFIG_SYSLOG_BUFFER=y CONFIG_SYSLOG_CONSOLE=y CONFIG_SYSLOG_INTBUFFER=y CONFIG_SYSLOG_PROCESSID=y -CONFIG_SYSTEM_COREDUMP=y CONFIG_SYSTEM_NSH=y CONFIG_SYSTEM_SYSTEM=y CONFIG_SYSTEM_TASKSET=y