Beispiel #1
0
    def start(self, cmd, discard_output=False):
        """Starts the given command and returns a handler to it.

        :param list cmd: Command to be run as a list of arguments (strings).
        :param bool discard_output: Should the output be discarded instead of
                                    being buffered so it can be obtained later?

        :returns: A handler to the started command (``subprocess.Popen``).

        If the output is irrelevant for you, you should set `discard_output` to
        ``True``.
        """
        # The implementation is platform-specific because we want to be able to
        # kill the children alongside with the process.
        kwargs = dict(
            args=cmd,
            stdin=subprocess.PIPE,
            stdout=subprocess.DEVNULL if discard_output else subprocess.PIPE,
            stderr=subprocess.DEVNULL if discard_output else subprocess.STDOUT)
        if on_windows():
            p = _WindowsProcess(**kwargs)
        else:
            p = _LinuxProcess(**kwargs)

        # We have to catch SIGTERM and terminate the subprocess to ensure that
        # we do not leave running processes behind when forcibly killing the
        # runner (= main process).
        def handler(signum, frame):
            p.kill()
            sys.exit(1)

        signal.signal(signal.SIGTERM, handler)

        return p
def exit_if_on_windows():
    """Exits the script if it is run on MS Windows."""
    # This script needs support of signal.SIGCONT, socket.AF_UNIX, and
    # os.killpg(), which are not present on MS Windows.
    if on_windows():
        print_error('this script cannot be run on MS Windows')
        sys.exit(1)
Beispiel #3
0
def setup_clang_bindings(clang_dir):
    """Sets up Clang bindings so they can be used.

    This function has to be called prior to using Clang bindings.
    """
    assert os.path.exists(clang_dir), '{}: no such directory'.format(clang_dir)

    # Set a proper path to libclang so that the bindings can find them.
    if on_windows():
        libclang_file_path = os.path.join(clang_dir, 'bin', 'libclang.dll')
    else:
        libclang_file_path = os.path.join(clang_dir, 'lib', 'libclang.so')
    assert os.path.exists(libclang_file_path), '{}: no such file'.format(libclang_file_path)
    clang.cindex.conf.set_library_file(libclang_file_path)

    # Set proper include paths. Without them, Clang cannot find some of the
    # standard headers. These include paths have to be specified as additional
    # arguments when calling cindex.Index.parse().
    #
    # (1) CLANG_DIR/lib/clang/VERSION/include
    # Detect the VERSION part automatically (this should be the only
    # subdirectory in CLANG_DIR/lib/clang).
    clang_lib_dir = os.path.join(clang_dir, 'lib', 'clang')
    assert os.path.exists(clang_lib_dir), '{}: no such directory'.format(clang_lib_dir)
    clang_version = os.listdir(clang_lib_dir)
    assert clang_version, 'expected a subdirectory in {}'.format(clang_lib_dir)
    include_path = os.path.join(clang_dir, 'lib', 'clang', clang_version[0], 'include')
    assert os.path.exists(include_path), '{}: no such directory'.format(include_path)
    INCLUDE_PATHS.append(include_path)
    # (2) CLANG_DIR/include
    clang_include_dir = os.path.join(clang_dir, 'include')
    assert os.path.exists(clang_include_dir), '{}: no such directory'.format(clang_include_dir)
    INCLUDE_PATHS.append(clang_include_dir)
Beispiel #4
0
def root_directory():
    """Returns the root directory to be used in absolute paths in tests."""
    if on_windows():
        # Use e.g. 'C:\', depending on the current working directory.
        return os.path.splitdrive(os.path.abspath(os.getcwd()))[0] + '\\'

    # Linux.
    return '/'
 def test_long_double_literal_is_correctly_recognized(self):
     if on_windows():
         # On Windows, the literal may either be 1e320L or inf, depending on
         # the compiler (MSVC does not support 80b long double, so it uses
         # double, in which the literal "overflows" to inf).
         assert self.out_c.contains('1.0e\+320L') or self.out_c.contains(
             'inf \* ') or self.out_c.contains('INFINITY \* ')
     else:  # Linux
         # Both GCC and Clang on Linux support 80b long double.
         assert self.out_c.contains('1.0e\+320L')
 def _get_compiler_for_out_c(self):
     """Returns a compiler for the output C file."""
     # Currently, we always use GCC.
     if on_windows():
         # Since MSYS2 does not support multilib, we have to use our custom
         # wrapper around gcc that properly handles the -m32 parameter.
         # Moreover, since this wrapper is a shell script, we have to run it
         # through sh.exe (otherwise, Windows doesn't find it).
         return ['sh', 'windows-gcc-32.sh']
     return ['gcc']
Beispiel #7
0
 def _get_compiler_for_out_c(self):
     """Returns a compiler for the output C file."""
     # Currently, we always use GCC.
     if on_windows():
         # Since MSYS2 does not support multilib, we have to use our custom
         # wrappers around gcc that properly handle the -m32/-m64 parameters.
         # Moreover, since these wrappers are shell scripts, we have to run
         # them through sh.exe (otherwise, Windows doesn't find them).
         if self._use_64_bit_compiler():
             return ['sh', 'windows-gcc-64.sh']
         else:
             return ['sh', 'windows-gcc-32.sh']
     return ['gcc']
    def start(self, cmd, discard_output=False):
        """Starts the given command and returns a handler to it.

        :param list cmd: Command to be run as a list of arguments (strings).
        :param bool discard_output: Should the output be discarded instead of
                                    being buffered so it can be obtained later?

        :returns: A handler to the started command (``subprocess.Popen``).

        If the output is irrelevant for you, you should set `discard_output` to
        ``True``.
        """
        # The implementation is platform-specific because we want to be able to
        # kill the children alongside with the process.
        kwargs = dict(
            args=cmd,
            stdin=subprocess.PIPE,
            stdout=subprocess.DEVNULL if discard_output else subprocess.PIPE,
            stderr=subprocess.DEVNULL if discard_output else subprocess.STDOUT)
        if on_windows():
            return _WindowsProcess(**kwargs)
        else:
            return _LinuxProcess(**kwargs)
Beispiel #9
0
 def is_gcc(self, args):
     """Checks if GCC is run in the given arguments."""
     # On Windows, GCC is run via `sh.exe windows-gcc-32` instead of `gcc`.
     if on_windows():
         return len(args[0]) > 1 and args[0][1] == 'windows-gcc-32.sh'
     return args[0][0] == 'gcc'
 def _get_tool_executable_name(self, tool_name):
     return 'retdec-decompiler' + ('.exe' if on_windows() else '')
Beispiel #11
0
 def test_get_tool_executable_name_returns_correct_name(self):
     self.assertEqual(
         self.decomp_runner._get_tool_executable_name('decompiler'),
         'retdec-decompiler.exe' if on_windows() else 'retdec-decompiler')