Exemple #1
0
 def test_ll_bc_filetypes(self):
   if not driver_test_utils.CanRunHost():
     return
   ll, bc = self.getFakeLLAndBitcodeFile()
   self.assertTrue(filetype.FileType(ll.name) == 'll')
   self.assertTrue(filetype.FileType(bc.name) == 'po')
   self.assertFalse(filetype.IsLLVMBitcode(ll.name))
   self.assertTrue(filetype.IsLLVMBitcode(bc.name))
Exemple #2
0
 def test_inplace_finalize(self):
   if not driver_test_utils.CanRunHost():
     return
   ll, bc = self.getFakeLLAndBitcodeFile()
   self.assertTrue(filetype.FileType(bc.name) == 'po')
   self.assertTrue(filetype.IsLLVMBitcode(bc.name))
   self.assertFalse(filetype.IsPNaClBitcode(bc.name))
   driver_tools.RunDriver('finalize', [bc.name])
   self.assertFalse(filetype.IsLLVMBitcode(bc.name))
   self.assertTrue(filetype.IsPNaClBitcode(bc.name))
   self.assertTrue(filetype.FileType(bc.name) == 'pexe')
  def test_ForceFunction(self):
    """Test the internal functions directly."""
    made_up_file1 = 'dummy1'
    filetype.SetForcedFileType('c')
    self.assertEqual(filetype.GetForcedFileType(), 'c')
    filetype.ForceFileType(made_up_file1)
    self.assertEqual(filetype.FileType(made_up_file1), 'c')
    filetype.ForceFileType(made_up_file1)

    made_up_file2 = 'dummy2'
    filetype.SetForcedFileType('cpp')
    filetype.ForceFileType(made_up_file2)
    self.assertEqual(filetype.FileType(made_up_file2), 'cpp')
    filetype.ForceFileType(made_up_file1)
Exemple #4
0
def ArchMerge(filename, must_match):
  file_type = filetype.FileType(filename)
  if file_type in ('o','so'):
    elfheader = elftools.GetELFHeader(filename)
    if not elfheader:
      Log.Fatal("%s: Cannot read ELF header", filename)
    new_arch = elfheader.arch
  elif filetype.IsNativeArchive(filename):
    new_arch = file_type[len('archive-'):]
  else:
    Log.Fatal('%s: Unexpected file type in ArchMerge', filename)

  existing_arch = GetArch()

  if not existing_arch:
    SetArch(new_arch)
    return True
  elif new_arch != existing_arch:
    if must_match:
      msg = "%s: Incompatible object file (%s != %s)"
      logfunc = Log.Fatal
    else:
      msg = "%s: Skipping incompatible object file (%s != %s)"
      logfunc = Log.Warning
    logfunc(msg, filename, new_arch, existing_arch)
    return False
  else: # existing_arch and new_arch == existing_arch
    return True
def CompileOne(infile, output_type, namegen, output=None):
    if output is None:
        output = namegen.TempNameForInput(infile, output_type)

    chain = DriverChain(infile, output, namegen)
    SetupChain(chain, filetype.FileType(infile), output_type)
    chain.run()
    return output
Exemple #6
0
def RunCC(infile, output, mode):
  intype = filetype.FileType(infile)
  typespec = filetype.FileTypeToGCCType(intype)
  include_cxx_headers = (env.get('LANGUAGE') == 'CXX') or (intype == 'c++')
  env.setbool('INCLUDE_CXX_HEADERS', include_cxx_headers)
  if IsStdinInput(infile):
    infile = '-'
  RunWithEnv("${RUN_CC}", infile=infile, output=output,
                          mode=mode,
                          typespec=typespec)
    def test_PathWithSpaces(self):
        '''Test that the driver correctly handles paths containing spaces'''
        if not driver_test_utils.CanRunHost():
            return

        name = os.path.join(self.ShorterTempDir, 'a file')
        self.WriteCFile(name + '.c')
        driver_tools.RunDriver('pnacl-clang',
                               [name + '.c', '-c', '-o', name + '.o'])
        self.assertEqual('po', filetype.FileType(name + '.o'))
Exemple #8
0
def RunCC(infile, output, mode, emit_llvm_flag='-emit-llvm'):
  intype = filetype.FileType(infile)
  typespec = filetype.FileTypeToGCCType(intype)
  include_cxx_headers = ((env.get('LANGUAGE') == 'CXX') or
                         (intype in ('c++', 'c++-header')))
  env.setbool('INCLUDE_CXX_HEADERS', include_cxx_headers)
  if IsStdinInput(infile):
    infile = '-'
  RunWithEnv("${RUN_CC}", infile=infile, output=output,
                          emit_llvm_flag=emit_llvm_flag, mode=mode,
                          typespec=typespec)
Exemple #9
0
 def test_finalize_keep_syms(self):
     """Test that finalize is still able to create a pexe w/ -no-strip-syms."""
     if not driver_test_utils.CanRunHost():
         return
     bc = self.getBCWithDebug()
     self.assertTrue(filetype.FileType(bc.name) == 'po')
     self.assertTrue(filetype.IsLLVMBitcode(bc.name))
     self.assertFalse(filetype.IsPNaClBitcode(bc.name))
     driver_tools.RunDriver('pnacl-finalize', [bc.name, '--no-strip-syms'])
     self.assertFalse(filetype.IsLLVMBitcode(bc.name))
     self.assertTrue(filetype.IsPNaClBitcode(bc.name))
     self.assertTrue(filetype.FileType(bc.name) == 'pexe')
     # Use pnacl-dis instead of llvm-nm, since llvm-nm won't know how to
     # handle finalized bitcode for now:
     # https://code.google.com/p/nativeclient/issues/detail?id=3993
     with self.getTemp(suffix='.ll') as temp_ll:
         driver_tools.RunDriver('pnacl-dis', [bc.name, '-o', temp_ll.name])
         with open(temp_ll.name, 'r') as dis_file:
             file_contents = dis_file.read()
             self.assertTrue(re.search(r'define .*@baz', file_contents))
             self.assertTrue(re.search(r'define .*@foo', file_contents))
Exemple #10
0
def CheckInputsArch(inputs):
  count = 0
  for f in inputs:
    if ldtools.IsFlag(f):
      continue
    elif filetype.IsLLVMBitcode(f) or filetype.IsBitcodeArchive(f):
      pass
    elif filetype.IsNative(f):
      ArchMerge(f, True)
    else:
      Log.Fatal("%s: Unexpected type of file for linking (%s)",
                pathtools.touser(f), filetype.FileType(f))
    count += 1

  if count == 0:
    Log.Fatal("no input files")
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
Exemple #12
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
Exemple #13
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
Exemple #14
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
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
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