Beispiel #1
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
Beispiel #2
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
Beispiel #3
0
def AddHostBinarySearchPath(prefix):
  """ Add a path to the list searched for host binaries. """
  prefix = pathtools.normalize(prefix)
  if pathtools.isdir(prefix) and not prefix.endswith('/'):
    prefix += '/'

  env.append('BPREFIXES', prefix)
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
Beispiel #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
Beispiel #6
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 GetArch(required=True) == 'X8664':
    env.append('LD_FLAGS', '--metadata-is64')

  if env.getbool('SANDBOXED'):
    RunLDSandboxed()
  else:
    Run('${RUN_LD}')
  env.pop()
  # only reached in case of no errors
  return 0
Beispiel #7
0
def AddHostBinarySearchPath(prefix):
  """ Add a path to the list searched for host binaries. """
  prefix = pathtools.normalize(prefix)
  if pathtools.isdir(prefix) and not prefix.endswith('/'):
    prefix += '/'

  env.append('BPREFIXES', prefix)
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;
Beispiel #9
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
Beispiel #10
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')
Beispiel #11
0
def AddBPrefix(prefix):
    prefix = pathtools.normalize(prefix)
    if pathtools.isdir(prefix) and not prefix.endswith("/"):
        prefix += "/"

    env.append("PREFIXES", prefix)

    # Add prefix/include to isystem if it exists
    include_dir = prefix + "include"
    if pathtools.isdir(include_dir):
        env.append("ISYSTEM_USER", include_dir)
def AddBPrefix(prefix):
  prefix = pathtools.normalize(prefix)
  if pathtools.isdir(prefix) and not prefix.endswith('/'):
    prefix += '/'

  env.append('PREFIXES', prefix)

  # Add prefix/include to isystem if it exists
  include_dir = prefix + 'include'
  if pathtools.isdir(include_dir):
    env.append('ISYSTEM_USER', include_dir)
Beispiel #13
0
def AddBPrefix(prefix):
  prefix = pathtools.normalize(prefix)
  if pathtools.isdir(prefix) and not prefix.endswith('/'):
    prefix += '/'

  env.append('PREFIXES', prefix)

  # Add prefix/include to isystem if it exists
  include_dir = prefix + 'include'
  if pathtools.isdir(include_dir):
    env.append('ISYSTEM_USER', include_dir)
Beispiel #14
0
def AddInputFileStdin():
    global stdin_count

    # When stdin is an input, -x or -E must be given.
    forced_type = GetForcedFileType()
    if not forced_type:
        # Only allowed if -E is specified.
        forced_type = "c"
        env.set("NEED_DASH_E", "1")

    stdin_name = "__stdin%d__" % stdin_count
    env.append("INPUTS", stdin_name)
    ForceFileType(stdin_name, forced_type)
    stdin_count += 1
def AddInputFileStdin():
  global stdin_count

  # When stdin is an input, -x or -E must be given.
  forced_type = filetype.GetForcedFileType()
  if not forced_type:
    # Only allowed if -E is specified.
    forced_type = 'c'
    env.set('NEED_DASH_E', '1')

  stdin_name = '__stdin%d__' % stdin_count
  env.append('INPUTS', stdin_name)
  filetype.ForceFileType(stdin_name, forced_type)
  stdin_count += 1
def AddInputFileStdin():
    global stdin_count

    # When stdin is an input, -x or -E must be given.
    forced_type = filetype.GetForcedFileType()
    if not forced_type:
        # Only allowed if -E is specified.
        forced_type = 'c'
        env.set('NEED_DASH_E', '1')

    stdin_name = '__stdin%d__' % stdin_count
    env.append('INPUTS', stdin_name)
    filetype.ForceFileType(stdin_name, forced_type)
    stdin_count += 1
def AddBPrefix(prefix):
  """ Add a path to the list searched for host binaries and include dirs. """
  AddHostBinarySearchPath(prefix)
  prefix = pathtools.normalize(prefix)
  if pathtools.isdir(prefix) and not prefix.endswith('/'):
    prefix += '/'

  # Add prefix/ to the library search dir if it exists
  if pathtools.isdir(prefix):
    env.append('SEARCH_DIRS', prefix)

  # Add prefix/include to isystem if it exists
  include_dir = prefix + 'include'
  if pathtools.isdir(include_dir):
    env.append('ISYSTEM_USER', include_dir)
def AddBPrefix(prefix):
    """ Add a path to the list searched for host binaries and include dirs. """
    AddHostBinarySearchPath(prefix)
    prefix = pathtools.normalize(prefix)
    if pathtools.isdir(prefix) and not prefix.endswith('/'):
        prefix += '/'

    # Add prefix/ to the library search dir if it exists
    if pathtools.isdir(prefix):
        env.append('SEARCH_DIRS', prefix)

    # Add prefix/include to isystem if it exists
    include_dir = prefix + 'include'
    if pathtools.isdir(include_dir):
        env.append('ISYSTEM_USER', include_dir)
Beispiel #19
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 driver_tools.IsLLVMBitcode(infile):
            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 driver_tools.IsELF(infile):
            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 = driver_tools.DriverOpen(output, 'w')
                driver_tools.Run('${OBJDUMP} ${FLAGS} ${input}',
                                 redirect_stdout=fp)
                driver_tools.DriverClose(fp)
        else:
            Log.Fatal('Unknown file type')
        env.pop()
    # only reached in case of no errors
    return 0
Beispiel #20
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 driver_tools.IsBitcode(infile):
      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 driver_tools.IsELF(infile):
      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 = driver_tools.DriverOpen(output, 'w')
        driver_tools.Run('${OBJDUMP} ${FLAGS} ${input}', redirect_stdout=fp)
        driver_tools.DriverClose(fp)
    else:
      Log.Fatal('Unknown file type')
    env.pop()
  # only reached in case of no errors
  return 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')
Beispiel #22
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')
Beispiel #23
0
def ParseArgs(argv,
              patternlist,
              driver_patternlist=DriverArgPatterns,
              driver_patternlist_not_inherited=DriverArgPatternsNotInherited):
  """Parse argv using the patterns in patternlist
     Also apply the built-in DriverArgPatterns unless instructed otherwise.
     This function must be called by all (real) drivers.
  """
  if driver_patternlist:
    driver_args, argv = ParseArgsBase(argv, driver_patternlist)

    # TODO(robertm): think about a less obscure mechanism to
    #                replace the inherited args feature
    assert not env.get('INHERITED_DRIVER_ARGS')
    env.append('INHERITED_DRIVER_ARGS', *driver_args)

  _, argv = ParseArgsBase(argv, driver_patternlist_not_inherited)

  _, unmatched = ParseArgsBase(argv, patternlist)
  if unmatched:
    for u in unmatched:
      Log.Error('Unrecognized argument: ' + u)
    Log.Fatal('unknown arguments')
Beispiel #24
0
def ParseArgs(argv,
              patternlist,
              driver_patternlist=DriverArgPatterns,
              driver_patternlist_not_inherited=DriverArgPatternsNotInherited):
  """Parse argv using the patterns in patternlist
     Also apply the built-in DriverArgPatterns unless instructed otherwise.
     This function must be called by all (real) drivers.
  """
  if driver_patternlist:
    driver_args, argv = ParseArgsBase(argv, driver_patternlist)

    # TODO(robertm): think about a less obscure mechanism to
    #                replace the inherited args feature
    assert not env.get('INHERITED_DRIVER_ARGS')
    env.append('INHERITED_DRIVER_ARGS', *driver_args)

  _, argv = ParseArgsBase(argv, driver_patternlist_not_inherited)

  _, unmatched = ParseArgsBase(argv, patternlist)
  if unmatched:
    for u in unmatched:
      Log.Error('Unrecognized argument: ' + u)
    Log.Fatal('unknown arguments')
def AddCCFlag(*args):
  env.append('CC_FLAGS', *args)
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')
Beispiel #27
0
def PassThrough(*args):
  env.append('LD_FLAGS', *args)
def AddLDFlag(*args):
  env.append('LD_FLAGS', *args)
Beispiel #29
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')
Beispiel #30
0
def AddToNativeFlags(*args):
  env.append('LD_FLAGS_NATIVE', *args)
def AddTranslatorFlag(*args):
    # pass translator args to ld in case we go all the way to .nexe
    env.append('LD_FLAGS', *['-Wt,' + a for a in args])
    # pass translator args to translator in case we go to .o
    env.append('TRANSLATE_FLAGS', *args)
Beispiel #32
0
def AddAllowCXXExceptions(*args):
  env.set('ALLOW_CXX_EXCEPTIONS', '1')
  env.append('TRANSLATE_FLAGS', *args)
Beispiel #33
0
def RecordRelevantArg(category, value):
  Env.append(category, value)
  RawRelevantArgs.append(value)
def AddLLVMPassDisableFlag(*args):
    env.append('LLVM_PASSES_TO_DISABLE', *args)
    env.append('LD_FLAGS', *args)
Beispiel #35
0
def AddToNativeFlags(*args):
  env.append('LD_FLAGS_NATIVE', *args)
Beispiel #36
0
def AddToBCLinkFlags(*args):
  env.append('LD_FLAGS', *args)
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': 'pentium4m',
      'X8664': 'x86-64',
      'ARM': 'cortex-a9',
      'MIPS32': 'mips32r2'}
  env.set('LLC_MCPU', '-mcpu=%s' % cpu_map[base_arch])

  llc_flags_map = {
      'ARM': ['-float-abi=hard', '-mattr=+neon'],
      'ARM_NONSFI': ['-float-abi=hard', '-arm-enable-dwarf-eh=1'],
      # To translate x86-32 binary, we set -malign-double option so that the
      # backend's datalayout matches the datalayout for "le32" used by the
      # frontend. The le32 datalayout uses 8-byte alignment for the types i64
      # and double. i386's datalayout usually uses only 4-byte alignment for
      # these types, but -malign-double changes that to 8-byte alignment.
      # This is only needed when translating LLVM IR that hasn't had PNaCl's IR
      # simplification passes applied to it.
      'X8632_NONSFI': ['-malign-double'],
      }
  env.set('LLC_FLAGS_ARCH', *llc_flags_map.get(env.getone('ARCH'), []))
  env.set('SZ_FLAGS_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')
  # For Subzero, determine -target and -sandbox options.
  env.append('SZ_FLAGS_ARCH', '--sandbox=' +
             ('1' if env.getone('TARGET_OS') == 'nacl' else '0'))
  env.append('SZ_FLAGS_ARCH', '--target=' + base_arch.lower())
  if base_arch != 'X8632':
    env.set('SZ_UNSUPPORTED', '1')
    # Hard-fail on an unsupported architecture.
    if env.getbool('USE_SZ'):
      Log.Fatal('Unsupported architecture when using --sz: ' + base_arch)
  # This is a fine place to map OPT_LEVEL to the Subzero equivalent, with
  # default of -O2.
  sz_opt_map = {
    '0': '-Om1',
    '1': '-O2',
    '2': '-O2',
    }
  env.append('SZ_FLAGS_EXTRA', sz_opt_map.get(env.getone('OPT_LEVEL'), '-O2'))
Beispiel #38
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
def AddDiagnosticFlag(*args):
    env.append('CC_FLAGS', *args)
    env.set('DIAGNOSTIC', '1')
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
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
def AddLDFlag(*args):
    env.append('LD_FLAGS', *args)
Beispiel #43
0
def AddCCFlag(*args):
    env.append("CC_FLAGS", *args)
def AddCCFlag(*args):
    env.append('CC_FLAGS', *args)
Beispiel #45
0
def AddLDFlag(*args):
    env.append("LD_FLAGS", *args)
Beispiel #46
0
def main(argv):
    env.update(EXTRA_ENV)
    driver_tools.ParseArgs(argv, DISPatterns)

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

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

    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
Beispiel #47
0
def AddAllowCXXExceptions(*args):
  env.set('ALLOW_CXX_EXCEPTIONS', '1')
  env.append('TRANSLATE_FLAGS', *args)
Beispiel #48
0
def AddToBCLinkFlags(*args):
  env.append('LD_FLAGS', *args)
Beispiel #49
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
Beispiel #50
0
def AddToBothFlags(*args):
  env.append('LD_FLAGS', *args)
  env.append('LD_FLAGS_NATIVE', *args)
Beispiel #51
0
def PassThrough(*args):
    env.append('LD_FLAGS', *args)
def AddLLVMPassDisableFlag(*args):
  env.append('LLVM_PASSES_TO_DISABLE', *args)
  env.append('LD_FLAGS', *args)
Beispiel #53
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 AddTranslatorFlag(*args):
  # pass translator args to ld in case we go all the way to .nexe
  env.append('LD_FLAGS', *['-Wt,' + a for a in args])
  # pass translator args to translator in case we go to .o
  env.append('TRANSLATE_FLAGS', *args)
Beispiel #55
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')
def AddDiagnosticFlag(*args):
  env.append('CC_FLAGS', *args)
  env.set('DIAGNOSTIC', '1')
Beispiel #57
0
def AddToNativeIgnoredFlags(*args):
    env.append('LD_FLAGS_NATIVE_OR_IGNORED', *args)
Beispiel #58
0
def AddToBothFlags(*args):
  env.append('LD_FLAGS', *args)
  env.append('LD_FLAGS_NATIVE', *args)
Beispiel #59
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',
             'X8664': 'x86_64-linux-gnux32'},
        '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': 'pentium4m',
      'X8664': 'x86-64',
      'ARM': 'cortex-a9',
      'MIPS32': 'mips32r2'}
  env.set('LLC_MCPU', '-mcpu=%s' % cpu_map[base_arch])

  llc_flags_map = {
      'ARM': ['-float-abi=hard', '-mattr=+neon'],
      'ARM_NONSFI': ['-float-abi=hard', '-arm-enable-dwarf-eh=1'],
      # To translate x86-32 binary, we set -malign-double option so that the
      # backend's datalayout matches the datalayout for "le32" used by the
      # frontend. The le32 datalayout uses 8-byte alignment for the types i64
      # and double. i386's datalayout usually uses only 4-byte alignment for
      # these types, but -malign-double changes that to 8-byte alignment.
      # This is only needed when translating LLVM IR that hasn't had PNaCl's IR
      # simplification passes applied to it.
      'X8632_NONSFI': ['-malign-double'],
      }
  env.set('LLC_FLAGS_ARCH', *llc_flags_map.get(env.getone('ARCH'), []))
  env.set('SZ_FLAGS_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')
  # For Subzero, determine -target, -sandbox, and -nonsfi options.
  is_sandbox = '0'
  is_nonsfi = '0'
  if env.getone('TARGET_OS') == 'nacl':
    if env.getbool('NONSFI_NACL'):
      is_nonsfi = '1'
    else:
      is_sandbox = '1'

  # Subzero arch setup below.
  if base_arch not in ('X8632', 'X8664', 'ARM'):
    env.set('SZ_UNSUPPORTED', '1')
    # Hard-fail on an unsupported architecture.
    if env.getbool('USE_SZ'):
      Log.Fatal('Unsupported architecture when using --sz: ' + base_arch)
    return

  sz_target = {
      'arm': 'arm32',
      'x8632': 'x8632',
      'x8664': 'x8664',
  }[base_arch.lower()]
  env.append('SZ_FLAGS_ARCH', '--sandbox=' + is_sandbox)
  env.append('SZ_FLAGS_ARCH', '--nonsfi=' + is_nonsfi)
  env.append('SZ_FLAGS_ARCH', '--target=' + sz_target)
  # This is a fine place to map OPT_LEVEL to the Subzero equivalent, with
  # default of -O2.
  sz_opt_map = {
    '0': '-Om1',
    '1': '-O2',
    '2': '-O2',
    }
  env.append('SZ_FLAGS_EXTRA', sz_opt_map.get(env.getone('OPT_LEVEL'), '-O2'))