diff options
Diffstat (limited to 'utils/sym_check')
-rw-r--r-- | utils/sym_check/sym_check/extract.py | 10 | ||||
-rw-r--r-- | utils/sym_check/sym_check/util.py | 169 | ||||
-rwxr-xr-x | utils/sym_check/sym_diff.py | 13 | ||||
-rwxr-xr-x | utils/sym_check/sym_extract.py | 5 |
4 files changed, 194 insertions, 3 deletions
diff --git a/utils/sym_check/sym_check/extract.py b/utils/sym_check/sym_check/extract.py index 7bafd8ec4c549..d132e22822bb8 100644 --- a/utils/sym_check/sym_check/extract.py +++ b/utils/sym_check/sym_check/extract.py @@ -12,9 +12,11 @@ extract - A set of function that extract symbol lists from shared libraries. """ import distutils.spawn import sys +import re from sym_check import util +extract_ignore_names = ['_init', '_fini'] class NMExtractor(object): """ @@ -65,7 +67,8 @@ class NMExtractor(object): return None new_sym = { 'name': bits[0], - 'type': bits[1] + 'type': bits[1], + 'is_defined': (bits[1].lower() != 'u') } new_sym['name'] = new_sym['name'].replace('@@', '@') new_sym = self._transform_sym_type(new_sym) @@ -81,6 +84,8 @@ class NMExtractor(object): """ if sym is None or len(sym) < 2: return False + if sym['name'] in extract_ignore_names: + return False bad_types = ['t', 'b', 'r', 'd', 'w'] return (sym['type'] not in bad_types and sym['name'] not in ['__bss_start', '_end', '_edata']) @@ -148,8 +153,11 @@ class ReadElfExtractor(object): 'name': parts[7], 'size': int(parts[2]), 'type': parts[3], + 'is_defined': (parts[6] != 'UND') } assert new_sym['type'] in ['OBJECT', 'FUNC', 'NOTYPE'] + if new_sym['name'] in extract_ignore_names: + continue if new_sym['type'] == 'NOTYPE': continue if new_sym['type'] == 'FUNC': diff --git a/utils/sym_check/sym_check/util.py b/utils/sym_check/sym_check/util.py index 6ae71b01080ae..9543984673cc7 100644 --- a/utils/sym_check/sym_check/util.py +++ b/utils/sym_check/sym_check/util.py @@ -12,7 +12,7 @@ import distutils.spawn import signal import subprocess import sys - +import re def execute_command(cmd, input_str=None): """ @@ -79,9 +79,9 @@ def write_syms(sym_list, out=None, names_only=False): """ out_str = '' out_list = sym_list + out_list.sort(key=lambda x: x['name']) 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: @@ -135,3 +135,168 @@ def extract_or_load(filename): if is_library_file(filename): return sym_check.extract.extract_symbols(filename) return read_syms_from_file(filename) + +def adjust_mangled_name(name): + if not name.startswith('__Z'): + return name + return name[1:] + +new_delete_std_symbols = [ + '_Znam', + '_Znwm', + '_ZdaPv', + '_ZdaPvm', + '_ZdlPv', + '_ZdlPvm' +] + +cxxabi_symbols = [ + '___dynamic_cast', + '___gxx_personality_v0', + '_ZTIDi', + '_ZTIDn', + '_ZTIDs', + '_ZTIPDi', + '_ZTIPDn', + '_ZTIPDs', + '_ZTIPKDi', + '_ZTIPKDn', + '_ZTIPKDs', + '_ZTIPKa', + '_ZTIPKb', + '_ZTIPKc', + '_ZTIPKd', + '_ZTIPKe', + '_ZTIPKf', + '_ZTIPKh', + '_ZTIPKi', + '_ZTIPKj', + '_ZTIPKl', + '_ZTIPKm', + '_ZTIPKs', + '_ZTIPKt', + '_ZTIPKv', + '_ZTIPKw', + '_ZTIPKx', + '_ZTIPKy', + '_ZTIPa', + '_ZTIPb', + '_ZTIPc', + '_ZTIPd', + '_ZTIPe', + '_ZTIPf', + '_ZTIPh', + '_ZTIPi', + '_ZTIPj', + '_ZTIPl', + '_ZTIPm', + '_ZTIPs', + '_ZTIPt', + '_ZTIPv', + '_ZTIPw', + '_ZTIPx', + '_ZTIPy', + '_ZTIa', + '_ZTIb', + '_ZTIc', + '_ZTId', + '_ZTIe', + '_ZTIf', + '_ZTIh', + '_ZTIi', + '_ZTIj', + '_ZTIl', + '_ZTIm', + '_ZTIs', + '_ZTIt', + '_ZTIv', + '_ZTIw', + '_ZTIx', + '_ZTIy', + '_ZTSDi', + '_ZTSDn', + '_ZTSDs', + '_ZTSPDi', + '_ZTSPDn', + '_ZTSPDs', + '_ZTSPKDi', + '_ZTSPKDn', + '_ZTSPKDs', + '_ZTSPKa', + '_ZTSPKb', + '_ZTSPKc', + '_ZTSPKd', + '_ZTSPKe', + '_ZTSPKf', + '_ZTSPKh', + '_ZTSPKi', + '_ZTSPKj', + '_ZTSPKl', + '_ZTSPKm', + '_ZTSPKs', + '_ZTSPKt', + '_ZTSPKv', + '_ZTSPKw', + '_ZTSPKx', + '_ZTSPKy', + '_ZTSPa', + '_ZTSPb', + '_ZTSPc', + '_ZTSPd', + '_ZTSPe', + '_ZTSPf', + '_ZTSPh', + '_ZTSPi', + '_ZTSPj', + '_ZTSPl', + '_ZTSPm', + '_ZTSPs', + '_ZTSPt', + '_ZTSPv', + '_ZTSPw', + '_ZTSPx', + '_ZTSPy', + '_ZTSa', + '_ZTSb', + '_ZTSc', + '_ZTSd', + '_ZTSe', + '_ZTSf', + '_ZTSh', + '_ZTSi', + '_ZTSj', + '_ZTSl', + '_ZTSm', + '_ZTSs', + '_ZTSt', + '_ZTSv', + '_ZTSw', + '_ZTSx', + '_ZTSy' +] + +def is_stdlib_symbol_name(name): + name = adjust_mangled_name(name) + if re.search("@GLIBC|@GCC", name): + return False + if re.search('(St[0-9])|(__cxa)|(__cxxabi)', name): + return True + if name in new_delete_std_symbols: + return True + if name in cxxabi_symbols: + return True + if name.startswith('_Z'): + return True + return False + +def filter_stdlib_symbols(syms): + stdlib_symbols = [] + other_symbols = [] + for s in syms: + canon_name = adjust_mangled_name(s['name']) + if not is_stdlib_symbol_name(canon_name): + assert not s['is_defined'] and "found defined non-std symbol" + other_symbols += [s] + else: + stdlib_symbols += [s] + return stdlib_symbols, other_symbols diff --git a/utils/sym_check/sym_diff.py b/utils/sym_check/sym_diff.py index 69c340028c6ba..842e908dd42ea 100755 --- a/utils/sym_check/sym_diff.py +++ b/utils/sym_check/sym_diff.py @@ -24,6 +24,13 @@ def main(): help='Only print symbol names', action='store_true', default=False) parser.add_argument( + '--removed-only', dest='removed_only', + help='Only print removed symbols', + action='store_true', default=False) + parser.add_argument('--only-stdlib-symbols', dest='only_stdlib', + help="Filter all symbols not related to the stdlib", + action='store_true', default=False) + parser.add_argument( '-o', '--output', dest='output', help='The output file. stdout is used if not given', type=str, action='store', default=None) @@ -40,7 +47,13 @@ def main(): old_syms_list = util.extract_or_load(args.old_syms) new_syms_list = util.extract_or_load(args.new_syms) + if args.only_stdlib: + old_syms_list, _ = util.filter_stdlib_symbols(old_syms_list) + new_syms_list, _ = util.filter_stdlib_symbols(new_syms_list) + added, removed, changed = diff.diff(old_syms_list, new_syms_list) + if args.removed_only: + added = {} report, is_break = diff.report_diff(added, removed, changed, names_only=args.names_only, demangle=args.demangle) diff --git a/utils/sym_check/sym_extract.py b/utils/sym_check/sym_extract.py index a0fbb3e6341a9..27765679ed809 100755 --- a/utils/sym_check/sym_extract.py +++ b/utils/sym_check/sym_extract.py @@ -25,11 +25,16 @@ def main(): parser.add_argument('--names-only', dest='names_only', help='Output only the name of the symbol', action='store_true', default=False) + parser.add_argument('--only-stdlib-symbols', dest='only_stdlib', + help="Filter all symbols not related to the stdlib", + action='store_true', default=False) args = parser.parse_args() if args.output is not None: print('Extracting symbols from %s to %s.' % (args.library, args.output)) syms = extract.extract_symbols(args.library) + if args.only_stdlib: + syms, other_syms = util.filter_stdlib_symbols(syms) util.write_syms(syms, out=args.output, names_only=args.names_only) |