mirror of
https://github.com/apache/nuttx-apps.git
synced 2026-08-01 20:29:00 +00:00
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 <anjiahao@xiaomi.com>
This commit is contained in:
parent
6630c08783
commit
63e2650487
3 changed files with 102 additions and 30 deletions
|
|
@ -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 >$@.tmp
|
||||
$(Q) $(APPDIR)$(DELIM)tools$(DELIM)mksymtab.sh $(ELFNAME) g_elf >$@.tmp
|
||||
$(Q) $(call TESTANDREPLACEFILE, $@.tmp, $@)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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 >$@.tmp
|
||||
$(Q) $(APPDIR)$(DELIM)tools$(DELIM)mksymtab.sh $(BINDIR)$(DELIM)$(MODLUE_NAME) g_mod >$@.tmp
|
||||
$(Q) $(call TESTANDREPLACEFILE, $@.tmp, $@)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
while [ $# -gt 0 ]; do
|
||||
# Check if this is an option flag
|
||||
if [ "x${1:0:1}" = "x-" ]; then
|
||||
break
|
||||
fi
|
||||
|
||||
arg_count=$((arg_count + 1))
|
||||
|
||||
# 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
|
||||
|
||||
# Check we have at least one argument
|
||||
if [ $arg_count -eq 0 ]; then
|
||||
usage "Missing <imagedirpath>"
|
||||
fi
|
||||
|
||||
# Get the symbol table prefix
|
||||
|
||||
if [ "x${2:0:1}" != "x-" ]; then
|
||||
prefix=$2
|
||||
OPTIND=3
|
||||
else
|
||||
OPTIND=2
|
||||
fi
|
||||
|
||||
# Parse remaining arguments
|
||||
|
||||
# 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`
|
||||
# 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
|
||||
|
||||
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 undefined symbol names
|
||||
varlist=`nm $execlist 2>/dev/null | grep -F ' U ' | sed -e "s/^[ ]*//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)
|
||||
|
||||
# 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`
|
||||
|
||||
# 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 "^,.*")"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue