6c3baf
#!/usr/bin/python
6c3baf
#
6c3baf
# check-kabi - Red Hat kABI reference checking tool
6c3baf
#
6c3baf
# We use this script to check against reference Module.kabi files.
6c3baf
#
6c3baf
# Author: Jon Masters <jcm@redhat.com>
6c3baf
# Copyright (C) 2007-2009 Red Hat, Inc.
6c3baf
#
6c3baf
# This software may be freely redistributed under the terms of the GNU
6c3baf
# General Public License (GPL).
6c3baf
6c3baf
# Changelog:
6c3baf
# 
6c3baf
# 2009/08/15 - Updated for use in RHEL6.
6c3baf
# 2007/06/13 - Initial rewrite in python by Jon Masters.
6c3baf
6c3baf
__author__ = "Jon Masters <jcm@redhat.com>"
6c3baf
__version__ = "2.0"
6c3baf
__date__ = "2009/08/15"
6c3baf
__copyright__ = "Copyright (C) 2007-2009 Red Hat, Inc"
6c3baf
__license__ = "GPL"
6c3baf
6c3baf
import getopt
6c3baf
import os
6c3baf
import re
6c3baf
import string
6c3baf
import sys
6c3baf
6c3baf
true = 1
6c3baf
false = 0
6c3baf
6c3baf
def load_symvers(symvers,filename):
6c3baf
	"""Load a Module.symvers file."""
6c3baf
6c3baf
	symvers_file = open(filename,"r")
6c3baf
6c3baf
	while true:
6c3baf
		in_line = symvers_file.readline()
6c3baf
		if in_line == "":
6c3baf
			break
6c3baf
		if in_line == "\n":
6c3baf
			continue
6c3baf
		checksum,symbol,directory,type = string.split(in_line)
6c3baf
6c3baf
		symvers[symbol] = in_line[0:-1]
6c3baf
6c3baf
def load_kabi(kabi,filename):
6c3baf
	"""Load a Module.kabi file."""
6c3baf
6c3baf
	kabi_file = open(filename,"r")
6c3baf
6c3baf
	while true:
6c3baf
		in_line = kabi_file.readline()
6c3baf
		if in_line == "":
6c3baf
			break
6c3baf
		if in_line == "\n":
6c3baf
			continue
6c3baf
		checksum,symbol,directory,type = string.split(in_line)
6c3baf
6c3baf
		kabi[symbol] = in_line[0:-1]
6c3baf
6c3baf
def check_kabi(symvers,kabi):
6c3baf
	"""Check Module.kabi and Module.symvers files."""
6c3baf
6c3baf
	fail=0
6c3baf
	warn=0
6c3baf
	changed_symbols=[]
6c3baf
	moved_symbols=[]
6c3baf
6c3baf
	for symbol in kabi:
6c3baf
		abi_hash,abi_sym,abi_dir,abi_type = string.split(kabi[symbol])
6c3baf
		if symvers.has_key(symbol):
6c3baf
			sym_hash,sym_sym,sym_dir,sym_type = string.split(symvers[symbol])
6c3baf
			if abi_hash != sym_hash:
6c3baf
				fail=1
6c3baf
				changed_symbols.append(symbol)
6c3baf
6c3baf
			if abi_dir != sym_dir:
6c3baf
				warn=1
6c3baf
				moved_symbols.append(symbol)
6c3baf
		else:
6c3baf
			fail=1
6c3baf
			changed_symbols.append(symbol)
6c3baf
6c3baf
	if fail:
6c3baf
		print "*** ERROR - ABI BREAKAGE WAS DETECTED ***"
6c3baf
		print ""
6c3baf
		print "The following symbols have been changed (this will cause an ABI breakage):"
6c3baf
		print ""
6c3baf
		for symbol in changed_symbols:
6c3baf
			print symbol
6c3baf
		print ""
6c3baf
6c3baf
	if warn:
6c3baf
		print "*** WARNING - ABI SYMBOLS MOVED ***"
6c3baf
		print ""
6c3baf
		print "The following symbols moved (typically caused by moving a symbol from being"
6c3baf
		print "provided by the kernel vmlinux out to a loadable module):"
6c3baf
		print ""
6c3baf
		for symbol in moved_symbols:
6c3baf
			print symbol
6c3baf
		print ""
6c3baf
6c3baf
	"""Halt the build, if we got errors and/or warnings. In either case,
6c3baf
	   double-checkig is required to avoid introducing / concealing
6c3baf
	   KABI inconsistencies."""
6c3baf
	if fail or warn:
6c3baf
		sys.exit(1)
6c3baf
	sys.exit(0)
6c3baf
6c3baf
def usage():
6c3baf
	print """
6c3baf
check-kabi: check Module.kabi and Module.symvers files.
6c3baf
6c3baf
	check-kabi [ -k Module.kabi ] [ -s Module.symvers ]
6c3baf
6c3baf
"""
6c3baf
6c3baf
if __name__ == "__main__":
6c3baf
6c3baf
	symvers_file = ""
6c3baf
	kabi_file = ""
6c3baf
6c3baf
	opts, args = getopt.getopt(sys.argv[1:], 'hk:s:')
6c3baf
6c3baf
	for o, v in opts:
6c3baf
		if o == "-s":
6c3baf
			symvers_file = v
6c3baf
		if o == "-h":
6c3baf
			usage()
6c3baf
			sys.exit(0)
6c3baf
		if o == "-k":
6c3baf
			kabi_file = v
6c3baf
	
6c3baf
	if (symvers_file == "") or (kabi_file == ""):
6c3baf
		usage()
6c3baf
		sys.exit(1)
6c3baf
6c3baf
	symvers={}
6c3baf
	kabi={}
6c3baf
6c3baf
	load_symvers(symvers,symvers_file)
6c3baf
	load_kabi(kabi,kabi_file)
6c3baf
	check_kabi(symvers,kabi)
6c3baf