mirror of
https://github.com/apache/nuttx.git
synced 2026-06-02 09:38:37 +08:00
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:
committed by
David Sidrane
parent
a5d1d2d4e5
commit
b5cd7c2a82
+84
-41
@@ -13,6 +13,8 @@ findEP()
|
|||||||
SIZE=${#SYM[@]}
|
SIZE=${#SYM[@]}
|
||||||
L=0
|
L=0
|
||||||
R=$((SIZE - 1))
|
R=$((SIZE - 1))
|
||||||
|
OLDL=99999999
|
||||||
|
OLDR=99999999
|
||||||
while [ ${L} -le ${R} ]
|
while [ ${L} -le ${R} ]
|
||||||
do
|
do
|
||||||
T=$(( L + R ))
|
T=$(( L + R ))
|
||||||
@@ -26,6 +28,11 @@ findEP()
|
|||||||
else
|
else
|
||||||
R=$(( M - 1 ))
|
R=$(( M - 1 ))
|
||||||
fi
|
fi
|
||||||
|
if [ ${OLDL} -eq ${L} -a ${OLDR} -eq ${R} ]; then
|
||||||
|
: return 0
|
||||||
|
fi
|
||||||
|
OLDL=${L}
|
||||||
|
OLDR=${R}
|
||||||
done
|
done
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@@ -38,30 +45,36 @@ getEP()
|
|||||||
{
|
{
|
||||||
for ((i = 0; i < ${#OBJ[@]}; i++))
|
for ((i = 0; i < ${#OBJ[@]}; i++))
|
||||||
do
|
do
|
||||||
FUNCS=`${NM} -g --defined-only ../staging/${OBJ[$i]} | awk '{print $3}' | sort | grep -Ev ${FILTER}`
|
if [ -f staging/${OBJ[$i]} ]; then
|
||||||
FUNC=(${FUNCS})
|
FUNCS=`${NM} -g --defined-only staging/${OBJ[$i]} 2>/dev/null | grep "^0" | awk '{print $3}' | sort | grep -Ev ${FILTER}`
|
||||||
for ((j = 0; j < ${#FUNC[@]}; j++))
|
FUNC=(${FUNCS})
|
||||||
do
|
for ((j = 0; j < ${#FUNC[@]}; j++))
|
||||||
findEP ${FUNC[$j]}
|
do
|
||||||
if [ $? -eq 1 ]; then
|
findEP ${FUNC[$j]}
|
||||||
EP[${I_EP}]=${FUNC[$j]}
|
if [ $? -eq 1 ]; then
|
||||||
I_EP=$((I_EP + 1))
|
EP[${I_EP}]=${FUNC[$j]}
|
||||||
fi
|
I_EP=$((I_EP + 1))
|
||||||
done
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
# Symbols to ignore within the NuttX libraries
|
# 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
|
# 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})
|
SYM=(${SYMS})
|
||||||
GLOBALS="../libs/libc/modlib/modlib_globals.S"
|
GLOBALS="libs/libc/modlib/modlib_globals.S"
|
||||||
I_EP=0
|
I_EP=0
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -80,70 +93,100 @@ EP=(${EPS})
|
|||||||
#
|
#
|
||||||
# Generate the modlib_xxxx_globals.S file
|
# Generate the modlib_xxxx_globals.S file
|
||||||
#
|
#
|
||||||
GLOBALS="libs/libc/modlib/modlib_${arch}_globals.S"
|
|
||||||
cat >${GLOBALS} <<__EOF__
|
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
|
#if __SIZEOF_POINTER__ == 8
|
||||||
.macro globalEntry index, ep
|
.macro globalEntry index, ep
|
||||||
.weak \p
|
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 \ep
|
WEAK SYMBOL(\ep)
|
||||||
.long .L\index
|
.long .l\index
|
||||||
.long \ep
|
.long \ep
|
||||||
.endm
|
.endm
|
||||||
# define ALIGN 4
|
# define ALIGN 4
|
||||||
#endif
|
#endif
|
||||||
#ifdef __ARM_ARCH_ISA_THUMB2
|
#ifdef __ARM_ARCH_ISA_THUMB2
|
||||||
# ifdef __ARM_ARCH_7M__
|
# ifdef __ARM_ARCH_7M__
|
||||||
.arch armv7e-m
|
.arch armv7e-m
|
||||||
# elif defined ___ARM_ARCH 8
|
# elif defined ___ARM_ARCH 8
|
||||||
.arch armv8-m.base
|
.arch armv8-m.base
|
||||||
#endif
|
#endif
|
||||||
#ifdef __ARM_ASM_SYNTAX_UNIFIED__
|
#ifdef __ARM_ASM_SYNTAX_UNIFIED__
|
||||||
.syntax unified
|
.syntax unified
|
||||||
#endif
|
#endif
|
||||||
.thumb
|
.thumb
|
||||||
#endif
|
#endif
|
||||||
.data
|
.data
|
||||||
.align ALIGN
|
.align ALIGN
|
||||||
.global globalNames
|
GLOBAL globalNames
|
||||||
|
|
||||||
globalNames:
|
SYMBOL(globalNames):
|
||||||
__EOF__
|
__EOF__
|
||||||
|
|
||||||
for ((i = 0; i < ${#EP[@]}; i++))
|
for ((i = 0; i < ${#EP[@]}; i++))
|
||||||
do
|
do
|
||||||
echo ".L${i}: .string \"${EP[$i]}\"" >>${GLOBALS}
|
echo ".l${i}: .string \"${EP[$i]}\"" >>${GLOBALS}
|
||||||
done
|
done
|
||||||
|
|
||||||
cat >>${GLOBALS} <<__EOF__
|
cat >>${GLOBALS} <<__EOF__
|
||||||
.size globalNames, . - globalNames
|
SIZE globalNames
|
||||||
|
|
||||||
.align ${ALIGN}
|
.align ALIGN
|
||||||
.global nGlobals
|
GLOBAL nGlobals
|
||||||
.type nGlobals, "object"
|
SYMBOL(nGlobals):
|
||||||
nGlobals:
|
|
||||||
.word ${#EP[@]}
|
.word ${#EP[@]}
|
||||||
.size nGlobals, . - nGlobals
|
SIZE nGlobals
|
||||||
|
|
||||||
.align ${ALIGN}
|
.align ALIGN
|
||||||
.global globalTable
|
GLOBAL globalTable
|
||||||
.type globalTable, "object"
|
SYMBOL(globalTable):
|
||||||
globalTable:
|
|
||||||
__EOF__
|
__EOF__
|
||||||
|
|
||||||
for ((i = 0; i < ${#EP[@]}; i++))
|
for ((i = 0; i < ${#EP[@]}; i++))
|
||||||
do
|
do
|
||||||
echo " globalEntry ${i}, ${EP[$i]}" >>${GLOBALS}
|
echo " globalEntry ${i}, ${EP[$i]}" >>${GLOBALS}
|
||||||
done
|
done
|
||||||
|
|
||||||
cat >>${GLOBALS} <<__EOF__
|
cat >>${GLOBALS} <<__EOF__
|
||||||
.size globalTable, . - globalTable
|
SIZE globalTable
|
||||||
__EOF__
|
__EOF__
|
||||||
|
|
||||||
done
|
|
||||||
echo "${#EP[@]} symbols defined"
|
echo "${#EP[@]} symbols defined"
|
||||||
|
|||||||
@@ -493,14 +493,10 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case R_ARM_RELATIVE :
|
case R_ARM_RELATIVE:
|
||||||
case R_ARM_JUMP_SLOT :
|
case R_ARM_JUMP_SLOT:
|
||||||
{
|
{
|
||||||
binfo("Relocating: RELATIVE/JUMP_SLOT at %p value: %08lx"
|
*(uint32_t *)addr = (uint32_t)sym->st_value;
|
||||||
"with %08lx\n",
|
|
||||||
(void *)addr, *(unsigned long *)addr,
|
|
||||||
(unsigned long)sym->st_value);
|
|
||||||
*(uint32_t *) addr = (uint32_t) sym->st_value;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
+58
-1126
File diff suppressed because it is too large
Load Diff
@@ -70,14 +70,6 @@ int modlib_loadhdrs(FAR struct mod_loadinfo_s *loadinfo)
|
|||||||
return -EINVAL;
|
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 */
|
/* Get the total size of the section header table */
|
||||||
|
|
||||||
shdrsize = (size_t)loadinfo->ehdr.e_shentsize *
|
shdrsize = (size_t)loadinfo->ehdr.e_shentsize *
|
||||||
@@ -88,19 +80,9 @@ int modlib_loadhdrs(FAR struct mod_loadinfo_s *loadinfo)
|
|||||||
return -ESPIPE;
|
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 */
|
/* 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)
|
if (!loadinfo->shdr)
|
||||||
{
|
{
|
||||||
berr("ERROR: Failed to allocate the section header table. Size: %ld\n",
|
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);
|
berr("ERROR: Failed to read section header table: %d\n", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate memory to hold a working copy of the program header table */
|
if (loadinfo->ehdr.e_phnum > 0)
|
||||||
|
|
||||||
loadinfo->phdr = (FAR FAR Elf_Phdr *)lib_malloc(phdrsize);
|
|
||||||
if (!loadinfo->shdr)
|
|
||||||
{
|
{
|
||||||
lib_free((FAR void *)loadinfo->shdr);
|
/* Get the total size of the program header table */
|
||||||
berr("ERROR: Failed to allocate the program header table. Size: %ld\n",
|
|
||||||
(long)phdrsize);
|
phdrsize = (size_t)loadinfo->ehdr.e_phentsize *
|
||||||
return -ENOMEM;
|
(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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* 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);
|
loadinfo->phdr = NULL;
|
||||||
lib_free((FAR void *)loadinfo->phdr);
|
|
||||||
lib_free((FAR void *)loadinfo->shdr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -80,11 +80,11 @@ int modlib_verifyheader(FAR const Elf_Ehdr *ehdr)
|
|||||||
|
|
||||||
if (ehdr->e_type != ET_REL)
|
if (ehdr->e_type != ET_REL)
|
||||||
{
|
{
|
||||||
if (ehdr->e_type != ET_DYN)
|
if (ehdr->e_type != ET_DYN)
|
||||||
{
|
{
|
||||||
berr("ERROR: Not a relocatable file: e_type=%d\n", ehdr->e_type);
|
berr("ERROR: Not a relocatable file: e_type=%d\n", ehdr->e_type);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Verify that this file works with the currently configured architecture */
|
/* 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
Reference in New Issue
Block a user