xref: /netbsd-src/external/apache2/llvm/dist/libcxx/utils/libcxx/sym_check/util.py (revision 4d6fc14bc9b0c5bf3e30be318c143ee82cadd108)
1*4d6fc14bSjoerg#===----------------------------------------------------------------------===##
2*4d6fc14bSjoerg#
3*4d6fc14bSjoerg# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*4d6fc14bSjoerg# See https://llvm.org/LICENSE.txt for license information.
5*4d6fc14bSjoerg# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*4d6fc14bSjoerg#
7*4d6fc14bSjoerg#===----------------------------------------------------------------------===##
8*4d6fc14bSjoerg
9*4d6fc14bSjoergimport ast
10*4d6fc14bSjoergimport distutils.spawn
11*4d6fc14bSjoergimport sys
12*4d6fc14bSjoergimport re
13*4d6fc14bSjoergimport libcxx.util
14*4d6fc14bSjoergfrom pprint import pformat
15*4d6fc14bSjoerg
16*4d6fc14bSjoerg
17*4d6fc14bSjoergdef read_syms_from_list(slist):
18*4d6fc14bSjoerg    """
19*4d6fc14bSjoerg    Read a list of symbols from a list of strings.
20*4d6fc14bSjoerg    Each string is one symbol.
21*4d6fc14bSjoerg    """
22*4d6fc14bSjoerg    return [ast.literal_eval(l) for l in slist]
23*4d6fc14bSjoerg
24*4d6fc14bSjoerg
25*4d6fc14bSjoergdef read_syms_from_file(filename):
26*4d6fc14bSjoerg    """
27*4d6fc14bSjoerg    Read a list of symbols in from a file.
28*4d6fc14bSjoerg    """
29*4d6fc14bSjoerg    with open(filename, 'r') as f:
30*4d6fc14bSjoerg        data = f.read()
31*4d6fc14bSjoerg    return read_syms_from_list(data.splitlines())
32*4d6fc14bSjoerg
33*4d6fc14bSjoerg
34*4d6fc14bSjoergdef read_exclusions(filename):
35*4d6fc14bSjoerg    with open(filename, 'r') as f:
36*4d6fc14bSjoerg        data = f.read()
37*4d6fc14bSjoerg    lines = [l.strip() for l in data.splitlines() if l.strip()]
38*4d6fc14bSjoerg    lines = [l for l in lines if not l.startswith('#')]
39*4d6fc14bSjoerg    return lines
40*4d6fc14bSjoerg
41*4d6fc14bSjoerg
42*4d6fc14bSjoergdef write_syms(sym_list, out=None, names_only=False, filter=None):
43*4d6fc14bSjoerg    """
44*4d6fc14bSjoerg    Write a list of symbols to the file named by out.
45*4d6fc14bSjoerg    """
46*4d6fc14bSjoerg    out_str = ''
47*4d6fc14bSjoerg    out_list = sym_list
48*4d6fc14bSjoerg    out_list.sort(key=lambda x: x['name'])
49*4d6fc14bSjoerg    if filter is not None:
50*4d6fc14bSjoerg        out_list = filter(out_list)
51*4d6fc14bSjoerg    if names_only:
52*4d6fc14bSjoerg        out_list = [sym['name'] for sym in out_list]
53*4d6fc14bSjoerg    for sym in out_list:
54*4d6fc14bSjoerg        # Use pformat for consistent ordering of keys.
55*4d6fc14bSjoerg        out_str += pformat(sym, width=100000) + '\n'
56*4d6fc14bSjoerg    if out is None:
57*4d6fc14bSjoerg        sys.stdout.write(out_str)
58*4d6fc14bSjoerg    else:
59*4d6fc14bSjoerg        with open(out, 'w') as f:
60*4d6fc14bSjoerg            f.write(out_str)
61*4d6fc14bSjoerg
62*4d6fc14bSjoerg
63*4d6fc14bSjoerg_cppfilt_exe = distutils.spawn.find_executable('c++filt')
64*4d6fc14bSjoerg
65*4d6fc14bSjoerg
66*4d6fc14bSjoergdef demangle_symbol(symbol):
67*4d6fc14bSjoerg    if _cppfilt_exe is None:
68*4d6fc14bSjoerg        return symbol
69*4d6fc14bSjoerg    out, _, exit_code = libcxx.util.executeCommandVerbose(
70*4d6fc14bSjoerg        [_cppfilt_exe], input=symbol)
71*4d6fc14bSjoerg    if exit_code != 0:
72*4d6fc14bSjoerg        return symbol
73*4d6fc14bSjoerg    return out
74*4d6fc14bSjoerg
75*4d6fc14bSjoerg
76*4d6fc14bSjoergdef is_elf(filename):
77*4d6fc14bSjoerg    with open(filename, 'rb') as f:
78*4d6fc14bSjoerg        magic_bytes = f.read(4)
79*4d6fc14bSjoerg    return magic_bytes == b'\x7fELF'
80*4d6fc14bSjoerg
81*4d6fc14bSjoerg
82*4d6fc14bSjoergdef is_mach_o(filename):
83*4d6fc14bSjoerg    with open(filename, 'rb') as f:
84*4d6fc14bSjoerg        magic_bytes = f.read(4)
85*4d6fc14bSjoerg    return magic_bytes in [
86*4d6fc14bSjoerg        b'\xfe\xed\xfa\xce',  # MH_MAGIC
87*4d6fc14bSjoerg        b'\xce\xfa\xed\xfe',  # MH_CIGAM
88*4d6fc14bSjoerg        b'\xfe\xed\xfa\xcf',  # MH_MAGIC_64
89*4d6fc14bSjoerg        b'\xcf\xfa\xed\xfe',  # MH_CIGAM_64
90*4d6fc14bSjoerg        b'\xca\xfe\xba\xbe',  # FAT_MAGIC
91*4d6fc14bSjoerg        b'\xbe\xba\xfe\xca'   # FAT_CIGAM
92*4d6fc14bSjoerg    ]
93*4d6fc14bSjoerg
94*4d6fc14bSjoerg
95*4d6fc14bSjoergdef is_library_file(filename):
96*4d6fc14bSjoerg    if sys.platform == 'darwin':
97*4d6fc14bSjoerg        return is_mach_o(filename)
98*4d6fc14bSjoerg    else:
99*4d6fc14bSjoerg        return is_elf(filename)
100*4d6fc14bSjoerg
101*4d6fc14bSjoerg
102*4d6fc14bSjoergdef extract_or_load(filename):
103*4d6fc14bSjoerg    import libcxx.sym_check.extract
104*4d6fc14bSjoerg    if is_library_file(filename):
105*4d6fc14bSjoerg        return libcxx.sym_check.extract.extract_symbols(filename)
106*4d6fc14bSjoerg    return read_syms_from_file(filename)
107*4d6fc14bSjoerg
108*4d6fc14bSjoergdef adjust_mangled_name(name):
109*4d6fc14bSjoerg    if not name.startswith('__Z'):
110*4d6fc14bSjoerg        return name
111*4d6fc14bSjoerg    return name[1:]
112*4d6fc14bSjoerg
113*4d6fc14bSjoergnew_delete_std_symbols = [
114*4d6fc14bSjoerg    '_Znam',
115*4d6fc14bSjoerg    '_Znwm',
116*4d6fc14bSjoerg    '_ZdaPv',
117*4d6fc14bSjoerg    '_ZdaPvm',
118*4d6fc14bSjoerg    '_ZdlPv',
119*4d6fc14bSjoerg    '_ZdlPvm'
120*4d6fc14bSjoerg]
121*4d6fc14bSjoerg
122*4d6fc14bSjoergcxxabi_symbols = [
123*4d6fc14bSjoerg    '___dynamic_cast',
124*4d6fc14bSjoerg    '___gxx_personality_v0',
125*4d6fc14bSjoerg    '_ZTIDi',
126*4d6fc14bSjoerg    '_ZTIDn',
127*4d6fc14bSjoerg    '_ZTIDs',
128*4d6fc14bSjoerg    '_ZTIPDi',
129*4d6fc14bSjoerg    '_ZTIPDn',
130*4d6fc14bSjoerg    '_ZTIPDs',
131*4d6fc14bSjoerg    '_ZTIPKDi',
132*4d6fc14bSjoerg    '_ZTIPKDn',
133*4d6fc14bSjoerg    '_ZTIPKDs',
134*4d6fc14bSjoerg    '_ZTIPKa',
135*4d6fc14bSjoerg    '_ZTIPKb',
136*4d6fc14bSjoerg    '_ZTIPKc',
137*4d6fc14bSjoerg    '_ZTIPKd',
138*4d6fc14bSjoerg    '_ZTIPKe',
139*4d6fc14bSjoerg    '_ZTIPKf',
140*4d6fc14bSjoerg    '_ZTIPKh',
141*4d6fc14bSjoerg    '_ZTIPKi',
142*4d6fc14bSjoerg    '_ZTIPKj',
143*4d6fc14bSjoerg    '_ZTIPKl',
144*4d6fc14bSjoerg    '_ZTIPKm',
145*4d6fc14bSjoerg    '_ZTIPKs',
146*4d6fc14bSjoerg    '_ZTIPKt',
147*4d6fc14bSjoerg    '_ZTIPKv',
148*4d6fc14bSjoerg    '_ZTIPKw',
149*4d6fc14bSjoerg    '_ZTIPKx',
150*4d6fc14bSjoerg    '_ZTIPKy',
151*4d6fc14bSjoerg    '_ZTIPa',
152*4d6fc14bSjoerg    '_ZTIPb',
153*4d6fc14bSjoerg    '_ZTIPc',
154*4d6fc14bSjoerg    '_ZTIPd',
155*4d6fc14bSjoerg    '_ZTIPe',
156*4d6fc14bSjoerg    '_ZTIPf',
157*4d6fc14bSjoerg    '_ZTIPh',
158*4d6fc14bSjoerg    '_ZTIPi',
159*4d6fc14bSjoerg    '_ZTIPj',
160*4d6fc14bSjoerg    '_ZTIPl',
161*4d6fc14bSjoerg    '_ZTIPm',
162*4d6fc14bSjoerg    '_ZTIPs',
163*4d6fc14bSjoerg    '_ZTIPt',
164*4d6fc14bSjoerg    '_ZTIPv',
165*4d6fc14bSjoerg    '_ZTIPw',
166*4d6fc14bSjoerg    '_ZTIPx',
167*4d6fc14bSjoerg    '_ZTIPy',
168*4d6fc14bSjoerg    '_ZTIa',
169*4d6fc14bSjoerg    '_ZTIb',
170*4d6fc14bSjoerg    '_ZTIc',
171*4d6fc14bSjoerg    '_ZTId',
172*4d6fc14bSjoerg    '_ZTIe',
173*4d6fc14bSjoerg    '_ZTIf',
174*4d6fc14bSjoerg    '_ZTIh',
175*4d6fc14bSjoerg    '_ZTIi',
176*4d6fc14bSjoerg    '_ZTIj',
177*4d6fc14bSjoerg    '_ZTIl',
178*4d6fc14bSjoerg    '_ZTIm',
179*4d6fc14bSjoerg    '_ZTIs',
180*4d6fc14bSjoerg    '_ZTIt',
181*4d6fc14bSjoerg    '_ZTIv',
182*4d6fc14bSjoerg    '_ZTIw',
183*4d6fc14bSjoerg    '_ZTIx',
184*4d6fc14bSjoerg    '_ZTIy',
185*4d6fc14bSjoerg    '_ZTSDi',
186*4d6fc14bSjoerg    '_ZTSDn',
187*4d6fc14bSjoerg    '_ZTSDs',
188*4d6fc14bSjoerg    '_ZTSPDi',
189*4d6fc14bSjoerg    '_ZTSPDn',
190*4d6fc14bSjoerg    '_ZTSPDs',
191*4d6fc14bSjoerg    '_ZTSPKDi',
192*4d6fc14bSjoerg    '_ZTSPKDn',
193*4d6fc14bSjoerg    '_ZTSPKDs',
194*4d6fc14bSjoerg    '_ZTSPKa',
195*4d6fc14bSjoerg    '_ZTSPKb',
196*4d6fc14bSjoerg    '_ZTSPKc',
197*4d6fc14bSjoerg    '_ZTSPKd',
198*4d6fc14bSjoerg    '_ZTSPKe',
199*4d6fc14bSjoerg    '_ZTSPKf',
200*4d6fc14bSjoerg    '_ZTSPKh',
201*4d6fc14bSjoerg    '_ZTSPKi',
202*4d6fc14bSjoerg    '_ZTSPKj',
203*4d6fc14bSjoerg    '_ZTSPKl',
204*4d6fc14bSjoerg    '_ZTSPKm',
205*4d6fc14bSjoerg    '_ZTSPKs',
206*4d6fc14bSjoerg    '_ZTSPKt',
207*4d6fc14bSjoerg    '_ZTSPKv',
208*4d6fc14bSjoerg    '_ZTSPKw',
209*4d6fc14bSjoerg    '_ZTSPKx',
210*4d6fc14bSjoerg    '_ZTSPKy',
211*4d6fc14bSjoerg    '_ZTSPa',
212*4d6fc14bSjoerg    '_ZTSPb',
213*4d6fc14bSjoerg    '_ZTSPc',
214*4d6fc14bSjoerg    '_ZTSPd',
215*4d6fc14bSjoerg    '_ZTSPe',
216*4d6fc14bSjoerg    '_ZTSPf',
217*4d6fc14bSjoerg    '_ZTSPh',
218*4d6fc14bSjoerg    '_ZTSPi',
219*4d6fc14bSjoerg    '_ZTSPj',
220*4d6fc14bSjoerg    '_ZTSPl',
221*4d6fc14bSjoerg    '_ZTSPm',
222*4d6fc14bSjoerg    '_ZTSPs',
223*4d6fc14bSjoerg    '_ZTSPt',
224*4d6fc14bSjoerg    '_ZTSPv',
225*4d6fc14bSjoerg    '_ZTSPw',
226*4d6fc14bSjoerg    '_ZTSPx',
227*4d6fc14bSjoerg    '_ZTSPy',
228*4d6fc14bSjoerg    '_ZTSa',
229*4d6fc14bSjoerg    '_ZTSb',
230*4d6fc14bSjoerg    '_ZTSc',
231*4d6fc14bSjoerg    '_ZTSd',
232*4d6fc14bSjoerg    '_ZTSe',
233*4d6fc14bSjoerg    '_ZTSf',
234*4d6fc14bSjoerg    '_ZTSh',
235*4d6fc14bSjoerg    '_ZTSi',
236*4d6fc14bSjoerg    '_ZTSj',
237*4d6fc14bSjoerg    '_ZTSl',
238*4d6fc14bSjoerg    '_ZTSm',
239*4d6fc14bSjoerg    '_ZTSs',
240*4d6fc14bSjoerg    '_ZTSt',
241*4d6fc14bSjoerg    '_ZTSv',
242*4d6fc14bSjoerg    '_ZTSw',
243*4d6fc14bSjoerg    '_ZTSx',
244*4d6fc14bSjoerg    '_ZTSy'
245*4d6fc14bSjoerg]
246*4d6fc14bSjoerg
247*4d6fc14bSjoergdef is_stdlib_symbol_name(name, sym):
248*4d6fc14bSjoerg    name = adjust_mangled_name(name)
249*4d6fc14bSjoerg    if re.search("@GLIBC|@GCC", name):
250*4d6fc14bSjoerg        # Only when symbol is defined do we consider it ours
251*4d6fc14bSjoerg        return sym['is_defined']
252*4d6fc14bSjoerg    if re.search('(St[0-9])|(__cxa)|(__cxxabi)', name):
253*4d6fc14bSjoerg        return True
254*4d6fc14bSjoerg    if name in new_delete_std_symbols:
255*4d6fc14bSjoerg        return True
256*4d6fc14bSjoerg    if name in cxxabi_symbols:
257*4d6fc14bSjoerg        return True
258*4d6fc14bSjoerg    if name.startswith('_Z'):
259*4d6fc14bSjoerg        return True
260*4d6fc14bSjoerg    return False
261*4d6fc14bSjoerg
262*4d6fc14bSjoergdef filter_stdlib_symbols(syms):
263*4d6fc14bSjoerg    stdlib_symbols = []
264*4d6fc14bSjoerg    other_symbols = []
265*4d6fc14bSjoerg    for s in syms:
266*4d6fc14bSjoerg        canon_name = adjust_mangled_name(s['name'])
267*4d6fc14bSjoerg        if not is_stdlib_symbol_name(canon_name, s):
268*4d6fc14bSjoerg            other_symbols += [s]
269*4d6fc14bSjoerg        else:
270*4d6fc14bSjoerg            stdlib_symbols += [s]
271*4d6fc14bSjoerg    return stdlib_symbols, other_symbols
272