summaryrefslogtreecommitdiff
path: root/chromium/buildtools/third_party/libc++/trunk/utils/sym_check/sym_check/util.py
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/buildtools/third_party/libc++/trunk/utils/sym_check/sym_check/util.py')
-rw-r--r--chromium/buildtools/third_party/libc++/trunk/utils/sym_check/sym_check/util.py128
1 files changed, 128 insertions, 0 deletions
diff --git a/chromium/buildtools/third_party/libc++/trunk/utils/sym_check/sym_check/util.py b/chromium/buildtools/third_party/libc++/trunk/utils/sym_check/sym_check/util.py
new file mode 100644
index 00000000000..1d3b424f6f3
--- /dev/null
+++ b/chromium/buildtools/third_party/libc++/trunk/utils/sym_check/sym_check/util.py
@@ -0,0 +1,128 @@
+import ast
+import distutils.spawn
+import signal
+import subprocess
+import sys
+
+
+def execute_command(cmd, input_str=None):
+ """
+ Execute a command, capture and return its output.
+ """
+ kwargs = {
+ 'stdin': subprocess.PIPE,
+ 'stdout': subprocess.PIPE,
+ 'stderr': subprocess.PIPE,
+ }
+ p = subprocess.Popen(cmd, **kwargs)
+ out, err = p.communicate(input=input_str)
+ exitCode = p.wait()
+ if exitCode == -signal.SIGINT:
+ raise KeyboardInterrupt
+ return out, err, exitCode
+
+
+def execute_command_verbose(cmd, input_str=None):
+ """
+ Execute a command and print its output on failure.
+ """
+ out, err, exitCode = execute_command(cmd, input_str=input_str)
+ if exitCode != 0:
+ report = "Command: %s\n" % ' '.join(["'%s'" % a for a in cmd])
+ report += "Exit Code: %d\n" % exitCode
+ if out:
+ report += "Standard Output:\n--\n%s--" % out
+ if err:
+ report += "Standard Error:\n--\n%s--" % err
+ report += "\n\nFailed!"
+ sys.stderr.write('%s\n' % report)
+ return out, err, exitCode
+
+
+def read_syms_from_list(slist):
+ """
+ Read a list of symbols from a list of strings.
+ Each string is one symbol.
+ """
+ return [ast.literal_eval(l) for l in slist]
+
+
+def read_syms_from_file(filename):
+ """
+ Read a list of symbols in from a file.
+ """
+ with open(filename, 'r') as f:
+ data = f.read()
+ return read_syms_from_list(data.splitlines())
+
+
+def read_blacklist(filename):
+ with open(filename, 'r') as f:
+ data = f.read()
+ lines = [l.strip() for l in data.splitlines() if l.strip()]
+ lines = [l for l in lines if not l.startswith('#')]
+ return lines
+
+
+def write_syms(sym_list, out=None, names_only=False):
+ """
+ Write a list of symbols to the file named by out.
+ """
+ out_str = ''
+ out_list = sym_list
+ if names_only:
+ out_list = [sym['name'] for sym in sym_list]
+ out_list.sort()
+ for sym in out_list:
+ out_str += '%s\n' % sym
+ if out is None:
+ sys.stdout.write(out_str)
+ else:
+ with open(out, 'w') as f:
+ f.write(out_str)
+
+
+_cppfilt_exe = distutils.spawn.find_executable('c++filt')
+
+
+def demangle_symbol(symbol):
+ if _cppfilt_exe is None:
+ return symbol
+ out, _, exit_code = execute_command_verbose(
+ [_cppfilt_exe], input_str=symbol)
+ if exit_code != 0:
+ return symbol
+ return out
+
+
+def is_elf(filename):
+ with open(filename, 'r') as f:
+ magic_bytes = f.read(4)
+ return magic_bytes == '\x7fELF'
+
+
+def is_mach_o(filename):
+ with open(filename, 'r') as f:
+ magic_bytes = f.read(4)
+ return magic_bytes in [
+ '\xfe\xed\xfa\xce', # MH_MAGIC
+ '\xce\xfa\xed\xfe', # MH_CIGAM
+ '\xfe\xed\xfa\xcf', # MH_MAGIC_64
+ '\xcf\xfa\xed\xfe', # MH_CIGAM_64
+ '\xca\xfe\xba\xbe', # FAT_MAGIC
+ '\xbe\xba\xfe\xca' # FAT_CIGAM
+ ]
+
+
+def is_library_file(filename):
+ if sys.platform == 'darwin':
+ return is_mach_o(filename)
+ else:
+ return is_elf(filename)
+
+
+def extract_or_load(filename):
+ import sym_check.extract
+ if is_library_file(filename):
+ return sym_check.extract.extract_symbols(filename)
+ return read_syms_from_file(filename)