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