diff options
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.py | 128 |
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) |