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
|
|
|
|