@@ -0,0 +1,235 @@
+#!/bin/bash
+# Tool to do kABI checks.
+# (c) Kurt Garloff <garloff@suse.de>, GNU GPL, 11/2005
+# $Id$
+#
+# This tool looks at the generated symvers and compares it to the
+# reference file (if existent). It prints warnings for changed symbol
+# versions.
+#
+# Return value:
+# 0 -- no changes
+# 1 -- usage/input error
+# 2 -- internal error
+# 4 -- only additions
+# >= 8 -- removed or changed symbols (see below)
+#
+# Severity classification:
+# - 8 -- 15: if it's not found in a list (commonsyms or usedsyms)
+# The score depends on the source; symbols in vmlinux are more
+# likely to be used by anyone.
+# - 16 -- 23: symbol is found in the list usedsyms
+# - 24 -- 31: symbol is found in the list commonsyms
+
+severities="
+# unimportant ---. .--- important
+# v v
+
+drivers/base/* 13
+drivers/char/ipmi/* 10
+drivers/char/tpm/tpm 9
+drivers/hwmon/* 10
+drivers/i2c/i2c-core 9
+drivers/md/* 13
+drivers/message/fusion/* 6
+drivers/pci/* 12
+drivers/pci/hotplug/pci_hotplug 10
+drivers/scsi/libata 12
+drivers/scsi/scsi* 12
+drivers/scsi/*/scsi_transport_* 12
+drivers/scsi/libiscsi* 12
+drivers/ide/ide-core 11
+drivers/usb/core/usbcore 10
+drivers/usb/serial/usbserial 9
+fs/dmapi/dmapi 11
+fs/fat/fat 11
+fs/jbd/jbd 11
+net/ipv4/netfilter/ip_tables 9
+vmlinux 15
+"
+
+# Turning off UTF-8 processing provides a major speedup.
+export LC_ALL=C
+
+echo "${0##*/} $@"
+
+unset quiet verbose
+if [ "$1" = "-q" ]; then
+ shift
+ quiet=1
+fi
+if [ "$1" = "-v" ]; then
+ shift
+ verbose=1
+fi
+
+if [ $# -lt 2 -o $# -gt 4 ]; then
+ echo "Usage: ${0##*/} [-q] [-v] reference symvers [commonsyms [usedsyms]]" >&2
+ exit 1
+fi
+for file in "$@"; do
+ [ -r "$file" ] && continue
+ echo "Cannot read from '$file'" >&2
+ exit 1
+done
+
+declare_symbol_severity() {
+ declare severity=$1
+
+ while [ $# -ge 2 ]; do
+ if ! eval "severity_of_${2//[^a-zA-Z0-9_]/_}=$severity"; then
+ echo "Internal error" >&2
+ exit 2
+ fi
+ shift
+ done
+}
+
+consistency_check() {
+ declare_symbol_severity 16 consistency_check_foo
+ check_modified_symbols >/dev/null <<-EOF
+ consistency_check_foo -0x12345678 consistency/check/foo +0x98765432 consistency/check/foo
+ EOF
+ if [ $? -ne 31 ]; then
+ echo "Internal error" >&2
+ exit 2
+ fi
+}
+
+#set -x
+eval '
+severity() {
+ case $2 in
+'"$(
+
+ ( echo "$severities"
+ echo "consistency/check/* 15" # For the consistency test
+ ) \
+ | sed -e '/^#/d' -e '/^$/d' \
+ | while read glob severity; do
+ echo " ($glob) _rc=$severity ;;"
+ done
+
+)"'
+ (*) _rc=8 ;;
+ esac
+
+ # Is a particular severity defined for this symbol?
+ declare severity=severity_of_$1
+ if [ -n "${!severity}" ]; then
+ ((_rc += ${!severity}))
+ fi
+
+ return $_rc
+}'
+#set +x
+
+grab_symvers_from_rpm() {(
+ # (Run in subshell to make trap work.)
+
+ tmpdir=$(mktemp -t -d ${0##*/}.XXXXXX)
+ trap "cd /; rm -rf $tmpdir" EXIT
+ cd $tmpdir
+ rpm2cpio "$file" \
+ | cpio -dim --quiet './boot/symvers-*.gz'
+ set -- boot/symvers-*.gz
+ if ! [ -e "$1" ]; then
+ echo "Failed to extract symvers-*.gz from $file" >&2
+ exit 1
+ fi
+ zcat "$1"
+)}
+
+grab_symvers() {
+ declare tag=$1 file=$2 pwd tmpdir
+
+ case "$(file -b - <"$file")" in
+ gzip*)
+ zcat "$file"
+ ;;
+ RPM*)
+ grab_symvers_from_rpm "$file"
+ ;;
+ *)
+ cat "$file"
+ ;;
+ esac \
+ | sed -e "/^#/d" -e "s/^/$tag/" \
+ | sort -k 2
+}
+
+filter_out_identical_symbols() {
+ # This expression works no matter how many columns the files have.
+ grep -v -P '^\S+ -(\S+)( \S+)+ \+\1( \S+)+$'
+}
+
+check_modified_symbols() {
+ declare -i RC=0 _rc
+ declare ignored
+
+ while read symbol tail; do
+ # Split in half no matter how many columns the files have.
+ set -- $tail ; half=$(($#/2+1))
+ version1=$1 ; version2=${!half} ; shift
+ source1=$1 ; source2=${!half} ; shift
+
+ case "$version1$version2" in
+ -\#*)
+ continue
+ ;;
+ -*+* | -*)
+ ignored=
+ case "$version1" in
+ *=\>*)
+ if [ "${version1#*=>}" = "${version2#+}" ]; then
+ version1="${version1%=>*}"
+ ignored="; ignored"
+ fi
+ ;;
+ esac
+ severity $symbol $source1 && continue
+ _rc=$?
+ if [ -z "$quiet" ]; then
+ echo -n "Warning: $source1: $symbol(${version1#-}) "
+ if [ -n "$version2" ]; then
+ echo -n "changed to $symbol(${version2#+})"
+ [ "$source1" != "$source2" ] &&
+ echo -n " and moved to $source2"
+ else
+ echo -n "removed"
|