#!/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 determining 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)
