diff options
Diffstat (limited to 'scripts/check-local-export')
-rwxr-xr-x | scripts/check-local-export | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/scripts/check-local-export b/scripts/check-local-export new file mode 100755 index 000000000000..2c46912be0ef --- /dev/null +++ b/scripts/check-local-export @@ -0,0 +1,65 @@ +#!/bin/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 + +declare -A symbol_types +declare -a export_symbols + +exit_code=0 + +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 + + # 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. + # + # 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: + # done < <(${NM} --quiet ${1}) +done < <(${NM} ${1} 2>/dev/null || { echo "${0}: ${NM} failed" >&2; false; } ) + +# Catch error in the process substitution +wait $! + +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} |