예제 #1
0
def UsePrivateLibraries(libs):
    """ Place libnacl_sys_private.a before libnacl.a
  Replace libpthread.a with libpthread_private.a
  Replace libnacl_dyncode.a with libnacl_dyncode_private.a
  This assumes that the private libs can be found at the same directory
  as the public libs.
  """
    result_libs = []
    for l in libs:
        base = pathtools.basename(l)
        dname = pathtools.dirname(l)
        if base == 'libnacl.a':
            Log.Info(
                'Not using IRT -- injecting libnacl_sys_private.a to link line'
            )
            result_libs.append(pathtools.join(dname, 'libnacl_sys_private.a'))
            result_libs.append(l)
        elif base == 'libpthread.a':
            Log.Info('Not using IRT -- swapping private lib for libpthread')
            result_libs.append(pathtools.join(dname, 'libpthread_private.a'))
        elif base == 'libnacl_dyncode.a':
            Log.Info(
                'Not using IRT -- swapping private lib for libnacl_dyncode')
            result_libs.append(
                pathtools.join(dname, 'libnacl_dyncode_private.a'))
        else:
            result_libs.append(l)
    return result_libs
예제 #2
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)
예제 #3
0
def RunDriver(invocation, args, suppress_inherited_arch_args=False):
  """
  RunDriver() is used to invoke "driver" tools, e.g.
  those prefixed  with "pnacl-"

  It automatically appends some additional flags to the invocation
  which were inherited from the current invocation.
  Those flags were preserved by ParseArgs
  """

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

  module_name = 'pnacl-%s' % invocation
  script = env.eval('${DRIVER_BIN}/%s' % module_name)
  script = shell.unescape(script)

  inherited_driver_args = env.get('INHERITED_DRIVER_ARGS')
  if suppress_inherited_arch_args:
    inherited_driver_args = FilterOutArchArgs(inherited_driver_args)

  script = pathtools.tosys(script)
  cmd = [script] + args + inherited_driver_args
  Log.Info('Driver invocation: %s', repr(cmd))

  module = __import__(module_name)
  # Save the environment, reset the environment, run
  # the driver module, and then restore the environment.
  env.push()
  env.reset()
  DriverMain(module, cmd)
  env.pop()
예제 #4
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
예제 #5
0
    redirect_stdin = None
    if stdin_contents:
      redirect_stdin = subprocess.PIPE

    p = subprocess.Popen(actual_args,
                         stdin=redirect_stdin,
                         stdout=redirect_stdout,
                         stderr=redirect_stderr)
    result_stdout, result_stderr = p.communicate(input=stdin_contents)
  except Exception, e:
    msg =  '%s\nCommand was: %s' % (str(e),
                                    StringifyCommand(args, stdin_contents))
    print msg
    DriverExit(1)

  Log.Info('Return Code: ' + str(p.returncode))

  if errexit and p.returncode != 0:
    if redirect_stdout == subprocess.PIPE:
      Log.Error('--------------stdout: begin')
      Log.Error(result_stdout)
      Log.Error('--------------stdout: end')

    if redirect_stderr == subprocess.PIPE:
      Log.Error('--------------stderr: begin')
      Log.Error(result_stderr)
      Log.Error('--------------stderr: end')
    DriverExit(p.returncode)

  return p.returncode, result_stdout, result_stderr
예제 #6
0
def ToggleDefaultCommandlineLD(inputs, infile):
  if env.getbool('USE_DEFAULT_CMD_LINE'):
    reason, non_standard = RequiresNonStandardLDCommandline(inputs, infile)
    if non_standard:
      Log.Info(reason + ' -- not using default SRPC commandline for LD!')
      inputs.append('--pnacl-driver-set-USE_DEFAULT_CMD_LINE=0')
예제 #7
0
def main(argv):
    argv = [env.getone('DRIVER_PATH')] + argv
    Log.Info('IGNORING: ' + StringifyCommand(argv))
    return 0
예제 #8
0
def main(argv):
    env.update(EXTRA_ENV)
    driver_tools.ParseArgs(argv, TranslatorPatterns)
    if env.getbool('SHARED'):
        env.set('PIC', '1')

    if env.getbool('SHARED') and env.getbool('STATIC'):
        Log.Fatal('Cannot mix -static and -shared')

    driver_tools.GetArch(required=True)

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

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

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

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

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

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

        if sfile:
            RunLLC(bcfile, sfile, filetype='asm')
            if ofile:
                RunAS(sfile, ofile)
        else:
            RunLLC(bcfile, ofile, filetype='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)

    # Get bitcode type and metadata
    if bcfile:
        # Until we stabilize the ABI for shared libraries,
        # assume that pnacl-translate only handles pexes
        # to avoid a dependency on bitcode metadata.
        assert not env.getbool('SHARED')
        bctype = driver_tools.GetBitcodeType(bcfile, True)
        metadata = driver_tools.GetBitcodeMetadata(bcfile, True)

    # Determine the output type, in this order of precedence:
    # 1) Output type can be specified on command-line (-S, -c, -shared, -static)
    # 2) If bitcode file given, use its output type. (pso->so, pexe->nexe, po->o)
    # 3) Otherwise, assume nexe output.
    if env.getbool('SHARED'):
        output_type = 'so'
    elif env.getbool('STATIC'):
        output_type = 'nexe'
    elif bcfile:
        DefaultOutputTypes = {
            'pso': 'so',
            'pexe': 'nexe',
            'po': 'o',
        }
        output_type = DefaultOutputTypes[bctype]
    else:
        output_type = 'nexe'

    # If the bitcode is of type "object", no linking is required.
    if output_type == 'o':
        # Copy ofile to output
        Log.Info('Copying %s to %s' % (ofile, output))
        shutil.copy(pathtools.tosys(ofile), pathtools.tosys(output))
        return 0

    if bcfile:
        ApplyBitcodeConfig(metadata, bctype)

    # NOTE: we intentionally delay setting STATIC here to give user choices
    #       preference but we should think about dropping the support for
    #       the -static, -shared flags in the translator and have everything
    #       be determined by bctype
    if metadata is None:
        env.set('STATIC', '1')
    elif len(metadata['NeedsLibrary']) == 0 and not env.getbool('SHARED'):
        env.set('STATIC', '1')

    assert output_type in ('so', 'nexe')
    RunLD(ofile, output)
    return 0