679 lines
17 KiB
Bash
Executable File
679 lines
17 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
unset MAKEFLAGS
|
|
unset CPP
|
|
unset ARCH
|
|
unset SYMBOL
|
|
|
|
set -euo pipefail
|
|
|
|
usage() {
|
|
sed 's/^\t//' <<EOF
|
|
Usage: $0 [-h] [-v] [-1] [-2] [-3] [-4] [-5] -a ARCH [-s SYMBOL]... [FILE]...
|
|
EOF
|
|
|
|
echo
|
|
[ "$(type -t usage_desc || :)" == "function" ] && usage_desc
|
|
echo
|
|
|
|
sed 's/^\t//' <<EOF
|
|
-a ARCH Supported architectures:
|
|
x86_64, s390x, aarch64, ppc64le
|
|
|
|
-s SYMBOL [-s SYMBOL ...] Symbol entry to update.
|
|
Updates the whole stablelist if omitted.
|
|
|
|
-h Prints this message.
|
|
|
|
-v Verbose output.
|
|
|
|
== DESCRIPTION
|
|
|
|
To calculate current symbol data, the file exporting the symbol on a given
|
|
arch must first be located. The following methods are attempted in order:
|
|
|
|
1. user-supplied FILEs, if given, (disable using -1)
|
|
2. stablelist-supplied FILEs, (disable using -2)
|
|
3. cscope, if available, (disable using -3)
|
|
4. naive regular expression search for exporting macro (disable
|
|
using -4),
|
|
5. compute all symvers and symtypes files (disable using -5)
|
|
6. compute all symvers and symtypes files following a local kernel
|
|
build (disable using -6).
|
|
|
|
If a method is successful in updating all of the required symbols,
|
|
the script early terminates. Methods are sorted by their time complexity
|
|
as well as generality.
|
|
|
|
If you're using the tool directly, please make sure to commit/stash your
|
|
changes.
|
|
|
|
You must also make sure that you have cross compilation toolchain
|
|
installed when computing non-native checksums. The tool uses
|
|
CROSS_COMPILE=/usr/bin/ARCH-linux-gnu-, override
|
|
KABI_CROSS_COMPILE_PREFIX=/usr/bin/
|
|
KABI_CROSS_COMPILE_SUFFIX=-linux-gnu-
|
|
as needed.
|
|
|
|
== NOTES
|
|
|
|
Method 3 can only find symbols exported using one of the following
|
|
macros:
|
|
|
|
ACPI_EXPORT_SYMBOL
|
|
ACPI_EXPORT_SYMBOL_INIT
|
|
EXPORT_DATA_SYMBOL
|
|
EXPORT_DATA_SYMBOL_GPL
|
|
EXPORT_INDIRECT_CALLABLE
|
|
EXPORT_PER_CPU_SYMBOL
|
|
EXPORT_PER_CPU_SYMBOL_GPL
|
|
EXPORT_STATIC_CALL
|
|
EXPORT_STATIC_CALL_GPL
|
|
EXPORT_STATIC_CALL_TRAMP
|
|
EXPORT_STATIC_CALL_TRAMP_GPL
|
|
EXPORT_SYMBOL
|
|
EXPORT_SYMBOL_FOR_TESTS_ONLY
|
|
EXPORT_SYMBOL_GPL
|
|
EXPORT_SYMBOL_NS
|
|
EXPORT_SYMBOL_NS_GPL
|
|
EXPORT_TRACEPOINT_SYMBOL
|
|
EXPORT_TRACEPOINT_SYMBOL_GPL
|
|
|
|
and the symbol name must not be constructed using preprocessor
|
|
concatenation.
|
|
EOF
|
|
exit
|
|
}
|
|
|
|
# --- decls
|
|
|
|
# list of temporary files created during execution
|
|
declare -ag TEMP_FILES
|
|
|
|
# list of makefile targets to invoke
|
|
declare -ag TARGETS
|
|
|
|
# list of source files to process
|
|
declare -ag SOURCES
|
|
|
|
# list of symbols to try and generate symbol versions/symtypes for
|
|
declare -ag SYMBOL
|
|
|
|
# list of symbols that couldn't have been resolved using previous method
|
|
declare -ag SYMFAIL
|
|
|
|
# current arch
|
|
declare -g CARCH
|
|
|
|
# dict[arch]=ARCH variable for kernel makefile
|
|
declare -Ag CC_ARCH
|
|
|
|
# dict[symbol]=checksum
|
|
# dict[symbol]=file_exporting_symbol
|
|
declare -Ag SYMCRC
|
|
declare -Ag SYMFILE
|
|
declare -Ag SYMFILE_T
|
|
declare -Ag SYMFILE_V
|
|
|
|
# kernel makefile cc var
|
|
declare -g CROSS_COMPILE
|
|
|
|
# compiler
|
|
declare -g CPP
|
|
|
|
# verbose level
|
|
declare -g V
|
|
|
|
# --- default assignments
|
|
|
|
V=${V:-0}
|
|
CPP=gcc
|
|
KABI_CROSS_COMPILE_PREFIX="${KABI_CROSS_COMPILE_PREFIX:-/usr/bin/}"
|
|
KABI_CROSS_COMPILE_SUFFIX="${KABI_CROSS_COMPILE_SUFFIX:--linux-gnu-}"
|
|
USE_ENTIRE_STABLELIST=1
|
|
MAKE_ARGS=(-k -i -j$(nproc))
|
|
CC_ARCH[s390x]="s390"
|
|
CC_ARCH[x86_64]="x86"
|
|
CC_ARCH[ppc64le]="powerpc"
|
|
CC_ARCH[aarch64]="arm64"
|
|
|
|
# --- helper fns
|
|
|
|
echo0() { echo " :: $*"; }
|
|
echo1() { echo " $*"; }
|
|
echo2() { echo " - $*"; }
|
|
echo3() { echo " $*"; }
|
|
err() { echo -e "ERROR:" "$@" >&2; }
|
|
warn() { echo -e "WARNING:" "$@" >&2; }
|
|
|
|
cleanup() {
|
|
[ -z "${TEMP_FILES[@]:-}" ] && return
|
|
echo0 "Cleaning up temporary files ..."
|
|
rm -f "${TEMP_FILES[@]}"
|
|
}
|
|
|
|
# find files containing symbol export statements of the form MACRO(NAME),
|
|
# where symbol name NAME is the entire symbol name and MACRO is one of:
|
|
# ACPI_EXPORT_SYMBOL
|
|
# ACPI_EXPORT_SYMBOL_INIT
|
|
# EXPORT_DATA_SYMBOL
|
|
# EXPORT_DATA_SYMBOL_GPL
|
|
# EXPORT_INDIRECT_CALLABLE
|
|
# EXPORT_PER_CPU_SYMBOL
|
|
# EXPORT_PER_CPU_SYMBOL_GPL
|
|
# EXPORT_STATIC_CALL
|
|
# EXPORT_STATIC_CALL_GPL
|
|
# EXPORT_STATIC_CALL_TRAMP
|
|
# EXPORT_STATIC_CALL_TRAMP_GPL
|
|
# EXPORT_SYMBOL
|
|
# EXPORT_SYMBOL_FOR_TESTS_ONLY
|
|
# EXPORT_SYMBOL_GPL
|
|
# EXPORT_SYMBOL_NS
|
|
# EXPORT_SYMBOL_NS_GPL
|
|
# EXPORT_TRACEPOINT_SYMBOL
|
|
# EXPORT_TRACEPOINT_SYMBOL_GPL
|
|
# export_try_find SYMBOL|REGEX
|
|
export_tryfind() {
|
|
grep -Prol --exclude-dir=redhat "^(ACPI_)?EXPORT_(DATA_|INDIRECT_CALLABLE|STATIC_CALL|TRACEPOINT_)?(PER_CPU_)?(SYMBOL|_TRAMP)?(_NS)?(_GPL|_INIT)?\($1(,[^)]*)?\);" || :
|
|
}
|
|
|
|
symbol_tryfind_symversions() {
|
|
# __crc_SYMBOL = CHECKSUM
|
|
# SECTIONS { .rodata : ALIGN(4) { __crc_SYMBOL = .; LONG(CHECKSUM); } }
|
|
grep -R --include="*.symversions" --exclude-dir=redhat -H -Po \
|
|
"^__crc_\K$1 = .*(?=;)" | tr -d ' ' && return || :
|
|
grep -R --include "*.symversions" --exclude-dir=redhat -H -Po \
|
|
"__crc_\K$1[ =].*0x[[:xdigit:]]+" \
|
|
| sed -e 's/ = .*\(0x[[:xdigit:]]\+\).*/=\1/'
|
|
|
|
}
|
|
|
|
# batch call to export_tryfind, limited to 10 symbols at the time to make sure
|
|
# argv doesn't overflow
|
|
# export_tryfind SYMBOL...
|
|
batch() {
|
|
local fn=$1
|
|
shift 1
|
|
local o=1
|
|
local d=10
|
|
while [ $o -le $# ]; do
|
|
[ $o -gt $# ] && d=$((o-$#))
|
|
# pass an array of symbols S1...Sn as a regex (S1|...|Sn)
|
|
$fn $(
|
|
echo ${@:$o:$d} \
|
|
| sed -e 's/ /|/g' -e 's/^/(/' -e 's/$/)/'
|
|
)
|
|
o=$((o+d))
|
|
done | sort | uniq
|
|
}
|
|
|
|
src_to_symversions() {
|
|
sed 's/\.[cS]$/.symversions/'
|
|
}
|
|
|
|
src_to_symtypes() {
|
|
sed 's/\.[cS]$/.symtypes/'
|
|
}
|
|
|
|
dump_failed_symbols() {
|
|
echo1 "Couldn't find the following symbols using this method:" >&3
|
|
for sym in ${SYMFAIL[@]}; do
|
|
echo2 $sym >&3
|
|
done
|
|
}
|
|
|
|
prepare_stage() {
|
|
# SYMBOL lists symbols to be searched
|
|
# SYMFAIL lists symbols that failed in the previous run
|
|
SYMBOL=(${SYMFAIL[@]})
|
|
SYMFAIL=()
|
|
TARGETS=()
|
|
FILE=()
|
|
}
|
|
|
|
process_Module_symvers() {
|
|
[ ! -e Module.symvers ] && return 1
|
|
|
|
# read checksums into SYMCRC
|
|
local IFS=$'\n'
|
|
for sym in $(comm -12 <(cut -f2 Module.symvers | sort) \
|
|
<(echo ${SYMBOL[@]} | tr ' ' '\n' | sort)); do
|
|
symcrc=$(grep -Po "^0x[[:xdigit:]]+(?=\t$sym\t)" Module.symvers)
|
|
file=$(grep -El -m 1 -r --include="*.symtypes" \
|
|
--exclude-dir=redhat "^[a-zA-Z#]{,2}$sym " | head -n1)
|
|
[ -z "$file" ] && continue
|
|
SYMCRC[$sym]=$symcrc
|
|
SYMFILE_T[$sym]=$file
|
|
SYMFILE_V[$sym]=Module.symvers
|
|
[ -e "${file/.symtypes/.c}" ] && file="${file/.symtypes/.c}"
|
|
[ -e "${file/.symtypes/.S}" ] && file="${file/.symtypes/.S}"
|
|
SYMFILE[$sym]=$file
|
|
echo3 "Found $sym in $file (crc: $symcrc)," \
|
|
"V: ${SYMFILE_V[$sym]}," \
|
|
"T: ${SYMFILE_T[$sym]}," \
|
|
"F: ${SYMFILE[$sym]}." >&3
|
|
done
|
|
|
|
return 0
|
|
}
|
|
|
|
process_symversions() {
|
|
# read checksums into SYMCRC and update stablelist, output format:
|
|
# filename.symversions:__crc_symbolname = 0x0000..
|
|
for match in $(batch symbol_tryfind_symversions "$@"); do
|
|
file=${match%:*}
|
|
symcrc=${match#*:}
|
|
sym=${symcrc%%=*}
|
|
SYMCRC[$sym]=${symcrc##*=}
|
|
SYMFILE_V[$sym]=$file
|
|
SYMFILE_T[$sym]=${file/.symversions/.symtypes}
|
|
[ -e ${file/.symversions/.c} ] && file=${file/.symversions/.c}
|
|
[ -e ${file/.symversions/.S} ] && file=${file/.symversions/.S}
|
|
SYMFILE[$sym]=$file
|
|
echo3 "Found $sym in $file (crc: $symcrc)," \
|
|
"V: ${SYMFILE_V[$sym]}," \
|
|
"T: ${SYMFILE_T[$sym]}," \
|
|
"F: ${SYMFILE[$sym]}." >&3
|
|
done
|
|
}
|
|
|
|
# generate MAKE_TARGET...
|
|
generate() {
|
|
if [ $# -eq 0 ]; then
|
|
echo "No targets given to generate."
|
|
SYMFAIL=(${SYMBOL[@]})
|
|
return 1
|
|
fi
|
|
|
|
echo1 "Building symtype and symversion files ..."
|
|
for file in $@; do
|
|
echo2 "$file" >&3
|
|
done
|
|
|
|
# batch build at most 100 targets (symvers, symtypes files)
|
|
while [ $# -gt 0 ]; do
|
|
if [ $# -gt 100 ]; then
|
|
make ${MAKE_ARGS[@]} ${@:1:100} >&3 2>&3 || :
|
|
shift 100
|
|
else
|
|
make ${MAKE_ARGS[@]} ${@:1:$#} >&3 2>&3 || :
|
|
shift $#
|
|
fi
|
|
done
|
|
|
|
if ! process_Module_symvers; then
|
|
process_symversions "${SYMBOL[@]}"
|
|
fi
|
|
|
|
echo1 "Looking for eligible symbol checksum updates ..." >&3
|
|
for sym in ${SYMBOL[@]}; do
|
|
if [ -z "${SYMCRC[$sym]:-}" ]; then
|
|
echo3 "Couldn't find crc for $sym" >&3
|
|
[[ ! " ${SYMFAIL[*]} " =~ " $sym " ]] && SYMFAIL+=($sym)
|
|
continue
|
|
fi
|
|
if [ ! -e "${SYMFILE[$sym]:-}" ]; then
|
|
echo3 "Couldn't find source file for $sym" >&3
|
|
continue
|
|
fi
|
|
if [ ! -e "${SYMFILE_V[$sym]:-}" ]; then
|
|
echo3 "Couldn't find version file for $sym" >&3
|
|
continue
|
|
fi
|
|
if [ ! -e "${SYMFILE_T[$sym]:-}" ]; then
|
|
echo3 "Couldn't find symtypes file for $sym" >&3
|
|
continue
|
|
fi
|
|
cb_checksum $CARCH $sym ${SYMCRC[$sym]:-} ${SYMFILE[$sym]} \
|
|
${SYMFILE_V[$sym]} ${SYMFILE_T[$sym]}
|
|
done
|
|
|
|
if [ -z "${SYMFAIL:-}" ]; then
|
|
cb_ready
|
|
return 0
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
# process argv
|
|
|
|
OPTIND=1
|
|
|
|
while getopts "TC12345hva:f:s:" opt; do
|
|
case "$opt" in
|
|
T)
|
|
CONFIG_NO_TEST=y
|
|
;;
|
|
C)
|
|
CONFIG_NO_CLEAN=y
|
|
;;
|
|
1)
|
|
CONFIG_NO_METH1=y
|
|
;;
|
|
2)
|
|
CONFIG_NO_METH2=y
|
|
;;
|
|
3)
|
|
CONFIG_NO_METH3=y
|
|
;;
|
|
4)
|
|
CONFIG_NO_METH4=y
|
|
;;
|
|
5)
|
|
CONFIG_NO_METH5=y
|
|
;;
|
|
6)
|
|
CONFIG_NO_METH6=y
|
|
;;
|
|
h)
|
|
usage
|
|
;;
|
|
v)
|
|
V=1
|
|
;;
|
|
s)
|
|
USE_ENTIRE_STABLELIST=0
|
|
[ -z "${CARCH:-}" ] && usage
|
|
if [ "$OPTARG" = "-" ]; then
|
|
SYMBOL+=($(cat))
|
|
continue
|
|
fi
|
|
SYMBOL+=($OPTARG)
|
|
;;
|
|
a)
|
|
CARCH=$OPTARG
|
|
;;
|
|
esac
|
|
done
|
|
shift $((OPTIND-1))
|
|
|
|
CARCH=${CARCH:-$(uname -m)}
|
|
SOURCES=("${@:-}")
|
|
|
|
if [ "$CARCH" = "$(uname -m)" ]; then
|
|
if ! command -v "$CPP" &> /dev/null; then
|
|
echo "ERROR: native gcc not found."
|
|
exit 1
|
|
fi
|
|
else
|
|
if [ -z "${CROSS_COMPILE:-}" ]; then
|
|
CROSS_COMPILE="${KABI_CROSS_COMPILE_PREFIX}"
|
|
CROSS_COMPILE+="$CARCH"
|
|
CROSS_COMPILE+="${KABI_CROSS_COMPILE_SUFFIX}"
|
|
fi
|
|
|
|
if ! [ -e "$CROSS_COMPILE$CPP" ]; then
|
|
echo "ERROR: $arch $CPP not found ($CROSS_COMPILE$CPP)"
|
|
exit 1
|
|
fi
|
|
|
|
MAKE_ARGS+=(ARCH=${CC_ARCH[$CARCH]} CROSS_COMPILE=$CROSS_COMPILE)
|
|
fi
|
|
|
|
# Set up is_verbose fd
|
|
if [ ${V:-0} -gt 0 ]; then
|
|
exec 3>&1
|
|
export PS4='$LINENO: '
|
|
set -x
|
|
else
|
|
exec 3> /dev/null
|
|
fi
|
|
|
|
export BASH_XTRACEFD="3"
|
|
|
|
if [ -z "$CARCH" ]; then
|
|
err "No architecture specified."
|
|
usage
|
|
fi
|
|
|
|
if [ ! -d "$REDHAT/kabi/kabi-module/kabi_$CARCH" ]; then
|
|
err "Architecture $CARCH not supported."
|
|
exit 1
|
|
fi
|
|
|
|
trap cleanup EXIT
|
|
|
|
# --- prep
|
|
|
|
cd "$(git rev-parse --show-toplevel)"
|
|
|
|
REDHAT=${REDHAT:-$(pwd)/redhat/}
|
|
|
|
if [ $USE_ENTIRE_STABLELIST -eq 1 ]; then
|
|
SYMBOL=($(find $REDHAT/kabi/kabi-module/kabi_$CARCH -type f \
|
|
-not -name ".*" -exec basename {} \; | sort | uniq))
|
|
if [ -z "${SYMBOL[*]}" ]; then
|
|
err "No symbols found on stablelist. Nothing to do."
|
|
exit
|
|
fi
|
|
elif [ -z "${SYMBOL[*]}" ]; then
|
|
err "No symbols given. Nothing to do."
|
|
exit
|
|
fi
|
|
|
|
echo0 "The following symbol entries will be updated:"
|
|
|
|
for symbol in ${SYMBOL[@]}; do
|
|
if find $REDHAT/kabi/kabi-module/${CARCH/#/kabi_} -name $symbol \
|
|
-exec false {} + &> /dev/null; then
|
|
echo1 "$symbol (not found on ${CARCH} stablelist)"
|
|
else
|
|
echo1 "$symbol"
|
|
fi
|
|
done
|
|
|
|
if [ -z "${CONFIG_NO_CLEAN+x}" ]; then
|
|
make -j$(nproc) V=$V mrproper >&3 2>&3
|
|
fi
|
|
|
|
if [ ! -e $REDHAT/configs/kernel*$CARCH.config ]; then
|
|
echo0 "Generating config files ..."
|
|
make dist-configs V=$V >&3
|
|
fi
|
|
|
|
cp $REDHAT/configs/kernel*$(uname -m).config .config
|
|
|
|
echo0 "Building scripts (genksyms) ..."
|
|
|
|
make -j$(nproc) V=$V scripts >&3 2>&3 # -> genksyms, requires native cc
|
|
|
|
cp $REDHAT/configs/kernel*$CARCH.config .config
|
|
|
|
if [ -z "${CONFIG_NO_TEST+x}" ]; then
|
|
TEST_FILE=$({ grep -rl EXPORT_SYMBOL net/core net/ . || : ; } | head -n1)
|
|
TEST_SYMVERSIONS="$(printf "$TEST_FILE" | src_to_symversions)"
|
|
TEST_SYMTYPES="$(printf "$TEST_FILE" | src_to_symtypes)"
|
|
echo1 "Checking that genksyms works as expected on a test file" \
|
|
"$TEST_FILE, expecting $TEST_SYMVERSIONS, $TEST_SYMTYPES ..." >&3
|
|
make V=$V ${MAKE_ARGS[@]} $TEST_SYMVERSIONS $TEST_SYMTYPES >&3 2>&3
|
|
if [ ! -e $TEST_SYMVERSIONS -o ! -e $TEST_SYMTYPES ]; then
|
|
warn "An attempt to test genksyms failed. Please re-run with" \
|
|
"-v and inspect the output and git diff to make sure" \
|
|
"that the script works correctly."
|
|
fi
|
|
fi
|
|
|
|
# ---
|
|
|
|
queue_target() {
|
|
for f in "$@"; do
|
|
symv=($(printf "$f" | src_to_symversions))
|
|
symt=($(printf "$f" | src_to_symtypes))
|
|
|
|
# ensure it's not queued already
|
|
if [[ ! " ${FILE[*]} " =~ " $symv " ]]; then
|
|
FILE+=($symv)
|
|
echo1 "$f: queued targets: $symv" >&3
|
|
fi
|
|
|
|
if [[ ! " ${FILE[*]} " =~ " $symt " ]]; then
|
|
FILE+=($symt)
|
|
echo1 "$f: queued targets: $symt" >&3
|
|
fi
|
|
done
|
|
}
|
|
|
|
targets_from_srclist() {
|
|
for src in "${@:-}"; do
|
|
if ! [ -e "$src" ]; then
|
|
err "File \`$src' not found!"
|
|
exit 1
|
|
fi
|
|
queue_target "$src"
|
|
done
|
|
}
|
|
|
|
targets_from_symlist() {
|
|
for sym in ${@:-}; do
|
|
if ! [ -e $REDHAT/kabi/kabi-module/kabi_$CARCH/$sym ]; then
|
|
echo1 "$sym not found in $CARCH stablelist, skipping" \
|
|
"(missing: $REDHAT/kabi/kabi-module/kabi_$CARCH/$sym)" >&3
|
|
[[ ! " ${SYMFAIL[*]} " =~ " $sym " ]] && SYMFAIL+=($sym)
|
|
continue
|
|
fi
|
|
src="$(grep -Po '^#P:\K.*' $REDHAT/kabi/kabi-module/kabi_$CARCH/$sym || :)"
|
|
if [ -z "$src" ]; then
|
|
echo1 "$sym does not reference source file, skipping" \
|
|
"(missing: $REDHAT/kabi/kabi-module/kabi_$CARCH/$sym)" >&3
|
|
[[ ! " ${SYMFAIL[*]} " =~ " $sym " ]] && SYMFAIL+=($sym)
|
|
continue
|
|
fi
|
|
if ! [ -e "$src" ]; then
|
|
echo1 "$sym: source $src got moved or removed, skipping" >&3
|
|
[[ ! " ${SYMFAIL[*]} " =~ " $sym " ]] && SYMFAIL+=($sym)
|
|
continue
|
|
fi
|
|
queue_target "$src"
|
|
done
|
|
}
|
|
|
|
targets_cscope() {
|
|
command -v cscope >&3 || return
|
|
for sym in "${@:-}"; do
|
|
queue_target $(cscope -k -d -L1$sym | cut -f1 -d' ' || :)
|
|
done
|
|
}
|
|
|
|
targets_from_symlist_any() {
|
|
for sym in ${@:-}; do
|
|
fil=($(find $REDHAT/kabi/kabi-module/ -type f -name "$sym"))
|
|
if [ ${#fil[@]} -eq 0 ]; then
|
|
echo1 "$sym not found in any stablelist, skipping" \
|
|
"(missing: $REDHAT/kabi/kabi-module/*/$sym)" >&3
|
|
[[ ! " ${SYMFAIL[*]} " =~ " $sym " ]] && SYMFAIL+=($sym)
|
|
continue
|
|
fi
|
|
for f in ${fil[@]}; do
|
|
queue_target $(grep -Po '^#P:\K.*' $f | sort | uniq || :)
|
|
done
|
|
done
|
|
}
|
|
|
|
targets_naive() {
|
|
# symbol got moved, naive greedy search for export statement
|
|
# can produce any non-negative number of results:
|
|
# #res > 1 : arch-specific code may yield multiple files in arch,
|
|
# leaving it to kbuild to fail instead of trying to
|
|
# mask them
|
|
# #res = 1 : ok, provided this is not a false positive (we can
|
|
# tell that when we generate checksums)
|
|
# #res = 0 : this may occur when the export symbol call/symbol
|
|
# name is composed using preprocessor concatenation;
|
|
# in this case we are forced to generate all checksums
|
|
for src in $(batch export_tryfind "$@"); do
|
|
queue_target "$src"
|
|
done
|
|
}
|
|
|
|
targets_dry_run() {
|
|
queue_target $({ make ${MAKE_ARGS[@]} --dry-run 2>&3 || : ; } \
|
|
| grep -E '(gcc|as)' \
|
|
| grep -Po " \K[a-zA-Z0-9][^ ,.]*[^/ ,.]\.[cS]" \
|
|
| sort \
|
|
| uniq \
|
|
| sed 's/^\(.*\)\.[cS]$/\1.symtypes\n\1.symversions/g')
|
|
}
|
|
|
|
targets_compile() {
|
|
declare -A wrappers
|
|
local template=$(mktemp -t -u "kabi-wrapper-XXXXXXXXX")
|
|
local list=$(mktemp -u "kabi-list-XXXXXXXXX")
|
|
TEMP_FILES=("${TEMP_FILES[@]}" "$list")
|
|
for wrapper in $(grep -Po '= \$\(CROSS_COMPILE\)\K.*' Makefile); do
|
|
wrappers[$wrapper]=$template-$wrapper
|
|
TEMP_FILES=("${TEMP_FILES[@]}" "${wrappers[$wrapper]}")
|
|
bin=${CROSS_COMPILE:-}$wrapper list=$list envsubst '$bin $list' \
|
|
> "${wrappers[$wrapper]}" <<-'EOF'
|
|
#!/usr/bin/env bash
|
|
echo "$*" | grep -Po " \K[a-zA-Z0-9_/-]+\.[cS]" | tr ' ' '\n' >> $list
|
|
$bin "$@"
|
|
EOF
|
|
chmod +x "${wrappers[$wrapper]}"
|
|
done
|
|
make ${MAKE_ARGS[@]} CROSS_COMPILE="$template-" >&3 2>&3 || :
|
|
# no need to build symvers, using Module.symvers instead
|
|
queue_target $(cat $list | src_to_symtypes | sort | uniq)
|
|
}
|
|
|
|
SYMFAIL=(${SYMBOL[@]})
|
|
|
|
if [ -z "${CONFIG_NO_METH1+x}" -a $# -gt 0 ]; then
|
|
prepare_stage
|
|
echo0 "Updating stablelist using user-supplied files ..."
|
|
targets_from_srclist "${SOURCES[@]}"
|
|
generate "${FILE[@]}" && exit 0 || :
|
|
dump_failed_symbols
|
|
fi
|
|
|
|
if [ -z "${CONFIG_NO_METH2+x}" ]; then
|
|
prepare_stage
|
|
echo0 "Updating stablelist using stablelist-provided files (arch specific) ..."
|
|
targets_from_symlist "${SYMBOL[@]}"
|
|
generate "${FILE[@]}" && exit 0 || :
|
|
dump_failed_symbols
|
|
|
|
prepare_stage
|
|
echo0 "Updating stablelist using stablelist-provided files (any archs) ..."
|
|
targets_from_symlist_any "${SYMBOL[@]}"
|
|
generate "${FILE[@]}" && exit 0 || :
|
|
dump_failed_symbols
|
|
fi
|
|
|
|
if [ -z "${CONFIG_NO_METH3+x}" ]; then
|
|
prepare_stage
|
|
echo0 "Updating stablelist using cscope-provided files ..."
|
|
targets_cscope "${SYMBOL[@]}"
|
|
generate "${FILE[@]}" && exit 0 || :
|
|
dump_failed_symbols
|
|
fi
|
|
|
|
if [ -z "${CONFIG_NO_METH4+x}" ]; then
|
|
prepare_stage
|
|
echo0 "Updating stablelist using naive method ..."
|
|
targets_naive "${SYMBOL[@]}"
|
|
generate "${FILE[@]}" && exit 0 || :
|
|
dump_failed_symbols
|
|
fi
|
|
|
|
if [ -z "${CONFIG_NO_METH5+x}" ]; then
|
|
prepare_stage
|
|
echo0 "Updating stablelist greedy method (this might take some time) ..."
|
|
targets_dry_run
|
|
generate "${FILE[@]}" && exit 0 || :
|
|
dump_failed_symbols
|
|
fi
|
|
|
|
if [ -z "${CONFIG_NO_METH6+x}" ]; then
|
|
prepare_stage
|
|
echo0 "Updating stablelist by compiling the kernel (this might take some time) ..."
|
|
targets_compile
|
|
generate "${FILE[@]}" && exit 0
|
|
fi
|
|
|
|
err "could not update all of the symbol checksums required:"
|
|
for sym in ${SYMFAIL[@]}; do
|
|
printf "\t%s\n" "$sym"
|
|
done
|
|
exit 1
|