libs/libc/modlib: fix dynamic loader issues

* build-globals.sh
    - Macros for defining symbols etc. based on assembler in use
    - Use the System.map to get all the nuttx symbols

  * libs/libc/modlib/modlib_globals.S
    - Provide an empty skeleton. If the dynamic loading functions
      are required then run build-global.sh after a clean build
      using the skeleton. This will fill out the skeleton with the
      symbols to be available to dynamically loaded modules.

  * libs/libc/modlib/modlib_loadhdrs.c
    - Fix case where there are no program headers are avaiable
This commit is contained in:
Neale Ferguson
2023-07-07 09:15:59 +10:00
committed by David Sidrane
parent a5d1d2d4e5
commit b5cd7c2a82
8 changed files with 185 additions and 4015 deletions
+84 -41
View File
@@ -13,6 +13,8 @@ findEP()
SIZE=${#SYM[@]}
L=0
R=$((SIZE - 1))
OLDL=99999999
OLDR=99999999
while [ ${L} -le ${R} ]
do
T=$(( L + R ))
@@ -26,6 +28,11 @@ findEP()
else
R=$(( M - 1 ))
fi
if [ ${OLDL} -eq ${L} -a ${OLDR} -eq ${R} ]; then
: return 0
fi
OLDL=${L}
OLDR=${R}
done
return 0
}
@@ -38,30 +45,36 @@ getEP()
{
for ((i = 0; i < ${#OBJ[@]}; i++))
do
FUNCS=`${NM} -g --defined-only ../staging/${OBJ[$i]} | 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
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
#
FILTER="^lib_low|^FUNCTION|^STUB|^__start|^_vect|^arm_|^arp_|^bch|^binfmt|^blake|^block_|^cdcacm|^chksum|^clock_|^close_|^crypto_|^devif_|^devnull|^devuran|^devzero|^emerg|^epoll_|^elf_|^_dbgR|^dq_|^env_|^file_|^files_|^fs_|^ftl_|^g_|^get_|^group_|^global|^hcom|^i2c_|^inode_|^iob_|^irq_|^kmm_|^lfs_|^lib_|^local_|^mm_|^modlib_|^mpu_|^mq_|^nGlobals|^net_|^netdev_|^nx|^pipecommon|^posix_spawn_file|^psock_|^ramlog|^rammap|^readline_|^register_|^sched_|^sockfd|^spawn_|^sq_|^stm32|^symtab_|^syslog_|^syslogstream|^task_|^tcp_|^timer_|^uart_|^ub[12]|^udp_|^umm_|^umount|^unload_|^unregister|^up_|^usb|^usrsock_|^watchdog|^wd_"
FILTER="^lib_low|^FUNCTION|^STUB|^__start|^_vect|^arm_|^arp_|^bch|^binfmt|^blake|^block_|^cdcacm|^chksum|^clock_|^close_|^crypto_|^devif_|^devnull|^devuran|^devzero|^emerg|^epoll_|^elf_|^_dbgR|^dq_|^env_|^file_|^files_|^fs_|^ftl_|^g_|^get_|^group_|^global|^hcom|^i2c_|^inode_|^iob_|^irq_|^kmm_|^lfs_|^lib_|^local_|^mm_|^modlib_|^mpu_|^mq_|^nGlobals|^net_|^netdev_|^nx|^pipecommon|^posix_spawn_file|^psock_|^ramlog|^rammap|^readline_|^register_|^sched_|^sockfd|^spawn_|^sq_|^stm32|^symtab_|^syslog_|^syslogstream|^task_|^tcp_|^timer_|^uart_|^ub[12]|^udp_|^umm_|^umount|^unload_|^unregister|^up_|^usb|^usrsock_|^watchdog|^wd_|globalNames$|nGlobals$|globalTable$|^\.l"
if [ -z "${NM}" ]; then
NM="nm"
fi
#
# Extract symbols from the runtime
#
SYMS=`${NM} ../nuttx | awk '{print $3}' | sort | grep -Ev ${FILTER}`
SYMS=`cat System.map | awk '{print $3}' | sort | grep -Ev ${FILTER}`
SYM=(${SYMS})
GLOBALS="../libs/libc/modlib/modlib_globals.S"
GLOBALS="libs/libc/modlib/modlib_globals.S"
I_EP=0
#
@@ -80,70 +93,100 @@ EP=(${EPS})
#
# Generate the modlib_xxxx_globals.S file
#
GLOBALS="libs/libc/modlib/modlib_${arch}_globals.S"
cat >${GLOBALS} <<__EOF__
#ifdef __CYGWIN__
# define SYMBOL(s) _##s
# define WEAK .weak
# define GLOBAL .global
# define SECTION .data
.macro GLOBAL ep
.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"
.endm
.macro SIZE 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)
.globl SYMBOL(\ep)
.endm
.macro SIZE ep
.endm
#endif
#if __SIZEOF_POINTER__ == 8
.macro globalEntry index, ep
.weak \p
.quad .L\index
.quad \ep
WEAK SYMBOL(\ep)
.quad .l\index
.quad \ep
.endm
# define ALIGN 8
#else
.macro globalEntry index, ep
.weak \ep
.long .L\index
.long \ep
WEAK SYMBOL(\ep)
.long .l\index
.long \ep
.endm
# define ALIGN 4
#endif
#ifdef __ARM_ARCH_ISA_THUMB2
# ifdef __ARM_ARCH_7M__
.arch armv7e-m
.arch armv7e-m
# elif defined ___ARM_ARCH 8
.arch armv8-m.base
#endif
#ifdef __ARM_ASM_SYNTAX_UNIFIED__
.syntax unified
.syntax unified
#endif
.thumb
.thumb
#endif
.data
.align ALIGN
.global globalNames
.data
.align ALIGN
GLOBAL globalNames
globalNames:
SYMBOL(globalNames):
__EOF__
for ((i = 0; i < ${#EP[@]}; i++))
do
echo ".L${i}: .string \"${EP[$i]}\"" >>${GLOBALS}
echo ".l${i}: .string \"${EP[$i]}\"" >>${GLOBALS}
done
cat >>${GLOBALS} <<__EOF__
.size globalNames, . - globalNames
SIZE globalNames
.align ${ALIGN}
.global nGlobals
.type nGlobals, "object"
nGlobals:
.align ALIGN
GLOBAL nGlobals
SYMBOL(nGlobals):
.word ${#EP[@]}
.size nGlobals, . - nGlobals
SIZE nGlobals
.align ${ALIGN}
.global globalTable
.type globalTable, "object"
globalTable:
.align ALIGN
GLOBAL globalTable
SYMBOL(globalTable):
__EOF__
for ((i = 0; i < ${#EP[@]}; i++))
do
echo " globalEntry ${i}, ${EP[$i]}" >>${GLOBALS}
echo " globalEntry ${i}, ${EP[$i]}" >>${GLOBALS}
done
cat >>${GLOBALS} <<__EOF__
.size globalTable, . - globalTable
SIZE globalTable
__EOF__
done
echo "${#EP[@]} symbols defined"
+3 -7
View File
@@ -493,14 +493,10 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
}
break;
case R_ARM_RELATIVE :
case R_ARM_JUMP_SLOT :
case R_ARM_RELATIVE:
case R_ARM_JUMP_SLOT:
{
binfo("Relocating: RELATIVE/JUMP_SLOT at %p value: %08lx"
"with %08lx\n",
(void *)addr, *(unsigned long *)addr,
(unsigned long)sym->st_value);
*(uint32_t *) addr = (uint32_t) sym->st_value;
*(uint32_t *)addr = (uint32_t)sym->st_value;
}
break;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+35 -36
View File
@@ -70,14 +70,6 @@ int modlib_loadhdrs(FAR struct mod_loadinfo_s *loadinfo)
return -EINVAL;
}
/* Verify that there are program headers */
if (loadinfo->ehdr.e_phnum < 1)
{
berr("ERROR: No program headers(?)\n");
return -EINVAL;
}
/* Get the total size of the section header table */
shdrsize = (size_t)loadinfo->ehdr.e_shentsize *
@@ -88,19 +80,9 @@ int modlib_loadhdrs(FAR struct mod_loadinfo_s *loadinfo)
return -ESPIPE;
}
/* 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("ERROR: Insufficent space in file for program header table\n");
return -ESPIPE;
}
/* Allocate memory to hold a working copy of the sector header table */
loadinfo->shdr = (FAR FAR Elf_Shdr *)lib_malloc(shdrsize);
loadinfo->shdr = (FAR Elf_Shdr *)lib_malloc(shdrsize);
if (!loadinfo->shdr)
{
berr("ERROR: Failed to allocate the section header table. Size: %ld\n",
@@ -117,26 +99,43 @@ int modlib_loadhdrs(FAR struct mod_loadinfo_s *loadinfo)
berr("ERROR: Failed to read section header table: %d\n", ret);
}
/* Allocate memory to hold a working copy of the program header table */
loadinfo->phdr = (FAR FAR Elf_Phdr *)lib_malloc(phdrsize);
if (!loadinfo->shdr)
if (loadinfo->ehdr.e_phnum > 0)
{
lib_free((FAR void *)loadinfo->shdr);
berr("ERROR: Failed to allocate the program header table. Size: %ld\n",
(long)phdrsize);
return -ENOMEM;
/* 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("ERROR: Insufficent space for program header table\n");
return -ESPIPE;
}
/* Allocate memory to hold a working copy of the program header table */
loadinfo->phdr = (FAR Elf_Phdr *)lib_malloc(phdrsize);
if (!loadinfo->phdr)
{
lib_free((FAR void *)loadinfo->shdr);
berr("ERROR: Failed to allocate the program header table."
"Size: %ld\n", (long)phdrsize);
return -ENOMEM;
}
/* Read the program header table into memory */
ret = modlib_read(loadinfo, (FAR uint8_t *)loadinfo->phdr, phdrsize,
loadinfo->ehdr.e_phoff);
if (ret < 0)
{
berr("ERROR: Failed to read program header table: %d\n", ret);
lib_free((FAR void *)loadinfo->phdr);
lib_free((FAR void *)loadinfo->shdr);
}
}
/* Read the program header table into memory */
ret = modlib_read(loadinfo, (FAR uint8_t *)loadinfo->phdr, phdrsize,
loadinfo->ehdr.e_phoff);
if (ret < 0)
else
{
berr("ERROR: Failed to read program header table: %d\n", ret);
lib_free((FAR void *)loadinfo->phdr);
lib_free((FAR void *)loadinfo->shdr);
loadinfo->phdr = NULL;
}
return ret;
+5 -5
View File
@@ -80,11 +80,11 @@ int modlib_verifyheader(FAR const Elf_Ehdr *ehdr)
if (ehdr->e_type != ET_REL)
{
if (ehdr->e_type != ET_DYN)
{
berr("ERROR: Not a relocatable file: e_type=%d\n", ehdr->e_type);
return -EINVAL;
}
if (ehdr->e_type != ET_DYN)
{
berr("ERROR: Not a relocatable file: e_type=%d\n", ehdr->e_type);
return -EINVAL;
}
}
/* Verify that this file works with the currently configured architecture */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff