#!/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='Enable sandboxing in the translator')
    argparser.add_argument('--enable-block-profile',
                           dest='enable_block_profile', action='store_true',
                           help='Enable basic block profiling.')
    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 []) +
                 (['-enable-block-profile'] if
                      args.enable_block_profile and not 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()
