Ejemplo n.º 1
0
def Exec(args: typing.List[str],
         timeout_seconds: int = 60,
         universal_newlines: bool = True) -> subprocess.Popen:
    """Run LLVM's optimizer.

  Args:
    args: A list of arguments to pass to binary.
    timeout_seconds: The number of seconds to allow opt to run for.
    universal_newlines: Argument passed to Popen() of opt process.

  Returns:
    A Popen instance with stdout and stderr set to strings.
  """
    cmd = ['timeout', '-s9', str(timeout_seconds), str(OPT)] + args
    logging.debug('$ %s', ' '.join(cmd))
    process = subprocess.Popen(cmd,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE,
                               universal_newlines=universal_newlines)
    stdout, stderr = process.communicate()
    if process.returncode == 9:
        raise llvm.LlvmTimeout(f'clang timed out after {timeout_seconds}s')
    process.stdout = stdout
    process.stderr = stderr
    return process
Ejemplo n.º 2
0
Archivo: opt.py Proyecto: SpringRi/phd
def Exec(args: typing.List[str],
         stdin: typing.Optional[typing.Union[str, bytes]] = None,
         timeout_seconds: int = 60,
         universal_newlines: bool = True) -> subprocess.Popen:
    """Run LLVM's optimizer.

  Args:
    args: A list of arguments to pass to binary.
    stdin: Optional input to pass to binary. If universal_newlines is set, this
      should be a string. If not, it should be bytes.
    timeout_seconds: The number of seconds to allow opt to run for.
    universal_newlines: Argument passed to Popen() of opt process.

  Returns:
    A Popen instance with stdout and stderr set to strings.
  """
    cmd = ['timeout', '-s9', str(timeout_seconds), str(OPT)] + args
    logging.debug('$ %s', ' '.join(cmd))
    process = subprocess.Popen(cmd,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE,
                               stdin=subprocess.PIPE if stdin else None,
                               universal_newlines=universal_newlines)
    if stdin:
        stdout, stderr = process.communicate(stdin)
    else:
        stdout, stderr = process.communicate()
    if process.returncode == 9:
        raise llvm.LlvmTimeout(f'clang timed out after {timeout_seconds}s')
    process.stdout = stdout
    process.stderr = stderr
    return process
Ejemplo n.º 3
0
def Exec(args: typing.List[str],
         stdin: typing.Optional[str] = None,
         timeout_seconds: int = 60) -> subprocess.Popen:
  """Run llvm-as.

  Args:
    args: A list of arguments to pass to binary.
    stdin: Optional input string to pass to binary.
    timeout_seconds: The number of seconds to allow llvm-as to run for.

  Returns:
    A Popen instance with stdout and stderr set to strings.

  Raises:
    LlvmTimeout: If llvm-as does not complete before timeout_seconds.
  """
  cmd = ['timeout', '-s9', str(timeout_seconds), str(LLVM_AS)] + args
  logging.debug('$ %s', ' '.join(cmd))
  process = subprocess.Popen(
      cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
      stdin=subprocess.PIPE if stdin else None, universal_newlines=True)
  if stdin:
    stdout, stderr = process.communicate(stdin)
  else:
    stdout, stderr = process.communicate()
  if process.returncode == 9:
    raise llvm.LlvmTimeout(f'llvm-as timed out after {timeout_seconds}s')
  process.stdout = stdout
  process.stderr = stderr
  return process
Ejemplo n.º 4
0
def Exec(text: str, suffix: str, args: typing.List[str],
         timeout_seconds: int = 60) -> str:
  """Run clang-format on a source.

  Args:
    text: The source code to run through clang-format.
    suffix: The suffix to append to the source code temporary file. E.g. '.c'
      for a C program.
    args: A list of additional arguments to pass to binary.
    timeout_seconds: The number of seconds to allow clang-format to run for.

  Returns:
    The output of clang-format.

  Raises:
    ClangFormatException: In case of an error.
    LlvmTimeout: If clang-format does not complete before timeout_seconds.
  """
  cmd = ['timeout', '-s9', str(timeout_seconds), str(CLANG_FORMAT),
         '-assume-filename', f'input{suffix}'] + args
  logging.debug('$ %s', ' '.join(cmd))
  process = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE, universal_newlines=True)
  stdout, stderr = process.communicate(text)
  if process.returncode == 9:
    raise llvm.LlvmTimeout(f'clang-format timed out after {timeout_seconds}s')
  elif process.returncode != 0:
    raise ClangFormatException(stderr)
  return stdout
Ejemplo n.º 5
0
def Compile(
  srcs: typing.List[pathlib.Path],
  out: pathlib.Path,
  copts: typing.Optional[typing.List[str]] = None,
  timeout_seconds: int = 60,
) -> pathlib.Path:
  """Compile input sources.

  This has some minor behavioural differences from calling into clang directly.
  The first is that necessary parent directories for the output path are created
  if necessary, rather than raising an error.

  Args:
    srcs: The path of the input bytecode file.
    out: The path of the binary to generate.
    copts: A list of additional flags to pass to the compiler.
    timeout_seconds: The number of seconds to allow clang to run for.

  Returns:
    The output path.

  Raises:
    FileNotFoundError: If any of the srcs do not exist.
    LlvmTimeout: If the compiler times out.
    ClangException: If the compilation fails.
  """
  copts = copts or []
  # Validate the input srcs.
  for src in srcs:
    if not src.is_file():
      raise FileNotFoundError(f"File not found: '{src}'")
  # Ensure the output directory exists.
  out.parent.mkdir(parents=True, exist_ok=True)

  proc = Exec(
    [str(x) for x in srcs] + ["-o", str(out)] + copts,
    timeout_seconds=timeout_seconds,
  )
  if proc.returncode == 9:
    raise llvm.LlvmTimeout(f"clang timed out after {timeout_seconds} seconds")
  elif proc.returncode:
    raise ClangException(
      f"clang exited with returncode {proc.returncode}: {proc.stderr}"
    )
  if not out.is_file():
    raise ClangException(f"Binary file not generated: '{out}'")
  return out
Ejemplo n.º 6
0
def RunOptPassOnBytecode(
    input_path: pathlib.Path,
    output_path: pathlib.Path,
    opts: typing.List[str],
    timeout_seconds: int = 60,
) -> pathlib.Path:
    """Run opt pass(es) on a bytecode file.

  Args:
    input_path: The input bytecode file.
    output_path: The file to generate.
    opts: Additional flags to pass to opt.
    timeout_seconds: The number of seconds to allow opt to run for.

  Returns:
    The output_path.

  Raises:
    OptException: In case of error.
    LlvmTimeout: If the process times out.
  """
    # We don't care about the output of opt, but we will try and decode it if
    # opt fails.
    proc = Exec(
        [str(input_path), "-o", str(output_path), "-S"] + opts,
        timeout_seconds=timeout_seconds,
        universal_newlines=False,
    )
    if proc.returncode == 9:
        raise llvm.LlvmTimeout(
            f"opt timed out after {timeout_seconds} seconds")
    elif proc.returncode:
        try:
            stderr = proc.stderr.decode("utf-8")
            raise OptException(
                f"clang exited with returncode {proc.returncode}: {stderr}")
        except UnicodeDecodeError:
            raise OptException(
                f"clang exited with returncode {proc.returncode}")
    if not output_path.is_file():
        raise OptException(f"Bytecode file {output_path} not generated")
    return output_path
Ejemplo n.º 7
0
def Exec(
    args: typing.List[str],
    stdin: typing.Optional[typing.Union[str, bytes]] = None,
    timeout_seconds: int = 60,
    universal_newlines: bool = True,
    log: bool = True,
    opt: typing.Optional[pathlib.Path] = None,
) -> subprocess.Popen:
    """Run LLVM's optimizer.

  Args:
    args: A list of arguments to pass to the opt binary.
    stdin: Optional input to pass to binary. If universal_newlines is set, this
      should be a string. If not, it should be bytes.
    timeout_seconds: The number of seconds to allow opt to run for.
    universal_newlines: Argument passed to Popen() of opt process.
    log: If true, print executed command to DEBUG log.
    opt: An optional `opt` binary path to use.

  Returns:
    A Popen instance with stdout and stderr set to strings.
  """
    opt = opt or OPT
    cmd = ["timeout", "-s9", str(timeout_seconds), str(opt)] + args
    #print(f"$ {' '.join(cmd)}")
    #app.Log(3, "$ %s", " ".join(cmd))
    process = subprocess.Popen(
        cmd,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        stdin=subprocess.PIPE if stdin else None,
        universal_newlines=universal_newlines,
    )
    if stdin:
        stdout, stderr = process.communicate(stdin)
    else:
        stdout, stderr = process.communicate()
    if process.returncode == 9:
        raise llvm.LlvmTimeout(f"clang timed out after {timeout_seconds}s")
    process.stdout = stdout
    process.stderr = stderr
    return process
Ejemplo n.º 8
0
def Exec(
  args: typing.List[str],
  stdin: typing.Optional[str] = None,
  timeout_seconds: int = 60,
  log: bool = True,
  stdout=subprocess.PIPE,
  stderr=subprocess.PIPE,
) -> subprocess.Popen:
  """Run clang.

  Args:
    args: A list of arguments to pass to binary.
    stdin: Optional input string to pass to binary.
    timeout_seconds: The number of seconds to allow clang to run for.
    log: If true, print executed command to DEBUG log.

  Returns:
    A Popen instance with stdout and stderr set to strings.

  Raises:
    LlvmTimeout: If clang does not complete before timeout_seconds.
  """
  cmd = ["timeout", "-s9", str(timeout_seconds), str(CLANG)] + args
  if log:
    app.Log(3, "$ %s", " ".join(cmd))
  process = subprocess.Popen(
    cmd,
    stdout=stdout,
    stderr=stderr,
    stdin=subprocess.PIPE if stdin else None,
    universal_newlines=True,
  )
  if stdin:
    stdout, stderr = process.communicate(stdin)
  else:
    stdout, stderr = process.communicate()
  if process.returncode == 9:
    raise llvm.LlvmTimeout(f"clang timed out after {timeout_seconds}s")
  process.stdout = stdout
  process.stderr = stderr
  return process
Ejemplo n.º 9
0
def Exec(args: typing.List[str],
         timeout_seconds: int = 60) -> subprocess.Popen:
    """Run LLVM's bitcode linker.

  Args:
    args: A list of arguments to pass to binary.
    timeout_seconds: The number of seconds to allow clang-format to run for.

  Returns:
    A Popen instance with stdout and stderr set to strings.
  """
    cmd = ['timeout', '-s9', str(timeout_seconds), str(LLVM_LINK)] + args
    logging.debug('$ %s', ' '.join(cmd))
    process = subprocess.Popen(cmd,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE,
                               universal_newlines=True)
    stdout, stderr = process.communicate()
    if process.returncode == 9:
        raise llvm.LlvmTimeout(f'llvm-link timed out after {timeout_seconds}s')
    process.stdout = stdout
    process.stderr = stderr
    return process