dump-static-initializers.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #!/usr/bin/env python
  2. # Copyright (c) 2013 The Chromium Authors. All rights reserved.
  3. # Use of this source code is governed by a BSD-style license that can be
  4. # found in the LICENSE file.
  5. """
  6. Dumps a list of files with static initializers. Use with release builds.
  7. Usage:
  8. tools/mac/dump-static-initializers.py out/Release/Chromium\ Framework.framework.dSYM/Contents/Resources/DWARF/Chromium\ Framework
  9. Do NOT use mac_strip_release=0 or component=shared_library if you want to use
  10. this script.
  11. This is meant to be used on a dSYM file. If only an unstripped executable is
  12. present, use show_mod_init_func.py.
  13. """
  14. from __future__ import print_function
  15. import optparse
  16. import re
  17. import subprocess
  18. import sys
  19. # Matches for example:
  20. # [ 1] 000001ca 64 (N_SO ) 00 0000 0000000000000000 'test.cc'
  21. dsymutil_file_re = re.compile("N_SO.*'([^']*)'")
  22. # Matches for example:
  23. # [ 2] 000001d2 66 (N_OSO ) 00 0001 000000004ed856a0 '/Volumes/MacintoshHD2/src/chrome-git/src/test.o'
  24. dsymutil_o_file_re = re.compile("N_OSO.*'([^']*)'")
  25. # Matches for example:
  26. # [ 8] 00000233 24 (N_FUN ) 01 0000 0000000000001b40 '__GLOBAL__I_s'
  27. # [185989] 00dc69ef 26 (N_STSYM ) 02 0000 00000000022e2290 '__GLOBAL__I_a'
  28. dsymutil_re = re.compile(r"(?:N_FUN|N_STSYM).*\s[0-9a-f]*\s'__GLOBAL__I_")
  29. def ParseDsymutil(binary):
  30. """Given a binary, prints source and object filenames for files with
  31. static initializers.
  32. """
  33. child = subprocess.Popen(['tools/clang/dsymutil/bin/dsymutil', '-s', binary],
  34. stdout=subprocess.PIPE)
  35. for line in child.stdout:
  36. file_match = dsymutil_file_re.search(line)
  37. if file_match:
  38. current_filename = file_match.group(1)
  39. else:
  40. o_file_match = dsymutil_o_file_re.search(line)
  41. if o_file_match:
  42. current_o_filename = o_file_match.group(1)
  43. else:
  44. match = dsymutil_re.search(line)
  45. if match:
  46. print(current_filename)
  47. print(current_o_filename)
  48. print()
  49. def main():
  50. parser = optparse.OptionParser(usage='%prog filename')
  51. opts, args = parser.parse_args()
  52. if len(args) != 1:
  53. parser.error('missing filename argument')
  54. return 1
  55. binary = args[0]
  56. ParseDsymutil(binary)
  57. return 0
  58. if '__main__' == __name__:
  59. sys.exit(main())