Exemplo n.º 1
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.IsBitcode(f):
      driver_tools.RunWithEnv('${RUN_OPT}', input=f, output=f_output)
      if env.getbool('DO_WRAP'):
        driver_tools.WrapBitcode(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
Exemplo n.º 2
0
def main(argv):
    env.update(EXTRA_ENV)
    driver_tools.ParseArgs(argv, PrepPatterns)

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

    if len(inputs) != 1:
        Log.Fatal('Can only have one input')
    f_input = inputs[0]

    # Allow in-place file changes if output isn't specified..
    if output != '':
        f_output = output
    else:
        f_output = f_input

    if env.getbool('DISABLE_FINALIZE'):
        # Just copy the input file to the output file.
        if f_input != f_output:
            shutil.copyfile(f_input, f_output)
        return 0

    # Transform the file, and convert it to a PNaCl bitcode file.
    driver_tools.RunWithEnv(' '.join(['${RUN_OPT}', '--bitcode-format=pnacl']),
                            input=inputs[0],
                            output=f_output)
    return 0
Exemplo n.º 3
0
def main(argv):
    env.update(EXTRA_ENV)

    ParseArgs(argv, LDPatterns)

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

    if output == '':
        output = pathtools.normalize('a.out')

    # Expand all parameters
    # This resolves -lfoo into actual filenames,
    # and expands linker scripts into command-line arguments.
    inputs = ldtools.ExpandInputs(inputs, env.get('SEARCH_DIRS'),
                                  env.getbool('STATIC'),
                                  ldtools.LibraryTypes.NATIVE)

    env.push()
    env.set('inputs', *inputs)
    env.set('output', output)

    if env.getbool('SANDBOXED'):
        RunLDSandboxed()
    else:
        Run('${RUN_LD}')
    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
Exemplo n.º 5
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
Exemplo n.º 6
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
Exemplo n.º 7
0
def main(argv):
  env.update(EXTRA_ENV)

  ParseArgs(argv, LDPatterns)

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

  if output == '':
    output = pathtools.normalize('a.out')

  # Expand all parameters
  # This resolves -lfoo into actual filenames,
  # and expands linker scripts into command-line arguments.
  inputs = ldtools.ExpandInputs(inputs,
                                env.get('SEARCH_DIRS'),
                                env.getbool('STATIC'),
                                ldtools.LibraryTypes.NATIVE)

  env.push()
  env.set('inputs', *inputs)
  env.set('output', output)

  if env.getbool('SANDBOXED'):
    RunLDSandboxed()
  else:
    Run('${RUN_LD}')
  env.pop()
  # only reached in case of no errors
  return 0
Exemplo n.º 8
0
def main(argv):
  env.update(EXTRA_ENV)
  driver_tools.ParseArgs(argv, PrepPatterns)

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

  if len(inputs) != 1:
    Log.Fatal('Can only have one input')
  f_input = inputs[0]

  # Allow in-place file changes if output isn't specified..
  if output != '':
    f_output = output
  else:
    f_output = f_input

  if env.getbool('DISABLE_FINALIZE') or filetype.IsPNaClBitcode(f_input):
    # Just copy the input file to the output file.
    if f_input != f_output:
      shutil.copyfile(f_input, f_output)
    return 0

  opt_flags = ['-disable-opt', '-strip', '-strip-metadata',
               '--bitcode-format=pnacl', f_input, '-o', f_output]
  # Transform the file, and convert it to a PNaCl bitcode file.
  driver_tools.RunDriver('opt', opt_flags)
  return 0
Exemplo n.º 9
0
def main(argv):
  env.update(EXTRA_ENV)
  driver_tools.ParseArgs(argv, PrepPatterns)

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

  if len(inputs) != 1:
    Log.Fatal('Can only have one input')
  f_input = inputs[0]

  # Allow in-place file changes if output isn't specified..
  if output != '':
    f_output = output
  else:
    f_output = f_input

  if env.getbool('DISABLE_FINALIZE') or filetype.IsPNaClBitcode(f_input):
    # Just copy the input file to the output file.
    if f_input != f_output:
      shutil.copyfile(f_input, f_output)
    return 0

  opt_flags = ['-disable-opt', '-strip', '-strip-metadata',
               '--bitcode-format=pnacl', f_input, '-o', f_output]
  # Transform the file, and convert it to a PNaCl bitcode file.
  driver_tools.RunDriver('opt', opt_flags)
  # Compress the result if requested.
  if env.getbool('COMPRESS'):
    driver_tools.RunDriver('compress', [f_output])
  return 0
Exemplo n.º 10
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
Exemplo n.º 11
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
Exemplo n.º 12
0
def main(argv):
  env.update(EXTRA_ENV)
  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)
    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
    Run('"${READELF}" ${FLAGS} ${input}')
    env.pop()

  # only reached in case of no errors
  return 0
Exemplo n.º 13
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
Exemplo n.º 14
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.IsBitcode(f):
      driver_tools.RunWithEnv('${RUN_OPT}', input=f, output=f_output)
      if env.getbool('DO_WRAP'):
        driver_tools.WrapBitcode(f_output)
    elif driver_tools.IsELF(f):
      driver_tools.RunWithEnv('${RUN_STRIP}', input=f, output=f_output)
    else:
      Log.Fatal('%s: File is neither ELF nor bitcode', pathtools.touser(f))
  return 0
Exemplo n.º 15
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
Exemplo n.º 16
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
Exemplo n.º 17
0
def main(argv):
    if len(argv) == 0:
        print get_help(argv)
        return 1

    env.update(EXTRA_ENV)
    ParseArgs(argv, PATTERNS)
    Run('"${RANLIB}" --plugin=${GOLD_PLUGIN_SO} ${ARGS}')
    # only reached in case of no errors
    return 0
Exemplo n.º 18
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
Exemplo n.º 19
0
def main(argv):
  if len(argv) == 0:
    print get_help(argv)
    return 1

  env.update(EXTRA_ENV)
  ParseArgs(argv, PATTERNS)
  Run('"${RANLIB}" --plugin=${GOLD_PLUGIN_SO} ${ARGS}')
  # only reached in case of no errors
  return 0
Exemplo n.º 20
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;
Exemplo n.º 21
0
def main(argv):
  env.update(EXTRA_ENV)

  ParseArgs(argv, LDPatterns)

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

  if output == '':
    output = pathtools.normalize('a.out')

  # As we will modify the output file in-place for non-SFI, we output
  # the file to a temporary file first and then rename it. Otherwise,
  # build systems such as make assume the output file is ready even
  # if the last build failed during the in-place update.
  tmp_output = output + '.tmp'

  # Expand all parameters
  # This resolves -lfoo into actual filenames,
  # and expands linker scripts into command-line arguments.
  inputs = ldtools.ExpandInputs(inputs,
                                env.get('SEARCH_DIRS'),
                                True,
                                ldtools.LibraryTypes.NATIVE)

  env.push()
  env.set('inputs', *inputs)
  env.set('output', tmp_output)

  if env.getbool('SANDBOXED'):
    RunLDSandboxed()
  else:
    Run('${RUN_LD}')

  if env.getbool('NONSFI_NACL'):
    # Remove PT_INTERP in non-SFI binaries as we never use host's
    # dynamic linker/loader.
    #
    # This is necessary otherwise we get a statically linked
    # executable that is not directly runnable by Linux, because Linux
    # tries to load the non-existent file that PT_INTERP points to.
    #
    # This is fairly hacky.  It would be better if the linker provided
    # an option for omitting PT_INTERP (e.g. "--dynamic-linker ''").
    RemoveInterpProgramHeader(tmp_output)
  if driver_tools.IsWindowsPython() and os.path.exists(output):
    # On Windows (but not on Unix), the os.rename() call would fail if the
    # output file already exists.
    os.remove(output)
  os.rename(tmp_output, output)
  env.pop()
  # only reached in case of no errors
  return 0
Exemplo n.º 22
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
Exemplo n.º 23
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
Exemplo n.º 24
0
def main(argv):
    env.update(EXTRA_ENV)

    ParseArgs(argv, LDPatterns)

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

    if output == '':
        output = pathtools.normalize('a.out')

    # As we will modify the output file in-place for non-SFI, we output
    # the file to a temporary file first and then rename it. Otherwise,
    # build systems such as make assume the output file is ready even
    # if the last build failed during the in-place update.
    tmp_output = output + '.tmp'

    # Expand all parameters
    # This resolves -lfoo into actual filenames,
    # and expands linker scripts into command-line arguments.
    inputs = ldtools.ExpandInputs(inputs, env.get('SEARCH_DIRS'), True,
                                  ldtools.LibraryTypes.NATIVE)

    env.push()
    env.set('inputs', *inputs)
    env.set('output', tmp_output)

    if env.getbool('SANDBOXED'):
        RunLDSandboxed()
    else:
        Run('${RUN_LD}')

    if env.getbool('NONSFI_NACL'):
        # Remove PT_INTERP in non-SFI binaries as we never use host's
        # dynamic linker/loader.
        #
        # This is necessary otherwise we get a statically linked
        # executable that is not directly runnable by Linux, because Linux
        # tries to load the non-existent file that PT_INTERP points to.
        #
        # This is fairly hacky.  It would be better if the linker provided
        # an option for omitting PT_INTERP (e.g. "--dynamic-linker ''").
        RemoveInterpProgramHeader(tmp_output)
    if driver_tools.IsWindowsPython() and os.path.exists(output):
        # On Windows (but not on Unix), the os.rename() call would fail if the
        # output file already exists.
        os.remove(output)
    os.rename(tmp_output, output)
    env.pop()
    # only reached in case of no errors
    return 0
Exemplo n.º 25
0
def get_help(argv):
  tool = env.getone('SCRIPT_NAME')

  if '--help-full' in argv:
    # To get ${CC}, etc.
    env.update(EXTRA_ENV)
    code, stdout, stderr = Run('"${CC}" -help',
                              redirect_stdout=subprocess.PIPE,
                              redirect_stderr=subprocess.STDOUT,
                              errexit=False)
    return stdout
  else:
    return """
This is a "GCC-compatible" driver using clang under the hood.

Usage: %s [options] <inputs> ...

BASIC OPTIONS:
  -o <file>             Output to <file>.
  -E                    Only run the preprocessor.
  -S                    Generate bitcode assembly.
  -c                    Generate bitcode object.
  -I <dir>              Add header search path.
  -L <dir>              Add library search path.
  -D<key>[=<val>]       Add definition for the preprocessor.
  -W<id>                Toggle warning <id>.
  -f<feature>           Enable <feature>.
  -Wl,<arg>             Pass <arg> to the linker.
  -Xlinker <arg>        Pass <arg> to the linker.
  -Wt,<arg>             Pass <arg> to the translator.
  -Xtranslator <arg>    Pass <arg> to the translator.
  -Wp,<arg>             Pass <arg> to the preprocessor.
  -Xpreprocessor,<arg>  Pass <arg> to the preprocessor.
  -x <language>         Treat subsequent input files as having type <language>.
  -static               Produce a static executable.
  -shared               Produce a shared object.
  -Bstatic              Link subsequent libraries statically.
  -Bdynamic             Link subsequent libraries dynamically.
  -fPIC                 Ignored (only used by translator backend)
                        (accepted for compatibility).
  -pipe                 Ignored (for compatibility).
  -O<n>                 Optimation level <n>: 0, 1, 2, 3, 4 or s.
  -g                    Generate complete debug information.
  -gline-tables-only    Generate debug line-information only
                        (allowing for stack traces).
  -flimit-debug-info    Generate limited debug information.
  -save-temps           Keep intermediate compilation results.
  -v                    Verbose output / show commands.
  -h | --help           Show this help.
  --help-full           Show underlying clang driver's help message
                        (warning: not all options supported).
""" % (tool)
Exemplo n.º 26
0
def get_help(argv):
  tool = env.getone('SCRIPT_NAME')

  if '--help-full' in argv:
    # To get ${CC}, etc.
    env.update(EXTRA_ENV)
    code, stdout, stderr = Run('"${CC}" -help',
                              redirect_stdout=subprocess.PIPE,
                              redirect_stderr=subprocess.STDOUT,
                              errexit=False)
    return stdout
  else:
    return """
This is a "GCC-compatible" driver using clang under the hood.

Usage: %s [options] <inputs> ...

BASIC OPTIONS:
  -o <file>             Output to <file>.
  -E                    Only run the preprocessor.
  -S                    Generate bitcode assembly.
  -c                    Generate bitcode object.
  -I <dir>              Add header search path.
  -L <dir>              Add library search path.
  -D<key>[=<val>]       Add definition for the preprocessor.
  -W<id>                Toggle warning <id>.
  -f<feature>           Enable <feature>.
  -Wl,<arg>             Pass <arg> to the linker.
  -Xlinker <arg>        Pass <arg> to the linker.
  -Wt,<arg>             Pass <arg> to the translator.
  -Xtranslator <arg>    Pass <arg> to the translator.
  -Wp,<arg>             Pass <arg> to the preprocessor.
  -Xpreprocessor,<arg>  Pass <arg> to the preprocessor.
  -x <language>         Treat subsequent input files as having type <language>.
  -static               Produce a static executable.
  -shared               Produce a shared object.
  -Bstatic              Link subsequent libraries statically.
  -Bdynamic             Link subsequent libraries dynamically.
  -fPIC                 Ignored (only used by translator backend)
                        (accepted for compatibility).
  -pipe                 Ignored (for compatibility).
  -O<n>                 Optimation level <n>: 0, 1, 2, 3, 4 or s.
  -g                    Generate complete debug information.
  -gline-tables-only    Generate debug line-information only
                        (allowing for stack traces).
  -flimit-debug-info    Generate limited debug information.
  -save-temps           Keep intermediate compilation results.
  -v                    Verbose output / show commands.
  -h | --help           Show this help.
  --help-full           Show underlying clang driver's help message
                        (warning: not all options supported).
""" % (tool)
Exemplo n.º 27
0
def main(argv):
  env.update(EXTRA_ENV)
  driver_tools.ParseArgs(argv, PATTERNS)

  # Binary output may go to stdout (when -o was not specified)
  driver_tools.Run('"${LLVM_OPT}" ${ARGS} ${HAVE_OUTPUT ? -o ${OUTPUT}}')

  if env.getbool('DO_WRAP'):
    if not env.getbool('HAVE_OUTPUT'):
      Log.Error("unable to wrap pexe on stdout, use: --do-no-wrap flag")
    else:
      driver_tools.WrapBitcode(env.getone('OUTPUT'))
  # only reached in case of no errors
  return 0
Exemplo n.º 28
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
Exemplo n.º 29
0
def main(argv):
    env.update(EXTRA_ENV)
    driver_tools.ParseArgs(argv, PrepPatterns)

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

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

    if len(inputs) != 1:
        Log.Fatal("Can only have one input")
    f_input = inputs[0]

    # Allow in-place file changes if output isn't specified..
    if output != "":
        f_output = output
    else:
        f_output = f_input

    if env.getbool("DISABLE_FINALIZE") or filetype.IsPNaClBitcode(f_input):
        # Just copy the input file to the output file.
        if f_input != f_output:
            shutil.copyfile(f_input, f_output)
        return 0

    opt_flags = [
        "-disable-opt",
        "-strip-metadata",
        "-strip-module-flags",
        "--bitcode-format=pnacl",
        f_input,
        "-o",
        f_output,
    ]
    if env.getbool("DISABLE_STRIP_SYMS"):
        opt_flags += ["-strip-debug"]
    else:
        opt_flags += ["-strip"]
    # Transform the file, and convert it to a PNaCl bitcode file.
    driver_tools.RunDriver("pnacl-opt", opt_flags)
    # Compress the result if requested.
    if env.getbool("COMPRESS"):
        driver_tools.RunDriver("pnacl-compress", [f_output])
    return 0
Exemplo n.º 30
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
Exemplo n.º 31
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
Exemplo n.º 32
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
Exemplo n.º 33
0
def main(argv):
  env.update(EXTRA_ENV)
  driver_tools.ParseArgs(argv, META_PATTERNS)

  inputs = env.get('INPUTS')

  if not inputs:
    Usage()
    DriverExit(1)

  for f in inputs:
    if not driver_tools.IsBitcode(f):
      Log.Fatal("%s: File is not bitcode", pathtools.touser(f))
    metadata = driver_tools.GetBitcodeMetadata(f)
    if env.getbool('RAW'):
      DumpRaw(metadata)
    else:
      DumpPretty(f, metadata)
  return 0
Exemplo n.º 34
0
def main(argv):
  env.update(EXTRA_ENV)
  driver_tools.ParseArgs(argv, PrepPatterns)
  inputs = env.get('INPUTS')
  output = env.getone('OUTPUT')

  if len(inputs) != 1:
    Log.Fatal('Can only have one input')

  # Allow in-place file changes if output isn't specified..
  if output != '':
    f_output = output
  else:
    f_output = inputs[0]

  # Transform the file, and wrap the result.
  driver_tools.RunWithEnv('${RUN_OPT}', input=inputs[0], output=f_output)
  driver_tools.WrapBitcode(f_output)
  return 0
Exemplo n.º 35
0
def main(argv):
  env.update(EXTRA_ENV)
  driver_tools.ParseArgs(argv, PrepPatterns)

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

  if len(inputs) != 1:
    Log.Fatal('Can only have one input')
  f_input = inputs[0]

  # Allow in-place file changes if output isn't specified.
  if output != '':
    f_output = output
  else:
    f_output = f_input

  Compress(f_input, f_output)
  return 0
Exemplo n.º 36
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
Exemplo n.º 37
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
Exemplo n.º 38
0
def main(argv):
    env.update(EXTRA_ENV)
    driver_tools.ParseArgs(argv, PrepPatterns)

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

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

    if len(inputs) != 1:
        Log.Fatal('Can only have one input')
    f_input = inputs[0]

    # Allow in-place file changes if output isn't specified..
    if output != '':
        f_output = output
    else:
        f_output = f_input

    if env.getbool('DISABLE_FINALIZE') or filetype.IsPNaClBitcode(f_input):
        # Just copy the input file to the output file.
        if f_input != f_output:
            shutil.copyfile(f_input, f_output)
        return 0

    opt_flags = [
        '-disable-opt', '-strip-metadata', '-strip-module-flags',
        '--bitcode-format=pnacl', f_input, '-o', f_output
    ]
    if env.getbool('DISABLE_STRIP_SYMS'):
        opt_flags += ['-strip-debug']
    else:
        opt_flags += ['-strip']
    # Transform the file, and convert it to a PNaCl bitcode file.
    driver_tools.RunDriver('pnacl-opt', opt_flags)
    # Compress the result if requested.
    if env.getbool('COMPRESS'):
        driver_tools.RunDriver('pnacl-compress', [f_output])
    return 0
Exemplo n.º 39
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')

  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
Exemplo n.º 40
0
def main(argv):
    env.update(EXTRA_ENV)
    ParseArgs(argv, NMF_PATTERNS)
    exe_file = env.getone('INPUTS')

    if not exe_file:
        Log.Fatal('Expecting input exe_file')
        DriverExit(1)

    baseline_file = env.getone('BASELINE_NMF')
    if not baseline_file:
        baseline_nmf = {}
    else:
        baseline_nmf = ReadBaselineNMF(baseline_file)

    output = env.getone('OUTPUT')
    if output == '':
        output_file = sys.stdout
    else:
        output_file = DriverOpen(output, 'w')

    if not FileType(exe_file) == 'pexe':
        EchoBaselineNMF(baseline_nmf, output_file)
        return 0
    needed = GetBitcodeMetadata(exe_file).get('NeedsLibrary', [])
    if len(needed) == 0:
        GenerateStaticNMF(exe_file, baseline_nmf, output_file)
    else:
        # runnable_ld.so is going to ask for libgcc_s.so.1 even though it does
        # not show up in the pexe's NEEDED metadata, so it won't show up
        # in the NMF and on the App's webserver.
        #
        # For now, hack in libgcc_s.so.1.
        # http://code.google.com/p/nativeclient/issues/detail?id=2582
        needed.append('libgcc_s.so.1')
        GenerateDynamicNMF(exe_file, baseline_nmf, needed, output_file)
    DriverClose(output_file)
    return 0
Exemplo n.º 41
0
def main(argv):
  env.update(EXTRA_ENV)
  ParseArgs(argv, NMF_PATTERNS)
  exe_file = env.getone('INPUTS')

  if not exe_file:
    Log.Fatal('Expecting input exe_file')
    DriverExit(1)

  baseline_file = env.getone('BASELINE_NMF')
  if not baseline_file:
    baseline_nmf = {}
  else:
    baseline_nmf = ReadBaselineNMF(baseline_file)

  output = env.getone('OUTPUT')
  if output == '':
    output_file = sys.stdout
  else:
    output_file = DriverOpen(output, 'w')

  if not FileType(exe_file) == 'pexe':
    EchoBaselineNMF(baseline_nmf, output_file)
    return 0
  needed = GetBitcodeMetadata(exe_file).get('NeedsLibrary', [])
  if len(needed) == 0:
    GenerateStaticNMF(exe_file, baseline_nmf, output_file)
  else:
    # runnable_ld.so is going to ask for libgcc_s.so.1 even though it does
    # not show up in the pexe's NEEDED metadata, so it won't show up
    # in the NMF and on the App's webserver.
    #
    # For now, hack in libgcc_s.so.1.
    # http://code.google.com/p/nativeclient/issues/detail?id=2582
    needed.append('libgcc_s.so.1')
    GenerateDynamicNMF(exe_file, baseline_nmf, needed, output_file)
  DriverClose(output_file)
  return 0
Exemplo n.º 42
0
def main(argv):
  env.update(EXTRA_ENV)
  driver_tools.ParseArgs(argv, StripPatterns)
  inputs = env.get('INPUTS')
  output = env.getone('OUTPUT')
  for path in inputs + [output]:
    driver_tools.CheckPathLength(path)

  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 filetype.IsPNaClBitcode(f):
      # PNaCl-format bitcode has no symbols, i.e. it is already stripped.
      if f != f_output:
        shutil.copyfile(f, f_output)
    elif filetype.IsLLVMBitcode(f):
      driver_tools.RunWithEnv('${RUN_OPT}', input=f, output=f_output)
    elif filetype.IsELF(f) or filetype.IsNativeArchive(f):
      driver_tools.RunWithEnv('${RUN_STRIP}', input=f, output=f_output)
    elif filetype.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
Exemplo n.º 43
0
def main(argv):
  DumpCommand("@incoming", argv)

  Env.update(EXTRA_ENV)
  driver_tools.ParseArgs(argv, ARG_PATTERNS)

  output = Env.getone('OUTPUT')

  if output == '':
    Log.Fatal('No output specified. Use -o to specify output')

  if Env.getone('ARCH') == '':
    Log.Fatal('No arch specified')

  mode = Env.getone('MODE')
  if mode == 'shared':
    BuildSharedLib()
  elif mode == 'dynamic':
    BuildDynamicExecutable()
  elif mode == 'static':
    BuildStaticExecutable()
  else:
    Log.Fatal('You must specify at least one of -static, -shared, -dynamic')
  return 0
Exemplo n.º 44
0
def main(argv):
    env.update(EXTRA_ENV)
    driver_tools.ParseArgs(argv, TranslatorPatterns)
    driver_tools.GetArch(required=True)

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

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

    if output == '':
        Log.Fatal("Please specify output file with -o")

    # Find the bitcode file on the command line.
    bcfiles = [
        f for f in inputs
        if not ldtools.IsFlag(f) and (filetype.IsPNaClBitcode(
            f) or filetype.IsLLVMBitcode(f) or filetype.FileType(f) == 'll')
    ]
    if len(bcfiles) > 1:
        Log.Fatal('Expecting at most 1 bitcode file')
    elif len(bcfiles) == 1:
        bcfile = bcfiles[0]
    else:
        bcfile = None

    if not env.getbool('SPLIT_MODULE'):
        try:
            env.set('SPLIT_MODULE', str(min(4, multiprocessing.cpu_count())))
        except NotImplementedError:
            env.set('SPLIT_MODULE', '2')
    elif int(env.getone('SPLIT_MODULE')) < 1:
        Log.Fatal('Value given for -split-module must be > 0')
    if (env.getbool('ALLOW_LLVM_BITCODE_INPUT')
            or env.getone('ARCH') == 'X8632_LINUX'
            or env.getbool('USE_EMULATOR')):
        # When llvm input is allowed, the pexe may not be ABI-stable, so do not
        # split it. For now also do not support threading non-SFI baremetal mode.
        # Non-ABI-stable pexes may have symbol naming and visibility issues that the
        # current splitting scheme doesn't account for.
        # If the link would require a non-standard command line, do not split the
        # modules because the sandboxed linker doesn't support that combination.
        # The x86->arm emulator is very flaky when threading is used, so don't
        # do module splitting when using it.
        env.set('SPLIT_MODULE', '1')
    else:
        modules = env.getone('SPLIT_MODULE')
        if modules != '1':
            env.append('LLC_FLAGS_EXTRA', '-split-module=' + modules)
            env.append('LD_FLAGS', '-split-module=' + modules)
        if not env.getbool('SANDBOXED') and env.getbool('STREAM_BITCODE'):
            # Do not set -streaming-bitcode for sandboxed mode, because it is already
            # in the default command line.
            env.append('LLC_FLAGS_EXTRA', '-streaming-bitcode')

    # If there's a bitcode file, translate it now.
    tng = driver_tools.TempNameGen(inputs + bcfiles, output)
    output_type = env.getone('OUTPUT_TYPE')
    if bcfile:
        sfile = None
        if output_type == 's':
            sfile = output

        ofile = None
        if output_type == 'o':
            ofile = output
        elif output_type != 's':
            ofile = tng.TempNameForInput(bcfile, 'o')

        if sfile:
            RunLLC(bcfile, sfile, outfiletype='asm')
            if ofile:
                RunAS(sfile, ofile)
        else:
            RunLLC(bcfile, ofile, outfiletype='obj')
    else:
        ofile = None

    # If we've been told to stop after translation, stop now.
    if output_type in ('o', 's'):
        return 0

    # Replace the bitcode file with __BITCODE__ in the input list
    if bcfile:
        inputs = ListReplace(inputs, bcfile, '__BITCODE__')
        env.set('INPUTS', *inputs)
    if int(env.getone('SPLIT_MODULE')) > 1:
        modules = int(env.getone('SPLIT_MODULE'))
        for i in range(1, modules):
            filename = ofile + '.module%d' % i
            TempFiles.add(filename)
            env.append('INPUTS', filename)

    if env.getone('ARCH') == 'X8632_LINUX':
        RunHostLD(ofile, output)
    else:
        RunLD(ofile, output)
    return 0
Exemplo n.º 45
0
def main(argv):
  env.update(EXTRA_ENV)
  ParseArgs(argv, LDPatterns)
  # If the user passed -arch, then they want native output.
  arch_flag_given = GetArch() is not None

  # Both LD_FLAGS_NATIVE and TRANSLATE_FLAGS_USER affect
  # the translation process. If they are non-empty,
  # then --pnacl-allow-native must be given.
  allow_native = env.getbool('ALLOW_NATIVE')
  native_flags = env.get('LD_FLAGS_NATIVE') + env.get('TRANSLATE_FLAGS_USER')
  if len(native_flags) > 0:
    if not allow_native:
      flagstr = ' '.join(native_flags)
      Log.Fatal('"%s" affects translation. '
                'To allow, specify --pnacl-allow-native' % flagstr)

  if env.getbool('ALLOW_NATIVE') and not arch_flag_given:
      Log.Fatal("--pnacl-allow-native given, but translation "
                "is not happening (missing -arch?)")

  # Overriding the lib target uses native-flavored bitcode libs rather than the
  # portable bitcode libs. It is currently only tested/supported for
  # building the IRT.
  if not IsPortable():
    env.set('BASE_USR', "${BASE_USR_ARCH}")
    env.set('BASE_LIB', "${BASE_LIB_ARCH}")

  if env.getbool('RELOCATABLE'):
    env.set('STATIC', '0')

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

  if output == '':
    output = pathtools.normalize('a.out')

  if not arch_flag_given:
    # If -arch is not given, assume X86-32.
    # This is because gold requires an arch (even for bitcode linking).
    SetArch('X8632')
  assert(GetArch() is not None)

  inputs = FixPrivateLibs(inputs)

  # Expand all parameters
  # This resolves -lfoo into actual filenames,
  # and expands linker scripts into command-line arguments.
  inputs = ldtools.ExpandInputs(inputs,
                                env.get('SEARCH_DIRS'),
                                env.getbool('STATIC'),
                                # Once all glibc bitcode link is purely
                                # bitcode (e.g., even libc_nonshared.a)
                                # we may be able to restrict this more.
                                # This is also currently used by
                                # pnacl_generate_pexe=0 with glibc,
                                # for user libraries.
                                ldtools.LibraryTypes.ANY)

  # Make sure the inputs have matching arch.
  CheckInputsArch(inputs)

  regular_inputs, native_objects = SplitLinkLine(inputs)

  if env.getbool('RELOCATABLE'):
    bitcode_type = 'po'
    native_type = 'o'
  else:
    bitcode_type = 'pexe'
    native_type = 'nexe'

  if native_objects and not allow_native:
    argstr = ' '.join(native_objects)
    Log.Fatal("Native objects '%s' detected in the link. "
              "To allow, specify --pnacl-allow-native" % argstr)

  tng = TempNameGen([], output)

  # Do the bitcode link.
  if HasBitcodeInputs(inputs):
    chain = DriverChain(inputs, output, tng)
    chain.add(LinkBC, 'pre_opt.' + bitcode_type)

    # Some ABI simplification passes assume the whole program is
    # available (e.g. -expand-varargs, -nacl-expand-ctors and
    # -nacl-expand-tls).  While we could try running a subset of
    # simplification passes when linking native objects, we don't
    # do this because it complicates testing.  For example,
    # it requires '-expand-constant-expr' to be able to handle
    # 'landingpad' instructions.
    # However, if we aren't using biased bitcode, then at least -expand-byval
    # must be run to work with the PPAPI shim calling convention, and
    # -expand-varargs is needed because after LLVM 3.5 the x86-32 backend does
    # not expand the llvm.va_arg intrinsic correctly.
    # (see https://code.google.com/p/nativeclient/issues/detail?id=3913#c24)
    abi_simplify = (env.getbool('STATIC') and
                    len(native_objects) == 0 and
                    not env.getbool('ALLOW_NEXE_BUILD_ID') and
                    IsPortable())
    still_need_expand_byval = IsPortable() and env.getbool('STATIC')
    still_need_expand_varargs = (still_need_expand_byval and
                                 len(native_objects) == 0)

    # A list of groups of args. Each group should contain a pass to run
    # along with relevant flags that go with that pass.
    opt_args = []
    if abi_simplify:
      pre_simplify = ['-pnacl-abi-simplify-preopt']
      if env.getone('CXX_EH_MODE') == 'sjlj':
        pre_simplify += ['-enable-pnacl-sjlj-eh']
      else:
        assert env.getone('CXX_EH_MODE') == 'none'
      opt_args.append(pre_simplify)
    else:
      # '-lowerinvoke' prevents use of C++ exception handling, which
      # is not yet supported in the PNaCl ABI.  '-simplifycfg' removes
      # landingpad blocks made unreachable by '-lowerinvoke'.
      #
      # We run this in order to remove 'resume' instructions,
      # otherwise these are translated to calls to _Unwind_Resume(),
      # which will not be available at native link time.
      opt_args.append(['-lowerinvoke', '-simplifycfg'])
      if still_need_expand_varargs:
        opt_args.append(['-expand-varargs'])

    if env.getone('OPT_LEVEL') != '' and env.getone('OPT_LEVEL') != '0':
      opt_args.append(env.get('OPT_FLAGS'))
    if env.getone('STRIP_MODE') != 'none':
      opt_args.append(env.get('STRIP_FLAGS'))

    if abi_simplify:
      post_simplify = ['-pnacl-abi-simplify-postopt']
      if not env.getbool('DISABLE_ABI_CHECK'):
        post_simplify += [
            '-verify-pnaclabi-module',
            '-verify-pnaclabi-functions',
            # A flag for the above -verify-pnaclabi-* passes.
            '-pnaclabi-allow-debug-metadata']
      opt_args.append(post_simplify)
    elif still_need_expand_byval:
      # We may still need -expand-byval to match the PPAPI shim
      # calling convention.
      opt_args.append(['-expand-byval'])
    if len(opt_args) != 0:
      if env.getbool('RUN_PASSES_SEPARATELY'):
        for i, group in enumerate(opt_args):
          chain.add(DoLLVMPasses(group),
                    'simplify_%d.%s' % (i, bitcode_type))
      else:
        flattened_opt_args = [flag for group in opt_args for flag in group]
        chain.add(DoLLVMPasses(flattened_opt_args),
                  'simplify_and_opt.' + bitcode_type)
  else:
    chain = DriverChain('', output, tng)

  if env.getbool('FINALIZE'):
    chain.add(DoFinalize, 'finalize.' + bitcode_type)

  # If -arch is also specified, invoke pnacl-translate afterwards.
  if arch_flag_given:
    env.set('NATIVE_OBJECTS', *native_objects)
    chain.add(DoTranslate, native_type)

  chain.run()

  if bitcode_type == 'pexe' and not arch_flag_given:
    # Mark .pexe files as executable.
    # Some versions of 'configure' expect this.
    SetExecutableMode(output)
  return 0
Exemplo n.º 46
0
def main(argv):
  env.update(EXTRA_ENV)
  driver_tools.ParseArgs(argv, TranslatorPatterns)
  driver_tools.GetArch(required = True)
  SetUpArch()
  SetUpLinkOptions()

  # Now commit to whether or not Subzero is used.
  use_sz = env.getbool('USE_SZ') and not env.getbool('SZ_UNSUPPORTED')

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

  if len(inputs) == 0:
    Log.Fatal("No input files")
  for path in inputs:
    driver_tools.CheckPathLength(path)

  if output == '':
    Log.Fatal("Please specify output file with -o")

  # Find the bitcode file on the command line.
  bcfiles = [f for f in inputs
             if not ldtools.IsFlag(f) and
               (filetype.IsPNaClBitcode(f)
                or filetype.IsLLVMBitcode(f)
                or filetype.FileType(f) == 'll')]
  if len(bcfiles) > 1:
    Log.Fatal('Expecting at most 1 bitcode file')
  elif len(bcfiles) == 1:
    bcfile = bcfiles[0]
  else:
    bcfile = None

  if ((env.getbool('ALLOW_LLVM_BITCODE_INPUT') or
       env.getone('TARGET_OS') != 'nacl' or
       env.getbool('USE_EMULATOR')) and
      env.getone('SPLIT_MODULE') == 'auto'):
    # When llvm input is allowed, the pexe may not be ABI-stable, so do not
    # split it.  Non-ABI-stable pexes may have symbol naming and visibility
    # issues that the current splitting scheme doesn't account for.
    #
    # For now, also do not enable multi-threaded translation when TARGET_OS !=
    # 'nacl', since in these cases we will be using the host toolchain's
    # linker.
    #
    # The x86->arm emulator is very flaky when threading is used, so don't
    # do module splitting when using it.
    env.set('SPLIT_MODULE', 'seq')
  # Do not set -streaming-bitcode for sandboxed mode, because it is already
  # in the default command line.
  if not env.getbool('SANDBOXED') and env.getbool('STREAM_BITCODE'):
    env.append('LLC_FLAGS_EXTRA', '-streaming-bitcode')

  if env.getone('SPLIT_MODULE') == 'seq':
    env.set('SPLIT_MODULE', '1')
    env.set('SZ_THREADS', '0')
  elif env.getone('SPLIT_MODULE') == 'auto':
    try:
      num_modules = min(4, multiprocessing.cpu_count())
    except NotImplementedError:
      num_modules = 2
    env.set('SPLIT_MODULE', str(num_modules))
    env.set('SZ_THREADS', str(num_modules))
  else:
    num_modules = int(env.getone('SPLIT_MODULE'))
    if num_modules < 1:
      Log.Fatal('Value given for -split-module must be > 0')
    env.set('SPLIT_MODULE', str(num_modules))
    env.set('SZ_THREADS', str(num_modules))

  modules = env.getone('SPLIT_MODULE')
  module_sched = env.getone('SPLIT_MODULE_SCHED')
  sz_threads = env.getone('SZ_THREADS')
  # TODO(dschuff,jvoung): No need to specify -split-module=X since the IPC
  # already has a parameter for the number of threads and modules.
  env.append('LLC_FLAGS_EXTRA', '-split-module=' + modules)
  env.append('LD_FLAGS', '-split-module=' + ('1' if use_sz else modules))
  env.append('LLC_FLAGS_EXTRA', '-split-module-sched=' + module_sched)
  # In sandboxed mode, the IPC already has a parameter for the number
  # of threads, so no need to specify that again via argv[].
  if not env.getbool('SANDBOXED'):
    env.append('SZ_FLAGS_EXTRA', '--threads=' + sz_threads)

  # If there's a bitcode file, translate it now.
  tng = driver_tools.TempNameGen(inputs + bcfiles, output)
  output_type = env.getone('OUTPUT_TYPE')
  if bcfile:
    sfile = None
    if output_type == 's':
      sfile = output

    ofile = None
    if output_type == 'o':
      ofile = output
    elif output_type != 's':
      ofile = tng.TempNameForInput(bcfile, 'o')

    if sfile:
      RunCompiler(bcfile, sfile, outfiletype='asm', use_sz=use_sz)
      if ofile:
        RunAS(sfile, ofile)
    else:
      RunCompiler(bcfile, ofile, outfiletype='obj', use_sz=use_sz)
  else:
    ofile = None

  # If we've been told to stop after translation, stop now.
  if output_type in ('o','s'):
    return 0

  if use_sz:
    # Reset SPLIT_MODULE to 1 to fall back to normal linking behavior.
    env.set('SPLIT_MODULE', '1')

  # Replace the bitcode file with __BITCODE__ in the input list
  if bcfile:
    inputs = ListReplace(inputs, bcfile, '__BITCODE__')
    env.set('INPUTS', *inputs)
  if int(env.getone('SPLIT_MODULE')) > 1:
    modules = int(env.getone('SPLIT_MODULE'))
    for i in range(1, modules):
      filename = ofile + '.module%d' % i
      TempFiles.add(filename)
      env.append('INPUTS', filename)

  if env.getone('TARGET_OS') != 'nacl':
    RunHostLD(ofile, output)
  else:
    RunLD(ofile, output)
  return 0
Exemplo n.º 47
0
def main(argv):
  env.update(EXTRA_ENV)
  CheckSetup()
  ParseArgs(argv, CustomPatterns + GCCPatterns)

  # "configure", especially when run as part of a toolchain bootstrap
  # process, will invoke gcc with various diagnostic options and
  # parse the output. In these cases we do not alter the incoming
  # commandline. It is also important to not emit spurious messages.
  if env.getbool('DIAGNOSTIC'):
    if env.getbool('SHOW_VERSION'):
      code, stdout, stderr = Run(env.get('CC') + env.get('CC_FLAGS'),
                                 redirect_stdout=subprocess.PIPE)
      out = stdout.split('\n')
      nacl_version = ReadDriverRevision()
      out[0] += ' nacl-version=%s' % nacl_version
      stdout = '\n'.join(out)
      print stdout,
    else:
      Run(env.get('CC') + env.get('CC_FLAGS'))
    return 0

  unmatched = env.get('UNMATCHED')
  if len(unmatched) > 0:
    UnrecognizedOption(*unmatched)

  # If -arch was given, we are compiling directly to native code
  compiling_to_native = GetArch() is not None

  if env.getbool('ALLOW_NATIVE'):
    if not compiling_to_native:
      Log.Fatal("--pnacl-allow-native without -arch is not meaningful.")
    # For native/mixed links, also bring in the native libgcc and
    # libcrt_platform to avoid link failure if pre-translated native
    # code needs functions from it.
    env.append('LD_FLAGS', env.eval('-L${LIBS_NATIVE_ARCH}'))
    env.append('STDLIBS', '-lgcc')
    env.append('STDLIBS', '-lcrt_platform')


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

  if len(flags_and_inputs) == 0:
    if env.getbool('VERBOSE'):
      # -v can be invoked without any inputs. Runs the original
      # command without modifying the commandline for this case.
      Run(env.get('CC') + env.get('CC_FLAGS'))
      return 0
    else:
      Log.Fatal('No input files')

  gcc_mode = env.getone('GCC_MODE')
  output_type = DriverOutputTypes(gcc_mode, compiling_to_native)
  # INPUTS consists of actual input files and a subset of flags like -Wl,<foo>.
  # Create a version with just the files.
  inputs = [f for f in flags_and_inputs if not IsFlag(f)]
  header_inputs = [f for f in inputs
                   if filetype.IsHeaderType(filetype.FileType(f))]
  # Handle PCH case specially (but only for a limited sense...)
  if header_inputs and gcc_mode != '-E':
    # We only handle doing pre-compiled headers for all inputs or not at
    # all at the moment. This is because DriverOutputTypes only assumes
    # one type of output, depending on the "gcc_mode" flag. When mixing
    # header inputs w/ non-header inputs, some of the outputs will be
    # pch while others will be output_type. We would also need to modify
    # the input->output chaining for the needs_linking case.
    if len(header_inputs) != len(inputs):
      Log.Fatal('mixed compiling of headers and source not supported')
    CompileHeaders(header_inputs, output)
    return 0

  needs_linking = (gcc_mode == '')

  if env.getbool('NEED_DASH_E') and gcc_mode != '-E':
    Log.Fatal("-E or -x required when input is from stdin")

  # There are multiple input files and no linking is being done.
  # There will be multiple outputs. Handle this case separately.
  if not needs_linking:
    if output != '' and len(inputs) > 1:
      Log.Fatal('Cannot have -o with -c, -S, or -E and multiple inputs: %s',
                repr(inputs))

    for f in inputs:
      intype = filetype.FileType(f)
      if not (filetype.IsSourceType(intype) or filetype.IsHeaderType(intype)):
        if ((output_type == 'pp' and intype != 'S') or
            (output_type == 'll') or
            (output_type == 'po' and intype != 'll') or
            (output_type == 's' and intype not in ('ll','po','S')) or
            (output_type == 'o' and intype not in ('ll','po','S','s'))):
          Log.Fatal("%s: Unexpected type of file for '%s'",
                    pathtools.touser(f), gcc_mode)

      if output == '':
        f_output = DefaultOutputName(f, output_type)
      else:
        f_output = output

      namegen = TempNameGen([f], f_output)
      CompileOne(f, output_type, namegen, f_output)
    return 0

  # Linking case
  assert(needs_linking)
  assert(output_type in ('pso','so','pexe','nexe'))

  if output == '':
    output = pathtools.normalize('a.out')
  namegen = TempNameGen(flags_and_inputs, output)

  # Compile all source files (c/c++/ll) to .po
  for i in xrange(0, len(flags_and_inputs)):
    if IsFlag(flags_and_inputs[i]):
      continue
    intype = filetype.FileType(flags_and_inputs[i])
    if filetype.IsSourceType(intype) or intype == 'll':
      flags_and_inputs[i] = CompileOne(flags_and_inputs[i], 'po', namegen)

  # Compile all .s/.S to .o
  if env.getbool('ALLOW_NATIVE'):
    for i in xrange(0, len(flags_and_inputs)):
      if IsFlag(flags_and_inputs[i]):
        continue
      intype = filetype.FileType(flags_and_inputs[i])
      if intype in ('s','S'):
        flags_and_inputs[i] = CompileOne(flags_and_inputs[i], 'o', namegen)

  # We should only be left with .po and .o and libraries
  for f in flags_and_inputs:
    if IsFlag(f):
      continue
    intype = filetype.FileType(f)
    if intype in ('o','s','S') or filetype.IsNativeArchive(f):
      if not env.getbool('ALLOW_NATIVE'):
        Log.Fatal('%s: Native object files not allowed in link. '
                  'Use --pnacl-allow-native to override.', pathtools.touser(f))
    assert(intype in ('po','o','so','ldscript') or filetype.IsArchive(f))

  # Fix the user-specified linker arguments
  ld_inputs = []
  for f in flags_and_inputs:
    if f.startswith('-Xlinker='):
      ld_inputs.append(f[len('-Xlinker='):])
    elif f.startswith('-Wl,'):
      ld_inputs += f[len('-Wl,'):].split(',')
    else:
      ld_inputs.append(f)

  if env.getbool('ALLOW_NATIVE'):
    ld_inputs.append('--pnacl-allow-native')

  # Invoke the linker
  env.set('ld_inputs', *ld_inputs)

  ld_args = env.get('LD_ARGS')
  ld_flags = env.get('LD_FLAGS')

  RunDriver('pnacl-ld', ld_flags + ld_args + ['-o', output])
  return 0
Exemplo n.º 48
0
def main(argv):
  env.update(EXTRA_ENV)
  driver_tools.ParseArgs(argv, TranslatorPatterns)
  if env.getbool('SHARED'):
    Log.Fatal('Not handling SHARED')

  driver_tools.GetArch(required = True)

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

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

  if output == '':
    Log.Fatal("Please specify output file with -o")

  # Find the bitcode file on the command line.
  bcfiles = [f for f in inputs
             if not ldtools.IsFlag(f) and
               (filetype.IsPNaClBitcode(f)
                or filetype.IsLLVMBitcode(f)
                or filetype.FileType(f) == 'll')]
  if len(bcfiles) > 1:
    Log.Fatal('Expecting at most 1 bitcode file')
  elif len(bcfiles) == 1:
    bcfile = bcfiles[0]
  else:
    bcfile = None

  # If there's a bitcode file, translate it now.
  tng = driver_tools.TempNameGen(inputs + bcfiles, output)
  output_type = env.getone('OUTPUT_TYPE')
  if bcfile:
    sfile = None
    if output_type == 's':
      sfile = output
    elif env.getbool('FORCE_INTERMEDIATE_S'):
      sfile = tng.TempNameForInput(bcfile, 's')

    ofile = None
    if output_type == 'o':
      ofile = output
    elif output_type != 's':
      ofile = tng.TempNameForInput(bcfile, 'o')

    if sfile:
      RunLLC(bcfile, sfile, outfiletype='asm')
      if ofile:
        RunAS(sfile, ofile)
    else:
      RunLLC(bcfile, ofile, outfiletype='obj')
  else:
    ofile = None

  # If we've been told to stop after translation, stop now.
  if output_type in ('o','s'):
    return 0

  # Replace the bitcode file with __BITCODE__ in the input list
  if bcfile:
    inputs = ListReplace(inputs, bcfile, '__BITCODE__')
    env.set('INPUTS', *inputs)

  # Determine the output type, in this order of precedence:
  # 1) Output type can be specified on command-line (-S, -c, -static)
  #    -S and -c are handled above by the check that output_type in ('o', 's').
  # 2) Otherwise, assume static nexe output.
  if env.getbool('STATIC'):
    output_type = 'nexe'
  else:
    # Until we stabilize the ABI for shared libraries,
    # assume that pnacl-translate only handles pexes -> nexes,
    # to avoid a dependency on bitcode metadata.
    output_type = 'nexe'
    env.set('STATIC', '1')

  assert output_type in ('so','nexe')
  if env.getone('ARCH') == 'LINUX_X8632':
    RunHostLD(ofile, output)
  else:
    RunLD(ofile, output)
  return 0
Exemplo n.º 49
0
def main(argv):
    env.update(EXTRA_ENV)
    driver_tools.ParseArgs(argv, TranslatorPatterns)
    driver_tools.GetArch(required=True)

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

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

    if output == '':
        Log.Fatal("Please specify output file with -o")

    # Find the bitcode file on the command line.
    bcfiles = [
        f for f in inputs
        if not ldtools.IsFlag(f) and (filetype.IsPNaClBitcode(
            f) or filetype.IsLLVMBitcode(f) or filetype.FileType(f) == 'll')
    ]
    if len(bcfiles) > 1:
        Log.Fatal('Expecting at most 1 bitcode file')
    elif len(bcfiles) == 1:
        bcfile = bcfiles[0]
    else:
        bcfile = None

    # If there's a bitcode file, translate it now.
    tng = driver_tools.TempNameGen(inputs + bcfiles, output)
    output_type = env.getone('OUTPUT_TYPE')
    if bcfile:
        sfile = None
        if output_type == 's':
            sfile = output

        ofile = None
        if output_type == 'o':
            ofile = output
        elif output_type != 's':
            ofile = tng.TempNameForInput(bcfile, 'o')

        if sfile:
            RunLLC(bcfile, sfile, outfiletype='asm')
            if ofile:
                RunAS(sfile, ofile)
        else:
            RunLLC(bcfile, ofile, outfiletype='obj')
    else:
        ofile = None

    # If we've been told to stop after translation, stop now.
    if output_type in ('o', 's'):
        return 0

    # Replace the bitcode file with __BITCODE__ in the input list
    if bcfile:
        inputs = ListReplace(inputs, bcfile, '__BITCODE__')
        env.set('INPUTS', *inputs)

    if env.getone('ARCH') == 'LINUX_X8632':
        RunHostLD(ofile, output)
    else:
        RunLD(ofile, output)
    return 0
Exemplo n.º 50
0
def main(argv):
  env.update(EXTRA_ENV)
  ParseArgs(argv, LDPatterns)
  # If the user passed -arch, then they want native output.
  arch_flag_given = GetArch() is not None

  # Both LD_FLAGS_NATIVE and TRANSLATE_FLAGS_USER affect
  # the translation process. If they are non-empty,
  # then --pnacl-allow-native must be given.
  allow_native = env.getbool('ALLOW_NATIVE')
  native_flags = env.get('LD_FLAGS_NATIVE') + env.get('TRANSLATE_FLAGS_USER')
  if len(native_flags) > 0:
    if not allow_native:
      flagstr = ' '.join(native_flags)
      Log.Fatal('"%s" affects translation. '
                'To allow, specify --pnacl-allow-native' % flagstr)

  if allow_native:
    if not arch_flag_given:
      Log.Fatal("--pnacl-allow-native given, but translation "
                "is not happening (missing -arch?)")
    if env.getbool('SHARED'):
      Log.Fatal('Native shared libraries are not supported with pnacl-ld.')

  if env.getbool('SHARED'):
    if env.getbool('RELOCATABLE'):
      Log.Fatal('-r/-relocatable and -shared may not be passed together.')
    env.set('RELOCATABLE', '1')

  # Overriding the lib target uses native-flavored bitcode libs rather than the
  # portable bitcode libs. It is currently only tested/supported for
  # building the IRT.
  if not IsPortable():
    env.set('BASE_USR', "${BASE_USR_ARCH}")
    env.set('BASE_LIB', "${BASE_LIB_ARCH}")

  if env.getbool('RELOCATABLE'):
    env.set('STATIC', '0')

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

  if output == '':
    output = pathtools.normalize('a.out')

  if not arch_flag_given:
    # If -arch is not given, assume X86-32.
    # This is because gold requires an arch (even for bitcode linking).
    SetArch('X8632')
  assert(GetArch() is not None)

  inputs = FixPrivateLibs(inputs)

  # Expand all parameters
  # This resolves -lfoo into actual filenames,
  # and expands linker scripts into command-line arguments.
  inputs = ldtools.ExpandInputs(inputs,
                                env.get('SEARCH_DIRS'),
                                env.getbool('STATIC'),
                                # Once all glibc bitcode link is purely
                                # bitcode (e.g., even libc_nonshared.a)
                                # we may be able to restrict this more.
                                # This is also currently used by
                                # pnacl_generate_pexe=0 with glibc,
                                # for user libraries.
                                ldtools.LibraryTypes.ANY)
  plls, inputs = FilterPlls(inputs)
  plls = [os.path.basename(pll) for pll in plls]

  if not env.getbool('SHARED') and plls != []:
    Log.Fatal('Passing a PLL to the linker requires the "-shared" option.')

  # Make sure the inputs have matching arch.
  CheckInputsArch(inputs)

  regular_inputs, native_objects = SplitLinkLine(inputs)

  if env.getbool('RELOCATABLE'):
    bitcode_type = 'po'
    native_type = 'o'
  else:
    bitcode_type = 'pexe'
    native_type = 'nexe'

  if native_objects and not allow_native:
    argstr = ' '.join(native_objects)
    Log.Fatal("Native objects '%s' detected in the link. "
              "To allow, specify --pnacl-allow-native" % argstr)

  tng = TempNameGen([], output)

  # Do the bitcode link.
  if HasBitcodeInputs(inputs):
    chain = DriverChain(inputs, output, tng)
    chain.add(LinkBC, 'pre_opt.' + bitcode_type)

    # Some ABI simplification passes assume the whole program is
    # available (e.g. -expand-varargs, -nacl-expand-ctors and
    # -nacl-expand-tls).  While we could try running a subset of
    # simplification passes when linking native objects, we don't
    # do this because it complicates testing.  For example,
    # it requires '-expand-constant-expr' to be able to handle
    # 'landingpad' instructions.
    # However, if we aren't using biased bitcode, then at least -expand-byval
    # must be run to work with the PPAPI shim calling convention, and
    # -expand-varargs is needed because after LLVM 3.5 the x86-32 backend does
    # not expand the llvm.va_arg intrinsic correctly.
    # (see https://code.google.com/p/nativeclient/issues/detail?id=3913#c24)
    abi_simplify = (env.getbool('STATIC') and
                    len(native_objects) == 0 and
                    not env.getbool('ALLOW_NEXE_BUILD_ID') and
                    IsPortable())
    still_need_expand_byval = IsPortable() and env.getbool('STATIC')
    still_need_expand_varargs = (still_need_expand_byval and
                                 len(native_objects) == 0)

    # A list of groups of args. Each group should contain a pass to run
    # along with relevant flags that go with that pass.
    opt_args = []
    if env.getbool('SHARED'):
      pre_simplify_shared = [
        # The following is a subset of "-pnacl-abi-simplify-preopt".  We don't
        # want to run the full "-pnacl-abi-simplify-preopt" because it
        # internalizes symbols that we want to export via "-convert-to-pso".
        '-nacl-global-cleanup',
        '-expand-varargs',
        '-rewrite-pnacl-library-calls',
        '-rewrite-llvm-intrinsic-calls',
        '-convert-to-pso',
      ]
      # ConvertToPso takes a list of comma-separated PLL dependencies as an
      # argument.
      if plls != []:
        pre_simplify_shared += ['-convert-to-pso-deps=' + ','.join(plls)]
      opt_args.append(pre_simplify_shared)
      # Post-opt is required, since '-convert-to-pso' adds metadata which must
      # be simplified before finalization. Additionally, all functions must be
      # simplified in the post-opt passes.
      abi_simplify = True
    elif abi_simplify:
      pre_simplify = ['-pnacl-abi-simplify-preopt']
      if env.getone('CXX_EH_MODE') == 'sjlj':
        pre_simplify += ['-enable-pnacl-sjlj-eh']
      else:
        assert env.getone('CXX_EH_MODE') == 'none'
      opt_args.append(pre_simplify)
    else:
      # '-lowerinvoke' prevents use of C++ exception handling, which
      # is not yet supported in the PNaCl ABI.  '-simplifycfg' removes
      # landingpad blocks made unreachable by '-lowerinvoke'.
      #
      # We run this in order to remove 'resume' instructions,
      # otherwise these are translated to calls to _Unwind_Resume(),
      # which will not be available at native link time.
      opt_args.append(['-lowerinvoke', '-simplifycfg'])
      if still_need_expand_varargs:
        opt_args.append(['-expand-varargs'])

    if env.getone('OPT_LEVEL') != '' and env.getone('OPT_LEVEL') != '0':
      opt_args.append(env.get('OPT_FLAGS'))
    if env.getone('STRIP_MODE') != 'none':
      opt_args.append(env.get('STRIP_FLAGS'))

    if abi_simplify:
      post_simplify = ['-pnacl-abi-simplify-postopt']
      if not env.getbool('DISABLE_ABI_CHECK'):
        post_simplify += [
            '-verify-pnaclabi-module',
            '-verify-pnaclabi-functions',
            # A flag for the above -verify-pnaclabi-* passes.
            '-pnaclabi-allow-debug-metadata']
      opt_args.append(post_simplify)
    elif still_need_expand_byval:
      # We may still need -expand-byval to match the PPAPI shim
      # calling convention.
      opt_args.append(['-expand-byval'])
    if len(opt_args) != 0:
      if env.getbool('RUN_PASSES_SEPARATELY'):
        for i, group in enumerate(opt_args):
          chain.add(DoLLVMPasses(group),
                    'simplify_%d.%s' % (i, bitcode_type))
      else:
        flattened_opt_args = [flag for group in opt_args for flag in group]
        chain.add(DoLLVMPasses(flattened_opt_args),
                  'simplify_and_opt.' + bitcode_type)
  else:
    chain = DriverChain('', output, tng)

  if env.getbool('FINALIZE'):
    chain.add(DoFinalize, 'finalize.' + bitcode_type)

  # If -arch is also specified, invoke pnacl-translate afterwards.
  if arch_flag_given:
    env.set('NATIVE_OBJECTS', *native_objects)
    chain.add(DoTranslate, native_type)

  chain.run()

  if bitcode_type == 'pexe' and not arch_flag_given:
    # Mark .pexe files as executable.
    # Some versions of 'configure' expect this.
    SetExecutableMode(output)
  return 0
Exemplo n.º 51
0
def main(argv):
    env.update(EXTRA_ENV)
    CheckSetup()
    ParseArgs(argv, CustomPatterns + GCCPatterns)

    # "configure", especially when run as part of a toolchain bootstrap
    # process, will invoke gcc with various diagnostic options and
    # parse the output. In these cases we do not alter the incoming
    # commandline. It is also important to not emit spurious messages.
    if env.getbool('DIAGNOSTIC'):
        if env.getbool('SHOW_VERSION'):
            code, stdout, stderr = Run(env.get('CC') + env.get('CC_FLAGS'),
                                       redirect_stdout=subprocess.PIPE)
            out = stdout.split('\n')
            nacl_version = ReadDriverRevision()
            out[0] += ' nacl-version=%s' % nacl_version
            stdout = '\n'.join(out)
            print stdout,
        else:
            Run(env.get('CC') + env.get('CC_FLAGS'))
        return 0

    unmatched = env.get('UNMATCHED')
    if len(unmatched) > 0:
        UnrecognizedOption(*unmatched)

    # If -arch was given, we are compiling directly to native code
    compiling_to_native = GetArch() is not None

    if env.getbool('ALLOW_NATIVE') and not compiling_to_native:
        Log.Fatal("--pnacl-allow-native without -arch is not meaningful.")

    if not env.get('STDLIB'):
        # Default C++ Standard Library.
        SetStdLib('libc++')

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

    if len(inputs) == 0:
        if env.getbool('VERBOSE'):
            # -v can be invoked without any inputs. Runs the original
            # command without modifying the commandline for this case.
            Run(env.get('CC') + env.get('CC_FLAGS'))
            return 0
        else:
            Log.Fatal('No input files')

    gcc_mode = env.getone('GCC_MODE')
    output_type = DriverOutputTypes(gcc_mode, compiling_to_native)
    needs_linking = (gcc_mode == '')

    if env.getbool('NEED_DASH_E') and gcc_mode != '-E':
        Log.Fatal("-E or -x required when input is from stdin")

    # There are multiple input files and no linking is being done.
    # There will be multiple outputs. Handle this case separately.
    if not needs_linking:
        # Filter out flags
        inputs = [f for f in inputs if not IsFlag(f)]
        if output != '' and len(inputs) > 1:
            Log.Fatal(
                'Cannot have -o with -c, -S, or -E and multiple inputs: %s',
                repr(inputs))

        for f in inputs:
            if IsFlag(f):
                continue
            intype = filetype.FileType(f)
            if not filetype.IsSourceType(intype):
                if ((output_type == 'pp' and intype != 'S')
                        or (output_type == 'll')
                        or (output_type == 'po' and intype != 'll') or
                    (output_type == 's' and intype not in ('ll', 'po', 'S'))
                        or (output_type == 'o'
                            and intype not in ('ll', 'po', 'S', 's'))):
                    Log.Fatal("%s: Unexpected type of file for '%s'",
                              pathtools.touser(f), gcc_mode)

            if output == '':
                f_output = DefaultOutputName(f, output_type)
            else:
                f_output = output

            namegen = TempNameGen([f], f_output)
            CompileOne(f, output_type, namegen, f_output)
        return 0

    # Linking case
    assert (needs_linking)
    assert (output_type in ('pso', 'so', 'pexe', 'nexe'))

    if output == '':
        output = pathtools.normalize('a.out')
    namegen = TempNameGen(inputs, output)

    # Compile all source files (c/c++/ll) to .po
    for i in xrange(0, len(inputs)):
        if IsFlag(inputs[i]):
            continue
        intype = filetype.FileType(inputs[i])
        if filetype.IsSourceType(intype) or intype == 'll':
            inputs[i] = CompileOne(inputs[i], 'po', namegen)

    # Compile all .s/.S to .o
    if env.getbool('ALLOW_NATIVE'):
        for i in xrange(0, len(inputs)):
            if IsFlag(inputs[i]):
                continue
            intype = filetype.FileType(inputs[i])
            if intype in ('s', 'S'):
                inputs[i] = CompileOne(inputs[i], 'o', namegen)

    # We should only be left with .po and .o and libraries
    for f in inputs:
        if IsFlag(f):
            continue
        intype = filetype.FileType(f)
        if intype in ('o', 's', 'S') or filetype.IsNativeArchive(f):
            if not env.getbool('ALLOW_NATIVE'):
                Log.Fatal(
                    '%s: Native object files not allowed in link. '
                    'Use --pnacl-allow-native to override.',
                    pathtools.touser(f))
        assert (intype in ('po', 'o', 'so', 'ldscript')
                or filetype.IsArchive(f))

    # Fix the user-specified linker arguments
    ld_inputs = []
    for f in inputs:
        if f.startswith('-Xlinker='):
            ld_inputs.append(f[len('-Xlinker='):])
        elif f.startswith('-Wl,'):
            ld_inputs += f[len('-Wl,'):].split(',')
        else:
            ld_inputs.append(f)

    if env.getbool('ALLOW_NATIVE'):
        ld_inputs.append('--pnacl-allow-native')

    # Invoke the linker
    env.set('ld_inputs', *ld_inputs)

    ld_args = env.get('LD_ARGS')
    ld_flags = env.get('LD_FLAGS')

    RunDriver('ld', ld_flags + ld_args + ['-o', output])
    return 0
Exemplo n.º 52
0
def main(argv):
  env.update(EXTRA_ENV)
  ParseArgs(argv, LDPatterns)
  # If the user passed -arch, then they want native output.
  arch_flag_given = GetArch() is not None

  # Both LD_FLAGS_NATIVE and TRANSLATE_FLAGS_USER affect
  # the translation process. If they are non-empty,
  # then --pnacl-allow-native must be given.
  allow_native = env.getbool('ALLOW_NATIVE')
  native_flags = env.get('LD_FLAGS_NATIVE') + env.get('TRANSLATE_FLAGS_USER')
  if len(native_flags) > 0:
    if not allow_native:
      flagstr = ' '.join(native_flags)
      Log.Fatal('"%s" affects translation. '
                'To allow, specify --pnacl-allow-native' % flagstr)

  if env.getbool('ALLOW_NATIVE') and not arch_flag_given:
      Log.Fatal("--pnacl-allow-native given, but translation "
                "is not happening (missing -arch?)")

  if env.getbool('RELOCATABLE'):
    if env.getbool('SHARED'):
      Log.Fatal("-r and -shared may not be used together")
    env.set('STATIC', '0')

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

  if output == '':
    output = pathtools.normalize('a.out')

  if not arch_flag_given:
    # If -arch is not given, assume X86-32.
    # This is because gold requires an arch (even for bitcode linking).
    SetArch('X8632')
  assert(GetArch() is not None)

  # Expand all parameters
  # This resolves -lfoo into actual filenames,
  # and expands linker scripts into command-line arguments.
  inputs = ldtools.ExpandInputs(inputs,
                                env.get('SEARCH_DIRS'),
                                env.getbool('STATIC'),
                                # Once all glibc bitcode link is purely
                                # bitcode (e.g., even libc_nonshared.a)
                                # we may be able to restrict this more.
                                # This is also currently used by
                                # pnacl_generate_pexe=0 with glibc,
                                # for user libraries.
                                ldtools.LibraryTypes.ANY)

  # Make sure the inputs have matching arch.
  CheckInputsArch(inputs)

  regular_inputs, native_objects = SplitLinkLine(inputs)

  if not env.getbool('USE_IRT'):
    inputs = UsePrivateLibraries(inputs)

  # Filter out object files which are currently used in the bitcode link.
  # These don't actually need to be treated separately, since the
  # translator includes them automatically. Eventually, these will
  # be compiled to bitcode or replaced by bitcode stubs, and this list
  # can go away.
  if env.getbool('STDLIB'):
    native_objects = RemoveNativeStdLibs(native_objects)

  if env.getbool('SHARED'):
    bitcode_type = 'pso'
    native_type = 'so'
  elif env.getbool('RELOCATABLE'):
    bitcode_type = 'po'
    native_type = 'o'
  else:
    bitcode_type = 'pexe'
    native_type = 'nexe'

  if native_objects and not allow_native:
    argstr = ' '.join(native_objects)
    Log.Fatal("Native objects '%s' detected in the link. "
              "To allow, specify --pnacl-allow-native" % argstr)

  tng = TempNameGen([], output)

  # Do the bitcode link.
  if HasBitcodeInputs(inputs):
    chain = DriverChain(inputs, output, tng)
    chain.add(LinkBC, 'pre_opt.' + bitcode_type)

    # Some ABI simplification passes assume the whole program is
    # available (e.g. -expand-varargs, -nacl-expand-ctors and
    # -nacl-expand-tls).  While we could try running a subset of
    # simplification passes when linking native objects or enabling
    # C++ exception handling, we don't do this because it complicates
    # testing.  For example, it requires '-expand-constant-expr' to be
    # able to handle 'landingpad' instructions.
    abi_simplify = (env.getbool('STATIC') and
                    len(native_objects) == 0 and
                    not env.getbool('ALLOW_CXX_EXCEPTIONS') and
                    not env.getbool('ALLOW_NEXE_BUILD_ID'))

    preopt_passes = []
    if abi_simplify:
      preopt_passes += ['-pnacl-abi-simplify-preopt']
    elif not env.getbool('ALLOW_CXX_EXCEPTIONS'):
      # '-lowerinvoke' prevents use of C++ exception handling, which
      # is not yet supported in the PNaCl ABI.  '-simplifycfg' removes
      # landingpad blocks made unreachable by '-lowerinvoke'.
      #
      # We run this in order to remove 'resume' instructions,
      # otherwise these are translated to calls to _Unwind_Resume(),
      # which will not be available at native link time.
      preopt_passes += ['-lowerinvoke', '-simplifycfg']
    if len(preopt_passes) != 0:
      chain.add(DoLLVMPasses(preopt_passes), 'simplify_preopt.' + bitcode_type)

    if env.getone('OPT_LEVEL') != '' and env.getone('OPT_LEVEL') != '0':
      chain.add(DoLTO, 'opt.' + bitcode_type)
    elif env.getone('STRIP_MODE') != 'none':
      chain.add(DoStrip, 'stripped.' + bitcode_type)

    if abi_simplify:
      postopt_passes = ['-pnacl-abi-simplify-postopt']
      if not env.getbool('DISABLE_ABI_CHECK'):
        postopt_passes += [
            '-verify-pnaclabi-module',
            '-verify-pnaclabi-functions',
            # A flag for the above -verify-pnaclabi-* passes.
            '-pnaclabi-allow-debug-metadata']
      chain.add(DoLLVMPasses(postopt_passes),
                'simplify_postopt.' + bitcode_type)
  else:
    chain = DriverChain('', output, tng)

  # If -arch is also specified, invoke pnacl-translate afterwards.
  if arch_flag_given:
    env.set('NATIVE_OBJECTS', *native_objects)
    chain.add(DoTranslate, native_type)

  chain.run()

  if bitcode_type == 'pexe' and not arch_flag_given:
    # Mark .pexe files as executable.
    # Some versions of 'configure' expect this.
    SetExecutableMode(output)
  return 0
Exemplo n.º 53
0
def main(argv):
    env.update(EXTRA_ENV)
    ParseArgs(argv, PATTERNS)
    Run('"${NM}" --plugin=${GOLD_PLUGIN_SO} ${ARGS}')
    # only reached in case of no errors
    return 0
Exemplo n.º 54
0
def main(argv):
    env.update(EXTRA_ENV)
    ParseArgs(argv, LDPatterns)
    # If the user passed -arch, then they want native output.
    arch_flag_given = GetArch() is not None

    # Both LD_FLAGS_NATIVE and TRANSLATE_FLAGS_USER affect
    # the translation process. If they are non-empty,
    # then --pnacl-allow-native must be given.
    allow_native = env.getbool('ALLOW_NATIVE')
    native_flags = env.get('LD_FLAGS_NATIVE') + env.get('TRANSLATE_FLAGS_USER')
    if len(native_flags) > 0:
        if not allow_native:
            flagstr = ' '.join(native_flags)
            Log.Fatal('"%s" affects translation. '
                      'To allow, specify --pnacl-allow-native' % flagstr)

    if env.getbool('ALLOW_NATIVE') and not arch_flag_given:
        Log.Fatal("--pnacl-allow-native given, but translation "
                  "is not happening (missing -arch?)")

    # Overriding the lib target uses native-flavored bitcode libs rather than the
    # portable bitcode libs. It is currently only tested/supported for
    # building the IRT.
    if not IsPortable():
        env.set('BASE_USR', "${BASE_USR_ARCH}")
        env.set('BASE_LIB', "${BASE_LIB_ARCH}")

    if env.getbool('RELOCATABLE'):
        env.set('STATIC', '0')

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

    if output == '':
        output = pathtools.normalize('a.out')

    if not arch_flag_given:
        # If -arch is not given, assume X86-32.
        # This is because gold requires an arch (even for bitcode linking).
        SetArch('X8632')
    assert (GetArch() is not None)

    inputs = FixPrivateLibs(inputs)

    # Expand all parameters
    # This resolves -lfoo into actual filenames,
    # and expands linker scripts into command-line arguments.
    inputs = ldtools.ExpandInputs(
        inputs,
        env.get('SEARCH_DIRS'),
        env.getbool('STATIC'),
        # Once all glibc bitcode link is purely
        # bitcode (e.g., even libc_nonshared.a)
        # we may be able to restrict this more.
        # This is also currently used by
        # pnacl_generate_pexe=0 with glibc,
        # for user libraries.
        ldtools.LibraryTypes.ANY)

    # Make sure the inputs have matching arch.
    CheckInputsArch(inputs)

    regular_inputs, native_objects = SplitLinkLine(inputs)

    if env.getbool('RELOCATABLE'):
        bitcode_type = 'po'
        native_type = 'o'
    else:
        bitcode_type = 'pexe'
        native_type = 'nexe'

    if native_objects and not allow_native:
        argstr = ' '.join(native_objects)
        Log.Fatal("Native objects '%s' detected in the link. "
                  "To allow, specify --pnacl-allow-native" % argstr)

    tng = TempNameGen([], output)

    # Do the bitcode link.
    if HasBitcodeInputs(inputs):
        chain = DriverChain(inputs, output, tng)
        chain.add(LinkBC, 'pre_opt.' + bitcode_type)

        # Some ABI simplification passes assume the whole program is
        # available (e.g. -expand-varargs, -nacl-expand-ctors and
        # -nacl-expand-tls).  While we could try running a subset of
        # simplification passes when linking native objects, we don't
        # do this because it complicates testing.  For example,
        # it requires '-expand-constant-expr' to be able to handle
        # 'landingpad' instructions.
        # However, if we aren't using biased bitcode, then at least -expand-byval
        # must be run to work with the PPAPI shim calling convention.
        # This assumes that PPAPI does not use var-args, so passes like
        # -expand-varargs and other calling-convention-changing passes are
        # not needed.
        abi_simplify = (env.getbool('STATIC') and len(native_objects) == 0
                        and env.getone('CXX_EH_MODE') != 'zerocost'
                        and not env.getbool('ALLOW_NEXE_BUILD_ID')
                        and IsPortable())
        still_need_expand_byval = IsPortable()

        abi_simplify_opts = []
        if env.getone('CXX_EH_MODE') == 'sjlj':
            abi_simplify_opts += ['-enable-pnacl-sjlj-eh']

        preopt_passes = []
        if abi_simplify:
            preopt_passes += ['-pnacl-abi-simplify-preopt'] + abi_simplify_opts
        elif env.getone('CXX_EH_MODE') != 'zerocost':
            # '-lowerinvoke' prevents use of C++ exception handling, which
            # is not yet supported in the PNaCl ABI.  '-simplifycfg' removes
            # landingpad blocks made unreachable by '-lowerinvoke'.
            #
            # We run this in order to remove 'resume' instructions,
            # otherwise these are translated to calls to _Unwind_Resume(),
            # which will not be available at native link time.
            preopt_passes += ['-lowerinvoke', '-simplifycfg']
        if len(preopt_passes) != 0:
            chain.add(DoLLVMPasses(preopt_passes),
                      'simplify_preopt.' + bitcode_type)

        if env.getone('OPT_LEVEL') != '' and env.getone('OPT_LEVEL') != '0':
            chain.add(DoLTO, 'opt.' + bitcode_type)
        elif env.getone('STRIP_MODE') != 'none':
            chain.add(DoStrip, 'stripped.' + bitcode_type)

        postopt_passes = []
        if abi_simplify:
            postopt_passes = ['-pnacl-abi-simplify-postopt'
                              ] + abi_simplify_opts
            if not env.getbool('DISABLE_ABI_CHECK'):
                postopt_passes += [
                    '-verify-pnaclabi-module',
                    '-verify-pnaclabi-functions',
                    # A flag for the above -verify-pnaclabi-* passes.
                    '-pnaclabi-allow-debug-metadata'
                ]
                if env.getbool('ALLOW_DEV_INTRINSICS'):
                    # A flag for the above -verify-pnaclabi-* passes.
                    postopt_passes += ['-pnaclabi-allow-dev-intrinsics']
        elif still_need_expand_byval:
            # We may still need -expand-byval to match the PPAPI shim
            # calling convention.
            postopt_passes = ['-expand-byval']
        if len(postopt_passes) != 0:
            chain.add(DoLLVMPasses(postopt_passes),
                      'simplify_postopt.' + bitcode_type)
    else:
        chain = DriverChain('', output, tng)

    # If -arch is also specified, invoke pnacl-translate afterwards.
    if arch_flag_given:
        env.set('NATIVE_OBJECTS', *native_objects)
        chain.add(DoTranslate, native_type)

    chain.run()

    if bitcode_type == 'pexe' and not arch_flag_given:
        # Mark .pexe files as executable.
        # Some versions of 'configure' expect this.
        SetExecutableMode(output)
    return 0
Exemplo n.º 55
0
def main(argv):
  env.update(EXTRA_ENV)
  ParseArgs(argv, LDPatterns)
  # If the user passed -arch, then they want native output.
  arch_flag_given = GetArch() is not None

  # Both LD_FLAGS_NATIVE and TRANSLATE_FLAGS_USER affect
  # the translation process. If they are non-empty,
  # then --pnacl-allow-native must be given.
  allow_native = env.getbool('ALLOW_NATIVE')
  native_flags = env.get('LD_FLAGS_NATIVE') + env.get('TRANSLATE_FLAGS_USER')
  if len(native_flags) > 0:
    if not allow_native:
      flagstr = ' '.join(native_flags)
      Log.Fatal('"%s" affects translation. '
                'To allow, specify --pnacl-allow-native' % flagstr)

  if env.getbool('ALLOW_NATIVE') and not arch_flag_given:
      Log.Fatal("--pnacl-allow-native given, but translation "
                "is not happening (missing -arch?)")

  if env.getbool('RELOCATABLE'):
    if env.getbool('SHARED'):
      Log.Fatal("-r and -shared may not be used together")
    env.set('STATIC', '0')

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

  if output == '':
    output = pathtools.normalize('a.out')

  if not arch_flag_given:
    # If -arch is not given, assume X86-32.
    # This is because gold requires an arch (even for bitcode linking).
    SetArch('X8632')
  assert(GetArch() is not None)

  # Expand all parameters
  # This resolves -lfoo into actual filenames,
  # and expands linker scripts into command-line arguments.
  inputs = ldtools.ExpandInputs(inputs,
                                env.get('SEARCH_DIRS'),
                                env.getbool('STATIC'),
                                # Once all glibc bitcode link is purely
                                # bitcode (e.g., even libc_nonshared.a)
                                # we may be able to restrict this more.
                                # This is also currently used by
                                # pnacl_generate_pexe=0 with glibc,
                                # for user libraries.
                                ldtools.LibraryTypes.ANY)

  # Make sure the inputs have matching arch.
  CheckInputsArch(inputs)

  regular_inputs, native_objects = SplitLinkLine(inputs)

  if not env.getbool('USE_IRT'):
    inputs = UsePrivateLibraries(inputs)

  # Filter out object files which are currently used in the bitcode link.
  # These don't actually need to be treated separately, since the
  # translator includes them automatically. Eventually, these will
  # be compiled to bitcode or replaced by bitcode stubs, and this list
  # can go away.
  if env.getbool('STDLIB'):
    native_objects = RemoveNativeStdLibs(native_objects)

  if env.getbool('SHARED'):
    bitcode_type = 'pso'
    native_type = 'so'
  elif env.getbool('RELOCATABLE'):
    bitcode_type = 'po'
    native_type = 'o'
  else:
    bitcode_type = 'pexe'
    native_type = 'nexe'

  if native_objects and not allow_native:
    argstr = ' '.join(native_objects)
    Log.Fatal("Native objects '%s' detected in the link. "
              "To allow, specify --pnacl-allow-native" % argstr)

  tng = TempNameGen([], output)

  # Do the bitcode link.
  if HasBitcodeInputs(inputs):
    chain = DriverChain(inputs, output, tng)
    chain.add(LinkBC, 'pre_opt.' + bitcode_type)
    if env.getbool('STATIC') and len(native_objects) == 0:
      chain.add(DoExpandCtors, 'expand_ctors.' + bitcode_type)
    if env.getone('OPT_LEVEL') != '0':
      chain.add(DoOPT, 'opt.' + bitcode_type)
    elif env.getone('STRIP_MODE') != 'none':
      chain.add(DoStrip, 'stripped.' + bitcode_type)
  else:
    chain = DriverChain('', output, tng)

  # If -arch is also specified, invoke pnacl-translate afterwards.
  if arch_flag_given:
    env.set('NATIVE_OBJECTS', *native_objects)
    chain.add(DoTranslate, native_type)

  chain.run()

  if bitcode_type == 'pexe' and not arch_flag_given:
    # Add bitcode wrapper header
    WrapBitcode(output)
    # Mark .pexe files as executable.
    # Some versions of 'configure' expect this.
    SetExecutableMode(output)
  return 0
def main(argv):
  env.update(EXTRA_ENV)
  driver_tools.ParseArgs(argv, TranslatorPatterns)
  driver_tools.GetArch(required = True)

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

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

  if output == '':
    Log.Fatal("Please specify output file with -o")

  # Find the bitcode file on the command line.
  bcfiles = [f for f in inputs
             if not ldtools.IsFlag(f) and
               (filetype.IsPNaClBitcode(f)
                or filetype.IsLLVMBitcode(f)
                or filetype.FileType(f) == 'll')]
  if len(bcfiles) > 1:
    Log.Fatal('Expecting at most 1 bitcode file')
  elif len(bcfiles) == 1:
    bcfile = bcfiles[0]
  else:
    bcfile = None

  # If there's a bitcode file, translate it now.
  tng = driver_tools.TempNameGen(inputs + bcfiles, output)
  output_type = env.getone('OUTPUT_TYPE')
  if bcfile:
    sfile = None
    if output_type == 's':
      sfile = output
    elif env.getbool('FORCE_INTERMEDIATE_S'):
      sfile = tng.TempNameForInput(bcfile, 's')

    ofile = None
    if output_type == 'o':
      ofile = output
    elif output_type != 's':
      ofile = tng.TempNameForInput(bcfile, 'o')

    if sfile:
      RunLLC(bcfile, sfile, outfiletype='asm')
      if ofile:
        RunAS(sfile, ofile)
    else:
      RunLLC(bcfile, ofile, outfiletype='obj')
  else:
    ofile = None

  # If we've been told to stop after translation, stop now.
  if output_type in ('o','s'):
    return 0

  # Replace the bitcode file with __BITCODE__ in the input list
  if bcfile:
    inputs = ListReplace(inputs, bcfile, '__BITCODE__')
    env.set('INPUTS', *inputs)

  if env.getone('ARCH') == 'LINUX_X8632':
    RunHostLD(ofile, output)
  else:
    RunLD(ofile, output)
  return 0
Exemplo n.º 57
0
def main(argv):
  env.update(EXTRA_ENV)
  CheckSetup()
  ParseArgs(argv, CustomPatterns + GCCPatterns)

  # "configure", especially when run as part of a toolchain bootstrap
  # process, will invoke gcc with various diagnostic options and
  # parse the output. In these cases we do not alter the incoming
  # commandline. It is also important to not emit spurious messages.
  if env.getbool('DIAGNOSTIC'):
    if env.getbool('SHOW_VERSION'):
      code, stdout, stderr = Run(env.get('CC') + env.get('CC_FLAGS'),
                                 redirect_stdout=subprocess.PIPE)
      out = stdout.split('\n')
      nacl_version = ReadDriverRevision()
      out[0] += ' nacl-version=%s' % nacl_version
      stdout = '\n'.join(out)
      print stdout,
    else:
      Run(env.get('CC') + env.get('CC_FLAGS'))
    return 0

  unmatched = env.get('UNMATCHED')
  if len(unmatched) > 0:
    UnrecognizedOption(*unmatched)

  # If -arch was given, we are compiling directly to native code
  compiling_to_native = GetArch() is not None

  if env.getbool('ALLOW_NATIVE') and not compiling_to_native:
    Log.Fatal("--pnacl-allow-native without -arch is not meaningful.")

  if not env.get('STDLIB'):
    # Default C++ Standard Library.
    SetStdLib('libc++')

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

  if len(inputs) == 0:
    if env.getbool('VERBOSE'):
      # -v can be invoked without any inputs. Runs the original
      # command without modifying the commandline for this case.
      Run(env.get('CC') + env.get('CC_FLAGS'))
      return 0
    else:
      Log.Fatal('No input files')

  gcc_mode = env.getone('GCC_MODE')
  output_type = DriverOutputTypes(gcc_mode, compiling_to_native)
  needs_linking = (gcc_mode == '')

  if env.getbool('NEED_DASH_E') and gcc_mode != '-E':
    Log.Fatal("-E or -x required when input is from stdin")

  # There are multiple input files and no linking is being done.
  # There will be multiple outputs. Handle this case separately.
  if not needs_linking:
    # Filter out flags
    inputs = [f for f in inputs if not IsFlag(f)]
    if output != '' and len(inputs) > 1:
      Log.Fatal('Cannot have -o with -c, -S, or -E and multiple inputs: %s',
                repr(inputs))

    for f in inputs:
      if IsFlag(f):
        continue
      intype = filetype.FileType(f)
      if not filetype.IsSourceType(intype):
        if ((output_type == 'pp' and intype != 'S') or
            (output_type == 'll') or
            (output_type == 'po' and intype != 'll') or
            (output_type == 's' and intype not in ('ll','po','S')) or
            (output_type == 'o' and intype not in ('ll','po','S','s'))):
          Log.Fatal("%s: Unexpected type of file for '%s'",
                    pathtools.touser(f), gcc_mode)

      if output == '':
        f_output = DefaultOutputName(f, output_type)
      else:
        f_output = output

      namegen = TempNameGen([f], f_output)
      CompileOne(f, output_type, namegen, f_output)
    return 0

  # Linking case
  assert(needs_linking)
  assert(output_type in ('pso','so','pexe','nexe'))

  if output == '':
    output = pathtools.normalize('a.out')
  namegen = TempNameGen(inputs, output)

  # Compile all source files (c/c++/ll) to .po
  for i in xrange(0, len(inputs)):
    if IsFlag(inputs[i]):
      continue
    intype = filetype.FileType(inputs[i])
    if filetype.IsSourceType(intype) or intype == 'll':
      inputs[i] = CompileOne(inputs[i], 'po', namegen)

  # Compile all .s/.S to .o
  if env.getbool('ALLOW_NATIVE'):
    for i in xrange(0, len(inputs)):
      if IsFlag(inputs[i]):
        continue
      intype = filetype.FileType(inputs[i])
      if intype in ('s','S'):
        inputs[i] = CompileOne(inputs[i], 'o', namegen)

  # We should only be left with .po and .o and libraries
  for f in inputs:
    if IsFlag(f):
      continue
    intype = filetype.FileType(f)
    if intype in ('o','s','S') or filetype.IsNativeArchive(f):
      if not env.getbool('ALLOW_NATIVE'):
        Log.Fatal('%s: Native object files not allowed in link. '
                  'Use --pnacl-allow-native to override.', pathtools.touser(f))
    assert(intype in ('po','o','so','ldscript') or filetype.IsArchive(f))

  # Fix the user-specified linker arguments
  ld_inputs = []
  for f in inputs:
    if f.startswith('-Xlinker='):
      ld_inputs.append(f[len('-Xlinker='):])
    elif f.startswith('-Wl,'):
      ld_inputs += f[len('-Wl,'):].split(',')
    else:
      ld_inputs.append(f)

  if env.getbool('ALLOW_NATIVE'):
    ld_inputs.append('--pnacl-allow-native')

  # Invoke the linker
  env.set('ld_inputs', *ld_inputs)

  ld_args = env.get('LD_ARGS')
  ld_flags = env.get('LD_FLAGS')

  RunDriver('ld', ld_flags + ld_args + ['-o', output])
  return 0
Exemplo n.º 58
0
def main(argv):
    env.update(EXTRA_ENV)
    CheckSetup()
    ParseArgs(argv, CustomPatterns + GCCPatterns)

    # "configure", especially when run as part of a toolchain bootstrap
    # process, will invoke gcc with various diagnostic options and
    # parse the output. In these cases we do not alter the incoming
    # commandline. It is also important to not emit spurious messages.
    if env.getbool('DIAGNOSTIC'):
        if env.getbool('SHOW_VERSION'):
            code, stdout, stderr = Run(env.get('CC') + env.get('CC_FLAGS'),
                                       redirect_stdout=subprocess.PIPE)
            out = stdout.split('\n')
            nacl_version = ReadDriverRevision()
            out[0] += ' nacl-version=%s' % nacl_version
            stdout = '\n'.join(out)
            print stdout,
        else:
            Run(env.get('CC') + env.get('CC_FLAGS'))
        return 0

    unmatched = env.get('UNMATCHED')
    if len(unmatched) > 0:
        UnrecognizedOption(*unmatched)

    # If -arch was given, we are compiling directly to native code
    compiling_to_native = GetArch() is not None

    if env.getbool('ALLOW_NATIVE'):
        if not compiling_to_native:
            Log.Fatal("--pnacl-allow-native without -arch is not meaningful.")
        # For native/mixed links, also bring in the native libgcc and
        # libcrt_platform to avoid link failure if pre-translated native
        # code needs functions from it.
        env.append('LD_FLAGS', env.eval('-L${LIBS_NATIVE_ARCH}'))
        env.append('STDLIBS', '-lgcc')
        env.append('STDLIBS', '-lcrt_platform')

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

    if len(flags_and_inputs) == 0:
        if env.getbool('VERBOSE'):
            # -v can be invoked without any inputs. Runs the original
            # command without modifying the commandline for this case.
            Run(env.get('CC') + env.get('CC_FLAGS'))
            return 0
        else:
            Log.Fatal('No input files')

    gcc_mode = env.getone('GCC_MODE')
    output_type = DriverOutputTypes(gcc_mode, compiling_to_native)

    # '-shared' modifies the output from the linker and should be considered when
    # determining the final output type.
    if env.getbool('SHARED'):
        if compiling_to_native:
            Log.Fatal('Building native shared libraries not supported')
        if gcc_mode != '':
            Log.Fatal('-c, -S, and -E are disallowed with -shared')
        output_type = 'pll'

    # INPUTS consists of actual input files and a subset of flags like -Wl,<foo>.
    # Create a version with just the files.
    inputs = [f for f in flags_and_inputs if not IsFlag(f)]
    header_inputs = [
        f for f in inputs if filetype.IsHeaderType(filetype.FileType(f))
    ]
    # Handle PCH case specially (but only for a limited sense...)
    if header_inputs and gcc_mode != '-E':
        # We only handle doing pre-compiled headers for all inputs or not at
        # all at the moment. This is because DriverOutputTypes only assumes
        # one type of output, depending on the "gcc_mode" flag. When mixing
        # header inputs w/ non-header inputs, some of the outputs will be
        # pch while others will be output_type. We would also need to modify
        # the input->output chaining for the needs_linking case.
        if len(header_inputs) != len(inputs):
            Log.Fatal('mixed compiling of headers and source not supported')
        CompileHeaders(header_inputs, output)
        return 0

    needs_linking = (gcc_mode == '')

    if env.getbool('NEED_DASH_E') and gcc_mode != '-E':
        Log.Fatal("-E or -x required when input is from stdin")

    # There are multiple input files and no linking is being done.
    # There will be multiple outputs. Handle this case separately.
    if not needs_linking:
        if output != '' and len(inputs) > 1:
            Log.Fatal(
                'Cannot have -o with -c, -S, or -E and multiple inputs: %s',
                repr(inputs))

        for f in inputs:
            intype = filetype.FileType(f)
            if not (filetype.IsSourceType(intype)
                    or filetype.IsHeaderType(intype)):
                if ((output_type == 'pp' and intype != 'S')
                        or (output_type == 'll')
                        or (output_type == 'po' and intype != 'll') or
                    (output_type == 's' and intype not in ('ll', 'po', 'S'))
                        or (output_type == 'o'
                            and intype not in ('ll', 'po', 'S', 's'))):
                    Log.Fatal("%s: Unexpected type of file for '%s'",
                              pathtools.touser(f), gcc_mode)

            if output == '':
                f_output = DefaultOutputName(f, output_type)
            else:
                f_output = output

            namegen = TempNameGen([f], f_output)
            CompileOne(f, output_type, namegen, f_output)
        return 0

    # Linking case
    assert (needs_linking)
    assert (output_type in ('pll', 'pexe', 'nexe'))

    if output == '':
        output = pathtools.normalize('a.out')
    namegen = TempNameGen(flags_and_inputs, output)

    # Compile all source files (c/c++/ll) to .po
    for i in xrange(0, len(flags_and_inputs)):
        if IsFlag(flags_and_inputs[i]):
            continue
        intype = filetype.FileType(flags_and_inputs[i])
        if filetype.IsSourceType(intype) or intype == 'll':
            flags_and_inputs[i] = CompileOne(flags_and_inputs[i], 'po',
                                             namegen)

    # Compile all .s/.S to .o
    if env.getbool('ALLOW_NATIVE'):
        for i in xrange(0, len(flags_and_inputs)):
            if IsFlag(flags_and_inputs[i]):
                continue
            intype = filetype.FileType(flags_and_inputs[i])
            if intype in ('s', 'S'):
                flags_and_inputs[i] = CompileOne(flags_and_inputs[i], 'o',
                                                 namegen)

    # We should only be left with .po and .o and libraries
    for f in flags_and_inputs:
        if IsFlag(f):
            continue
        intype = filetype.FileType(f)
        if intype in ('o', 's', 'S') or filetype.IsNativeArchive(f):
            if not env.getbool('ALLOW_NATIVE'):
                Log.Fatal(
                    '%s: Native object files not allowed in link. '
                    'Use --pnacl-allow-native to override.',
                    pathtools.touser(f))
        assert (intype in ('po', 'o', 'so', 'ldscript')
                or filetype.IsArchive(f))

    # Fix the user-specified linker arguments
    ld_inputs = []
    for f in flags_and_inputs:
        if f.startswith('-Xlinker='):
            ld_inputs.append(f[len('-Xlinker='):])
        elif f.startswith('-Wl,'):
            ld_inputs += f[len('-Wl,'):].split(',')
        else:
            ld_inputs.append(f)

    if env.getbool('ALLOW_NATIVE'):
        ld_inputs.append('--pnacl-allow-native')

    # Invoke the linker
    env.set('ld_inputs', *ld_inputs)

    ld_args = env.get('LD_ARGS')
    ld_flags = env.get('LD_FLAGS')

    RunDriver('pnacl-ld', ld_flags + ld_args + ['-o', output])
    return 0