Example #1
0
def main(argv):
    env.update(EXTRA_ENV)
    driver_tools.ParseArgs(argv, DISPatterns)

    inputs = env.get('INPUTS')
    output = env.getone('OUTPUT')

    if len(inputs) == 0:
        Log.Fatal("No input files given")

    if len(inputs) > 1 and output != '':
        Log.Fatal("Cannot have -o with multiple inputs")

    for infile in inputs:
        env.push()
        env.set('input', infile)
        env.set('output', output)

        # When we output to stdout, set redirect_stdout and set log_stdout
        # to False to bypass the driver's line-by-line handling of stdout
        # which is extremely slow when you have a lot of output

        if (filetype.IsLLVMBitcode(infile) or filetype.IsPNaClBitcode(infile)):
            bitcodetype = 'PNaCl' if filetype.IsPNaClBitcode(
                infile) else 'LLVM'
            format = bitcodetype.lower()

            if env.has('FILE_TYPE'):
                sys.stdout.write('%s: %s bitcode\n' % (infile, bitcodetype))
                continue
            env.append('FLAGS', '-bitcode-format=' + format)
            if output == '':
                # LLVM by default outputs to a file if -o is missing
                # Let's instead output to stdout
                env.set('output', '-')
                env.append('FLAGS', '-f')
            driver_tools.Run('${LLVM_DIS} ${FLAGS} ${input} -o ${output}')
        elif filetype.IsELF(infile):
            if env.has('FILE_TYPE'):
                sys.stdout.write('%s: ELF\n' % infile)
                continue
            flags = env.get('FLAGS')
            if len(flags) == 0:
                env.append('FLAGS', '-d')
            if output == '':
                # objdump to stdout
                driver_tools.Run('"${OBJDUMP}" ${FLAGS} ${input}')
            else:
                # objdump always outputs to stdout, and doesn't recognize -o
                # Let's add this feature to be consistent.
                fp = DriverOpen(output, 'w')
                driver_tools.Run('${OBJDUMP} ${FLAGS} ${input}',
                                 redirect_stdout=fp)
                DriverClose(fp)
        else:
            Log.Fatal('Unknown file type')
        env.pop()
    # only reached in case of no errors
    return 0
Example #2
0
def RunHostLD(infile, outfile):
  driver_tools.Run(['objcopy', '--redefine-sym', '_start=_user_start', infile])
  lib_dir = env.getone('BASE_LIB_NATIVE') + 'linux-x86-32'
  driver_tools.Run(['gcc', '-m32', infile,
                    os.path.join(lib_dir, 'unsandboxed_irt.o'),
                    '-lpthread',
                    '-lrt',  # For clock_gettime()
                    '-o', outfile])
Example #3
0
def RunHostLD(infile, outfile):
    if env.getone('TARGET_OS') == 'linux':
        driver_tools.Run(
            ['objcopy', '--redefine-sym', '_start=_user_start', infile])
    lib_dir = (env.getone('BASE_LIB_NATIVE') +
               'x86-32-%s' % env.getone('TARGET_OS'))
    args = [
        'gcc', '-m32', infile, '-o', outfile,
        os.path.join(lib_dir, 'unsandboxed_irt.o'), '-lpthread'
    ]
    if env.getone('TARGET_OS') == 'linux':
        args.append('-lrt')  # For clock_gettime()
    driver_tools.Run(args)
Example #4
0
def main(argv):
    env.update(EXTRA_ENV)
    driver_tools.ParseArgs(argv, PATTERNS)

    inputs = env.get('INPUTS')

    if len(inputs) == 0:
        Log.Fatal("No input files given")

    for infile in inputs:
        env.push()
        env.set('input', infile)

        # For frozen PNaCl bitcode, use 'llvm-nm -bitcode-format=pnacl'. For all
        # other formats, use the binutils nm with our gold plugin.
        if filetype.IsPNaClBitcode(infile):
            env.set('TOOLNAME', '${LLVM_NM}')
            env.append('FLAGS', '-bitcode-format=pnacl')
        else:
            env.set('TOOLNAME', '${NM}')
            env.append('FLAGS', '--plugin=${GOLD_PLUGIN_SO}')

        driver_tools.Run('"${TOOLNAME}" ${FLAGS} ${input}')
        env.pop()

    # only reached in case of no errors
    return 0
def main(argv):
    env.update(EXTRA_ENV)
    driver_tools.ParseArgs(argv, PATTERNS)
    inputs = env.get('INPUTS')
    if len(inputs) == 0:
        Log.Fatal("No input files given")

    for infile in inputs:
        driver_tools.CheckPathLength(infile)
        env.push()
        env.set('input', infile)
        if filetype.IsLLVMBitcode(infile):
            # Hack to support newlib build.
            # Newlib determines whether the toolchain supports .init_array, etc., by
            # compiling a small test and looking for a specific section tidbit using
            # "readelf -S". Since pnacl compiles to bitcode, readelf isn't available.
            # (there is a line: "if ${READELF} -S conftest | grep -e INIT_ARRAY"
            # in newlib's configure file).
            # TODO(sehr): we may want to implement a whole readelf on bitcode.
            flags = env.get('FLAGS')
            if len(flags) == 1 and flags[0] == '-S':
                print('INIT_ARRAY')
                return 0
            Log.Fatal('Cannot handle pnacl-readelf %s' % str(argv))
            return 1
        driver_tools.Run('"${READELF}" ${FLAGS} ${input}')
        env.pop()

    # only reached in case of no errors
    return 0
Example #6
0
def main(argv):
    env.update(EXTRA_ENV)
    driver_tools.ParseArgs(argv, StripPatterns)
    inputs = env.get('INPUTS')
    output = env.getone('OUTPUT')

    if len(inputs) > 1 and output != '':
        Log.Fatal('Cannot have -o with multiple inputs')

    if '--info' in env.get('STRIP_FLAGS'):
        code, _, _ = driver_tools.Run('${STRIP} ${STRIP_FLAGS}')
        return code

    for f in inputs:
        if output != '':
            f_output = output
        else:
            f_output = f
        if driver_tools.IsLLVMBitcode(f):
            driver_tools.RunWithEnv('${RUN_OPT}', input=f, output=f_output)
        elif driver_tools.IsELF(f) or driver_tools.IsNativeArchive(f):
            driver_tools.RunWithEnv('${RUN_STRIP}', input=f, output=f_output)
        elif driver_tools.IsBitcodeArchive(f):
            # The strip tool supports native archives, but it does not support the
            # LLVM gold plugin so cannot handle bitcode.  There is also no bitcode
            # tool like opt that support archives.
            Log.Fatal('%s: strip does not support bitcode archives',
                      pathtools.touser(f))
        else:
            Log.Fatal('%s: File is neither ELF, nor bitcode',
                      pathtools.touser(f))
    return 0
Example #7
0
def RunLLCSandboxed():
    driver_tools.CheckTranslatorPrerequisites()
    infile = env.getone('input')
    outfile = env.getone('output')
    if not driver_tools.IsPNaClBitcode(infile):
        Log.Fatal('Input to sandboxed translator must be PNaCl bitcode')
    script = MakeSelUniversalScriptForLLC(infile, outfile)
    command = (
        '${SEL_UNIVERSAL_PREFIX} ${SEL_UNIVERSAL} ${SEL_UNIVERSAL_FLAGS} '
        '-- ${LLC_SB}')
    _, stdout, _ = driver_tools.Run(
        command,
        stdin_contents=script,
        # stdout/stderr will be automatically dumped
        # upon failure
        redirect_stderr=subprocess.PIPE,
        redirect_stdout=subprocess.PIPE)
    # Get the values returned from the llc RPC to use in input to ld
    is_shared = re.search(r'output\s+0:\s+i\(([0|1])\)', stdout).group(1)
    is_shared = (is_shared == '1')
    soname = re.search(r'output\s+1:\s+s\("(.*)"\)', stdout).group(1)
    needed_str = re.search(r'output\s+2:\s+s\("(.*)"\)', stdout).group(1)
    # If the delimiter changes, this line needs to change
    needed_libs = [lib for lib in needed_str.split(r'\n') if lib]
    return is_shared, soname, needed_libs
Example #8
0
def main(argv):
    env.update(EXTRA_ENV)
    driver_tools.ParseArgs(argv, PATTERNS)

    inputs = env.get('INPUTS')

    if len(inputs) == 0:
        Log.Fatal("No input files given")

    for infile in inputs:
        driver_tools.CheckPathLength(infile)
        env.push()
        env.set('input', infile)

        # For frozen PNaCl bitcode, use 'llvm-nm -bitcode-format=pnacl'. For all
        # other formats, use the binutils nm with our gold plugin.
        # Update: llvm-nm -bitcode-format=pnacl is currently disabled.
        if filetype.IsPNaClBitcode(infile):
            Log.Fatal(
                'nm on finalized bitcode is currently disabled.\n'
                'See: https://code.google.com/p/nativeclient/issues/detail?id=3993'
            )
        else:
            env.set('TOOLNAME', '${NM}')
            env.append('FLAGS', '--plugin=${GOLD_PLUGIN_SO}')

        driver_tools.Run('"${TOOLNAME}" ${FLAGS} ${input}')
        env.pop()

    # only reached in case of no errors
    return 0
Example #9
0
def RunSandboxedCompiler(use_sz):
  driver_tools.CheckTranslatorPrerequisites()
  infile = env.getone('input')
  is_pnacl = filetype.IsPNaClBitcode(infile)
  if not is_pnacl and not env.getbool('ALLOW_LLVM_BITCODE_INPUT'):
    Log.Fatal('Translator expects finalized PNaCl bitcode. '
              'Pass --allow-llvm-bitcode-input to override.')
  threads = int(env.getone('SPLIT_MODULE'))
  command = [driver_tools.SelLdrCommand(),
             '-a', # Allow file access
             '-E NACL_IRT_PNACL_TRANSLATOR_COMPILE_INPUT=%s' % infile]
  driver_tools.AddListToEnv(command, 'NACL_IRT_PNACL_TRANSLATOR_COMPILE_OUTPUT',
                            GetObjectFiles(use_sz))
  driver_tools.AddListToEnv(command, 'NACL_IRT_PNACL_TRANSLATOR_COMPILE_ARG',
                            BuildOverrideCompilerCommandLine(is_pnacl, use_sz))
  command.extend(['-E NACL_IRT_PNACL_TRANSLATOR_COMPILE_THREADS=%d' % threads,
                  '--'])
  if use_sz:
    command.append('${PNACL_SZ_SB}')
  else:
    command.append('${LLC_SB}')
  driver_tools.Run(' '.join(command),
                   # stdout/stderr will be automatically dumped
                   # upon failure
                   redirect_stderr=subprocess.PIPE,
                   redirect_stdout=subprocess.PIPE)
Example #10
0
def RunHostLD(infile, outfile):
  if env.getone('TARGET_OS') == 'linux':
    driver_tools.Run(['objcopy', '--redefine-sym', '_start=_user_start',
                      infile])
  lib_dir = (env.getone('BASE_LIB_NATIVE')
             + 'x86-32-%s/lib' % env.getone('TARGET_OS'))
  # TODO(stichnot): Consider making fully linked executable smaller by packaging
  # the .o files into an archive, and/or building the .o files with
  # -function-sections and linking with -gc-sections.
  args = ['gcc', '-m32', infile, '-o', outfile,
          os.path.join(lib_dir, 'unsandboxed_irt.o'),
          os.path.join(lib_dir, 'irt_random.o'),
          os.path.join(lib_dir, 'irt_query_list.o'),
          os.path.join(lib_dir, 'szrt.o'),
          os.path.join(lib_dir, 'szrt_ll.o'),
          '-lm', '-lpthread']
  if env.getone('TARGET_OS') == 'linux':
    args.append('-lrt')  # For clock_gettime()
  driver_tools.Run(args)
Example #11
0
def get_help(unused_argv):
    # Set errexit=False -- Do not exit early to allow testing.
    # For some reason most the llvm tools return non-zero with --help,
    # while all of the gnu tools return 0 with --help.
    # On windows, the exit code is also inconsistent =(
    code, stdout, stderr = driver_tools.Run('${LLVM_OPT} -help',
                                            redirect_stdout=subprocess.PIPE,
                                            redirect_stderr=subprocess.STDOUT,
                                            errexit=False)
    return stdout
Example #12
0
def main(argv):
    env.update(EXTRA_ENV)
    driver_tools.ParseArgs(argv, PATTERNS)

    args = env.get('ARGS')
    input = pathtools.normalize(args[-1])
    if filetype.IsPNaClBitcode(input):
        env.append('ARGS', '--bitcode-format=pnacl')
    driver_tools.Run('"${PNACL_ABICHECK}" ${ARGS}')
    return 0
Example #13
0
def main(argv):
  env.update(EXTRA_ENV)
  driver_tools.ParseArgs(argv, ASPatterns)
  arch = driver_tools.GetArch()

  inputs = env.get('INPUTS')
  output = env.getone('OUTPUT')

  for path in inputs + [output]:
    driver_tools.CheckPathLength(path)

  num_inputs = len(inputs)
  if num_inputs > 1:
    Log.Fatal('Expecting exactly one input file')
  elif num_inputs == 1:
    the_input = inputs[0]
  else:
    # stdin
    the_input = '-'


  if arch:
    output_type = 'o'
  else:
    output_type = 'po'

  if output == '':
    output = 'a.out'

  env.push()
  env.set('input', the_input)
  env.set('output', output)

  if output_type == 'po':
    # .ll to .po
    driver_tools.Run("${RUN_LLVM_AS}")
  else:
    # .s to .o
    driver_tools.Run("${RUN_LLVM_MC}")
  env.pop()
  # only reached in case of no errors
  return 0
Example #14
0
def main(argv):
    env.update(EXTRA_ENV)
    driver_tools.ParseArgs(argv, PATTERNS)

    driver_tools.Run(
        '"${LLVM_OPT}" ${ARGS} ' +
        '${DISABLE_SIMPLIFY_LIBCALLS ? -disable-simplify-libcalls} ' +
        '${HAVE_OUTPUT ? -o ${OUTPUT}}')

    # only reached in case of no errors
    return 0
Example #15
0
def RunLLC(infile, outfile, filetype):
    env.push()
    env.setmany(input=infile, output=outfile, filetype=filetype)
    if env.getbool('SANDBOXED'):
        is_shared, soname, needed = RunLLCSandboxed()
        env.pop()
        # soname and dt_needed libs are returned from LLC and passed to LD
        driver_tools.SetBitcodeMetadata(infile, is_shared, soname, needed)
    else:
        args = ["${RUN_LLC}"]
        if driver_tools.IsPNaClBitcode(infile):
            args.append("-bitcode-format=pnacl")
        driver_tools.Run(' '.join(args))
        env.pop()
    return 0
Example #16
0
def RunCompiler(infile, outfile, outfiletype, use_sz):
  env.push()
  env.setmany(input=infile, output=outfile, outfiletype=outfiletype)
  if env.getbool('SANDBOXED'):
    RunSandboxedCompiler(use_sz)
  else:
    args = ["${RUN_SZ}" if use_sz else "${RUN_LLC}"]
    if filetype.IsPNaClBitcode(infile):
      args.append("-bitcode-format=pnacl")
    elif filetype.IsLLVMBitcode(infile):
      if not env.getbool('ALLOW_LLVM_BITCODE_INPUT'):
        Log.Fatal('Translator expects finalized PNaCl bitcode. '
                  'Pass --allow-llvm-bitcode-input to override.')
    driver_tools.Run(' '.join(args))
  env.pop()
  return 0
def RunLLCSandboxed():
    driver_tools.CheckTranslatorPrerequisites()
    infile = env.getone('input')
    outfile = env.getone('output')
    if not filetype.IsPNaClBitcode(infile):
        Log.Fatal('Input to sandboxed translator must be PNaCl bitcode')
    script = MakeSelUniversalScriptForLLC(infile, outfile)
    command = (
        '${SEL_UNIVERSAL_PREFIX} ${SEL_UNIVERSAL} ${SEL_UNIVERSAL_FLAGS} '
        '-- ${LLC_SB}')
    driver_tools.Run(
        command,
        stdin_contents=script,
        # stdout/stderr will be automatically dumped
        # upon failure
        redirect_stderr=subprocess.PIPE,
        redirect_stdout=subprocess.PIPE)
Example #18
0
def main(argv):
    env.update(EXTRA_ENV)
    driver_tools.ParseArgs(argv, PATTERNS)

    driver_tools.Run(
        '"${LLVM_OPT}" ${ARGS} ' +
        '${DISABLE_SIMPLIFY_LIBCALLS ? -disable-simplify-libcalls} ' +
        '${HAVE_OUTPUT ? -o ${OUTPUT}} ' + '${INPUT}')

    # Opt is the only tool that will modify a file in-place. If this happens we
    # need to clear the filetype cache so future invocations of the type checking
    # routines will re-check the file.
    if env.getone('INPUT') == env.getone('OUTPUT'):
        filetype.ClearFileTypeCaches()

    # only reached in case of no errors
    return 0
Example #19
0
def main(argv):
    if len(argv) == 0:
        print get_help(argv)
        return 1

    env.update(EXTRA_ENV)
    driver_tools.ParseArgs(argv, PATTERNS)

    # Note: --plugin must come after the command flags, but before the filename.
    #       (definitely confirmed that it cannot go before the command)
    #       for now assume command is just the very first args
    args = env.get('ARGS')
    command = args.pop(0)
    env.set('COMMAND', command)
    env.set('ARGS', *args)
    driver_tools.Run('"${AR}" ${COMMAND} --plugin=${GOLD_PLUGIN_SO} ${ARGS}')
    # only reached in case of no errors
    return 0
Example #20
0
def RunLLCSandboxed():
    driver_tools.CheckTranslatorPrerequisites()
    infile = env.getone('input')
    outfile = env.getone('output')
    is_pnacl = filetype.IsPNaClBitcode(infile)
    if not is_pnacl and not env.getbool('ALLOW_LLVM_BITCODE_INPUT'):
        Log.Fatal('Translator expects finalized PNaCl bitcode. '
                  'Pass --allow-llvm-bitcode-input to override.')
    script = MakeSelUniversalScriptForLLC(infile, outfile, is_pnacl)
    command = (
        '${SEL_UNIVERSAL_PREFIX} ${SEL_UNIVERSAL} ${SEL_UNIVERSAL_FLAGS} '
        '-- ${LLC_SB}')
    driver_tools.Run(
        command,
        stdin_contents=script,
        # stdout/stderr will be automatically dumped
        # upon failure
        redirect_stderr=subprocess.PIPE,
        redirect_stdout=subprocess.PIPE)
Example #21
0
def RunLLC(infile, outfile, outfiletype):
  env.push()
  env.setmany(input=infile, output=outfile, outfiletype=outfiletype)
  if env.getbool('SANDBOXED'):
    is_shared, soname, needed = RunLLCSandboxed()
    # Ignore is_shared, soname, and needed for now, since we aren't
    # dealing with bitcode shared libraries.
    env.pop()
  else:
    args = ["${RUN_LLC}"]
    if filetype.IsPNaClBitcode(infile):
      args.append("-bitcode-format=pnacl")
    elif filetype.IsLLVMBitcode(infile):
      if not env.getbool('ALLOW_LLVM_BITCODE_INPUT'):
        Log.Fatal('Translator expects finalized PNaCl bitcode. '
                  'Pass --allow-llvm-bitcode-input to override.')
    driver_tools.Run(' '.join(args))
    env.pop()
  return 0
Example #22
0
def Compress(f_input, f_output):
  """ Hill climb to smallest file.

      This code calls pnacl-compress multiple times to attempt to
      compress the file. That tool works by adding abbreviations that
      have a good likelyhood of shrinking the bitcode file. Unfortunately,
      any time abbreviations are added to PNaCl bitcode files, they can
      get larger because the addition of more abbreviations will require
      more bits to save abbreviation indices, resulting in the file
      actually increasing in size.

      To mitigate this, this driver hill climbs assuming that there
      may be local minima that are the best solution. Hence, anytime
      a local minima is reached, an additional number of attempts
      to see if we can find a smaller bitcode file, which implies
      you are moving closer to another local minima.
  """

  verbose = env.getbool('VERBOSE')

  # Number of times we will continue to retry after finding local
  # minimum file size.
  #    max_retry_count: The maximum number of retries.
  #    retry_count: The number of retries left before we give up.
  max_retry_count = int(env.getone('RETRIES'))
  retry_count = max_retry_count
  if max_retry_count < 1:
    Log.Fatal("RETRIES must be >= 1")

  # The suffix to append to the input file, to generate intermediate files.
  #    test_suffix: The prefix of the suffix.
  #    test_index: The index of the current test file (appened to test_suffix).
  test_suffix = env.getone('SUFFIX')
  test_index = 1

  # The maximum number of times we will attempt to compress the file before
  # giving up.
  max_attempts = int(env.getone('MAX_ATTEMPTS'))
  if max_attempts < 1:
    Log.Fatal("MAX_ATTEMPTS must be >= 1")

  # The result of the last attempt to compress a file.
  #    last_file: The name of the file
  #    last_size: The number of bytes in last_file.
  #    last_saved: True if we did not remove last_file.
  last_file = f_input
  last_size = pathtools.getsize(f_input)
  last_saved = True

  # Keeps track of the current best compressed file.
  current_smallest_file = last_file
  current_smallest_size = last_size

  while max_attempts > 0 and retry_count > 0:

    next_file = f_input + test_suffix + str(test_index)
    if verbose:
      print "Compressing %s: %s bytes" % (last_file, last_size)

    driver_tools.Run('"${PNACL_COMPRESS}" ' + last_file + ' -o ' + next_file)
    next_size = pathtools.getsize(next_file)
    if not last_saved:
      os.remove(last_file)

    if next_size < current_smallest_size:
      old_file = current_smallest_file
      current_smallest_file = next_file
      current_smallest_size = next_size
      if (f_input != old_file):
        os.remove(old_file)
      retry_count = max_retry_count
      next_saved = True
    else:
      next_saved = False
      retry_count -= 1
    last_file = next_file
    last_size = next_size
    last_saved = next_saved
    max_attempts -= 1
    test_index += 1

  # Install results.
  if verbose:
    print "Compressed  %s: %s bytes" % (last_file, last_size)
    print "Best        %s: %s bytes" % (current_smallest_file,
                                        current_smallest_size)
  if not last_saved:
    os.remove(last_file)

  if (f_input == f_output):
    if (f_input == current_smallest_file): return
    # python os.rename/shutil.move on Windows will raise an error when
    # dst already exists, and f_input already exists.
    f_temp = f_input + test_suffix + "0"
    shutil.move(f_input, f_temp)
    shutil.move(current_smallest_file, f_input)
    os.remove(f_temp)
  elif f_input == current_smallest_file:
    shutil.copyfile(current_smallest_file, f_output)
  else:
    shutil.move(current_smallest_file, f_output)
Example #23
0
def main(argv):
    driver_env.env.update(EXTRA_ENV)
    driver_tools.ParseArgs(argv, PATTERNS)

    driver_tools.Run('"${PNACL_ABICHECK}" ${ARGS}')
    return 0