| Index: tools/linux/dump-static-initializers.py
|
| ===================================================================
|
| --- tools/linux/dump-static-initializers.py (revision 104532)
|
| +++ tools/linux/dump-static-initializers.py (working copy)
|
| @@ -47,11 +47,26 @@
|
| return self.cppfilt.stdout.readline().strip()
|
|
|
|
|
| -# Regex matching nm output for the symbols we're interested in.
|
| -# Example line:
|
| -# 0000000001919920 0000000000000008 b _ZN12_GLOBAL__N_119g_nine_box_prelightE
|
| +# Regex matching nm output.
|
| +# Example bss section symbol:
|
| +# 0000000004021a20 0000000000000008 b _ZGVZL16GetProcessLocalevE6locale
|
| +bss_section_re = re.compile(r'\S+ \S+ b (.*)')
|
| +def GetBSSFromNm(binary):
|
| + """Given a binary, return a set of symbols from the BSS section."""
|
| + bss_section = set()
|
| + nm = subprocess.Popen(['nm', '-S', binary], stdout=subprocess.PIPE)
|
| + for line in nm.stdout:
|
| + match = bss_section_re.match(line)
|
| + if match:
|
| + bss_section.add(match.groups()[0])
|
| + return bss_section
|
| +
|
| +
|
| +# Regex matching nm output.
|
| +# Example static initializer section line to yield:
|
| +# 0000000001919920 0000000000000008 t _ZN12_GLOBAL__I_safe_browsing_service.cc
|
| nm_re = re.compile(r'(\S+) (\S+) t _GLOBAL__I_(.*)')
|
| -def ParseNm(binary):
|
| +def GetStaticInitializersFromNm(binary):
|
| """Given a binary, yield static initializers as (start, size, file) pairs."""
|
|
|
| nm = subprocess.Popen(['nm', '-S', binary], stdout=subprocess.PIPE)
|
| @@ -98,37 +113,52 @@
|
| parser = optparse.OptionParser(usage='%prog filename')
|
| parser.add_option('-i', '--instances', dest='calculate_instances',
|
| action='store_true', default=False,
|
| - help='Only print out the number of static initializers')
|
| + help='Only print out the number of files with '
|
| + 'static initializers')
|
| + parser.add_option('-I', '--show-instances', dest='show_instances',
|
| + action='store_true', default=False,
|
| + help='Only print out the static initializers without'
|
| + 'references')
|
| opts, args = parser.parse_args()
|
| if len(args) != 1:
|
| parser.error('missing filename argument')
|
| return 1
|
| + if opts.calculate_instances and opts.show_instances:
|
| + parser.error('-i and -I are mutually exclusive')
|
| + return 1
|
| binary = args[0]
|
|
|
| demangler = Demangler()
|
| static_initializers_count = 0
|
| - for addr, size, filename in ParseNm(binary):
|
| + if opts.calculate_instances or opts.show_instances:
|
| + bss_section = GetBSSFromNm(binary)
|
| +
|
| + for addr, size, filename in GetStaticInitializersFromNm(binary):
|
| if size == 2:
|
| # gcc generates a two-byte 'repz retq' initializer when there is nothing
|
| # to do. jyasskin tells me this is fixed in gcc 4.6.
|
| # Two bytes is too small to do anything, so just ignore it.
|
| continue
|
|
|
| - if (opts.calculate_instances):
|
| - static_initializers_count += 1
|
| - continue
|
| + if opts.calculate_instances:
|
| + for ref in ExtractSymbolReferences(binary, addr, addr+size):
|
| + if ref in bss_section:
|
| + static_initializers_count += 1
|
| + else:
|
| + print '%s (initializer offset 0x%x size 0x%x)' % (filename, addr, size)
|
| + for ref in ExtractSymbolReferences(binary, addr, addr+size):
|
| + if opts.show_instances and ref not in bss_section:
|
| + continue
|
| + ref = demangler.Demangle(ref)
|
| + if ref in NOTES:
|
| + print ' ', '%s [%s]' % (ref, NOTES[ref])
|
| + else:
|
| + print ' ', ref
|
| + print
|
|
|
| - print '%s (initializer offset 0x%x size 0x%x)' % (filename, addr, size)
|
| - for ref in ExtractSymbolReferences(binary, addr, addr+size):
|
| - ref = demangler.Demangle(ref)
|
| - if ref in NOTES:
|
| - print ' ', '%s [%s]' % (ref, NOTES[ref])
|
| - else:
|
| - print ' ', ref
|
| - print
|
| -
|
| if opts.calculate_instances:
|
| print static_initializers_count
|
| +
|
| return 0
|
|
|
|
|
|
|