brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.3 KiB · 9d14a58 Raw
131 lines · python
1#!/usr/bin/env python2 3import subprocess4import optparse5import os6import os.path7import re8import sys9 10 11def extract_exe_symbol_names(arch, exe_path, match_str):12    command = 'dsymutil --arch %s -s "%s" | grep "%s" | colrm 1 69' % (13        arch,14        exe_path,15        match_str,16    )17    (command_exit_status, command_output) = subprocess.getstatusoutput(command)18    if command_exit_status == 0:19        if command_output:20            return command_output[0:-1].split("'\n")21        else:22            print("error: command returned no output")23    else:24        print(25            "error: command failed with exit status %i\n    command: %s"26            % (command_exit_status, command)27        )28    return list()29 30 31def verify_api(all_args):32    """Verify the API in the specified library is valid given one or more binaries."""33    usage = "usage: verify_api --library <path> [ --library <path> ...] executable1 [executable2 ...]"34    description = """Verify the API in the specified library is valid given one or more binaries.35 36    Example:37 38        verify_api.py --library ~/Documents/src/lldb/build/Debug/LLDB.framework/LLDB --arch x86_64 /Applications/Xcode.app/Contents/PlugIns/DebuggerLLDB.ideplugin/Contents/MacOS/DebuggerLLDB --api-regex lldb39    """40    parser = optparse.OptionParser(41        description=description, prog="verify_api", usage=usage42    )43    parser.add_option(44        "-v",45        "--verbose",46        action="store_true",47        dest="verbose",48        help="display verbose debug info",49        default=False,50    )51    parser.add_option(52        "-a",53        "--arch",54        type="string",55        action="append",56        dest="archs",57        help="architecture to use when checking the api",58    )59    parser.add_option(60        "-r",61        "--api-regex",62        type="string",63        dest="api_regex_str",64        help="Exclude any undefined symbols that do not match this regular expression when searching for missing APIs.",65    )66    parser.add_option(67        "-l",68        "--library",69        type="string",70        action="append",71        dest="libraries",72        help="Specify one or more libraries that will contain all needed APIs for the executables.",73    )74    (options, args) = parser.parse_args(all_args)75 76    api_external_symbols = list()77    if options.archs:78        for arch in options.archs:79            for library in options.libraries:80                external_symbols = extract_exe_symbol_names(81                    arch, library, "(     SECT EXT)"82                )83                if external_symbols:84                    for external_symbol in external_symbols:85                        api_external_symbols.append(external_symbol)86                else:87                    sys.exit(1)88    else:89        print("error: must specify one or more architectures with the --arch option")90        sys.exit(4)91    if options.verbose:92        print("API symbols:")93        for i, external_symbol in enumerate(api_external_symbols):94            print("[%u] %s" % (i, external_symbol))95 96    api_regex = None97    if options.api_regex_str:98        api_regex = re.compile(options.api_regex_str)99 100    for arch in options.archs:101        for exe_path in args:102            print('Verifying (%s) "%s"...' % (arch, exe_path))103            exe_errors = 0104            undefined_symbols = extract_exe_symbol_names(105                arch, exe_path, "(     UNDF EXT)"106            )107            for undefined_symbol in undefined_symbols:108                if api_regex:109                    match = api_regex.search(undefined_symbol)110                    if not match:111                        if options.verbose:112                            print("ignoring symbol: %s" % (undefined_symbol))113                        continue114                if undefined_symbol in api_external_symbols:115                    if options.verbose:116                        print("verified symbol: %s" % (undefined_symbol))117                else:118                    print("missing symbol: %s" % (undefined_symbol))119                    exe_errors += 1120            if exe_errors:121                print(122                    "error: missing %u API symbols from %s"123                    % (exe_errors, options.libraries)124                )125            else:126                print("success")127 128 129if __name__ == "__main__":130    verify_api(sys.argv[1:])131