unwcheck.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. #!/usr/bin/python
  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. #
  14. import os
  15. import re
  16. import sys
  17. if len(sys.argv) != 2:
  18. print("Usage: %s FILE" % sys.argv[0])
  19. sys.exit(2)
  20. readelf = os.getenv("READELF", "readelf")
  21. start_pattern = re.compile("<([^>]*)>: \[0x([0-9a-f]+)-0x([0-9a-f]+)\]")
  22. rlen_pattern = re.compile(".*rlen=([0-9]+)")
  23. def check_func (func, slots, rlen_sum):
  24. if slots != rlen_sum:
  25. global num_errors
  26. num_errors += 1
  27. if not func: func = "[%#x-%#x]" % (start, end)
  28. print("ERROR: %s: %lu slots, total region length = %lu" % (func, slots, rlen_sum))
  29. return
  30. num_funcs = 0
  31. num_errors = 0
  32. func = False
  33. slots = 0
  34. rlen_sum = 0
  35. for line in os.popen("%s -u %s" % (readelf, sys.argv[1])):
  36. m = start_pattern.match(line)
  37. if m:
  38. check_func(func, slots, rlen_sum)
  39. func = m.group(1)
  40. start = int(m.group(2), 16)
  41. end = int(m.group(3), 16)
  42. slots = 3 * (end - start) / 16
  43. rlen_sum = 0
  44. num_funcs += 1
  45. else:
  46. m = rlen_pattern.match(line)
  47. if m:
  48. rlen_sum += int(m.group(1))
  49. check_func(func, slots, rlen_sum)
  50. if num_errors == 0:
  51. print("No errors detected in %u functions." % num_funcs)
  52. else:
  53. if num_errors > 1:
  54. err="errors"
  55. else:
  56. err="error"
  57. print("%u %s detected in %u functions." % (num_errors, err, num_funcs))
  58. sys.exit(1)