70 lines · 1.7 KB · Text
RawDownload
#!/bin/sh# SPDX-License-Identifier: GPL-2.0-only## Copyright (C) 2022 Masahiro Yamada <masahiroy@kernel.org># Copyright (C) 2022 Owen Rafferty <owen@owenrafferty.com>## Exit with error if a local exported symbol is found.# EXPORT_SYMBOL should be used for global symbols. set -epid=$$ # 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 simpler:#   { ${NM} --quiet ${1} || kill 0; } | { ${NM} ${1} 2>/dev/null || { echo "${0}: ${NM} failed" >&2; kill $pid; } } |${AWK} -v "file=${1}" 'BEGIN {	i = 0} # 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"!length($3) {	next} # save (name, type) in the associative array{ symbol_types[$3]=$2 } # append the exported symbol to the array($3 ~ /^__ksymtab_/) {	export_symbols[i] = $3	sub(/^__ksymtab_/, "", export_symbols[i])	i++} END {	exit_code = 0	for (j = 0; j < i; ++j) {		name = export_symbols[j]		# nm(3) says "If lowercase, the symbol is usually local"		if (symbol_types[name] ~ /[a-z]/) {			printf "%s: error: local symbol %s was exported\n",				file, name | "cat 1>&2"			exit_code = 1		}	} 	exit exit_code}' exit $?