#!/usr/bin/env python

"""A tool for extracting a list of symbols to export

When exporting symbols from a dll or exe we either need to mark the symbols in
the source code as __declspec(dllexport) or supply a list of symbols to the
linker. This program automates the latter by inspecting the symbol tables of a
list of link inputs and deciding which of those symbols need to be exported.

We can't just export all the defined symbols, as there's a limit of 65535
exported symbols and in clang we go way over that, particularly in a debug
build. Therefore a large part of the work is pruning symbols either which can't
be imported, or which we think are things that have definitions in public header
files (i.e. template instantiations) and we would get defined in the thing
importing these symbols anyway.
"""

from __future__ import print_function
import sys
import re
import os
import subprocess
import multiprocessing
import argparse

# Define functions which extract a list of symbols from a library using several
# different tools. We use subprocess.Popen and yield a symbol at a time instead
# of using subprocess.check_output and returning a list as, especially on
# Windows, waiting for the entire output to be ready can take a significant
# amount of time.

def dumpbin_get_symbols(lib):
    process = subprocess.Popen(['dumpbin','/symbols',lib], bufsize=1,
                               stdout=subprocess.PIPE, stdin=subprocess.PIPE,
                               universal_newlines=True)
    process.stdin.close()
    for line in process.stdout:
        # Look for external symbols that are defined in some section
        match = re.match("^.+SECT.+External\s+\|\s+(\S+).*$", line)
        if match:
            yield match.group(1)
    process.wait()

def nm_get_symbols(lib):
    process = subprocess.Popen(['nm',lib], bufsize=1,
                               stdout=subprocess.PIPE, stdin=subprocess.PIPE,
                               universal_newlines=True)
    process.stdin.close()
    for line in process.stdout:
        # Look for external symbols that are defined in some section
        match = re.match("^\S+\s+[BDGRSTVW]\s+(\S+)$", line)
        if match:
            yield match.group(1)
    process.wait()

def readobj_get_symbols(lib):
    process = subprocess.Popen(['llvm-readobj','-symbols',lib], bufsize=1,
                               stdout=subprocess.PIPE, stdin=subprocess.PIPE,
                               universal_newlines=True)
    process.stdin.close()
    for line in process.stdout:
        # When looking through the output of llvm-readobj we expect to see Name,
        # Section, then StorageClass, so record Name and Section when we see
        # them and decide if this is a defined external symbol when we see
        # StorageClass.
        match = re.search('Name: (\S+)', line)
        if match:
            name = match.group(1)
        match = re.search('Section: (\S+)', line)
        if match:
            section = match.group(1)
        match = re.search('StorageClass: (\S+)', line)
        if match:
            storageclass = match.group(1)
            if section != 'IMAGE_SYM_ABSOLUTE' and \
               section != 'IMAGE_SYM_UNDEFINED' and \
               storageclass == 'External':
                yield name
    process.wait()

# Define functions which determine if the target is 32-bit Windows (as that's
# where calling convention name decoration happens).

def dumpbin_is_32bit_windows(lib):
    # dumpbin /headers can output a huge amount of data (>100MB in a debug
    # build) so we read only up to the 'machine' line then close the output.
    process = subprocess.Popen(['dumpbin','/headers',lib], bufsize=1,
                               stdout=subprocess.PIPE, stdin=subprocess.PIPE,
                               universal_newlines=True)
    process.stdin.close()
    retval = False
    for line in process.stdout:
        match = re.match('.+machine \((\S+)\)', line)
        if match:
            retval = (match.group(1) == 'x86')
            break
    process.stdout.close()
    process.wait()
    return retval

def objdump_is_32bit_windows(lib):
    output = subprocess.check_output(['objdump','-f',lib],
                                     universal_newlines=True)
    for line in output:
        match = re.match('.+file format (\S+)', line)
        if match:
            return (match.group(1) == 'pe-i386')
    return False

def readobj_is_32bit_windows(lib):
    output = subprocess.check_output(['llvm-readobj','-file-headers',lib],
                                     universal_newlines=True)
    for line in output:
        match = re.match('Format: (\S+)', line)
        if match:
            return (match.group(1) == 'COFF-i386')
    return False

# MSVC mangles names to ?<identifier_mangling>@<type_mangling>. By examining the
# identifier/type mangling we can decide which symbols could possibly be
# required and which we can discard.
def should_keep_microsoft_symbol(symbol, calling_convention_decoration):
    # Keep unmangled (i.e. extern "C") names
    if not '?' in symbol:
        if calling_convention_decoration:
            # Remove calling convention decoration from names
            match = re.match('[_@]([^@]+)', symbol)
            if match:
                return match.group(1)
        return symbol
    # Function template instantiations start with ?$; keep the instantiations of
    # clang::Type::getAs, as some of them are explipict specializations that are
    # defined in clang's lib/AST/Type.cpp; discard the rest as it's assumed that
    # the definition is public
    elif re.match('\?\?\$getAs@.+@Type@clang@@', symbol):
        return symbol
    elif symbol.startswith('??$'):
        return None
    # Deleting destructors start with ?_G or ?_E and can be discarded because
    # link.exe gives you a warning telling you they can't be exported if you
    # don't
    elif symbol.startswith('??_G') or symbol.startswith('??_E'):
        return None
    # Constructors (?0) and destructors (?1) of templates (?$) are assumed to be
    # defined in headers and not required to be kept
    elif symbol.startswith('??0?$') or symbol.startswith('??1?$'):
        return None
    # An anonymous namespace is mangled as ?A(maybe hex number)@. Any symbol
    # that mentions an anonymous namespace can be discarded, as the anonymous
    # namespace doesn't exist outside of that translation unit.
    elif re.search('\?A(0x\w+)?@', symbol):
        return None
    # Keep mangled llvm:: and clang:: function symbols. How we detect these is a
    # bit of a mess and imprecise, but that avoids having to completely demangle
    # the symbol name. The outermost namespace is at the end of the identifier
    # mangling, and the identifier mangling is followed by the type mangling, so
    # we look for (llvm|clang)@@ followed by something that looks like a
    # function type mangling. To spot a function type we use (this is derived
    # from clang/lib/AST/MicrosoftMangle.cpp):
    # <function-type> ::= <function-class> <this-cvr-qualifiers>
    #                     <calling-convention> <return-type>
    #                     <argument-list> <throw-spec>
    # <function-class> ::= [A-Z]
    # <this-cvr-qualifiers> ::= [A-Z0-9_]*
    # <calling-convention> ::= [A-JQ]
    # <return-type> ::= .+
    # <argument-list> ::= X   (void)
    #                 ::= .+@ (list of types)
    #                 ::= .*Z (list of types, varargs)
    # <throw-spec> ::= exceptions are not allowed
    elif re.search('(llvm|clang)@@[A-Z][A-Z0-9_]*[A-JQ].+(X|.+@|.*Z)$', symbol):
        return symbol
    return None

# Itanium manglings are of the form _Z<identifier_mangling><type_mangling>. We
# demangle the identifier mangling to identify symbols that can be safely
# discarded.
def should_keep_itanium_symbol(symbol, calling_convention_decoration):
    # Start by removing any calling convention decoration (which we expect to
    # see on all symbols, even mangled C++ symbols)
    if calling_convention_decoration and symbol.startswith('_'):
        symbol = symbol[1:]
    # Keep unmangled names
    if not symbol.startswith('_') and not symbol.startswith('.'):
        return symbol
    # Discard manglings that aren't nested names
    match = re.match('_Z(T[VTIS])?(N.+)', symbol)
    if not match:
        return None
    # Demangle the name. If the name is too complex then we don't need to keep
    # it, but it the demangling fails then keep the symbol just in case.
    try:
        names, _ = parse_itanium_nested_name(match.group(2))
    except TooComplexName:
        return None
    if not names:
        return symbol
    # Constructors and destructors of templates classes are assumed to be
    # defined in headers and not required to be kept
    if re.match('[CD][123]', names[-1][0]) and names[-2][1]:
        return None
    # Keep the instantiations of clang::Type::getAs, as some of them are
    # explipict specializations that are defined in clang's lib/AST/Type.cpp;
    # discard any other function template instantiations as it's assumed that
    # the definition is public
    elif symbol.startswith('_ZNK5clang4Type5getAs'):
        return symbol
    elif names[-1][1]:
        return None
    # Keep llvm:: and clang:: names
    elif names[0][0] == '4llvm' or names[0][0] == '5clang':
        return symbol
    # Discard everything else
    else:
        return None

# Certain kinds of complex manglings we assume cannot be part of a public
# interface, and we handle them by raising an exception.
class TooComplexName(Exception):
    pass

# Parse an itanium mangled name from the start of a string and return a
# (name, rest of string) pair.
def parse_itanium_name(arg):
    # Check for a normal name
    match = re.match('(\d+)(.+)', arg)
    if match:
        n = int(match.group(1))
        name = match.group(1)+match.group(2)[:n]
        rest = match.group(2)[n:]
        return name, rest
    # Check for constructor/destructor names
    match = re.match('([CD][123])(.+)', arg)
    if match:
        return match.group(1), match.group(2)
    # Assume that a sequence of characters that doesn't end a nesting is an
    # operator (this is very imprecise, but appears to be good enough)
    match = re.match('([^E]+)(.+)', arg)
    if match:
        return match.group(1), match.group(2)
    # Anything else: we can't handle it
    return None, arg

# Parse an itanium mangled template argument list from the start of a string
# and throw it away, returning the rest of the string.
def skip_itanium_template(arg):
    # A template argument list starts with I
    assert arg.startswith('I'), arg
    tmp = arg[1:]
    while tmp:
        # Check for names
        match = re.match('(\d+)(.+)', tmp)
        if match:
            n = int(match.group(1))
            tmp =  match.group(2)[n:]
            continue
        # Check for substitutions
        match = re.match('S[A-Z0-9]*_(.+)', tmp)
        if match:
            tmp = match.group(1)
        # Start of a template
        elif tmp.startswith('I'):
            tmp = skip_itanium_template(tmp)
        # Start of a nested name
        elif tmp.startswith('N'):
            _, tmp = parse_itanium_nested_name(tmp)
        # Start of an expression: assume that it's too complicated
        elif tmp.startswith('L') or tmp.startswith('X'):
            raise TooComplexName
        # End of the template
        elif tmp.startswith('E'):
            return tmp[1:]
        # Something else: probably a type, skip it
        else:
            tmp = tmp[1:]
    return None

# Parse an itanium mangled nested name and transform it into a list of pairs of
# (name, is_template), returning (list, rest of string).
def parse_itanium_nested_name(arg):
    # A nested name starts with N
    assert arg.startswith('N'), arg
    ret = []

    # Skip past the N, and possibly a substitution
    match = re.match('NS[A-Z0-9]*_(.+)', arg)
    if match:
        tmp = match.group(1)
    else:
        tmp = arg[1:]

    # Skip past CV-qualifiers and ref qualifiers
    match = re.match('[rVKRO]*(.+)', tmp);
    if match:
        tmp = match.group(1)

    # Repeatedly parse names from the string until we reach the end of the
    # nested name
    while tmp:
        # An E ends the nested name
        if tmp.startswith('E'):
            return ret, tmp[1:]
        # Parse a name
        name_part, tmp = parse_itanium_name(tmp)
        if not name_part:
            # If we failed then we don't know how to demangle this
            return None, None
        is_template = False
        # If this name is a template record that, then skip the template
        # arguments
        if tmp.startswith('I'):
            tmp = skip_itanium_template(tmp)
            is_template = True
        # Add the name to the list
        ret.append((name_part, is_template))

    # If we get here then something went wrong
    return None, None

def extract_symbols(arg):
    get_symbols, should_keep_symbol, calling_convention_decoration, lib = arg
    symbols = dict()
    for symbol in get_symbols(lib):
        symbol = should_keep_symbol(symbol, calling_convention_decoration)
        if symbol:
            symbols[symbol] = 1 + symbols.setdefault(symbol,0)
    return symbols

if __name__ == '__main__':
    tool_exes = ['dumpbin','nm','objdump','llvm-readobj']
    parser = argparse.ArgumentParser(
        description='Extract symbols to export from libraries')
    parser.add_argument('--mangling', choices=['itanium','microsoft'],
                        required=True, help='expected symbol mangling scheme')
    parser.add_argument('--tools', choices=tool_exes, nargs='*',
                        help='tools to use to extract symbols and determine the'
                        ' target')
    parser.add_argument('libs', metavar='lib', type=str, nargs='+',
                        help='libraries to extract symbols from')
    parser.add_argument('-o', metavar='file', type=str, help='output to file')
    args = parser.parse_args()

    # Determine the function to use to get the list of symbols from the inputs,
    # and the function to use to determine if the target is 32-bit windows.
    tools = { 'dumpbin' : (dumpbin_get_symbols, dumpbin_is_32bit_windows),
              'nm' : (nm_get_symbols, None),
              'objdump' : (None, objdump_is_32bit_windows),
              'llvm-readobj' : (readobj_get_symbols, readobj_is_32bit_windows) }
    get_symbols = None
    is_32bit_windows = None
    # If we have a tools argument then use that for the list of tools to check
    if args.tools:
        tool_exes = args.tools
    # Find a tool to use by trying each in turn until we find one that exists
    # (subprocess.call will throw OSError when the program does not exist)
    get_symbols = None
    for exe in tool_exes:
        try:
            # Close std streams as we don't want any output and we don't
            # want the process to wait for something on stdin.
            p = subprocess.Popen([exe], stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE,
                                 stdin=subprocess.PIPE,
                                 universal_newlines=True)
            p.stdout.close()
            p.stderr.close()
            p.stdin.close()
            p.wait()
            # Keep going until we have a tool to use for both get_symbols and
            # is_32bit_windows
            if not get_symbols:
                get_symbols = tools[exe][0]
            if not is_32bit_windows:
                is_32bit_windows = tools[exe][1]
            if get_symbols and is_32bit_windows:
                break
        except OSError:
            continue
    if not get_symbols:
        print("Couldn't find a program to read symbols with", file=sys.stderr)
        exit(1)
    if not is_32bit_windows:
        print("Couldn't find a program to determing the target", file=sys.stderr)
        exit(1)

    # How we determine which symbols to keep and which to discard depends on
    # the mangling scheme
    if args.mangling == 'microsoft':
        should_keep_symbol = should_keep_microsoft_symbol
    else:
        should_keep_symbol = should_keep_itanium_symbol

    # Get the list of libraries to extract symbols from
    libs = list()
    for lib in args.libs:
        # When invoked by cmake the arguments are the cmake target names of the
        # libraries, so we need to add .lib/.a to the end and maybe lib to the
        # start to get the filename. Also allow objects.
        suffixes = ['.lib','.a','.obj','.o']
        if not any([lib.endswith(s) for s in suffixes]):
            for s in suffixes:
                if os.path.exists(lib+s):
                    lib = lib+s
                    break
                if os.path.exists('lib'+lib+s):
                    lib = 'lib'+lib+s
                    break
        if not any([lib.endswith(s) for s in suffixes]):
            print("Don't know what to do with argument "+lib, file=sys.stderr)
            exit(1)
        libs.append(lib)

    # Check if calling convention decoration is used by inspecting the first
    # library in the list
    calling_convention_decoration = is_32bit_windows(libs[0])

    # Extract symbols from libraries in parallel. This is a huge time saver when
    # doing a debug build, as there are hundreds of thousands of symbols in each
    # library.
    pool = multiprocessing.Pool()
    try:
        # Only one argument can be passed to the mapping function, and we can't
        # use a lambda or local function definition as that doesn't work on
        # windows, so create a list of tuples which duplicates the arguments
        # that are the same in all calls.
        vals = [(get_symbols, should_keep_symbol, calling_convention_decoration, x) for x in libs]
        # Do an async map then wait for the result to make sure that
        # KeyboardInterrupt gets caught correctly (see
        # http://bugs.python.org/issue8296)
        result = pool.map_async(extract_symbols, vals)
        pool.close()
        libs_symbols = result.get(3600)
    except KeyboardInterrupt:
        # On Ctrl-C terminate everything and exit
        pool.terminate()
        pool.join()
        exit(1)

    # Merge everything into a single dict
    symbols = dict()
    for this_lib_symbols in libs_symbols:
        for k,v in list(this_lib_symbols.items()):
            symbols[k] = v + symbols.setdefault(k,0)

    # Count instances of member functions of template classes, and map the
    # symbol name to the function+class. We do this under the assumption that if
    # a member function of a template class is instantiated many times it's
    # probably declared in a public header file.
    template_function_count = dict()
    template_function_mapping = dict()
    template_function_count[""] = 0
    for k in symbols:
        name = None
        if args.mangling == 'microsoft':
            # Member functions of templates start with
            # ?<fn_name>@?$<class_name>@, so we map to <fn_name>@?$<class_name>.
            # As manglings go from the innermost scope to the outermost scope
            # this means:
            #  * When we have a function member of a subclass of a template
            #    class then <fn_name> will actually contain the mangling of
            #    both the subclass and the function member. This is fine.
            #  * When we have a function member of a template subclass of a
            #    (possibly template) class then it's the innermost template
            #    subclass that becomes <class_name>. This should be OK so long
            #    as we don't have multiple classes with a template subclass of
            #    the same name.
            match = re.search("^\?(\??\w+\@\?\$\w+)\@", k)
            if match:
                name = match.group(1)
        else:
            # Find member functions of templates by demangling the name and
            # checking if the second-to-last name in the list is a template.
            match = re.match('_Z(T[VTIS])?(N.+)', k)
            if match:
                try:
                    names, _ = parse_itanium_nested_name(match.group(2))
                    if names and names[-2][1]:
                        name = ''.join([x for x,_ in names])
                except TooComplexName:
                    # Manglings that are too complex should already have been
                    # filtered out, but if we happen to somehow see one here
                    # just leave it as-is.
                    pass
        if name:
            old_count = template_function_count.setdefault(name,0)
            template_function_count[name] = old_count + 1
            template_function_mapping[k] = name
        else:
            template_function_mapping[k] = ""

    # Print symbols which both:
    #  * Appear in exactly one input, as symbols defined in multiple
    #    objects/libraries are assumed to have public definitions.
    #  * Aren't instances of member functions of templates which have been
    #    instantiated 100 times or more, which are assumed to have public
    #    definitions. (100 is an arbitrary guess here.)
    if args.o:
        outfile = open(args.o,'w')
    else:
        outfile = sys.stdout
    for k,v in list(symbols.items()):
        template_count = template_function_count[template_function_mapping[k]]
        if v == 1 and template_count < 100:
            print(k, file=outfile)
