This is an automated email from the ASF dual-hosted git repository. ligd pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git
commit 63e26504879e2b5abee7f210806a39375ed22331 Author: anjiahao <[email protected]> AuthorDate: Tue Nov 25 20:32:40 2025 +0800 elf:avoid interference between different ELFs generated by symtab if defined CONFIG_EXAMPLES_ELF and CONFIG_EXAMPLES_MODLUE, elf will generated BINDIR, so generated symtab will interference. It supports inputting multiple specified files in mksymtab.sh to avoid interference. Signed-off-by: anjiahao <[email protected]> --- examples/elf/main/Makefile | 28 ++++++++++++- examples/module/main/Makefile | 5 +-- tools/mksymtab.sh | 97 ++++++++++++++++++++++++++++++++----------- 3 files changed, 101 insertions(+), 29 deletions(-) diff --git a/examples/elf/main/Makefile b/examples/elf/main/Makefile index 074ea6a3d..76093ea5f 100644 --- a/examples/elf/main/Makefile +++ b/examples/elf/main/Makefile @@ -30,8 +30,34 @@ MAINSRC = elf_main.c SYMTABSRC = test_symtab.c SYMTABOBJ = $(SYMTABSRC:.c=$(OBJEXT)) +ELFNAME_BASE = errno hello +ifneq ($(CONFIG_DISABLE_SIGNALS),y) + ELFNAME_BASE += signal +endif + +ifeq ($(CONFIG_HAVE_CXX),y) + ELFNAME_BASE += hello++1 hello++2 + ifeq ($(CONFIG_HAVE_CXXINITIALIZE),y) + ELFNAME_BASE += hello++3 + endif + ifeq ($(CONFIG_EXAMPLES_ELF_CXX),y) + ELFNAME_BASE += hello++4 hello++5 + endif +endif +ifeq ($(CONFIG_EXAMPLES_ELF_LONGJMP),y) + ELFNAME_BASE += longjmp +endif +ifneq ($(CONFIG_DISABLE_PTHREAD),y) + ELFNAME_BASE += pthread mutex +endif +ifneq ($(CONFIG_ARCH_ADDRENV),y) + ELFNAME_BASE += task +endif + +ELFNAME = $(addprefix $(BINDIR)$(DELIM),$(ELFNAME_BASE)) + $(SYMTABSRC): - $(Q) $(APPDIR)$(DELIM)tools$(DELIM)mksymtab.sh $(BINDIR) g_elf >[email protected] + $(Q) $(APPDIR)$(DELIM)tools$(DELIM)mksymtab.sh $(ELFNAME) g_elf >[email protected] $(Q) $(call TESTANDREPLACEFILE, [email protected], $@) diff --git a/examples/module/main/Makefile b/examples/module/main/Makefile index f5294b257..466af6dbf 100644 --- a/examples/module/main/Makefile +++ b/examples/module/main/Makefile @@ -34,14 +34,13 @@ MAINSRC = module_main.c SYMTABSRC = mod_symtab.c SYMTABOBJ = $(SYMTABSRC:.c=$(OBJEXT)) - +MODLUE_NAME = chardev ifneq ($(CONFIG_BUILD_FLAT),y) PASS1_SYMTAB = $(TOPDIR)/pass1/mod_symtab.c - MODLUE_NAME = chardev endif $(SYMTABSRC): - $(Q) $(APPDIR)$(DELIM)tools$(DELIM)mksymtab.sh $(BINDIR) g_mod >[email protected] + $(Q) $(APPDIR)$(DELIM)tools$(DELIM)mksymtab.sh $(BINDIR)$(DELIM)$(MODLUE_NAME) g_mod >[email protected] $(Q) $(call TESTANDREPLACEFILE, [email protected], $@) diff --git a/tools/mksymtab.sh b/tools/mksymtab.sh index 1f9d7ed8c..cdb141b03 100755 --- a/tools/mksymtab.sh +++ b/tools/mksymtab.sh @@ -27,28 +27,43 @@ usage() { if [ $# -ne 0 ]; then echo "ERROR: $@" fi - echo -e "\nUsage: $0 <imagedirpath> [symtabprefix] [-a additionalsymbolspath]" + echo -e "\nUsage: $0 <imagedirpath1> [imagedirpath2 ... ] [symtabprefix] [-a additionalsymbolspath]" exit 1 } -# Check for the required directory path +# Collect all image directory/file paths until we hit a non-path argument +dirs=() +prefix="" +arg_count=0 -dir=$1 -if [ -z "$dir" ]; then - usage "Missing <imagedirpath>" -fi +while [ $# -gt 0 ]; do + # Check if this is an option flag + if [ "x${1:0:1}" = "x-" ]; then + break + fi -# Get the symbol table prefix + arg_count=$((arg_count + 1)) -if [ "x${2:0:1}" != "x-" ]; then - prefix=$2 - OPTIND=3 -else - OPTIND=2 -fi + # Always collect the argument (whether path exists or not) + # Only treat as prefix if it doesn't look like a path + if [[ "$1" =~ ^/ ]] || [ -e "$1" ]; then + # Looks like a path (starts with /) or exists + dirs+=("$1") + shift + else + # Doesn't look like a path, treat as prefix + prefix=$1 + shift + break + fi +done -# Parse remaining arguments +# Check we have at least one argument +if [ $arg_count -eq 0 ]; then + usage "Missing <imagedirpath>" +fi +# Parse remaining arguments for options while getopts a: opt; do case $opt in a) @@ -63,28 +78,60 @@ if [ $OPTIND != $(($# + 1)) ]; then usage "Arguments remaining: \"${@:$OPTIND}\"" fi +# Function to get exec list from a path (file or directory) +get_exec_list() { + local path=$1 + if [ -f "$path" ]; then + echo "$path" + elif [ -d "$path" ]; then + find "$path" -type f 2>/dev/null + fi +} + # Extract all of the undefined symbols from the ELF files and create a # list of sorted, unique undefined variable names. -varlist=`find $dir -name *-thunk.S 2>/dev/null | xargs grep -h asciz | cut -f3 | sort | uniq` +# First try to find thunk files from all directories +varlist="" +for dir in "${dirs[@]}"; do + if [ -d "$dir" ]; then + thunklist=`find $dir -name *-thunk.S 2>/dev/null | xargs grep -h asciz 2>/dev/null | cut -f3` + if [ ! -z "$thunklist" ]; then + varlist="${varlist} ${thunklist}" + fi + fi +done + if [ -z "$varlist" ]; then - execlist=`find $dir -type f 2>/dev/null` - if [ ! -z "$execlist" ]; then + # Collect all executable files from all paths + execlist="" + for dir in "${dirs[@]}"; do + # Only process if path exists + if [ -e "$dir" ]; then + pathlist=`get_exec_list "$dir"` + if [ ! -z "$pathlist" ]; then + execlist="${execlist} ${pathlist}" + fi + fi + done -# Get all undefined symbol names - varlist=`nm $execlist 2>/dev/null | grep -F ' U ' | sed -e "s/^[ ]*//g" | cut -d' ' -f2 | sort | uniq` + if [ ! -z "$execlist" ]; then + # Get all undefined symbol names + varlist=$(nm $execlist 2>/dev/null | grep -F ' U ' | sed -e "s/^[ ]*//g" | cut -d' ' -f2) -# Get all defined symbol names - deflist=`nm $execlist 2>/dev/null | grep -F -v -e ' U ' -e ':' | sed -e "s/^[0-9a-z]* //g" | cut -d' ' -f2 | sort | uniq` + # Get all defined symbol names + deflist=$(nm $execlist 2>/dev/null | grep -F -v -e ' U ' -e ':' | sed -e "s/^[0-9a-z]* //g" | cut -d' ' -f2) -# Remove the intersection between them, and the remaining symbols are found in the main image - common=`echo "$varlist" | tr ' ' '\n' | grep -Fxf <(echo "$deflist" | tr ' ' '\n') | tr '\n' ' '` - if [ "x$common" != "x" ]; then - varlist=`echo $varlist | sed "s/$common//g"` + # Remove the intersection between them, and the remaining symbols are found in the main image + if [ ! -z "$varlist" ] && [ ! -z "$deflist" ]; then + varlist=$(echo "$varlist" | tr ' ' '\n' | sort -u | grep -vFxf <(echo "$deflist" | tr ' ' '\n' | sort -u) | tr '\n' ' ') fi fi fi +# Sort and unique the varlist +varlist=`echo "$varlist" | tr ' ' '\n' | sort | uniq | tr '\n' ' '` + for addsym in ${addlist[@]}; do if [ -f $addsym ]; then varlist="${varlist}\n$(cat $addsym | grep -v "^,.*")"
