1#!/usr/bin/env python 2# 3# Usage: unwcheck.py FILE 4# 5# This script checks the unwind info of each function in file FILE 6# and verifies that the sum of the region-lengths matches the total 7# length of the function. 8# 9# Based on a shell/awk script originally written by Harish Patil, 10# which was converted to Perl by Matthew Chapman, which was converted 11# to Python by David Mosberger. 12# 13import os 14import re 15import sys 16 17if len(sys.argv) != 2: 18 print "Usage: %s FILE" % sys.argv[0] 19 sys.exit(2) 20 21readelf = os.getenv("READELF", "readelf") 22 23start_pattern = re.compile("<([^>]*)>: \[0x([0-9a-f]+)-0x([0-9a-f]+)\]") 24rlen_pattern = re.compile(".*rlen=([0-9]+)") 25 26def check_func (func, slots, rlen_sum): 27 if slots != rlen_sum: 28 global num_errors 29 num_errors += 1 30 if not func: func = "[%#x-%#x]" % (start, end) 31 print "ERROR: %s: %lu slots, total region length = %lu" % (func, slots, rlen_sum) 32 return 33 34num_funcs = 0 35num_errors = 0 36func = False 37slots = 0 38rlen_sum = 0 39for line in os.popen("%s -u %s" % (readelf, sys.argv[1])): 40 m = start_pattern.match(line) 41 if m: 42 check_func(func, slots, rlen_sum) 43 44 func = m.group(1) 45 start = long(m.group(2), 16) 46 end = long(m.group(3), 16) 47 slots = 3 * (end - start) / 16 48 rlen_sum = 0L 49 num_funcs += 1 50 else: 51 m = rlen_pattern.match(line) 52 if m: 53 rlen_sum += long(m.group(1)) 54check_func(func, slots, rlen_sum) 55 56if num_errors == 0: 57 print "No errors detected in %u functions." % num_funcs 58else: 59 if num_errors > 1: 60 err="errors" 61 else: 62 err="error" 63 print "%u %s detected in %u functions." % (num_errors, err, num_funcs) 64 sys.exit(1) 65