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
This commit is contained in:
Neale Ferguson 2023-09-04 10:37:48 +10:00 committed by Alan Carvalho de Assis
parent f47991e34d
commit 5d7f2fdf16
12 changed files with 248 additions and 176 deletions

View File

@ -230,6 +230,7 @@ CMODULEFLAGS += -fno-stack-protector
LDMODULEFLAGS = -r -e module_initialize --gc-sections LDMODULEFLAGS = -r -e module_initialize --gc-sections
LDMODULEFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/modlib/gnu-elf.ld) LDMODULEFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/modlib/gnu-elf.ld)
SHMODULEFLAGS = -Bsymbolic -G -Bdynamic
# NuttX modules are ELF binaries. # NuttX modules are ELF binaries.
# Non-ELF platforms like macOS need to use a separate ELF toolchain. # Non-ELF platforms like macOS need to use a separate ELF toolchain.
@ -270,5 +271,6 @@ ifeq ($(CONFIG_SIM_M32),y)
LDLINKFLAGS += -melf_i386 LDLINKFLAGS += -melf_i386
LDFLAGS += -m32 LDFLAGS += -m32
LDMODULEFLAGS += -melf_i386 LDMODULEFLAGS += -melf_i386
SHMODULEFLAGS += -melf_i386
LDELFFLAGS += -melf_i386 LDELFFLAGS += -melf_i386
endif endif

View File

@ -142,9 +142,9 @@ typedef struct
Elf64_Off p_offset; /* Offset in file */ Elf64_Off p_offset; /* Offset in file */
Elf64_Addr p_vaddr; /* Virtual address in memory */ Elf64_Addr p_vaddr; /* Virtual address in memory */
Elf64_Addr p_paddr; /* Reserved */ Elf64_Addr p_paddr; /* Reserved */
Elf64_Word p_filesz; /* Size of segment in file */ Elf64_Xword p_filesz; /* Size of segment in file */
Elf64_Word p_memsz; /* Size of segment in memory */ Elf64_Xword p_memsz; /* Size of segment in memory */
Elf64_Word p_align; /* Alignment of segment */ Elf64_Xword p_align; /* Alignment of segment */
} Elf64_Phdr; } Elf64_Phdr;
/* Figure 7. Format of a Note Section */ /* Figure 7. Format of a Note Section */

View File

@ -159,6 +159,7 @@ struct module_s
struct mod_info_s modinfo; /* Module information */ struct mod_info_s modinfo; /* Module information */
FAR void *textalloc; /* Allocated kernel text memory */ FAR void *textalloc; /* Allocated kernel text memory */
FAR void *dataalloc; /* Allocated kernel 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) #if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE)
size_t textsize; /* Size of the kernel .text memory allocation */ size_t textsize; /* Size of the kernel .text memory allocation */
size_t datasize; /* Size of the kernel .bss/.data memory allocation */ size_t datasize; /* Size of the kernel .bss/.data memory allocation */

View File

@ -125,21 +125,21 @@ static inline int dlremove(FAR void *handle)
/* Release resources held by the module */ /* Release resources held by the module */
/* 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)
{
if (modp->textalloc != NULL) if (modp->textalloc != NULL)
{ {
/* Free the module memory */ /* Free the module memory */
#if defined(CONFIG_ARCH_USE_TEXT_HEAP) #if defined(CONFIG_ARCH_USE_TEXT_HEAP)
up_textheap_free(modp->textalloc); up_textheap_free((FAR void *)modp->textalloc);
#else #else
lib_free(modp->textalloc); lib_free((FAR void *)modp->textalloc);
#endif
/* Nullify so that the memory cannot be freed again */
modp->textalloc = NULL;
#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE)
modp->textsize = 0;
#endif #endif
} }
@ -147,15 +147,22 @@ static inline int dlremove(FAR void *handle)
{ {
/* Free the module memory */ /* Free the module memory */
lib_free(modp->dataalloc); lib_free((FAR void *)modp->dataalloc);
}
}
else
{
lib_free((FAR void *)modp->textalloc);
}
/* Nullify so that the memory cannot be freed again */ /* Nullify so that the memory cannot be freed again */
modp->textalloc = NULL;
modp->dataalloc = NULL; modp->dataalloc = NULL;
#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) #if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE)
modp->textsize = 0;
modp->datasize = 0; modp->datasize = 0;
#endif #endif
}
/* Free the modules exported symmbols table */ /* Free the modules exported symmbols table */

View File

@ -232,6 +232,7 @@ static inline FAR void *dlinsert(FAR const char *filename)
modp->textalloc = (FAR void *)loadinfo.textalloc; modp->textalloc = (FAR void *)loadinfo.textalloc;
modp->dataalloc = (FAR void *)loadinfo.datastart; 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) #if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE)
modp->textsize = loadinfo.textsize; modp->textsize = loadinfo.textsize;
modp->datasize = loadinfo.datasize; modp->datasize = loadinfo.datasize;

View File

@ -64,9 +64,10 @@ struct
int stroff; /* offset to string table */ int stroff; /* offset to string table */
int symoff; /* offset to symbol table */ int symoff; /* offset to symbol table */
int lsymtab; /* size of 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 reloff[2]; /* offset to the relocation section */
int relsz[2]; /* size of relocation table */ int relsz[2]; /* size of relocation table */
int relrela[2]; /* type of relocation type - 0: DT_REL / 1: DT_RELA */
} reldata; } reldata;
/**************************************************************************** /****************************************************************************
@ -558,6 +559,8 @@ static int modlib_relocatedyn(FAR struct module_s *modp,
FAR Elf_Dyn *dyn = NULL; FAR Elf_Dyn *dyn = NULL;
FAR Elf_Rel *rels = NULL; FAR Elf_Rel *rels = NULL;
FAR Elf_Rel *rel; FAR Elf_Rel *rel;
FAR Elf_Rela *relas = NULL;
FAR Elf_Rela *rela;
FAR Elf_Sym *sym = NULL; FAR Elf_Sym *sym = NULL;
uintptr_t addr; uintptr_t addr;
int ret; int ret;
@ -574,7 +577,9 @@ static int modlib_relocatedyn(FAR struct module_s *modp,
return ret; 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) if (!rels)
{ {
berr("Failed to allocate memory for elf relocation rels\n"); 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)); memset((void *)&reldata, 0, sizeof(reldata));
relas = (FAR Elf_Rela *)rels;
for (i = 0; dyn[i].d_tag != DT_NULL; i++) 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; reldata.relsz[I_REL] = dyn[i].d_un.d_val;
break; break;
case DT_RELENT: case DT_RELENT:
reldata.relentsz = dyn[i].d_un.d_val; reldata.relentsz[I_REL] = dyn[i].d_un.d_val;
break; break;
case DT_SYMTAB: case DT_SYMTAB:
reldata.symoff = dyn[i].d_un.d_val; reldata.symoff = dyn[i].d_un.d_val;
@ -609,6 +615,18 @@ static int modlib_relocatedyn(FAR struct module_s *modp,
case DT_PLTRELSZ: case DT_PLTRELSZ:
reldata.relsz[I_PLT] = dyn[i].d_un.d_val; reldata.relsz[I_PLT] = dyn[i].d_un.d_val;
break; 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++) 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; continue;
} }
@ -645,16 +665,30 @@ static int modlib_relocatedyn(FAR struct module_s *modp,
/* Examine each relocation in the .rel.* section. */ /* Examine each relocation in the .rel.* section. */
ret = OK; 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
*/
if (reldata.relrela[idx_rel] == 0)
{
rel = &rels[i % CONFIG_MODLIB_RELOCATION_BUFFERCOUNT]; 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)) if (!(i % CONFIG_MODLIB_RELOCATION_BUFFERCOUNT))
{ {
size_t relsize = (sizeof(Elf_Rel) * size_t relsize = (sizeof(Elf_Rela) *
CONFIG_MODLIB_RELOCATION_BUFFERCOUNT); CONFIG_MODLIB_RELOCATION_BUFFERCOUNT);
if (reldata.relsz[idx_rel] < relsize) 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; addr = rel->r_offset + loadinfo->textalloc;
if (reldata.relrela[idx_rel] == 1)
{
addr += rela->r_addend;
}
*(FAR uintptr_t *)addr = (uintptr_t)ep; *(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; 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) if ((*(FAR uint32_t *)addr) < loadinfo->datasec)
{ {
dynsym.st_value = *(FAR uint32_t *)addr + 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 /* Iterate through the dynamic symbol table looking for global symbols
* put in our own symbol table for use with dlgetsym() * to put in our own symbol table for use with dlgetsym()
*/ */
/* Relocate the entries in the table */ /* 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) if (loadinfo->ehdr.e_type == ET_DYN)
{ {
modp->dynamic = 1;
switch (loadinfo->shdr[i].sh_type) switch (loadinfo->shdr[i].sh_type)
{ {
case SHT_DYNAMIC: case SHT_DYNAMIC:
@ -864,8 +910,10 @@ int modlib_bind(FAR struct module_s *modp,
} }
else else
{ {
/* Make sure that the section is allocated. We can't relocate modp->dynamic = 0;
* sections that were not loaded into memory.
/* 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) if ((loadinfo->shdr[infosec].sh_flags & SHF_ALLOC) == 0)

View File

@ -1,6 +1,5 @@
#ifdef __CYGWIN__ #ifdef __CYGWIN__
# define SYMBOL(s) s # define SYMBOL(s) _##s
# define WEAK .weak
# define GLOBAL .global # define GLOBAL .global
# define SECTION .data # define SECTION .data
.macro GLOBAL ep .macro GLOBAL ep
@ -11,7 +10,6 @@
.endm .endm
#elif defined(__ELF__) #elif defined(__ELF__)
# define SYMBOL(s) s # define SYMBOL(s) s
# define WEAK .weak
# define SECTION .data # define SECTION .data
.macro GLOBAL ep .macro GLOBAL ep
.global SYMBOL(\ep) .global SYMBOL(\ep)
@ -22,7 +20,6 @@
.endm .endm
#else #else
# define SYMBOL(s) _##s # define SYMBOL(s) _##s
# define WEAK .weak_definition
# define SECTION .section __DATA,__data # define SECTION .section __DATA,__data
.macro GLOBAL ep .macro GLOBAL ep
.private_extern SYMBOL(\ep) .private_extern SYMBOL(\ep)
@ -34,14 +31,12 @@
#if __SIZEOF_POINTER__ == 8 #if __SIZEOF_POINTER__ == 8
.macro globalEntry index, ep .macro globalEntry index, ep
WEAK SYMBOL(\ep)
.quad .l\index .quad .l\index
.quad \ep .quad \ep
.endm .endm
# define ALIGN 8 # define ALIGN 8
#else #else
.macro globalEntry index, ep .macro globalEntry index, ep
WEAK SYMBOL(\ep)
.long .l\index .long .l\index
.long \ep .long \ep
.endm .endm

View File

@ -309,6 +309,13 @@ int modlib_load(FAR struct mod_loadinfo_s *loadinfo)
/* Allocate memory to hold the ELF image */ /* Allocate memory to hold the ELF image */
/* 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 (loadinfo->textsize > 0) if (loadinfo->textsize > 0)
{ {
#if defined(CONFIG_ARCH_USE_TEXT_HEAP) #if defined(CONFIG_ARCH_USE_TEXT_HEAP)
@ -340,6 +347,25 @@ int modlib_load(FAR struct mod_loadinfo_s *loadinfo)
goto errout_with_buffers; goto errout_with_buffers;
} }
} }
}
else
{
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\n");
ret = -ENOMEM;
goto errout_with_buffers;
}
loadinfo->datastart = loadinfo->textalloc +
loadinfo->textsize +
loadinfo->segpad;
}
/* Load ELF section data into memory */ /* Load ELF section data into memory */

View File

@ -58,6 +58,10 @@ int modlib_unload(FAR struct mod_loadinfo_s *loadinfo)
/* Release memory holding the relocated ELF image */ /* Release memory holding the relocated ELF image */
/* ET_DYN has a single allocation so we only free textalloc */
if (loadinfo->ehdr.e_type != ET_DYN)
{
if (loadinfo->textalloc != 0) if (loadinfo->textalloc != 0)
{ {
#if defined(CONFIG_ARCH_USE_TEXT_HEAP) #if defined(CONFIG_ARCH_USE_TEXT_HEAP)
@ -71,6 +75,11 @@ int modlib_unload(FAR struct mod_loadinfo_s *loadinfo)
{ {
lib_free((FAR void *)loadinfo->datastart); lib_free((FAR void *)loadinfo->datastart);
} }
}
else
{
lib_free((FAR void *)loadinfo->textalloc);
}
/* Clear out all indications of the allocated address environment */ /* Clear out all indications of the allocated address environment */

View File

@ -155,7 +155,9 @@ FAR void *insmod(FAR const char *filename, FAR const char *modname)
struct mod_loadinfo_s loadinfo; struct mod_loadinfo_s loadinfo;
FAR struct module_s *modp; FAR struct module_s *modp;
mod_initializer_t initializer; mod_initializer_t initializer;
FAR void (**array)(void);
int ret; int ret;
int i;
DEBUGASSERT(filename != NULL && modname != NULL); DEBUGASSERT(filename != NULL && modname != NULL);
binfo("Loading file: %s\n", filename); binfo("Loading file: %s\n", filename);
@ -237,12 +239,38 @@ FAR void *insmod(FAR const char *filename, FAR const char *modname)
/* Call the module initializer */ /* Call the module initializer */
switch (loadinfo.ehdr.e_type)
{
case ET_REL :
ret = initializer(&modp->modinfo); ret = initializer(&modp->modinfo);
if (ret < 0) if (ret < 0)
{ {
binfo("Failed to initialize the module: %d\n", ret); binfo("Failed to initialize the module: %d\n", ret);
goto errout_with_load; 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 */ /* Add the new module entry to the registry */

View File

@ -116,16 +116,27 @@ int rmmod(FAR void *handle)
if (modp->textalloc != NULL || modp->dataalloc != NULL) if (modp->textalloc != NULL || modp->dataalloc != NULL)
{ {
/* Free the module memory /* Free the module memory and nullify so that the memory cannot
* and nullify so that the memory cannot be freed again * 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) #if defined(CONFIG_ARCH_USE_TEXT_HEAP)
up_textheap_free(modp->textalloc); up_textheap_free((FAR void *)modp->textalloc);
#else #else
kmm_free(modp->textalloc); kmm_free((FAR void *)modp->textalloc);
#endif #endif
kmm_free(modp->dataalloc); kmm_free((FAR void *)modp->dataalloc);
}
else
{
kmm_free((FAR void *)modp->textalloc);
}
modp->textalloc = NULL; modp->textalloc = NULL;
modp->dataalloc = NULL; modp->dataalloc = NULL;
#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) #if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE)

View File

@ -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 # Script to create modlib_global.S which contains a structure define
# the API names and addresses we will export for resolving symbols in # the API names and addresses we will export for resolving symbols in
# dynamic loaded shared objects. Typically these are libc APIs. # 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 # Symbols to ignore within the NuttX libraries
# #
@ -75,20 +38,6 @@ fi
SYMS=`cat System.map | awk '{print $3}' | sort | grep -Ev ${FILTER}` SYMS=`cat System.map | awk '{print $3}' | sort | grep -Ev ${FILTER}`
SYM=(${SYMS}) SYM=(${SYMS})
GLOBALS="libs/libc/modlib/modlib_globals.S" 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 # Generate the modlib_xxxx_globals.S file
@ -96,7 +45,6 @@ EP=(${EPS})
cat >${GLOBALS} <<__EOF__ cat >${GLOBALS} <<__EOF__
#ifdef __CYGWIN__ #ifdef __CYGWIN__
# define SYMBOL(s) _##s # define SYMBOL(s) _##s
# define WEAK .weak
# define GLOBAL .global # define GLOBAL .global
# define SECTION .data # define SECTION .data
.macro GLOBAL ep .macro GLOBAL ep
@ -107,7 +55,6 @@ cat >${GLOBALS} <<__EOF__
.endm .endm
#elif defined(__ELF__) #elif defined(__ELF__)
# define SYMBOL(s) s # define SYMBOL(s) s
# define WEAK .weak
# define SECTION .data # define SECTION .data
.macro GLOBAL ep .macro GLOBAL ep
.global SYMBOL(\ep) .global SYMBOL(\ep)
@ -118,7 +65,6 @@ cat >${GLOBALS} <<__EOF__
.endm .endm
#else #else
# define SYMBOL(s) _##s # define SYMBOL(s) _##s
# define WEAK .weak_definition
# define SECTION .section __DATA,__data # define SECTION .section __DATA,__data
.macro GLOBAL ep .macro GLOBAL ep
.private_extern SYMBOL(\ep) .private_extern SYMBOL(\ep)
@ -130,14 +76,12 @@ cat >${GLOBALS} <<__EOF__
#if __SIZEOF_POINTER__ == 8 #if __SIZEOF_POINTER__ == 8
.macro globalEntry index, ep .macro globalEntry index, ep
WEAK SYMBOL(\ep)
.quad .l\index .quad .l\index
.quad \ep .quad \ep
.endm .endm
# define ALIGN 8 # define ALIGN 8
#else #else
.macro globalEntry index, ep .macro globalEntry index, ep
WEAK SYMBOL(\ep)
.long .l\index .long .l\index
.long \ep .long \ep
.endm .endm
@ -161,9 +105,9 @@ cat >${GLOBALS} <<__EOF__
SYMBOL(globalNames): SYMBOL(globalNames):
__EOF__ __EOF__
for ((i = 0; i < ${#EP[@]}; i++)) for ((i = 0; i < ${#SYM[@]}; i++))
do do
echo ".l${i}: .string \"${EP[$i]}\"" >>${GLOBALS} echo ".l${i}: .string \"${SYM[$i]}\"" >>${GLOBALS}
done done
cat >>${GLOBALS} <<__EOF__ cat >>${GLOBALS} <<__EOF__
@ -172,7 +116,7 @@ cat >>${GLOBALS} <<__EOF__
.align ALIGN .align ALIGN
GLOBAL nglobals GLOBAL nglobals
SYMBOL(nglobals): SYMBOL(nglobals):
.word ${#EP[@]} .word ${#SYM[@]}
SIZE nglobals SIZE nglobals
.align ALIGN .align ALIGN
@ -180,13 +124,13 @@ SYMBOL(nglobals):
SYMBOL(global_table): SYMBOL(global_table):
__EOF__ __EOF__
for ((i = 0; i < ${#EP[@]}; i++)) for ((i = 0; i < ${#SYM[@]}; i++))
do do
echo " globalEntry ${i}, ${EP[$i]}" >>${GLOBALS} echo " globalEntry ${i}, ${SYM[$i]}" >>${GLOBALS}
done done
cat >>${GLOBALS} <<__EOF__ cat >>${GLOBALS} <<__EOF__
SIZE global_table SIZE global_table
__EOF__ __EOF__
echo "${#EP[@]} symbols defined" echo "${#SYM[@]} symbols defined"