Example #1
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, 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
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
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
Example #5
0
def RunTranslate(infile, output, mode):
  if not env.getbool('ALLOW_TRANSLATE'):
    Log.Fatal('%s: Trying to convert bitcode to an object file before '
              'bitcode linking. This is supposed to wait until '
              'translation. Use --pnacl-allow-translate to override.',
              pathtools.touser(infile))
  args = env.get('TRANSLATE_FLAGS') + [mode, infile, '-o', output]
  if env.getbool('PIC'):
    args += ['-fPIC']
  RunDriver('translate', args)
Example #6
0
def RunTranslate(infile, output, mode):
  if not env.getbool('ALLOW_TRANSLATE'):
    Log.Fatal('%s: Trying to convert bitcode to an object file before '
              'bitcode linking. This is supposed to wait until '
              'translation. Use --pnacl-allow-translate to override.',
              pathtools.touser(infile))
  args = env.get('TRANSLATE_FLAGS') + [mode, infile, '-o', output]
  if env.getbool('PIC'):
    args += ['-fPIC']
  RunDriver('translate', args)
Example #7
0
def SetUpArch():
  base_arch = env.getone('BASE_ARCH')
  env.set('TARGET_OS', 'nacl')
  if base_arch.endswith('_LINUX'):
    base_arch = base_arch[:-len('_LINUX')]
    env.set('TARGET_OS', 'linux')
  elif base_arch.endswith('_MAC'):
    base_arch = base_arch[:-len('_MAC')]
    env.set('TARGET_OS', 'mac')

  if env.getbool('NONSFI_NACL'):
    triple_map = {
        'nacl':
            {'X8632': 'i686-linux-gnu',
             'ARM': 'armv7a-linux-gnueabihf'}}
  else:
    triple_map = {
        'nacl':
            {'X8632': 'i686-none-nacl-gnu',
             'X8664': 'x86_64-none-nacl-gnu',
             'ARM': 'armv7a-none-nacl-gnueabihf',
             'MIPS32': 'mipsel-none-nacl-gnu'},
        'linux': {'X8632': 'i686-linux-gnu'},
        'mac': {'X8632': 'i686-apple-darwin'}}
  env.set('TRIPLE', triple_map[env.getone('TARGET_OS')][base_arch])

  # CPU that is representative of baseline feature requirements for NaCl
  # and/or chrome.  We may want to make this more like "-mtune"
  # by specifying both "-mcpu=X" and "-mattr=+feat1,-feat2,...".
  # Note: this may be different from the in-browser translator, which may
  # do auto feature detection based on CPUID, but constrained by what is
  # accepted by NaCl validators.
  cpu_map = {
      'X8632': 'pentium4',
      'X8664': 'core2',
      'ARM': 'cortex-a9',
      'MIPS32': 'mips32r2'}
  env.set('LLC_MCPU', '-mcpu=%s' % cpu_map[base_arch])

  llc_flags_map = {
      'ARM': ['-arm-reserve-r9', '-sfi-disable-cp', '-sfi-load', '-sfi-store',
              '-sfi-stack', '-sfi-branch', '-sfi-data',
              '-no-inline-jumptables', '-float-abi=hard', '-mattr=+neon'],
      # Once PNaCl's build of compiler-rt (libgcc.a) defines __aeabi_*
      # functions, we can drop the following ad-hoc option.
      'ARM_NONSFI': ['-arm-enable-aeabi-functions=0'],
      'MIPS32': ['-sfi-load', '-sfi-store', '-sfi-stack',
                 '-sfi-branch', '-sfi-data']}
  env.set('LLC_FLAGS_ARCH', *llc_flags_map.get(env.getone('ARCH'), []))
  # When linking against a host OS's libc (such as Linux glibc), don't
  # use %gs:0 to read the thread pointer because that won't be
  # compatible with the libc's use of %gs:0.  Similarly, Non-SFI Mode
  # currently offers no optimized path for reading the thread pointer.
  if env.getone('TARGET_OS') != 'nacl' or env.getbool('NONSFI_NACL'):
    env.append('LLC_FLAGS_ARCH', '-mtls-use-call')
Example #8
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
Example #9
0
def RunTranslate(infile, output, mode):
    if not env.getbool("ALLOW_TRANSLATE"):
        Log.Fatal(
            "%s: Trying to convert bitcode to an object file before "
            "bitcode linking. This is supposed to wait until "
            "translation. Use --pnacl-allow-translate to override.",
            pathtools.touser(infile),
        )
    args = env.get("TRANSLATE_FLAGS") + [mode, infile, "-o", output]
    if env.getbool("PIC"):
        args += ["-fPIC"]
    RunDriver("translate", args)
Example #10
0
def RunLD(infile, outfile):
    inputs = env.get('INPUTS')
    if infile:
        inputs = ListReplace(inputs, '__BITCODE__',
                             '--llc-translated-file=' + infile)
    ToggleDefaultCommandlineLD(inputs, infile)
    env.set('ld_inputs', *inputs)
    args = env.get('LD_ARGS') + ['-o', outfile]
    if not env.getbool('SHARED') and env.getbool('STDLIB'):
        args += env.get('LD_ARGS_ENTRY')
    args += env.get('LD_FLAGS')
    driver_tools.RunDriver('nativeld', args)
Example #11
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
Example #12
0
def RunLD(infile, outfile):
    inputs = env.get("INPUTS")
    if infile:
        inputs = ListReplace(inputs, "__BITCODE__", "--llc-translated-file=" + infile)
    ToggleDefaultCommandlineLD(inputs, infile)
    env.set("ld_inputs", *inputs)
    args = env.get("LD_ARGS") + ["-o", outfile]
    if not env.getbool("SHARED") and env.getbool("STDLIB"):
        args += env.get("LD_ARGS_ENTRY")
    args += env.get("LD_FLAGS")
    # If there is bitcode, there is also a metadata file.
    if infile and env.getbool("USE_META"):
        args += ["--metadata", "%s.meta" % infile]
    driver_tools.RunDriver("nativeld", args)
Example #13
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
Example #14
0
def RunLLC(infile, outfile, filetype):
  env.push()
  env.setmany(input=infile, output=outfile, filetype=filetype)
  if env.getbool('SANDBOXED'):
    is_shared, soname, needed = RunLLCSandboxed()
    env.pop()
    # soname and dt_needed libs are returned from LLC and passed to LD
    driver_tools.SetBitcodeMetadata(infile, is_shared, soname, needed)
  else:
    driver_tools.Run("${RUN_LLC}")
    # As a side effect, this creates a temporary file
    if not env.getbool('SAVE_TEMPS'):
      TempFiles.add(outfile + '.meta')
    env.pop()
  return 0
Example #15
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
Example #16
0
def RunCompiler(infile, outfile, outfiletype, use_sz):
  env.push()
  env.setmany(input=infile, output=outfile, outfiletype=outfiletype)
  if env.getbool('SANDBOXED'):
    RunSandboxedCompiler(use_sz)
  else:
    args = ["${RUN_SZ}" if use_sz else "${RUN_LLC}"]
    if filetype.IsPNaClBitcode(infile):
      args.append("-bitcode-format=pnacl")
    elif filetype.IsLLVMBitcode(infile):
      if not env.getbool('ALLOW_LLVM_BITCODE_INPUT'):
        Log.Fatal('Translator expects finalized PNaCl bitcode. '
                  'Pass --allow-llvm-bitcode-input to override.')
    driver_tools.Run(' '.join(args))
  env.pop()
  return 0
Example #17
0
def RunSandboxedCompiler(use_sz):
  driver_tools.CheckTranslatorPrerequisites()
  infile = env.getone('input')
  is_pnacl = filetype.IsPNaClBitcode(infile)
  if not is_pnacl and not env.getbool('ALLOW_LLVM_BITCODE_INPUT'):
    Log.Fatal('Translator expects finalized PNaCl bitcode. '
              'Pass --allow-llvm-bitcode-input to override.')
  threads = int(env.getone('SPLIT_MODULE'))
  command = [driver_tools.SelLdrCommand(),
             '-a', # Allow file access
             '-E NACL_IRT_PNACL_TRANSLATOR_COMPILE_INPUT=%s' % infile]
  driver_tools.AddListToEnv(command, 'NACL_IRT_PNACL_TRANSLATOR_COMPILE_OUTPUT',
                            GetObjectFiles(use_sz))
  driver_tools.AddListToEnv(command, 'NACL_IRT_PNACL_TRANSLATOR_COMPILE_ARG',
                            BuildOverrideCompilerCommandLine(is_pnacl, use_sz))
  command.extend(['-E NACL_IRT_PNACL_TRANSLATOR_COMPILE_THREADS=%d' % threads,
                  '--'])
  if use_sz:
    command.append('${PNACL_SZ_SB}')
  else:
    command.append('${LLC_SB}')
  driver_tools.Run(' '.join(command),
                   # stdout/stderr will be automatically dumped
                   # upon failure
                   redirect_stderr=subprocess.PIPE,
                   redirect_stdout=subprocess.PIPE)
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
Example #19
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
def RunCompiler(infile, outfile, outfiletype, use_sz):
  env.push()
  env.setmany(input=infile, output=outfile, outfiletype=outfiletype)
  if env.getbool('SANDBOXED'):
    RunSandboxedCompiler(use_sz)
  else:
    args = ["${RUN_SZ}" if use_sz else "${RUN_LLC}"]
    if filetype.IsPNaClBitcode(infile):
      args.append("-bitcode-format=pnacl")
    elif filetype.IsLLVMBitcode(infile):
      if not env.getbool('ALLOW_LLVM_BITCODE_INPUT'):
        Log.Fatal('Translator expects finalized PNaCl bitcode. '
                  'Pass --allow-llvm-bitcode-input to override.')
    driver_tools.Run(' '.join(args))
  env.pop()
  return 0
Example #21
0
def RunLD(infile, outfile):
  inputs = env.get('INPUTS')
  if infile:
    # Put llc-translated-file at the beginning of the inputs so that it will
    # pull in all needed symbols from any native archives that may also be
    # in the input list. This is in case there are any mixed groups of bitcode
    # and native archives in the link (as is the case with irt_browser_lib)
    inputs.remove('__BITCODE__')
    inputs = ['--llc-translated-file=' + infile] + inputs
  ToggleDefaultCommandlineLD(inputs, infile)
  env.set('ld_inputs', *inputs)
  args = env.get('LD_ARGS') + ['-o', outfile]
  if not env.getbool('SHARED') and env.getbool('USE_STDLIB'):
    args += env.get('LD_ARGS_ENTRY')
  args += env.get('LD_FLAGS')
  driver_tools.RunDriver('nativeld', args)
Example #22
0
def RunLD(infile, outfile):
  inputs = env.get('INPUTS')
  if infile:
    inputs = ListReplace(inputs,
                         '__BITCODE__',
                         '--llc-translated-file=' + infile)
  ToggleDefaultCommandlineLD(inputs, infile)
  env.set('ld_inputs', *inputs)
  args = env.get('LD_ARGS') + ['-o', outfile]
  if not env.getbool('SHARED') and env.getbool('STDLIB'):
    args += env.get('LD_ARGS_ENTRY')
  args += env.get('LD_FLAGS')
  # If there is bitcode, there is also a metadata file.
  if infile and env.getbool('USE_META'):
    args += ['--metadata', '%s.meta' % infile]
  driver_tools.RunDriver('nativeld', args)
Example #23
0
def AddUrlForAllArches(json_dict, shortname):
  KNOWN_NMF_ARCHES = ['x86-32', 'x86-64', 'arm']
  for arch in KNOWN_NMF_ARCHES:
    json_dict[arch] = {}
    if env.getbool('FLAT_URL_SCHEME'):
      json_dict[arch]['url'] = '%s' % shortname
    else:
      json_dict[arch]['url'] = 'lib-%s/%s' % (arch, shortname)
Example #24
0
def AddUrlForAllArches(json_dict, shortname):
    KNOWN_NMF_ARCHES = ['x86-32', 'x86-64', 'arm']
    for arch in KNOWN_NMF_ARCHES:
        json_dict[arch] = {}
        if env.getbool('FLAT_URL_SCHEME'):
            json_dict[arch]['url'] = '%s' % shortname
        else:
            json_dict[arch]['url'] = 'lib-%s/%s' % (arch, shortname)
Example #25
0
def MakeSelUniversalScriptForLD(ld_flags,
                                main_input,
                                files,
                                outfile):
  """ Return sel_universal script text for invoking LD.nexe with the
      given ld_flags, main_input (which is treated specially), and
      other input files. The output will be written to outfile.  """
  script = []

  # Open the output file.
  script.append('readwrite_file nexefile %s' % outfile)

  # Need to include the linker script file as a linker resource for glibc.
  files_to_map = list(files)

  use_default = env.getbool('USE_DEFAULT_CMD_LINE')
  # Create a mapping for each input file and add it to the command line.
  for f in files_to_map:
    basename = pathtools.basename(f)
    # If we are using the dummy shim, map it with the filename of the real
    # shim, so the baked-in commandline will work
    if basename == 'libpnacl_irt_shim_dummy.a' and use_default:
       basename = 'libpnacl_irt_shim.a'
    script.append('reverse_service_add_manifest_mapping files/%s %s' %
                  (basename, f))

  if use_default:
    # Assume static linking for now.
    soname = ''
    needed = ''
    is_shared_library = 0

    script.append('readonly_file objfile %s' % main_input)
    script.append(('rpc RunWithDefaultCommandLine ' +
                   'h(objfile) h(nexefile) i(%d) s("%s") s("%s") *'
                   % (is_shared_library, soname, needed)))
  else:
    # Join all the arguments.
    # Based on the format of RUN_LD, the order of arguments is:
    # ld_flags, then input files (which are more sensitive to order).

    # For the sandboxed build, we don't want "real" filesystem paths,
    # because we use the reverse-service to do a lookup -- make sure
    # everything is a basename first.
    ld_flags = [ pathtools.basename(flag) for flag in ld_flags ]
    kTerminator = '\0'
    command_line = kTerminator.join(['ld'] + ld_flags) + kTerminator
    for f in files:
      basename = pathtools.basename(f)
      command_line = command_line + basename + kTerminator

    command_line_escaped = command_line.replace(kTerminator, '\\x00')
    # Assume that the commandline captures all necessary metadata for now.
    script.append('rpc Run h(nexefile) C(%d,%s) *' %
                  (len(command_line), command_line_escaped))
  script.append('echo "ld complete"')
  script.append('')
  return '\n'.join(script)
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
def UseDefaultCommandlineLLC():
  if not env.getbool('USE_DEFAULT_CMD_LINE'):
    return False
  else:
    reason, non_standard = RequiresNonStandardLLCCommandline()
    if non_standard:
      Log.Info(reason + ' -- not using default SRPC commandline for LLC!')
      return False
    return True
Example #28
0
def RequiresNonStandardLDCommandline(inputs, infile):
    """ Determine when we must force USE_DEFAULT_CMD_LINE off for running
  the sandboxed LD (if link line is completely non-standard).
  """
    if len(inputs) > 1:
        # There must have been some native objects on the link line.
        # In that case, if we are using the sandboxed translator, we cannot
        # currently allow that with the default commandline (only one input).
        return ("Native link with more than one native object: %s" % str(inputs), True)
    if not infile:
        return ("No bitcode input: %s" % str(infile), True)
    if not env.getbool("STDLIB"):
        return ("NOSTDLIB", True)
    if not env.getbool("USE_IRT"):
        return ("USE_IRT false when normally true", True)
    if not env.getbool("SHARED") and not env.getbool("USE_IRT_SHIM"):
        return ("USE_IRT_SHIM false when normally true", True)
    return (None, False)
Example #29
0
def UseDefaultCommandlineLLC():
  if not env.getbool('USE_DEFAULT_CMD_LINE'):
    return False
  else:
    reason, non_standard = RequiresNonStandardLLCCommandline()
    if non_standard:
      Log.Info(reason + ' -- not using default SRPC commandline for LLC!')
      return False
    return True
Example #30
0
def RequiresNonStandardLLCCommandline():
  if env.getbool('FAST_TRANSLATION'):
    return ('FAST_TRANSLATION', True)

  extra_flags = env.get('LLC_FLAGS_EXTRA')
  if extra_flags != []:
    reason = 'Has additional llc flags: %s' % extra_flags
    return (reason, True)

  return (None, False)
Example #31
0
def RunLLC(infile, outfile, outfiletype):
  env.push()
  env.setmany(input=infile, output=outfile, outfiletype=outfiletype)
  if env.getbool('SANDBOXED'):
    is_shared, soname, needed = RunLLCSandboxed()
    # Ignore is_shared, soname, and needed for now, since we aren't
    # dealing with bitcode shared libraries.
    env.pop()
  else:
    args = ["${RUN_LLC}"]
    if filetype.IsPNaClBitcode(infile):
      args.append("-bitcode-format=pnacl")
    elif filetype.IsLLVMBitcode(infile):
      if not env.getbool('ALLOW_LLVM_BITCODE_INPUT'):
        Log.Fatal('Translator expects finalized PNaCl bitcode. '
                  'Pass --allow-llvm-bitcode-input to override.')
    driver_tools.Run(' '.join(args))
    env.pop()
  return 0
Example #32
0
def RemoveNativeStdLibs(objs):
  # For newlib, all standard libraries are already bitcode.
  if env.getbool('LIBMODE_NEWLIB'):
    return objs

  # GLibC standard libraries
  defaultlibs = ['libc_nonshared.a', 'libpthread_nonshared.a',
                 'libc.a', 'libstdc++.a', 'libgcc.a', 'libgcc_eh.a',
                 'libm.a']
  return [f for f in objs if pathtools.split(f)[1] not in defaultlibs]
Example #33
0
def RemoveNativeStdLibs(objs):
  # For newlib, all standard libraries are already bitcode.
  if env.getbool('LIBMODE_NEWLIB'):
    return objs

  # GLibC standard libraries
  defaultlibs = ['libc_nonshared.a', 'libpthread_nonshared.a',
                 'libc.a', 'libstdc++.a', 'libgcc.a', 'libgcc_eh.a',
                 'libm.a']
  return [f for f in objs if pathtools.split(f)[1] not in defaultlibs]
def RunLLC(infile, outfile, outfiletype):
  env.push()
  env.setmany(input=infile, output=outfile, outfiletype=outfiletype)
  if env.getbool('SANDBOXED'):
    is_shared, soname, needed = RunLLCSandboxed()
    # Ignore is_shared, soname, and needed for now, since we aren't
    # dealing with bitcode shared libraries.
    env.pop()
  else:
    args = ["${RUN_LLC}"]
    if filetype.IsPNaClBitcode(infile):
      args.append("-bitcode-format=pnacl")
    elif filetype.IsLLVMBitcode(infile):
      if not env.getbool('ALLOW_LLVM_BITCODE_INPUT'):
        Log.Fatal('Translator expects finalized PNaCl bitcode. '
                  'Pass --allow-llvm-bitcode-input to override.')
    driver_tools.Run(' '.join(args))
    env.pop()
  return 0
Example #35
0
def RequiresNonStandardLLCCommandline():
    if env.getbool("FAST_TRANSLATION"):
        return ("FAST_TRANSLATION", True)

    extra_flags = env.get("LLC_FLAGS_EXTRA")
    if extra_flags != []:
        reason = "Has additional llc flags: %s" % extra_flags
        return (reason, True)

    return (None, False)
def Run(args,
        errexit=True,
        redirect_stdout=None,
        redirect_stderr=None):
  """ Run: Run a command.
      Returns: return_code, stdout, stderr

      Run() is used to invoke "other" tools, e.g.
      those NOT prefixed with "pnacl-"

      stdout and stderr only contain meaningful data if
          redirect_{stdout,stderr} == subprocess.PIPE

      Run will terminate the program upon failure unless errexit == False
      TODO(robertm): errexit == True has not been tested and needs more work

      redirect_stdout and redirect_stderr are passed straight
      to subprocess.Popen
  """

  result_stdout = None
  result_stderr = None
  if isinstance(args, str):
    args = shell.split(env.eval(args))

  args = [pathtools.tosys(args[0])] + args[1:]

  Log.Info('Running: ' + StringifyCommand(args))

  if env.getbool('DRY_RUN'):
    if redirect_stderr or redirect_stdout:
      # TODO(pdox): Prevent this from happening, so that
      # dry-run is more useful.
      Log.Fatal("Unhandled dry-run case.")
    return 0, None, None

  try:
    # If we have too long of a cmdline on windows, running it would fail.
    # Attempt to use a file with the command line options instead in that case.
    if ArgsTooLongForWindows(args):
      actual_args = ConvertArgsToFile(args)
      Log.Info('Wrote long commandline to file for Windows: ' +
               StringifyCommand(actual_args))

    else:
      actual_args = args

    p = subprocess.Popen(actual_args,
                         stdout=redirect_stdout,
                         stderr=redirect_stderr)
    result_stdout, result_stderr = p.communicate()
  except Exception, e:
    msg =  '%s\nCommand was: %s' % (str(e), StringifyCommand(args))
    print(msg)
    DriverExit(1)
Example #37
0
def Run(args,
        errexit=True,
        redirect_stdout=None,
        redirect_stderr=None):
  """ Run: Run a command.
      Returns: return_code, stdout, stderr

      Run() is used to invoke "other" tools, e.g.
      those NOT prefixed with "pnacl-"

      stdout and stderr only contain meaningful data if
          redirect_{stdout,stderr} == subprocess.PIPE

      Run will terminate the program upon failure unless errexit == False
      TODO(robertm): errexit == True has not been tested and needs more work

      redirect_stdout and redirect_stderr are passed straight
      to subprocess.Popen
  """

  result_stdout = None
  result_stderr = None
  if isinstance(args, str):
    args = shell.split(env.eval(args))

  args = [pathtools.tosys(args[0])] + args[1:]

  Log.Info('Running: ' + StringifyCommand(args))

  if env.getbool('DRY_RUN'):
    if redirect_stderr or redirect_stdout:
      # TODO(pdox): Prevent this from happening, so that
      # dry-run is more useful.
      Log.Fatal("Unhandled dry-run case.")
    return 0, None, None

  try:
    # If we have too long of a cmdline on windows, running it would fail.
    # Attempt to use a file with the command line options instead in that case.
    if ArgsTooLongForWindows(args):
      actual_args = ConvertArgsToFile(args)
      Log.Info('Wrote long commandline to file for Windows: ' +
               StringifyCommand(actual_args))

    else:
      actual_args = args

    p = subprocess.Popen(actual_args,
                         stdout=redirect_stdout,
                         stderr=redirect_stderr)
    result_stdout, result_stderr = p.communicate()
  except Exception, e:
    msg =  '%s\nCommand was: %s' % (str(e), StringifyCommand(args))
    print msg
    DriverExit(1)
Example #38
0
def SetUpLinkOptions():
  if env.getbool('TRANSLATE_PSO'):
    # Using "-pie" rather than "-shared" has the effect of suppressing the
    # creation of a PLT and R_*_JUMP_SLOT relocations, which come from the
    # external symbol references that multi-threaded translation produces.
    env.append('LD_FLAGS', '-pie')
    return

  if env.getbool('NONSFI_NACL'):
    # "_begin" allows a PIE to find its load address in order to apply
    # dynamic relocations.
    env.append('LD_FLAGS', '-defsym=_begin=0')
    env.append('LD_FLAGS', '-pie')
  else:
    env.append('LD_FLAGS', '-static')
    # Give non-IRT builds 12MB of text before starting rodata instead of
    # the larger default gap. The gap cannot be too small (e.g., 0) because
    # sel_ldr requires space for adding a halt sled.
    if not env.getbool('USE_IRT'):
      env.append('LD_FLAGS', '--rosegment-gap=0xc00000')
def SetUpLinkOptions():
  if env.getbool('TRANSLATE_PSO'):
    # Using "-pie" rather than "-shared" has the effect of suppressing the
    # creation of a PLT and R_*_JUMP_SLOT relocations, which come from the
    # external symbol references that multi-threaded translation produces.
    env.append('LD_FLAGS', '-pie')
    return

  if env.getbool('NONSFI_NACL'):
    # "_begin" allows a PIE to find its load address in order to apply
    # dynamic relocations.
    env.append('LD_FLAGS', '-defsym=_begin=0')
    env.append('LD_FLAGS', '-pie')
  else:
    env.append('LD_FLAGS', '-static')
    # Give non-IRT builds 12MB of text before starting rodata instead of
    # the larger default gap. The gap cannot be too small (e.g., 0) because
    # sel_ldr requires space for adding a halt sled.
    if not env.getbool('USE_IRT'):
      env.append('LD_FLAGS', '--rosegment-gap=0xc00000')
Example #40
0
  def TempNameForInput(self, input, imtype):
    fullpath = pathtools.abspath(input)
    # If input is already a temporary name, just change the extension
    if fullpath.startswith(self.TempBase):
      temp = self.TempBase + '.' + imtype
    else:
      # Source file
      temp = self.TempMap[fullpath] + '.' + imtype

    if not env.getbool('SAVE_TEMPS'):
      TempFiles.add(temp)
    return temp
def RequiresNonStandardLDCommandline(inputs, infile):
    ''' Determine when we must force USE_DEFAULT_CMD_LINE off for running
  the sandboxed LD (if link line is completely non-standard).
  '''
    if len(inputs) > 1:
        # There must have been some native objects on the link line.
        # In that case, if we are using the sandboxed translator, we cannot
        # currently allow that with the default commandline (only one input).
        return ('Native link with more than one native object: %s' %
                str(inputs), True)
    if not infile:
        return ('No bitcode input: %s' % str(infile), True)
    if not env.getbool('USE_STDLIB'):
        return ('NOSTDLIB', True)
    if env.getbool('ALLOW_ZEROCOST_CXX_EH'):
        return ('ALLOW_ZEROCOST_CXX_EH', True)
    if not env.getbool('USE_IRT'):
        return ('USE_IRT false when normally true', True)
    if not env.getbool('USE_IRT_SHIM'):
        return ('USE_IRT_SHIM false when normally true', True)
    return (None, False)
def RequiresNonStandardLDCommandline(inputs, infile):
  ''' Determine when we must force USE_DEFAULT_CMD_LINE off for running
  the sandboxed LD (if link line is completely non-standard).
  '''
  if len(inputs) > 1:
    # There must have been some native objects on the link line.
    # In that case, if we are using the sandboxed translator, we cannot
    # currently allow that with the default commandline (only one input).
    return ('Native link with more than one native object: %s' % str(inputs),
            True)
  if not infile:
    return ('No bitcode input: %s' % str(infile), True)
  if not env.getbool('USE_STDLIB'):
    return ('NOSTDLIB', True)
  if env.getbool('ALLOW_CXX_EXCEPTIONS'):
    return ('ALLOW_CXX_EXCEPTIONS', True)
  if not env.getbool('USE_IRT'):
    return ('USE_IRT false when normally true', True)
  if not env.getbool('USE_IRT_SHIM'):
    return ('USE_IRT_SHIM false when normally true', True)
  return (None, False)
Example #43
0
  def TempNameForInput(self, input, imtype):
    fullpath = pathtools.abspath(input)
    # If input is already a temporary name, just change the extension
    if fullpath.startswith(self.TempBase):
      temp = self.TempBase + '.' + imtype
    else:
      # Source file
      temp = self.TempMap[fullpath] + '.' + imtype

    if not env.getbool('SAVE_TEMPS'):
      TempFiles.add(temp)
    return temp
Example #44
0
def CheckTranslatorPrerequisites():
  """ Assert that the scons artifacts for running the sandboxed translator
      exist: sel_ldr, and the IRT blob. """
  if env.getbool('DRY_RUN'):
    return
  reqs = ['SEL_LDR', 'IRT_BLOB']
  # Linux also requires the nacl bootstrap helper.
  if GetBuildOS() == 'linux':
    reqs.append('BOOTSTRAP_LDR')
  for var in reqs:
    needed_file = env.getone(var)
    if not pathtools.exists(needed_file):
      Log.Fatal('Could not find %s [%s]', var, needed_file)
Example #45
0
def CheckTranslatorPrerequisites():
  """ Assert that the scons artifacts for running the sandboxed translator
      exist: sel_universal, and sel_ldr. """
  if env.getbool('DRY_RUN'):
    return
  reqs = ['SEL_UNIVERSAL', 'SEL_LDR']
  # Linux also requires the nacl bootstrap helper.
  if GetBuildOS() == 'linux':
    reqs.append('BOOTSTRAP_LDR')
  for var in reqs:
    needed_file = env.getone(var)
    if not pathtools.exists(needed_file):
      Log.Fatal('Could not find %s [%s]', var, needed_file)
Example #46
0
def SetUpLinkOptions():
  if env.getbool('NONSFI_NACL'):
    # "_begin" allows a PIE to find its load address in order to apply
    # dynamic relocations.
    env.append('LD_FLAGS', '-defsym=_begin=0')
    if env.getbool('USE_IRT'):
      env.append('LD_FLAGS', '-pie')
    else:
      # Note that we really want to use "-pie" for this case, but it
      # currently adds a PT_INTERP header to the executable that we don't
      # want because it stops the executable from being loadable by Linux.
      # TODO(mseaborn): Add a linker option to omit PT_INTERP.
      env.append('LD_FLAGS', '-static')
      # Set _DYNAMIC to a dummy value.  TODO(mseaborn): Remove this when we
      # use "-pie" instead of "-static" for this case.
      env.append('LD_FLAGS', '-defsym=_DYNAMIC=1')
  else:
    env.append('LD_FLAGS', '-static')
    # Give non-IRT builds 12MB of text before starting rodata instead of
    # the larger default gap. The gap cannot be too small (e.g., 0) because
    # sel_ldr requires space for adding a halt sled.
    if not env.getbool('USE_IRT'):
      env.append('LD_FLAGS', '--rosegment-gap=0xc00000')
Example #47
0
def RunLLC(infile, outfile, filetype):
    env.push()
    env.setmany(input=infile, output=outfile, filetype=filetype)
    if env.getbool('SANDBOXED'):
        is_shared, soname, needed = RunLLCSandboxed()
        env.pop()
        # soname and dt_needed libs are returned from LLC and passed to LD
        driver_tools.SetBitcodeMetadata(infile, is_shared, soname, needed)
    else:
        args = ["${RUN_LLC}"]
        if driver_tools.IsPNaClBitcode(infile):
            args.append("-bitcode-format=pnacl")
        driver_tools.Run(' '.join(args))
        env.pop()
    return 0
Example #48
0
def SetStdLib(*args):
    """Set the C++ Standard Library."""
    lib = args[0]
    assert lib == 'libc++' or lib == 'libstdc++', (
        'Invalid C++ standard library: -stdlib=%s' % lib)
    env.set('STDLIB', lib)
    env.set('STDLIB_TRUNC', lib[3:])
    if lib == 'libc++':
        env.set('STDLIB_IDIR', 'v1')
        if env.getbool('IS_CXX'):
            # libc++ depends on pthread for C++11 features as well as some
            # exception handling (which may get removed later by the PNaCl ABI
            # simplification) and initialize-once.
            env.set('PTHREAD', '1')
    elif lib == 'libstdc++':
        env.set('STDLIB_IDIR', '4.6.2')
Example #49
0
def DriverOutputTypes(driver_flag, compiling_to_native):
  if env.getbool('SHARED'):
    bclink_output = 'pso'
    link_output = 'so'
  else:
    bclink_output = 'pexe'
    link_output = 'nexe'
  output_type_map = {
    ('-E', False) : 'pp',
    ('-E', True)  : 'pp',
    ('-c', False) : 'po',
    ('-c', True)  : 'o',
    ('-S', False) : 'll',
    ('-S', True)  : 's',
    ('',   False) : bclink_output,
    ('',   True)  : link_output
  }
  return output_type_map[(driver_flag, compiling_to_native)]
Example #50
0
def ApplyBitcodeConfig(metadata, bctype):
    # Read the bitcode metadata to extract library
    # dependencies and SOName.
    # For now, we use LD_FLAGS to convey the information.
    # However, if the metadata becomes richer we will need another mechanism.
    # TODO(jvoung): at least grep out the SRPC output from LLC and transmit
    # that directly to LD to avoid issues with mismatching delimiters.
    for needed in metadata['NeedsLibrary']:
        env.append('LD_FLAGS', '--add-extra-dt-needed=' + needed)
    if bctype == 'pso':
        soname = metadata['SOName']
        if soname:
            env.append('LD_FLAGS', '-soname=' + soname)

    # For the current LD final linker, native libraries still need to be
    # linked directly, since --add-extra-dt-needed isn't enough.
    # BUG= http://code.google.com/p/nativeclient/issues/detail?id=2451
    # For the under-construction gold final linker, it expects to have
    # the needed libraries on the commandline as "-llib1 -llib2", which actually
    # refer to the stub metadata file.
    for needed in metadata['NeedsLibrary']:
        # Specify the ld-nacl-${arch}.so as the --dynamic-linker to set PT_INTERP.
        # Also, the original libc.so linker script had it listed as --as-needed,
        # so let's do that.
        if needed.startswith('ld-nacl-'):
            env.append('NEEDED_LIBRARIES', '--dynamic-linker=' + needed)
            env.append(
                'NEEDED_LIBRARIES',
                '--as-needed',
                # We normally would have a symlink between
                # ld-2.9 <-> ld-nacl-${arch}.so, but our native lib directory
                # has no symlinks (to make windows + cygwin happy).
                # Link to ld-2.9.so instead for now.
                '-l:ld-2.9.so',
                '--no-as-needed')
        else:
            env.append('NEEDED_LIBRARIES', '-l:' + needed)
        # libc and libpthread may need the nonshared components too.
        # Normally these are enclosed in --start-group and --end-group...
        if not env.getbool('NEWLIB_SHARED_EXPERIMENT'):
            if needed.startswith('libc.so'):
                env.append('NEEDED_LIBRARIES', '-l:libc_nonshared.a')
            elif needed.startswith('libpthread.so'):
                env.append('NEEDED_LIBRARIES', '-l:libpthread_nonshared.a')
Example #51
0
def RunLLCSandboxed():
    driver_tools.CheckTranslatorPrerequisites()
    infile = env.getone('input')
    outfile = env.getone('output')
    is_pnacl = filetype.IsPNaClBitcode(infile)
    if not is_pnacl and not env.getbool('ALLOW_LLVM_BITCODE_INPUT'):
        Log.Fatal('Translator expects finalized PNaCl bitcode. '
                  'Pass --allow-llvm-bitcode-input to override.')
    script = MakeSelUniversalScriptForLLC(infile, outfile, is_pnacl)
    command = (
        '${SEL_UNIVERSAL_PREFIX} ${SEL_UNIVERSAL} ${SEL_UNIVERSAL_FLAGS} '
        '-- ${LLC_SB}')
    driver_tools.Run(
        command,
        stdin_contents=script,
        # stdout/stderr will be automatically dumped
        # upon failure
        redirect_stderr=subprocess.PIPE,
        redirect_stdout=subprocess.PIPE)
Example #52
0
def BuildSharedLib():
  # Shared libs must be built PIC
  Env.set('GENERATE_PIC', '1')
  inputs = Env.get('INPUTS')
  if len(inputs) == 0:
    Log.Fatal('No input specified.')
  if not Env.getbool('GENERATE_PIC'):
    Log.Fatal('Shared libs must be build in pic mode. Use -fPIC')
  if Env.getone('SONAME_FLAG') == '':
    Log.Fatal('Shared libs must be given a soname.')

  pso_command = ProcessBuildCommand(BUILD_COMMAND_PSO_FROM_BC)
  DumpCommand("@bc->pso", pso_command)
  # suppress_arch is needed to prevent clang to inherit the
  # -arch argument
  driver_tools.RunDriver('clang', pso_command, suppress_arch=True)

  so_command = ProcessBuildCommand(BUILD_COMMAND_SO_FROM_PSO)
  DumpCommand("@pso->so", so_command)
  driver_tools.RunDriver('translate', so_command)
Example #53
0
def RunLDSandboxed():
    if not env.getbool('USE_STDLIB'):
        Log.Fatal('-nostdlib is not supported by the sandboxed translator')
    CheckTranslatorPrerequisites()
    # The "main" input file is the application's combined object file.
    all_inputs = env.get('inputs')

    main_input = env.getone('LLC_TRANSLATED_FILE')
    if not main_input:
        Log.Fatal("Sandboxed LD requires one shm input file")

    outfile = env.getone('output')

    modules = int(env.getone('SPLIT_MODULE'))
    assert modules >= 1
    first_mainfile = all_inputs.index(main_input)
    first_extra = all_inputs.index(main_input) + modules
    # Have a list of just the split module files.
    llc_outputs = all_inputs[first_mainfile:first_extra]
    # Have a list of everything else.
    other_inputs = all_inputs[:first_mainfile] + all_inputs[first_extra:]

    native_libs_dirname = pathtools.tosys(GetNativeLibsDirname(other_inputs))
    command = [driver_tools.SelLdrCommand(), '-a']  # Allow file access
    driver_tools.AddListToEnv(command, 'NACL_IRT_PNACL_TRANSLATOR_LINK_INPUT',
                              llc_outputs)
    command.extend([
        '-E',
        'NACL_IRT_PNACL_TRANSLATOR_LINK_OUTPUT=%s ' % outfile, '-E',
        'NACL_IRT_OPEN_RESOURCE_BASE=%s' % native_libs_dirname, '-E',
        'NACL_IRT_OPEN_RESOURCE_REMAP=%s' %
        'libpnacl_irt_shim.a:libpnacl_irt_shim_dummy.a', '--', '${LD_SB}'
    ])
    Run(
        ' '.join(command),
        # stdout/stderr will be automatically dumped
        # upon failure
        redirect_stderr=subprocess.PIPE,
        redirect_stdout=subprocess.PIPE)
Example #54
0
def RunLDSandboxed():
    if not env.getbool('USE_STDLIB'):
        Log.Fatal('-nostdlib is not supported by the sandboxed translator')
    CheckTranslatorPrerequisites()
    # The "main" input file is the application's combined object file.
    all_inputs = env.get('inputs')

    main_input = env.getone('LLC_TRANSLATED_FILE')
    if not main_input:
        Log.Fatal("Sandboxed LD requires one shm input file")

    outfile = env.getone('output')

    modules = int(env.getone('SPLIT_MODULE'))
    if modules > 1:
        first_mainfile = all_inputs.index(main_input)
        first_extra = all_inputs.index(main_input) + modules
        # Just the split module files
        llc_outputs = all_inputs[first_mainfile:first_extra]
        # everything else
        all_inputs = all_inputs[:first_mainfile] + all_inputs[first_extra:]
    else:
        llc_outputs = [main_input]

    files = LinkerFiles(all_inputs)
    ld_flags = env.get('LD_FLAGS')

    script = MakeSelUniversalScriptForLD(ld_flags, llc_outputs, files, outfile)

    Run(
        '${SEL_UNIVERSAL_PREFIX} ${SEL_UNIVERSAL} ' +
        '${SEL_UNIVERSAL_FLAGS} -- ${LD_SB}',
        stdin_contents=script,
        # stdout/stderr will be automatically dumped
        # upon failure
        redirect_stderr=subprocess.PIPE,
        redirect_stdout=subprocess.PIPE)
Example #55
0
def FixPrivateLibs(user_libs):
  """If not using the IRT or if private libraries are used:
    - Place private libraries that can coexist before their public
      equivalent (keep both);
    - Replace public libraries that can't coexist with their private
      equivalent.

  This occurs before path resolution (important because public/private
  libraries aren't always colocated) and assumes that -l:libfoo.a syntax
  isn't used by the driver for relevant libraries.
  """
  special_libs = {
      # Public library name: (private library name, can coexist?)
      '-lnacl': ('-lnacl_sys_private', True),
      '-lpthread': ('-lpthread_private', False),
      }
  private_libs = [v[0] for v in special_libs.values()]
  public_libs = special_libs.keys()
  private_lib_for = lambda user_lib: special_libs[user_lib][0]
  can_coexist = lambda user_lib: special_libs[user_lib][1]

  no_irt = not env.getbool('USE_IRT')
  uses_private_libs = set(user_libs) & set(private_libs)

  if not (no_irt or uses_private_libs):
    return user_libs

  result_libs = []
  for user_lib in user_libs:
    if user_lib in public_libs:
      result_libs.append(private_lib_for(user_lib))
      if can_coexist(user_lib):
        result_libs.append(user_lib)
    else:
      result_libs.append(user_lib)
  return result_libs
Example #56
0
def SetupChain(chain, input_type, output_type):
    assert (output_type in ('pp', 'll', 'po', 's', 'o'))
    cur_type = input_type

    # source file -> pp
    if filetype.IsSourceType(cur_type) and output_type == 'pp':
        chain.add(RunCC, 'cpp', mode='-E')
        cur_type = 'pp'
    if cur_type == output_type:
        return

    # source file -> ll
    if (filetype.IsSourceType(cur_type)
            and (env.getbool('FORCE_INTERMEDIATE_LL') or output_type == 'll')):
        chain.add(RunCC, 'll', mode='-S')
        cur_type = 'll'
    if cur_type == output_type:
        return

    # ll -> po
    if cur_type == 'll':
        chain.add(RunLLVMAS, 'po')
        cur_type = 'po'
    if cur_type == output_type:
        return

    # source file -> po (we also force native output to go through this phase
    if filetype.IsSourceType(cur_type) and output_type in ('po', 'o', 's'):
        chain.add(RunCC, 'po', mode='-c')
        cur_type = 'po'
    if cur_type == output_type:
        return

    # po -> o
    if (cur_type == 'po' and output_type == 'o'):
        # If we aren't using biased bitcode, then at least -expand-byval
        # must be run to work with the PPAPI shim calling convention.
        if IsPortable():
            chain.add(RunOpt, 'expand.po', pass_list=['-expand-byval'])
        chain.add(RunTranslate, 'o', mode='-c')
        cur_type = 'o'
    if cur_type == output_type:
        return

    # po -> s
    if cur_type == 'po':
        # If we aren't using biased bitcode, then at least -expand-byval
        # must be run to work with the PPAPI shim calling convention.
        if IsPortable():
            chain.add(RunOpt, 'expand.po', pass_list=['-expand-byval'])
        chain.add(RunTranslate, 's', mode='-S')
        cur_type = 's'
    if cur_type == output_type:
        return

    # S -> s
    if cur_type == 'S':
        chain.add(RunCC, 's', mode='-E')
        cur_type = 's'
        if output_type == 'pp':
            return
    if cur_type == output_type:
        return

    # s -> o
    if cur_type == 's' and output_type == 'o':
        chain.add(RunNativeAS, 'o')
        cur_type = 'o'
    if cur_type == output_type:
        return

    Log.Fatal("Unable to compile .%s to .%s", input_type, output_type)
Example #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