Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(319)

Side by Side Diff: tools/linux/dump-static-initializers.py

Issue 8207001: dump-static-initializers: Add an option to show the size of static initializers, and change insta... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: add options to show only variables in bss Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Dump functions called by static intializers in a Linux Release binary. 6 """Dump functions called by static intializers in a Linux Release binary.
7 7
8 Usage example: 8 Usage example:
9 tools/linux/dump-static-intializers.py out/Release/chrome 9 tools/linux/dump-static-intializers.py out/Release/chrome
10 10
(...skipping 29 matching lines...) Expand all
40 self.cppfilt = subprocess.Popen(['c++filt'], 40 self.cppfilt = subprocess.Popen(['c++filt'],
41 stdin=subprocess.PIPE, 41 stdin=subprocess.PIPE,
42 stdout=subprocess.PIPE) 42 stdout=subprocess.PIPE)
43 43
44 def Demangle(self, sym): 44 def Demangle(self, sym):
45 """Given mangled symbol |sym|, return its demangled form.""" 45 """Given mangled symbol |sym|, return its demangled form."""
46 self.cppfilt.stdin.write(sym + '\n') 46 self.cppfilt.stdin.write(sym + '\n')
47 return self.cppfilt.stdout.readline().strip() 47 return self.cppfilt.stdout.readline().strip()
48 48
49 49
50 # Regex matching nm output for the symbols we're interested in. 50 # Regex matching nm output.
51 # Example line: 51 # Example bss section symbol:
52 # 0000000001919920 0000000000000008 b _ZN12_GLOBAL__N_119g_nine_box_prelightE 52 # 0000000004021a20 0000000000000008 b _ZGVZL16GetProcessLocalevE6locale
53 bss_section_re = re.compile(r'\S+ \S+ b (.*)')
54 def GetBSSFromNm(binary):
55 """Given a binary, return a set of symbols from the BSS section."""
56 bss_section = set()
57 nm = subprocess.Popen(['nm', '-S', binary], stdout=subprocess.PIPE)
58 for line in nm.stdout:
59 match = bss_section_re.match(line)
60 if match:
61 bss_section.add(match.groups()[0])
62 return bss_section
63
64
65 # Regex matching nm output.
66 # Example static initializer section line to yield:
67 # 0000000001919920 0000000000000008 t _ZN12_GLOBAL__I_safe_browsing_service.cc
53 nm_re = re.compile(r'(\S+) (\S+) t _GLOBAL__I_(.*)') 68 nm_re = re.compile(r'(\S+) (\S+) t _GLOBAL__I_(.*)')
54 def ParseNm(binary): 69 def GetStaticInitializersFromNm(binary):
55 """Given a binary, yield static initializers as (start, size, file) pairs.""" 70 """Given a binary, yield static initializers as (start, size, file) pairs."""
56 71
57 nm = subprocess.Popen(['nm', '-S', binary], stdout=subprocess.PIPE) 72 nm = subprocess.Popen(['nm', '-S', binary], stdout=subprocess.PIPE)
58 for line in nm.stdout: 73 for line in nm.stdout:
59 match = nm_re.match(line) 74 match = nm_re.match(line)
60 if match: 75 if match:
61 addr, size, filename = match.groups() 76 addr, size, filename = match.groups()
62 yield int(addr, 16), int(size, 16), filename 77 yield int(addr, 16), int(size, 16), filename
63 78
64 79
(...skipping 26 matching lines...) Expand all
91 continue 106 continue
92 107
93 for ref in sorted(refs): 108 for ref in sorted(refs):
94 yield ref 109 yield ref
95 110
96 111
97 def main(): 112 def main():
98 parser = optparse.OptionParser(usage='%prog filename') 113 parser = optparse.OptionParser(usage='%prog filename')
99 parser.add_option('-i', '--instances', dest='calculate_instances', 114 parser.add_option('-i', '--instances', dest='calculate_instances',
100 action='store_true', default=False, 115 action='store_true', default=False,
101 help='Only print out the number of static initializers') 116 help='Only print out the number of files with '
117 'static initializers')
118 parser.add_option('-I', '--show-instances', dest='show_instances',
119 action='store_true', default=False,
120 help='Only print out the static initializers without'
121 'references')
102 opts, args = parser.parse_args() 122 opts, args = parser.parse_args()
103 if len(args) != 1: 123 if len(args) != 1:
104 parser.error('missing filename argument') 124 parser.error('missing filename argument')
105 return 1 125 return 1
126 if opts.calculate_instances and opts.show_instances:
127 parser.error('-i and -I are mutually exclusive')
128 return 1
106 binary = args[0] 129 binary = args[0]
107 130
108 demangler = Demangler() 131 demangler = Demangler()
109 static_initializers_count = 0 132 static_initializers_count = 0
110 for addr, size, filename in ParseNm(binary): 133 if opts.calculate_instances or opts.show_instances:
134 bss_section = GetBSSFromNm(binary)
135
136 for addr, size, filename in GetStaticInitializersFromNm(binary):
111 if size == 2: 137 if size == 2:
112 # gcc generates a two-byte 'repz retq' initializer when there is nothing 138 # gcc generates a two-byte 'repz retq' initializer when there is nothing
113 # to do. jyasskin tells me this is fixed in gcc 4.6. 139 # to do. jyasskin tells me this is fixed in gcc 4.6.
114 # Two bytes is too small to do anything, so just ignore it. 140 # Two bytes is too small to do anything, so just ignore it.
115 continue 141 continue
116 142
117 if (opts.calculate_instances): 143 if opts.calculate_instances:
118 static_initializers_count += 1 144 for ref in ExtractSymbolReferences(binary, addr, addr+size):
119 continue 145 if ref in bss_section:
120 146 static_initializers_count += 1
121 print '%s (initializer offset 0x%x size 0x%x)' % (filename, addr, size) 147 else:
122 for ref in ExtractSymbolReferences(binary, addr, addr+size): 148 print '%s (initializer offset 0x%x size 0x%x)' % (filename, addr, size)
123 ref = demangler.Demangle(ref) 149 for ref in ExtractSymbolReferences(binary, addr, addr+size):
124 if ref in NOTES: 150 if opts.show_instances and ref not in bss_section:
125 print ' ', '%s [%s]' % (ref, NOTES[ref]) 151 continue
126 else: 152 ref = demangler.Demangle(ref)
127 print ' ', ref 153 if ref in NOTES:
128 print 154 print ' ', '%s [%s]' % (ref, NOTES[ref])
155 else:
156 print ' ', ref
157 print
129 158
130 if opts.calculate_instances: 159 if opts.calculate_instances:
131 print static_initializers_count 160 print static_initializers_count
161
132 return 0 162 return 0
133 163
134 164
135 if '__main__' == __name__: 165 if '__main__' == __name__:
136 sys.exit(main()) 166 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698