Home | History | Annotate | Download | only in mac
      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 """
      7 Dumps a list of files with static initializers. Use with release builds.
      8 
      9 Usage:
     10   tools/mac/dump-static-initializers.py out/Release/Chromium\ Framework.framework.dSYM/Contents/Resources/DWARF/Chromium\ Framework 
     11 
     12 Do NOT use mac_strip_release=0 or component=shared_library if you want to use
     13 this script.
     14 """
     15 
     16 import optparse
     17 import re
     18 import subprocess
     19 import sys
     20 
     21 # Matches for example:
     22 # [     1] 000001ca 64 (N_SO         ) 00     0000   0000000000000000 'test.cc'
     23 dsymutil_file_re = re.compile("N_SO.*'([^']*)'")
     24 
     25 # Matches for example:
     26 # [     2] 000001d2 66 (N_OSO        ) 00     0001   000000004ed856a0 '/Volumes/MacintoshHD2/src/chrome-git/src/test.o'
     27 dsymutil_o_file_re = re.compile("N_OSO.*'([^']*)'")
     28 
     29 # Matches for example:
     30 # [     8] 00000233 24 (N_FUN        ) 01     0000   0000000000001b40 '__GLOBAL__I_s'
     31 # [185989] 00dc69ef 26 (N_STSYM      ) 02     0000   00000000022e2290 '__GLOBAL__I_a'
     32 dsymutil_re = re.compile(r"(?:N_FUN|N_STSYM).*\s[0-9a-f]*\s'__GLOBAL__I_")
     33 
     34 def ParseDsymutil(binary):
     35   """Given a binary, prints source and object filenames for files with
     36   static initializers.
     37   """
     38 
     39   child = subprocess.Popen(['dsymutil', '-s', binary], stdout=subprocess.PIPE)
     40   for line in child.stdout:
     41     file_match = dsymutil_file_re.search(line)
     42     if file_match:
     43       current_filename = file_match.group(1)
     44     else:
     45       o_file_match = dsymutil_o_file_re.search(line)
     46       if o_file_match:
     47         current_o_filename = o_file_match.group(1)
     48       else:
     49         match = dsymutil_re.search(line)
     50         if match:
     51           print current_filename
     52           print current_o_filename
     53           print
     54 
     55 
     56 def main():
     57   parser = optparse.OptionParser(usage='%prog filename')
     58   opts, args = parser.parse_args()
     59   if len(args) != 1:
     60     parser.error('missing filename argument')
     61     return 1
     62   binary = args[0]
     63 
     64   ParseDsymutil(binary)
     65   return 0
     66 
     67 
     68 if '__main__' == __name__:
     69   sys.exit(main())
     70