#!/usr/bin/env python2

import argparse
import os
import pipes
import re
import sys

from utils import shellcmd
from utils import FindBaseNaCl

def NewerThanOrNotThere(old_path, new_path):
    """Returns whether old_path is newer than new_path.

    Also returns true if either path doesn't exist.
    """
    if not (os.path.exists(old_path) and os.path.exists(new_path)):
        return True
    return os.path.getmtime(old_path) > os.path.getmtime(new_path)

def BuildRegex(patterns, syms):
    """Build a regular expression string for inclusion or exclusion.

    Creates a regex string from an array of patterns and an array
    of symbol names.  Each element in the patterns array is either a
    regex, or a range of entries in the symbol name array, e.g. '2:9'.
    """
    pattern_list = []
    for pattern in patterns:
        if pattern[0].isdigit() or pattern[0] == ':':
            # Legitimate symbols or regexes shouldn't start with a
            # digit or a ':', so interpret the pattern as a range.
            interval = pattern.split(':')
            if len(interval) == 1:
                # Treat singleton 'n' as 'n:n+1'.
                lower = int(interval[0])
                upper = lower + 1
            elif len(interval) == 2:
                # Handle 'a:b', 'a:', and ':b' with suitable defaults.
                lower = int(interval[0]) if len(interval[0]) else 0
                upper = int(interval[1]) if len(interval[1]) else len(syms)
            else:
                print 'Invalid range syntax: {p}'.format(p=pattern)
                exit(1)
            pattern = '$|^'.join([re.escape(p) for p in syms[lower:upper]])
        pattern_list.append('^' + pattern + '$')
    return '|'.join(pattern_list) if len(pattern_list) else '^$'

def MatchSymbol(sym, re_include, re_exclude, default_match):
    """Match a symbol name against inclusion/exclusion rules.

    Returns True or False depending on whether the given symbol
    matches the compiled include or exclude regexes.  The default is
    returned if neither the include nor the exclude regex matches.
    """
    if re_exclude.match(sym):
        # Always honor an explicit exclude before considering
        # includes.
        return False
    if re_include.match(sym):
        return True
    return default_match

def AddOptionalArgs(argparser):
    argparser.add_argument('--force', dest='force', action='store_true',
                           help='Force all re-translations of the pexe')
    argparser.add_argument('--include', '-i', default=[], dest='include',
                           action='append',
                           help='Subzero symbols to include ' +
                                '(regex or line range)')
    argparser.add_argument('--exclude', '-e', default=[], dest='exclude',
                           action='append',
                           help='Subzero symbols to exclude ' +
                                '(regex or line range)')
    argparser.add_argument('--output', '-o', default='a.out', dest='output',
                           action='store',
                           help='Output executable. Default %(default)s.')
    argparser.add_argument('-O', default='2', dest='optlevel',
                           choices=['m1', '-1', '0', '1', '2'],
                           help='Optimization level ' +
                                '(m1 and -1 are equivalent).' +
                                ' Default %(default)s.')
    argparser.add_argument('--filetype', default='iasm', dest='filetype',
                           choices=['obj', 'asm', 'iasm'],
                           help='Output file type.  Default %(default)s.')
    argparser.add_argument('--sandbox', dest='sandbox', action='store_true',
                           help='Enabled sandboxing in the translator')
    argparser.add_argument('--verbose', '-v', dest='verbose',
                           action='store_true',
                           help='Display some extra debugging output')
    argparser.add_argument('--sz', dest='sz_args', action='append', default=[],
                           help='Extra arguments for Subzero')
    argparser.add_argument('--llc', dest='llc_args', action='append',
                           default=[], help='Extra arguments for llc')

def main():
    """Create a hybrid translation from Subzero and llc.

    Takes a finalized pexe and builds a native executable as a hybrid of Subzero
    and llc translated bitcode.  Linker tricks are used to determine whether
    Subzero or llc generated symbols are used, on a per-symbol basis.

    By default, for every symbol, its Subzero version is used.  Subzero and llc
    symbols can be selectively enabled/disabled via regular expressions on the
    symbol name, or by ranges of lines in this program's auto-generated symbol
    file.

    For each symbol, the --exclude arguments are first checked (the symbol is
    'rejected' on a match), followed by the --include arguments (the symbol is
    'accepted' on a match), followed by unconditional 'rejection'.  The Subzero
    version is used for an 'accepted' symbol, and the llc version is used for a
    'rejected' symbol.

    Each --include and --exclude argument can be a regular expression or a range
    of lines in the symbol file.  Each regular expression is wrapped inside
    '^$', so if you want a substring match on 'foo', use '.*foo.*' instead.
    Ranges use python-style 'first:last' notation, so e.g. use '0:10' or ':10'
    for the first 10 lines of the file, or '1' for the second line of the file.

    If no --include or --exclude arguments are given, the executable is produced
    entirely using Subzero, without using llc or linker tricks.

    This script uses file modification timestamps to determine whether llc and
    Subzero re-translation are needed.  It checks timestamps of llc, pnacl-sz,
    and the pexe against the translated object files to determine the minimal
    work necessary.  The --force option suppresses those checks and
    re-translates everything.

    This script augments PATH so that various PNaCl and LLVM tools can be run.
    These extra paths are within the native_client tree.  When changes are made
    to these tools, copy them this way:
      cd native_client
      toolchain_build/toolchain_build_pnacl.py llvm_x86_64_linux \\
      --install=toolchain/linux_x86/pnacl_newlib_raw
    """
    argparser = argparse.ArgumentParser(
        description='    ' + main.__doc__,
        formatter_class=argparse.RawTextHelpFormatter)
    AddOptionalArgs(argparser)
    argparser.add_argument('pexe', help='Finalized pexe to translate')
    args = argparser.parse_args()
    pexe = args.pexe
    exe = args.output
    ProcessPexe(args, pexe, exe)

def ProcessPexe(args, pexe, exe):
    [pexe_base, ext] = os.path.splitext(pexe)
    if ext != '.pexe':
        pexe_base = pexe
    pexe_base_unescaped = pexe_base
    pexe_base = pipes.quote(pexe_base)
    pexe = pipes.quote(pexe)

    nacl_root = FindBaseNaCl()
    path_addition = (
        '{root}/toolchain/linux_x86/pnacl_newlib_raw/bin'
        ).format(root=nacl_root)
    os.environ['PATH'] = (
        '{dir}{sep}{path}'
        ).format(dir=path_addition, sep=os.pathsep, path=os.environ['PATH'])
    obj_llc = pexe_base + '.llc.o'
    obj_sz = pexe_base + '.sz.o'
    asm_sz = pexe_base + '.sz.s'
    obj_llc_weak = pexe_base + '.weak.llc.o'
    obj_sz_weak = pexe_base + '.weak.sz.o'
    obj_partial = obj_sz  # overridden for hybrid mode
    sym_llc = pexe_base + '.sym.llc.txt'
    sym_sz = pexe_base + '.sym.sz.txt'
    sym_sz_unescaped = pexe_base_unescaped + '.sym.sz.txt'
    whitelist_sz = pexe_base + '.wl.sz.txt'
    whitelist_sz_unescaped = pexe_base_unescaped + '.wl.sz.txt'
    pnacl_sz = (
        '{root}/toolchain_build/src/subzero/pnacl-sz'
        ).format(root=nacl_root)
    llcbin = '{base}/pnacl-llc'.format(base=path_addition)
    gold = 'le32-nacl-ld.gold'
    opt_level = args.optlevel
    opt_level_map = { 'm1':'0', '-1':'0', '0':'0', '1':'1', '2':'2' }
    hybrid = args.include or args.exclude

    if hybrid and (args.force or
                   NewerThanOrNotThere(pexe, obj_llc) or
                   NewerThanOrNotThere(llcbin, obj_llc)):
        # Only run pnacl-translate in hybrid mode.
        shellcmd(['pnacl-translate',
                  '-split-module=1',
                  '-ffunction-sections',
                  '-fdata-sections',
                  '-c',
                  '-arch', 'x86-32' if args.sandbox else 'x86-32-linux',
                  '-O' + opt_level_map[opt_level],
                  '--pnacl-driver-append-LLC_FLAGS_EXTRA=-externalize',
                  '-o', obj_llc] +
                 (['--pnacl-driver-verbose'] if args.verbose else []) +
                 args.llc_args +
                 [pexe],
                 echo=args.verbose)
        if not args.sandbox:
            shellcmd((
                'objcopy --redefine-sym _start=_user_start {obj}'
                ).format(obj=obj_llc), echo=args.verbose)
        # Generate llc syms file for consistency, even though it's not used.
        shellcmd((
            'nm {obj} | sed -n "s/.* [a-zA-Z] //p" > {sym}'
            ).format(obj=obj_llc, sym=sym_llc), echo=args.verbose)

    if (args.force or
        NewerThanOrNotThere(pexe, obj_sz) or
        NewerThanOrNotThere(pnacl_sz, obj_sz)):
        # Run pnacl-sz regardless of hybrid mode.
        shellcmd([pnacl_sz,
                  '-O' + opt_level,
                  '-bitcode-format=pnacl',
                  '-filetype=' + args.filetype,
                  '-o', obj_sz if args.filetype == 'obj' else asm_sz] +
                 (['-externalize',
                   '-ffunction-sections',
                   '-fdata-sections'] if hybrid else []) +
                 (['-sandbox'] if args.sandbox else []) +
                 args.sz_args +
                 [pexe],
                 echo=args.verbose)
        if args.filetype != 'obj':
            shellcmd((
                'llvm-mc -triple={triple} -filetype=obj -o {obj} {asm}'
                ).format(asm=asm_sz, obj=obj_sz,
                         triple='i686-nacl' if args.sandbox else 'i686'),
                     echo=args.verbose)
        if not args.sandbox:
            shellcmd((
                'objcopy --redefine-sym _start=_user_start {obj}'
                ).format(obj=obj_sz), echo=args.verbose)
        if hybrid:
            shellcmd((
                'nm {obj} | sed -n "s/.* [a-zA-Z] //p" > {sym}'
                ).format(obj=obj_sz, sym=sym_sz), echo=args.verbose)

    if hybrid:
        with open(sym_sz_unescaped) as f:
            sz_syms = f.read().splitlines()
        re_include_str = BuildRegex(args.include, sz_syms)
        re_exclude_str = BuildRegex(args.exclude, sz_syms)
        re_include = re.compile(re_include_str)
        re_exclude = re.compile(re_exclude_str)
        # If a symbol doesn't explicitly match re_include or re_exclude,
        # the default MatchSymbol() result is True, unless some --include
        # args are provided.
        default_match = not args.include

        whitelist_has_items = False
        with open(whitelist_sz_unescaped, 'w') as f:
            for sym in sz_syms:
                if MatchSymbol(sym, re_include, re_exclude, default_match):
                    f.write(sym + '\n')
                    whitelist_has_items = True
        shellcmd((
            'objcopy --weaken {obj} {weak}'
            ).format(obj=obj_sz, weak=obj_sz_weak), echo=args.verbose)
        if whitelist_has_items:
            # objcopy returns an error if the --weaken-symbols file is empty.
            shellcmd((
                'objcopy --weaken-symbols={whitelist} {obj} {weak}'
                ).format(whitelist=whitelist_sz, obj=obj_llc,
                         weak=obj_llc_weak),
                     echo=args.verbose)
        else:
            shellcmd((
                'objcopy {obj} {weak}'
                ).format(obj=obj_llc, weak=obj_llc_weak), echo=args.verbose)
        obj_partial = pexe_base + '.o'
        shellcmd((
            'ld -r -m elf_i386 -o {partial} {sz} {llc}'
            ).format(partial=obj_partial, sz=obj_sz_weak, llc=obj_llc_weak),
                 echo=args.verbose)
        shellcmd((
            'objcopy -w --localize-symbol="*" {partial}'
            ).format(partial=obj_partial), echo=args.verbose)
        shellcmd((
            'objcopy --globalize-symbol={start} {partial}'
            ).format(partial=obj_partial,
                     start='_start' if args.sandbox else '_user_start'),
                 echo=args.verbose)

    # Run the linker regardless of hybrid mode.
    linker = (
        '{root}/../third_party/llvm-build/Release+Asserts/bin/clang'
        ).format(root=nacl_root)
    if args.sandbox:
        linklib = ('{root}/toolchain/linux_x86/pnacl_newlib_raw/translator/' +
                   'x86-32/lib').format(root=nacl_root)
        shellcmd((
            '{gold} -nostdlib --no-fix-cortex-a8 --eh-frame-hdr -z text ' +
            '--build-id --entry=__pnacl_start -static ' +
            '{linklib}/crtbegin.o {partial} ' +
            '{root}/toolchain_build/src/subzero/build/runtime/' +
            'szrt_sb_x8632.o ' +
            '{linklib}/libpnacl_irt_shim_dummy.a --start-group ' +
            '{linklib}/libgcc.a {linklib}/libcrt_platform.a ' +
            '--end-group {linklib}/crtend.o --undefined=_start ' +
            '--defsym=__Sz_AbsoluteZero=0 ' +
            '-o {exe}'
            ).format(gold=gold, linklib=linklib, partial=obj_partial, exe=exe,
                     root=nacl_root),
                 echo=args.verbose)
    else:
        shellcmd((
            '{ld} -m32 {partial} -o {exe} ' +
            # Keep the rest of this command line (except szrt_native_x8632.o) in
            # sync with RunHostLD() in pnacl-translate.py.
            '{root}/toolchain/linux_x86/pnacl_newlib_raw/translator/' +
            'x86-32-linux/lib/' +
            '{{unsandboxed_irt,irt_random,irt_query_list}}.o ' +
            '{root}/toolchain_build/src/subzero/build/runtime/' +
            'szrt_native_x8632.o -lpthread -lrt ' +
            '-Wl,--defsym=__Sz_AbsoluteZero=0'
            ).format(ld=linker, partial=obj_partial, exe=exe, root=nacl_root),
                 echo=args.verbose)

    # Put the extra verbose printing at the end.
    if args.verbose:
        print 'PATH: {path}'.format(path=path_addition)
        if hybrid:
            print 'include={regex}'.format(regex=re_include_str)
            print 'exclude={regex}'.format(regex=re_exclude_str)
            print 'default_match={dm}'.format(dm=default_match)
            print 'Number of Subzero syms = {num}'.format(num=len(sz_syms))

if __name__ == '__main__':
    main()
