
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@232858 91177308-0d34-0410-b5e6-96231b3b80d8
129 lines
3.2 KiB
Python
129 lines
3.2 KiB
Python
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)
|