1 #===----------------------------------------------------------------------===##
3 # The LLVM Compiler Infrastructure
5 # This file is dual licensed under the MIT and the University of Illinois Open
6 # Source Licenses. See LICENSE.TXT for details.
8 #===----------------------------------------------------------------------===##
11 import distutils.spawn
17 def read_syms_from_list(slist):
19 Read a list of symbols from a list of strings.
20 Each string is one symbol.
22 return [ast.literal_eval(l) for l in slist]
25 def read_syms_from_file(filename):
27 Read a list of symbols in from a file.
29 with open(filename, 'r') as f:
31 return read_syms_from_list(data.splitlines())
34 def read_blacklist(filename):
35 with open(filename, 'r') as f:
37 lines = [l.strip() for l in data.splitlines() if l.strip()]
38 lines = [l for l in lines if not l.startswith('#')]
42 def write_syms(sym_list, out=None, names_only=False):
44 Write a list of symbols to the file named by out.
48 out_list.sort(key=lambda x: x['name'])
50 out_list = [sym['name'] for sym in sym_list]
52 out_str += '%s\n' % sym
54 sys.stdout.write(out_str)
56 with open(out, 'w') as f:
60 _cppfilt_exe = distutils.spawn.find_executable('c++filt')
63 def demangle_symbol(symbol):
64 if _cppfilt_exe is None:
66 out, _, exit_code = libcxx.util.executeCommandVerbose(
67 [_cppfilt_exe], input=symbol)
74 with open(filename, 'rb') as f:
75 magic_bytes = f.read(4)
76 return magic_bytes == b'\x7fELF'
79 def is_mach_o(filename):
80 with open(filename, 'rb') as f:
81 magic_bytes = f.read(4)
82 return magic_bytes in [
83 '\xfe\xed\xfa\xce', # MH_MAGIC
84 '\xce\xfa\xed\xfe', # MH_CIGAM
85 '\xfe\xed\xfa\xcf', # MH_MAGIC_64
86 '\xcf\xfa\xed\xfe', # MH_CIGAM_64
87 '\xca\xfe\xba\xbe', # FAT_MAGIC
88 '\xbe\xba\xfe\xca' # FAT_CIGAM
92 def is_library_file(filename):
93 if sys.platform == 'darwin':
94 return is_mach_o(filename)
96 return is_elf(filename)
99 def extract_or_load(filename):
100 import libcxx.sym_check.extract
101 if is_library_file(filename):
102 return libcxx.sym_check.extract.extract_symbols(filename)
103 return read_syms_from_file(filename)
105 def adjust_mangled_name(name):
106 if not name.startswith('__Z'):
110 new_delete_std_symbols = [
121 '___gxx_personality_v0',
244 def is_stdlib_symbol_name(name):
245 name = adjust_mangled_name(name)
246 if re.search("@GLIBC|@GCC", name):
248 if re.search('(St[0-9])|(__cxa)|(__cxxabi)', name):
250 if name in new_delete_std_symbols:
252 if name in cxxabi_symbols:
254 if name.startswith('_Z'):
258 def filter_stdlib_symbols(syms):
262 canon_name = adjust_mangled_name(s['name'])
263 if not is_stdlib_symbol_name(canon_name):
264 assert not s['is_defined'] and "found defined non-std symbol"
267 stdlib_symbols += [s]
268 return stdlib_symbols, other_symbols