From 5d7f2fdf1678af53d3393c5000b66cfabbb78cab Mon Sep 17 00:00:00 2001 From: Neale Ferguson Date: Mon, 4 Sep 2023 10:37:48 +1000 Subject: [PATCH] Fix loading of ET_DYN type of shared objects * build-globals.sh - Only look in the nuttx for external symbols used when loading dynamic shared objects * include/elf64.h - Correct the type of fields in the Elf64_Phdr structure * libs/libc/dlfcn/lib_dlclose.c - Distinguish between ET_DYN and other objects as the former has both text and data in a single allocation to reserve GOT offsets * libs/libc/dlfcn/lib_dlopen.c - Code formatting * libs/libc/modlib/modlib_bind.c - Distinguish between relocation entry sizes by section type - Handle RELA style relocations * libs/libc/modlib/modlib_globals.S - Formatting fixes - Symbols should not be weak - they exist or they don't * include/nuttx/lib/modlib.h - Add an inidcator to module_s to distinguish between ET_DYN and other * libs/libc/modlib/modlib_load.c - ET_DYN objects need to keep the relative displacement between the text and data sections due to GOT references from the former to the latter. This also implies that linking may require modification from the default for the shared objects being produced. For example, default alignment may mean nearly 64K of wasted space. * libs/libc/modlib/modlib_unload.c sched/module/mod_rmmod.c - Distingusih between freeing of ET_DYN storage and other as the former is a single allocation. * libs/libc/modlib/mod_insmod.c - Cater for ET_DYN objects having init and preinit sections --- boards/sim/sim/sim/scripts/Make.defs | 2 + include/elf64.h | 6 +- include/nuttx/lib/modlib.h | 1 + libs/libc/dlfcn/lib_dlclose.c | 49 +++++---- libs/libc/dlfcn/lib_dlopen.c | 1 + libs/libc/modlib/modlib_bind.c | 72 ++++++++++--- libs/libc/modlib/modlib_globals.S | 25 ++--- libs/libc/modlib/modlib_load.c | 68 ++++++++---- libs/libc/modlib/modlib_unload.c | 29 ++++-- sched/module/mod_insmod.c | 36 ++++++- sched/module/mod_rmmod.c | 21 +++- build-globals.sh => tools/build-globals.sh | 114 ++++++--------------- 12 files changed, 248 insertions(+), 176 deletions(-) rename build-globals.sh => tools/build-globals.sh (58%) diff --git a/boards/sim/sim/sim/scripts/Make.defs b/boards/sim/sim/sim/scripts/Make.defs index 37f3810376..fcaae3c420 100644 --- a/boards/sim/sim/sim/scripts/Make.defs +++ b/boards/sim/sim/sim/scripts/Make.defs @@ -230,6 +230,7 @@ CMODULEFLAGS += -fno-stack-protector LDMODULEFLAGS = -r -e module_initialize --gc-sections LDMODULEFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/modlib/gnu-elf.ld) +SHMODULEFLAGS = -Bsymbolic -G -Bdynamic # NuttX modules are ELF binaries. # Non-ELF platforms like macOS need to use a separate ELF toolchain. @@ -270,5 +271,6 @@ ifeq ($(CONFIG_SIM_M32),y) LDLINKFLAGS += -melf_i386 LDFLAGS += -m32 LDMODULEFLAGS += -melf_i386 + SHMODULEFLAGS += -melf_i386 LDELFFLAGS += -melf_i386 endif diff --git a/include/elf64.h b/include/elf64.h index 58dc673cb7..f5139255d5 100644 --- a/include/elf64.h +++ b/include/elf64.h @@ -142,9 +142,9 @@ typedef struct Elf64_Off p_offset; /* Offset in file */ Elf64_Addr p_vaddr; /* Virtual address in memory */ Elf64_Addr p_paddr; /* Reserved */ - Elf64_Word p_filesz; /* Size of segment in file */ - Elf64_Word p_memsz; /* Size of segment in memory */ - Elf64_Word p_align; /* Alignment of segment */ + Elf64_Xword p_filesz; /* Size of segment in file */ + Elf64_Xword p_memsz; /* Size of segment in memory */ + Elf64_Xword p_align; /* Alignment of segment */ } Elf64_Phdr; /* Figure 7. Format of a Note Section */ diff --git a/include/nuttx/lib/modlib.h b/include/nuttx/lib/modlib.h index 48144a115f..77fc8a545c 100644 --- a/include/nuttx/lib/modlib.h +++ b/include/nuttx/lib/modlib.h @@ -159,6 +159,7 @@ struct module_s struct mod_info_s modinfo; /* Module information */ FAR void *textalloc; /* Allocated kernel text memory */ FAR void *dataalloc; /* Allocated kernel memory */ + int dynamic; /* Module is a dynamic shared object */ #if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) size_t textsize; /* Size of the kernel .text memory allocation */ size_t datasize; /* Size of the kernel .bss/.data memory allocation */ diff --git a/libs/libc/dlfcn/lib_dlclose.c b/libs/libc/dlfcn/lib_dlclose.c index 873f838d0a..9586f7a7a7 100644 --- a/libs/libc/dlfcn/lib_dlclose.c +++ b/libs/libc/dlfcn/lib_dlclose.c @@ -125,38 +125,45 @@ static inline int dlremove(FAR void *handle) /* Release resources held by the module */ - if (modp->textalloc != NULL) + /* Dynamic shared objects have text and data allocated in one + * operation to keep the relative positions between the two + * areas relative otherwise references to the GOT will fail + */ + + if (!modp->dynamic) { - /* Free the module memory */ + if (modp->textalloc != NULL) + { + /* Free the module memory */ #if defined(CONFIG_ARCH_USE_TEXT_HEAP) - up_textheap_free(modp->textalloc); + up_textheap_free((FAR void *)modp->textalloc); #else - lib_free(modp->textalloc); + lib_free((FAR void *)modp->textalloc); #endif + } - /* Nullify so that the memory cannot be freed again */ + if (modp->dataalloc != NULL) + { + /* Free the module memory */ - modp->textalloc = NULL; -#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) - modp->textsize = 0; -#endif + lib_free((FAR void *)modp->dataalloc); + } } - - if (modp->dataalloc != NULL) + else { - /* Free the module memory */ - - lib_free(modp->dataalloc); - - /* Nullify so that the memory cannot be freed again */ - - modp->dataalloc = NULL; -#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) - modp->datasize = 0; -#endif + lib_free((FAR void *)modp->textalloc); } + /* Nullify so that the memory cannot be freed again */ + + modp->textalloc = NULL; + modp->dataalloc = NULL; +#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) + modp->textsize = 0; + modp->datasize = 0; +#endif + /* Free the modules exported symmbols table */ modlib_freesymtab(modp); diff --git a/libs/libc/dlfcn/lib_dlopen.c b/libs/libc/dlfcn/lib_dlopen.c index c93e2b8898..d603a3248d 100644 --- a/libs/libc/dlfcn/lib_dlopen.c +++ b/libs/libc/dlfcn/lib_dlopen.c @@ -232,6 +232,7 @@ static inline FAR void *dlinsert(FAR const char *filename) modp->textalloc = (FAR void *)loadinfo.textalloc; modp->dataalloc = (FAR void *)loadinfo.datastart; + modp->dynamic = (loadinfo.ehdr.e_type == ET_DYN); #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_bind.c b/libs/libc/modlib/modlib_bind.c index 14d7a0d60d..c79359dd77 100644 --- a/libs/libc/modlib/modlib_bind.c +++ b/libs/libc/modlib/modlib_bind.c @@ -64,9 +64,10 @@ struct int stroff; /* offset to string table */ int symoff; /* offset to symbol table */ int lsymtab; /* size of symbol table */ - int relentsz; /* size of relocation entry */ + int relentsz[2]; /* size of relocation entry */ int reloff[2]; /* offset to the relocation section */ int relsz[2]; /* size of relocation table */ + int relrela[2]; /* type of relocation type - 0: DT_REL / 1: DT_RELA */ } reldata; /**************************************************************************** @@ -558,6 +559,8 @@ static int modlib_relocatedyn(FAR struct module_s *modp, FAR Elf_Dyn *dyn = NULL; FAR Elf_Rel *rels = NULL; FAR Elf_Rel *rel; + FAR Elf_Rela *relas = NULL; + FAR Elf_Rela *rela; FAR Elf_Sym *sym = NULL; uintptr_t addr; int ret; @@ -574,7 +577,9 @@ static int modlib_relocatedyn(FAR struct module_s *modp, return ret; } - rels = lib_malloc(CONFIG_MODLIB_RELOCATION_BUFFERCOUNT * sizeof(Elf_Rel)); + /* Assume DT_RELA to get maximum size required */ + + rels = lib_malloc(CONFIG_MODLIB_RELOCATION_BUFFERCOUNT * sizeof(Elf_Rela)); if (!rels) { berr("Failed to allocate memory for elf relocation rels\n"); @@ -583,6 +588,7 @@ static int modlib_relocatedyn(FAR struct module_s *modp, } memset((void *)&reldata, 0, sizeof(reldata)); + relas = (FAR Elf_Rela *)rels; for (i = 0; dyn[i].d_tag != DT_NULL; i++) { @@ -595,7 +601,7 @@ static int modlib_relocatedyn(FAR struct module_s *modp, reldata.relsz[I_REL] = dyn[i].d_un.d_val; break; case DT_RELENT: - reldata.relentsz = dyn[i].d_un.d_val; + reldata.relentsz[I_REL] = dyn[i].d_un.d_val; break; case DT_SYMTAB: reldata.symoff = dyn[i].d_un.d_val; @@ -609,6 +615,18 @@ static int modlib_relocatedyn(FAR struct module_s *modp, case DT_PLTRELSZ: reldata.relsz[I_PLT] = dyn[i].d_un.d_val; break; + case DT_PLTREL: + if (dyn[i].d_un.d_val == DT_REL) + { + reldata.relentsz[I_PLT] = sizeof(Elf_Rel); + reldata.relrela[I_PLT] = 0; + } + else + { + reldata.relentsz[I_PLT] = sizeof(Elf_Rela); + reldata.relrela[I_PLT] = 1; + } + break; } } @@ -637,7 +655,9 @@ static int modlib_relocatedyn(FAR struct module_s *modp, for (idx_rel = 0; idx_rel < N_RELS; idx_rel++) { - if (reldata.reloff[idx_rel] == 0) + int lrelent; + + if ((reldata.relsz[idx_rel] == 0) || (reldata.reloff[idx_rel] == 0)) { continue; } @@ -645,16 +665,30 @@ static int modlib_relocatedyn(FAR struct module_s *modp, /* Examine each relocation in the .rel.* section. */ ret = OK; + lrelent = reldata.relsz[idx_rel] / reldata.relentsz[idx_rel]; - for (i = 0; i < reldata.relsz[idx_rel] / reldata.relentsz; i++) + for (i = 0; i < lrelent; i++) { - /* Process each relocation entry */ + /* Process each relocation entry + * - we cheat by using the fact the 1st two fields of Elf_Rel + * and Elf_Rela are identical so can do things based on the + * former until it's important + */ - rel = &rels[i % CONFIG_MODLIB_RELOCATION_BUFFERCOUNT]; + if (reldata.relrela[idx_rel] == 0) + { + rel = &rels[i % CONFIG_MODLIB_RELOCATION_BUFFERCOUNT]; + rela = (Elf_Rela *)rel; /* Just to keep the compiler happy */ + } + else + { + rela = &relas[i % CONFIG_MODLIB_RELOCATION_BUFFERCOUNT]; + rel = (Elf_Rel *)rela; + } if (!(i % CONFIG_MODLIB_RELOCATION_BUFFERCOUNT)) { - size_t relsize = (sizeof(Elf_Rel) * + size_t relsize = (sizeof(Elf_Rela) * CONFIG_MODLIB_RELOCATION_BUFFERCOUNT); if (reldata.relsz[idx_rel] < relsize) @@ -713,6 +747,12 @@ static int modlib_relocatedyn(FAR struct module_s *modp, } addr = rel->r_offset + loadinfo->textalloc; + + if (reldata.relrela[idx_rel] == 1) + { + addr += rela->r_addend; + } + *(FAR uintptr_t *)addr = (uintptr_t)ep; } } @@ -722,6 +762,11 @@ static int modlib_relocatedyn(FAR struct module_s *modp, addr = rel->r_offset - loadinfo->datasec + loadinfo->datastart; + if (reldata.relrela[idx_rel] == 1) + { + addr += rela->r_addend; + } + if ((*(FAR uint32_t *)addr) < loadinfo->datasec) { dynsym.st_value = *(FAR uint32_t *)addr + @@ -748,8 +793,8 @@ static int modlib_relocatedyn(FAR struct module_s *modp, } } - /* Iterate through the dynamic symbol table looking for global symbols to - * put in our own symbol table for use with dlgetsym() + /* Iterate through the dynamic symbol table looking for global symbols + * to put in our own symbol table for use with dlgetsym() */ /* Relocate the entries in the table */ @@ -831,6 +876,7 @@ int modlib_bind(FAR struct module_s *modp, if (loadinfo->ehdr.e_type == ET_DYN) { + modp->dynamic = 1; switch (loadinfo->shdr[i].sh_type) { case SHT_DYNAMIC: @@ -864,8 +910,10 @@ int modlib_bind(FAR struct module_s *modp, } else { - /* Make sure that the section is allocated. We can't relocate - * sections that were not loaded into memory. + modp->dynamic = 0; + + /* Make sure that the section is allocated. We can't + * relocate sections that were not loaded into memory. */ if ((loadinfo->shdr[infosec].sh_flags & SHF_ALLOC) == 0) diff --git a/libs/libc/modlib/modlib_globals.S b/libs/libc/modlib/modlib_globals.S index fe0b174feb..bdc8912271 100644 --- a/libs/libc/modlib/modlib_globals.S +++ b/libs/libc/modlib/modlib_globals.S @@ -1,28 +1,25 @@ #ifdef __CYGWIN__ -# define SYMBOL(s) s -# define WEAK .weak +# define SYMBOL(s) _##s # define GLOBAL .global # define SECTION .data .macro GLOBAL ep - .global SYMBOL(\ep) - .type SYMBOL(\ep), "object" + .global SYMBOL(\ep) + .type SYMBOL(\ep), "object" .endm .macro SIZE ep .endm #elif defined(__ELF__) # define SYMBOL(s) s -# define WEAK .weak # define SECTION .data .macro GLOBAL ep - .global SYMBOL(\ep) - .type SYMBOL(\ep), "object" + .global SYMBOL(\ep) + .type SYMBOL(\ep), "object" .endm .macro SIZE ep - .size SYMBOL(\ep), . - SYMBOL(\ep) + .size SYMBOL(\ep), . - SYMBOL(\ep) .endm #else # define SYMBOL(s) _##s -# define WEAK .weak_definition # define SECTION .section __DATA,__data .macro GLOBAL ep .private_extern SYMBOL(\ep) @@ -34,14 +31,12 @@ #if __SIZEOF_POINTER__ == 8 .macro globalEntry index, ep - WEAK SYMBOL(\ep) .quad .l\index .quad \ep .endm # define ALIGN 8 #else .macro globalEntry index, ep - WEAK SYMBOL(\ep) .long .l\index .long \ep .endm @@ -54,20 +49,20 @@ .arch armv8-m.base #endif #ifdef __ARM_ASM_SYNTAX_UNIFIED__ - .syntax unified + .syntax unified #endif .thumb #endif .data .align ALIGN - GLOBAL globalNames + GLOBAL globalNames SYMBOL(globalNames): - SIZE globalNames + SIZE globalNames .align ALIGN GLOBAL nglobals -SYMBOL(nglobals): +SYMBOL(nglobals): .word 0 SIZE nglobals diff --git a/libs/libc/modlib/modlib_load.c b/libs/libc/modlib/modlib_load.c index 3c86754b59..e77cd82e0a 100644 --- a/libs/libc/modlib/modlib_load.c +++ b/libs/libc/modlib/modlib_load.c @@ -309,36 +309,62 @@ int modlib_load(FAR struct mod_loadinfo_s *loadinfo) /* Allocate memory to hold the ELF image */ - if (loadinfo->textsize > 0) + /* For Dynamic shared objects the relative positions between + * text and data must be maintained due to references to the + * GOT. Therefore we cannot do two different allocations. + */ + + if (loadinfo->ehdr.e_type == ET_REL) { -#if defined(CONFIG_ARCH_USE_TEXT_HEAP) - loadinfo->textalloc = (uintptr_t) - up_textheap_memalign(loadinfo->textalign, - loadinfo->textsize + - loadinfo->segpad); -#else - loadinfo->textalloc = (uintptr_t)lib_memalign(loadinfo->textalign, - loadinfo->textsize + - loadinfo->segpad); -#endif - if (!loadinfo->textalloc) + if (loadinfo->textsize > 0) { - berr("ERROR: Failed to allocate memory for the module text\n"); - ret = -ENOMEM; - goto errout_with_buffers; +#if defined(CONFIG_ARCH_USE_TEXT_HEAP) + loadinfo->textalloc = (uintptr_t) + up_textheap_memalign(loadinfo->textalign, + loadinfo->textsize + + loadinfo->segpad); +#else + loadinfo->textalloc = (uintptr_t)lib_memalign(loadinfo->textalign, + loadinfo->textsize + + loadinfo->segpad); +#endif + if (!loadinfo->textalloc) + { + berr("ERROR: Failed to allocate memory for the module text\n"); + ret = -ENOMEM; + goto errout_with_buffers; + } + } + + if (loadinfo->datasize > 0) + { + loadinfo->datastart = (uintptr_t)lib_memalign(loadinfo->dataalign, + loadinfo->datasize); + if (!loadinfo->datastart) + { + berr("ERROR: Failed to allocate memory for the module data\n"); + ret = -ENOMEM; + goto errout_with_buffers; + } } } - - if (loadinfo->datasize > 0) + else { - loadinfo->datastart = (uintptr_t)lib_memalign(loadinfo->dataalign, - loadinfo->datasize); - if (!loadinfo->datastart) + loadinfo->textalloc = (uintptr_t)lib_memalign(loadinfo->textalign, + loadinfo->textsize + + loadinfo->datasize + + loadinfo->segpad); + + if (!loadinfo->textalloc) { - berr("ERROR: Failed to allocate memory for the module data\n"); + berr("ERROR: Failed to allocate memory for the module\n"); ret = -ENOMEM; goto errout_with_buffers; } + + loadinfo->datastart = loadinfo->textalloc + + loadinfo->textsize + + loadinfo->segpad; } /* Load ELF section data into memory */ diff --git a/libs/libc/modlib/modlib_unload.c b/libs/libc/modlib/modlib_unload.c index 03c59c6571..cc8810f61e 100644 --- a/libs/libc/modlib/modlib_unload.c +++ b/libs/libc/modlib/modlib_unload.c @@ -58,18 +58,27 @@ int modlib_unload(FAR struct mod_loadinfo_s *loadinfo) /* Release memory holding the relocated ELF image */ - if (loadinfo->textalloc != 0) - { -#if defined(CONFIG_ARCH_USE_TEXT_HEAP) - up_textheap_free((FAR void *)loadinfo->textalloc); -#else - lib_free((FAR void *)loadinfo->textalloc); -#endif - } + /* ET_DYN has a single allocation so we only free textalloc */ - if (loadinfo->datastart != 0) + if (loadinfo->ehdr.e_type != ET_DYN) { - lib_free((FAR void *)loadinfo->datastart); + if (loadinfo->textalloc != 0) + { +#if defined(CONFIG_ARCH_USE_TEXT_HEAP) + up_textheap_free((FAR void *)loadinfo->textalloc); +#else + lib_free((FAR void *)loadinfo->textalloc); +#endif + } + + if (loadinfo->datastart != 0) + { + lib_free((FAR void *)loadinfo->datastart); + } + } + else + { + lib_free((FAR void *)loadinfo->textalloc); } /* Clear out all indications of the allocated address environment */ diff --git a/sched/module/mod_insmod.c b/sched/module/mod_insmod.c index 990c50428e..b8ad7443dc 100644 --- a/sched/module/mod_insmod.c +++ b/sched/module/mod_insmod.c @@ -155,7 +155,9 @@ FAR void *insmod(FAR const char *filename, FAR const char *modname) struct mod_loadinfo_s loadinfo; FAR struct module_s *modp; mod_initializer_t initializer; + FAR void (**array)(void); int ret; + int i; DEBUGASSERT(filename != NULL && modname != NULL); binfo("Loading file: %s\n", filename); @@ -237,11 +239,37 @@ FAR void *insmod(FAR const char *filename, FAR const char *modname) /* Call the module initializer */ - ret = initializer(&modp->modinfo); - if (ret < 0) + switch (loadinfo.ehdr.e_type) { - binfo("Failed to initialize the module: %d\n", ret); - goto errout_with_load; + case ET_REL : + ret = initializer(&modp->modinfo); + if (ret < 0) + { + binfo("Failed to initialize the module: %d\n", ret); + goto errout_with_load; + } + break; + case ET_DYN : + + /* Process any preinit_array entries */ + + array = (FAR void (**)(void))loadinfo.preiarr; + for (i = 0; i < loadinfo.nprei; i++) + { + array[i](); + } + + /* Process any init_array entries */ + + array = (FAR void (**)(void))loadinfo.initarr; + for (i = 0; i < loadinfo.ninit; i++) + { + array[i](); + } + + modp->finiarr = loadinfo.finiarr; + modp->nfini = loadinfo.nfini; + break; } /* Add the new module entry to the registry */ diff --git a/sched/module/mod_rmmod.c b/sched/module/mod_rmmod.c index 2dccf3840e..7760e51d89 100644 --- a/sched/module/mod_rmmod.c +++ b/sched/module/mod_rmmod.c @@ -116,16 +116,27 @@ int rmmod(FAR void *handle) if (modp->textalloc != NULL || modp->dataalloc != NULL) { - /* Free the module memory - * and nullify so that the memory cannot be freed again + /* Free the module memory and nullify so that the memory cannot + * be freed again + * + * NOTE: For dynamic shared objects there is only a single + * allocation: the text/data were allocated in one operation */ + if (!modp->dynamic) + { #if defined(CONFIG_ARCH_USE_TEXT_HEAP) - up_textheap_free(modp->textalloc); + up_textheap_free((FAR void *)modp->textalloc); #else - kmm_free(modp->textalloc); + kmm_free((FAR void *)modp->textalloc); #endif - kmm_free(modp->dataalloc); + kmm_free((FAR void *)modp->dataalloc); + } + else + { + kmm_free((FAR void *)modp->textalloc); + } + modp->textalloc = NULL; modp->dataalloc = NULL; #if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) diff --git a/build-globals.sh b/tools/build-globals.sh similarity index 58% rename from build-globals.sh rename to tools/build-globals.sh index 6337966334..3661a35180 100755 --- a/build-globals.sh +++ b/tools/build-globals.sh @@ -1,65 +1,28 @@ -#!/bin/bash +#!/usr/bin/env bash +############################################################################ +# tools/build-globals.sh +# +# 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. +# +############################################################################ # # Script to create modlib_global.S which contains a structure define # the API names and addresses we will export for resolving symbols in # dynamic loaded shared objects. Typically these are libc APIs. -# -# Find an entrypoint using a binary search -# -findep() -{ - CHECK=$1 - SIZE=${#SYM[@]} - L=0 - R=$((SIZE - 1)) - OLDL=99999999 - OLDR=99999999 - while [ ${L} -le ${R} ] - do - T=$(( L + R )) - M=$(( T / 2 )) - N=$(( T % 2 )) - M=$(( M - N )) - if [ ${SYM[${M}]} \< ${CHECK} ]; then - L=$(( M + 1 )) - elif [ ${SYM[${M}]} = ${CHECK} ]; then - return 1 - else - R=$(( M - 1 )) - fi - if [ ${OLDL} -eq ${L} -a ${OLDR} -eq ${R} ]; then - : return 0 - fi - OLDL=${L} - OLDR=${R} - done - return 0 -} - -# -# Extract entrypoints from a library after applying a filter to -# exclude those we aren't interested in. -# -getEP() -{ - for ((i = 0; i < ${#OBJ[@]}; i++)) - do - if [ -f staging/${OBJ[$i]} ]; then - FUNCS=`${NM} -g --defined-only staging/${OBJ[$i]} 2>/dev/null | grep "^0" | awk '{print $3}' | sort | grep -Ev ${FILTER}` - FUNC=(${FUNCS}) - for ((j = 0; j < ${#FUNC[@]}; j++)) - do - findep ${FUNC[$j]} - if [ $? -eq 1 ]; then - EP[${I_EP}]=${FUNC[$j]} - I_EP=$((I_EP + 1)) - fi - done - fi - done -} - # # Symbols to ignore within the NuttX libraries # @@ -75,20 +38,6 @@ fi SYMS=`cat System.map | awk '{print $3}' | sort | grep -Ev ${FILTER}` SYM=(${SYMS}) GLOBALS="libs/libc/modlib/modlib_globals.S" -I_EP=0 - -# -# Libraries to be searched -# -OBJS="libsched.a libdrivers.a libconfigs.a libstubs.a libkc.a libkmm.a libkarch.a libpass1.a libnet.a libcrypto.a libfs.a libbinfmt.a libxx.a libuc.a libumm.a libuarch.a libapps.a" -OBJ=(${OBJS}) - -# -# Perform the extraction from the libraries -# -getEP -EPS=`printf '%s\n' "${EP[@]}" | sort -u` -EP=(${EPS}) # # Generate the modlib_xxxx_globals.S file @@ -96,7 +45,6 @@ EP=(${EPS}) cat >${GLOBALS} <<__EOF__ #ifdef __CYGWIN__ # define SYMBOL(s) _##s -# define WEAK .weak # define GLOBAL .global # define SECTION .data .macro GLOBAL ep @@ -107,7 +55,6 @@ cat >${GLOBALS} <<__EOF__ .endm #elif defined(__ELF__) # define SYMBOL(s) s -# define WEAK .weak # define SECTION .data .macro GLOBAL ep .global SYMBOL(\ep) @@ -118,7 +65,6 @@ cat >${GLOBALS} <<__EOF__ .endm #else # define SYMBOL(s) _##s -# define WEAK .weak_definition # define SECTION .section __DATA,__data .macro GLOBAL ep .private_extern SYMBOL(\ep) @@ -130,14 +76,12 @@ cat >${GLOBALS} <<__EOF__ #if __SIZEOF_POINTER__ == 8 .macro globalEntry index, ep - WEAK SYMBOL(\ep) .quad .l\index .quad \ep .endm # define ALIGN 8 #else .macro globalEntry index, ep - WEAK SYMBOL(\ep) .long .l\index .long \ep .endm @@ -156,23 +100,23 @@ cat >${GLOBALS} <<__EOF__ #endif .data .align ALIGN - GLOBAL globalNames + GLOBAL globalNames SYMBOL(globalNames): __EOF__ -for ((i = 0; i < ${#EP[@]}; i++)) +for ((i = 0; i < ${#SYM[@]}; i++)) do - echo ".l${i}: .string \"${EP[$i]}\"" >>${GLOBALS} + echo ".l${i}: .string \"${SYM[$i]}\"" >>${GLOBALS} done cat >>${GLOBALS} <<__EOF__ - SIZE globalNames + SIZE globalNames .align ALIGN GLOBAL nglobals -SYMBOL(nglobals): - .word ${#EP[@]} +SYMBOL(nglobals): + .word ${#SYM[@]} SIZE nglobals .align ALIGN @@ -180,13 +124,13 @@ SYMBOL(nglobals): SYMBOL(global_table): __EOF__ -for ((i = 0; i < ${#EP[@]}; i++)) +for ((i = 0; i < ${#SYM[@]}; i++)) do - echo " globalEntry ${i}, ${EP[$i]}" >>${GLOBALS} + echo " globalEntry ${i}, ${SYM[$i]}" >>${GLOBALS} done cat >>${GLOBALS} <<__EOF__ SIZE global_table __EOF__ -echo "${#EP[@]} symbols defined" +echo "${#SYM[@]} symbols defined"