forked from Minki/linux
da4288b95b
Bash 4.4, released in 2016, supports 'wait $!' to check the exit status
of a process substitution, but it seems too new.
Some people using older bash versions (on CentOS 7, Ubuntu 16.04, etc.)
reported an error like this:
./scripts/check-local-export: line 54: wait: pid 17328 is not a child of this shell
I used the process substitution to avoid a pipeline, which executes each
command in a subshell. If the while-loop is executed in the subshell
context, variable changes within are lost after the subshell terminates.
Fortunately, Bash 4.2, released in 2011, supports the 'lastpipe' option,
which makes the last element of a pipeline run in the current shell process.
Switch to the pipeline with 'lastpipe' solution, and also set 'pipefail'
to catch errors from ${NM}.
Add the bash requirement to Documentation/process/changes.rst.
Fixes: 31cb50b559
("kbuild: check static EXPORT_SYMBOL* by script instead of modpost")
Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Reported-by: Michael Ellerman <mpe@ellerman.id.au>
Reported-by: Wang Yugui <wangyugui@e16-tech.com>
Tested-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Tested-by: Jon Hunter <jonathanh@nvidia.com>
Acked-by: Nick Desaulniers <ndesaulniers@google.com>
Tested-by: Sedat Dilek <sedat.dilek@gmail.com> # LLVM-14 (x86-64)
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
72 lines
1.9 KiB
Bash
Executable File
72 lines
1.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# SPDX-License-Identifier: GPL-2.0-only
|
|
#
|
|
# Copyright (C) 2022 Masahiro Yamada <masahiroy@kernel.org>
|
|
#
|
|
# Exit with error if a local exported symbol is found.
|
|
# EXPORT_SYMBOL should be used for global symbols.
|
|
|
|
set -e
|
|
|
|
# catch errors from ${NM}
|
|
set -o pipefail
|
|
|
|
# Run the last element of a pipeline in the current shell.
|
|
# Without this, the while-loop would be executed in a subshell, and
|
|
# the changes made to 'symbol_types' and 'export_symbols' would be lost.
|
|
shopt -s lastpipe
|
|
|
|
declare -A symbol_types
|
|
declare -a export_symbols
|
|
|
|
exit_code=0
|
|
|
|
# If there is no symbol in the object, ${NM} (both GNU nm and llvm-nm) shows
|
|
# 'no symbols' diagnostic (but exits with 0). It is harmless and hidden by
|
|
# '2>/dev/null'. However, it suppresses real error messages as well. Add a
|
|
# hand-crafted error message here.
|
|
#
|
|
# TODO:
|
|
# Use --quiet instead of 2>/dev/null when we upgrade the minimum version of
|
|
# binutils to 2.37, llvm to 13.0.0.
|
|
# Then, the following line will be really simple:
|
|
# ${NM} --quiet ${1} |
|
|
|
|
{ ${NM} ${1} 2>/dev/null || { echo "${0}: ${NM} failed" >&2; false; } } |
|
|
while read value type name
|
|
do
|
|
# Skip the line if the number of fields is less than 3.
|
|
#
|
|
# case 1)
|
|
# For undefined symbols, the first field (value) is empty.
|
|
# The outout looks like this:
|
|
# " U _printk"
|
|
# It is unneeded to record undefined symbols.
|
|
#
|
|
# case 2)
|
|
# For Clang LTO, llvm-nm outputs a line with type 't' but empty name:
|
|
# "---------------- t"
|
|
if [[ -z ${name} ]]; then
|
|
continue
|
|
fi
|
|
|
|
# save (name, type) in the associative array
|
|
symbol_types[${name}]=${type}
|
|
|
|
# append the exported symbol to the array
|
|
if [[ ${name} == __ksymtab_* ]]; then
|
|
export_symbols+=(${name#__ksymtab_})
|
|
fi
|
|
done
|
|
|
|
for name in "${export_symbols[@]}"
|
|
do
|
|
# nm(3) says "If lowercase, the symbol is usually local"
|
|
if [[ ${symbol_types[$name]} =~ [a-z] ]]; then
|
|
echo "$@: error: local symbol '${name}' was exported" >&2
|
|
exit_code=1
|
|
fi
|
|
done
|
|
|
|
exit ${exit_code}
|