summaryrefslogtreecommitdiff
path: root/build/util/count_ctors.py
diff options
context:
space:
mode:
Diffstat (limited to 'build/util/count_ctors.py')
-rw-r--r--build/util/count_ctors.py64
1 files changed, 64 insertions, 0 deletions
diff --git a/build/util/count_ctors.py b/build/util/count_ctors.py
new file mode 100644
index 0000000000..6a3a870685
--- /dev/null
+++ b/build/util/count_ctors.py
@@ -0,0 +1,64 @@
+
+#!/usr/bin/python
+import json
+import re
+import subprocess
+import sys
+
+def count_ctors(filename):
+ proc = subprocess.Popen(
+ ['readelf', '-W', '-S', filename], stdout=subprocess.PIPE)
+
+ # Some versions of ld produce both .init_array and .ctors. So we have
+ # to check for both.
+ n_init_array_ctors = 0
+ have_init_array = False
+ n_ctors_ctors = 0
+ have_ctors = False
+
+ for line in proc.stdout:
+ f = line.split()
+ if len(f) != 11:
+ continue
+ # Don't try to int()-parse the header line for the section summaries.
+ if not re.match("\\[\\d+\\]", f[0]):
+ continue
+ section_name, contents, size, align = f[1], f[2], int(f[5], 16), int(f[10])
+ if section_name == ".ctors" and contents == "PROGBITS":
+ have_ctors = True
+ # Subtract 2 for the uintptr_t(-1) header and the null terminator.
+ n_ctors_ctors = size / align - 2
+ if section_name == ".init_array" and contents == "INIT_ARRAY":
+ have_init_array = True
+ n_init_array_ctors = size / align
+
+ if have_init_array:
+ # Even if we have .ctors, we shouldn't have any constructors in .ctors.
+ # Complain if .ctors does not look how we expect it to.
+ if have_ctors and n_ctors_ctors != 0:
+ print >>sys.stderr, "Unexpected .ctors contents for", filename
+ sys.exit(1)
+ return n_init_array_ctors
+ if have_ctors:
+ return n_ctors_ctors
+
+ # We didn't find anything; somebody switched initialization mechanisms on
+ # us, or the binary is completely busted. Complain either way.
+ print >>sys.stderr, "Couldn't find .init_array or .ctors in", filename
+ sys.exit(1)
+
+if __name__ == '__main__':
+ for f in sys.argv[1:]:
+ perfherder_data = {
+ "framework": {"name": "build_metrics"},
+ "suites": [{
+ "name": "compiler_metrics",
+ "subtests": [{
+ "name": "num_constructors",
+ "value": count_ctors(f),
+ "alertThreshold": 0.25
+ }]}
+ ]
+ }
+ print "PERFHERDER_DATA: %s" % json.dumps(perfherder_data)
+