71 lines · 1.9 KB · Text
RawDownload
#!/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_typesdeclare -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 namedo	# 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_})	fidone 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	fidone exit ${exit_code}