Example #1
0
    def test_skip_object_files(self):
        open(os.path.join(self.fake_elf.root_path, "object_file.o"),
             "w").close()

        elf_files = elf.get_elf_files(self.fake_elf.root_path,
                                      {"object_file.o"})
        self.assertThat(elf_files, Equals(set()))
Example #2
0
    def test_symlinks(self):
        symlinked_path = os.path.join(self.fake_elf.root_path, "symlinked")
        os.symlink("/bin/dash", symlinked_path)

        elf_files = elf.get_elf_files(self.fake_elf.root_path, {"symlinked"})

        self.assertThat(elf_files, Equals(set()))
Example #3
0
    def test_non_elf_files(self):
        with open(os.path.join(self.fake_elf.root_path, "non-elf"), "wb") as f:
            # A bz2 header
            f.write(b"\x42\x5a\x68")

        elf_files = elf.get_elf_files(self.fake_elf.root_path, {"non-elf"})
        self.assertThat(elf_files, Equals(set()))
Example #4
0
    def test_skip_object_files(self):
        open(os.path.join(self.fake_elf.root_path, 'object_file.o'),
             'w').close()

        elf_files = elf.get_elf_files(self.fake_elf.root_path,
                                      {'object_file.o'})
        self.assertThat(elf_files, Equals(set()))
Example #5
0
    def test_get_elf_files(self):
        elf_files = elf.get_elf_files(self.fake_elf.root_path,
                                      {'fake_elf-2.23'})

        self.assertThat(len(elf_files), Equals(1))
        elf_file = set(elf_files).pop()
        self.assertThat(elf_file.interp, Equals('/lib64/ld-linux-x86-64.so.2'))
Example #6
0
    def test_symlinks(self):
        symlinked_path = os.path.join(self.fake_elf.root_path, 'symlinked')
        os.symlink('/bin/dash', symlinked_path)

        elf_files = elf.get_elf_files(self.fake_elf.root_path, {'symlinked'})

        self.assertThat(elf_files, Equals(set()))
Example #7
0
    def test_non_elf_files(self):
        with open(os.path.join(self.fake_elf.root_path, 'non-elf'), 'wb') as f:
            # A bz2 header
            f.write(b'\x42\x5a\x68')

        elf_files = elf.get_elf_files(self.fake_elf.root_path, {'non-elf'})
        self.assertThat(elf_files, Equals(set()))
Example #8
0
    def test_get_elf_files(self):
        elf_files = elf.get_elf_files(self.fake_elf.root_path,
                                      {'fake_elf-2.23'})

        self.assertThat(len(elf_files), Equals(1))
        elf_file = set(elf_files).pop()
        self.assertThat(elf_file.is_executable(), Equals(True))
Example #9
0
 def test_get_elf_files_to_patch(self):
     elf_files = elf.get_elf_files(
         self.fake_elf.root_path,
         {'libc.so.6', 'libssl.so.1.0.0', 'fake_elf-shared-object',
          'fake_elf-2.26'})
     to_patch = elf.get_elf_files_to_patch(elf_files)
     self.assertThat({os.path.basename(e.path) for e in to_patch},
                     Equals({'fake_elf-shared-object', 'fake_elf-2.26'}))
Example #10
0
    def test_get_elf_is_library(self):
        elf_files = elf.get_elf_files(self.fake_elf.root_path,
                                      {'fake_elf-shared-object'})

        self.assertThat(len(elf_files), Equals(1))
        elf_file = set(elf_files).pop()
        self.assertThat(elf_file.is_executable(), Equals(False))
        self.assertThat(elf_file.is_shared_object(), Equals(True))
Example #11
0
    def test_skip_object_files(self):
        open(os.path.join(self.workdir, 'object_file.o'), 'w').close()

        elf_files = elf.get_elf_files(self.workdir, {'object_file.o'})

        self.assertFalse(self.ms_mock.file.called,
                         'Expected object file to be skipped')
        self.assertThat(elf_files, Equals(set()))
Example #12
0
    def test_symlinks(self):
        symlinked_path = os.path.join(self.workdir, 'symlinked')
        os.symlink('/bin/dash', symlinked_path)

        elf_files = elf.get_elf_files(self.workdir, {'symlinked'})

        self.assertFalse(self.ms_mock.file.called,
                         'magic is not needed for symlinks')
        self.assertThat(elf_files, Equals(set()))
Example #13
0
    def prime(self, force=False) -> None:
        self.makedirs()
        self.notify_part_progress('Priming')
        snap_files, snap_dirs = self.migratable_fileset_for('prime')
        _migrate_files(snap_files, snap_dirs, self.stagedir, self.primedir)

        elf_files = elf.get_elf_files(self.primedir, snap_files)
        all_dependencies = set()
        # TODO: base snap support
        core_path = common.get_core_path()

        for elf_file in elf_files:
            all_dependencies.update(
                elf_file.load_dependencies(root_path=self.primedir,
                                           core_base_path=core_path))

        # Split the necessary dependencies into their corresponding location.
        # We'll both migrate and track the system dependencies, but we'll only
        # track the part and staged dependencies, since they should have
        # already been primed by other means, and migrating them again could
        # potentially override the `stage` or `snap` filtering.
        (in_part, staged, primed, system) = _split_dependencies(
            all_dependencies, self.installdir, self.stagedir, self.primedir)

        part_dependency_paths = {os.path.dirname(d) for d in in_part}
        staged_dependency_paths = {os.path.dirname(d) for d in staged}

        dependency_paths = part_dependency_paths | staged_dependency_paths

        if not self._build_attributes.no_system_libraries():
            system_dependency_paths = {os.path.dirname(d) for d in system}
            dependency_paths.update(system_dependency_paths)

            if system:
                # Lots of dependencies are linked with a symlink, so we need to
                # make sure we follow those symlinks when we migrate the
                # dependencies.
                _migrate_files(system, system_dependency_paths, '/',
                               self.primedir, follow_symlinks=True)
                formatted_system = '\n'.join(sorted(system))
                logger.warning(
                    'Files from the build host were migrated into the snap to '
                    'satisfy dependencies that would otherwise not be met. '
                    'This feature will be removed in a future release. If '
                    'these libraries are needed in the final snap, ensure '
                    'that the following are either satisfied by a '
                    'stage-packages entry or through a part:\n{}'.format(
                        formatted_system))

        if self._confinement == 'classic':
            dynamic_linker = self._project_options.get_core_dynamic_linker()
            elf_patcher = elf.Patcher(dynamic_linker=dynamic_linker,
                                      root_path=self.primedir)
            for elf_file in elf_files:
                elf_patcher.patch(elf_file=elf_file)

        self.mark_prime_done(snap_files, snap_dirs, dependency_paths)
Example #14
0
    def test_non_elf_files(self):
        non_elf_path = os.path.join(self.workdir, 'non-elf')
        open(non_elf_path, 'w').close()

        non_elf_path_b = non_elf_path.encode(sys.getfilesystemencoding())

        self.ms_mock.file.return_value = 'JPEG image data, Exif standard: ...'

        elf_files = elf.get_elf_files(self.workdir, {'non-elf'})

        self.ms_mock.file.assert_called_once_with(non_elf_path_b)
        self.assertThat(elf_files, Equals(set()))
Example #15
0
    def test_get_elf_files(self):
        linked_elf_path = os.path.join(self.workdir, 'linked')
        open(linked_elf_path, 'w').close()

        linked_elf_path_b = linked_elf_path.encode(sys.getfilesystemencoding())

        elf_files = elf.get_elf_files(self.workdir, {'linked'})

        self.assertThat(len(elf_files), Equals(1))
        self.ms_mock.file.assert_called_once_with(linked_elf_path_b)

        elf_file = set(elf_files).pop()
        self.assertThat(elf_file.path, Equals(linked_elf_path))
        self.assertThat(elf_file.is_executable, Equals(True))
Example #16
0
    def test_no_find_dependencies_of_non_dynamically_linked(self):
        statically_linked_elf_path = os.path.join(self.workdir,
                                                  'statically-linked')
        open(statically_linked_elf_path, 'w').close()

        statically_linked_elf_path_b = statically_linked_elf_path.encode(
            sys.getfilesystemencoding())

        self.ms_mock.file.return_value = (
            'ELF 64-bit LSB executable, x86-64, version 1 (SYSV), '
            'statically linked, for GNU/Linux 2.6.32, '
            'BuildID[sha1]=XYZ, stripped')

        elf_files = elf.get_elf_files(self.workdir, {'statically-linked'})

        self.ms_mock.file.assert_called_once_with(statically_linked_elf_path_b)
        self.assertThat(elf_files, Equals(set()))
Example #17
0
    def prime(self, force=False) -> None:
        self.makedirs()
        self.notify_part_progress('Priming')
        snap_files, snap_dirs = self.migratable_fileset_for('prime')
        _migrate_files(snap_files, snap_dirs, self.stagedir, self.primedir)

        elf_files = elf.get_elf_files(self.primedir, snap_files)
        dependencies = set()
        for elf_file in elf_files:
            dependencies.update(elf.get_dependencies(elf_file.path))

        # Split the necessary dependencies into their corresponding location.
        # We'll both migrate and track the system dependencies, but we'll only
        # track the part and staged dependencies, since they should have
        # already been primed by other means, and migrating them again could
        # potentially override the `stage` or `snap` filtering.
        (in_part, staged, primed,
         system) = _split_dependencies(dependencies, self.installdir,
                                       self.stagedir, self.primedir)

        part_dependency_paths = {os.path.dirname(d) for d in in_part}
        staged_dependency_paths = {os.path.dirname(d) for d in staged}

        dependency_paths = part_dependency_paths | staged_dependency_paths

        if not self._build_attributes.no_system_libraries():
            system_dependency_paths = {os.path.dirname(d) for d in system}
            dependency_paths.update(system_dependency_paths)

            if system:
                # Lots of dependencies are linked with a symlink, so we need to
                # make sure we follow those symlinks when we migrate the
                # dependencies.
                _migrate_files(system,
                               system_dependency_paths,
                               '/',
                               self.primedir,
                               follow_symlinks=True)

        if self._confinement == 'classic':
            dynamic_linker = self._project_options.get_core_dynamic_linker()
            elf_patcher = elf.Patcher(dynamic_linker=dynamic_linker)
            for elf_file in elf_files:
                elf_patcher.patch(elf_file=elf_file)

        self.mark_prime_done(snap_files, snap_dirs, dependency_paths)
Example #18
0
    def test_get_elf_is_library(self):
        self.ms_mock.file.return_value = (
            'ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), '
            'dynamically linked, '
            'BuildID[sha1]=62b2bc59168b25ab9b025182c1f5f43194ba167b, stripped')
        linked_elf_path = os.path.join(self.workdir, 'linked')
        open(linked_elf_path, 'w').close()

        linked_elf_path_b = linked_elf_path.encode(sys.getfilesystemencoding())

        elf_files = elf.get_elf_files(self.workdir, {'linked'})

        self.assertThat(len(elf_files), Equals(1))
        self.ms_mock.file.assert_called_once_with(linked_elf_path_b)

        elf_file = set(elf_files).pop()
        self.assertThat(elf_file.path, Equals(linked_elf_path))
        self.assertThat(elf_file.is_executable, Equals(False))
Example #19
0
    def _handle_elf(self, snap_files: Sequence[str]) -> Set[str]:
        elf_files = elf.get_elf_files(self.primedir, snap_files)
        all_dependencies = set()
        # TODO: base snap support
        core_path = common.get_core_path(self._base)

        # Clear the cache of all libs that aren't already in the primedir
        self._soname_cache.reset_except_root(self.primedir)
        for elf_file in elf_files:
            all_dependencies.update(
                elf_file.load_dependencies(
                    root_path=self.primedir,
                    core_base_path=core_path,
                    soname_cache=self._soname_cache,
                )
            )

        dependency_paths = self._handle_dependencies(all_dependencies)

        if not self._build_attributes.keep_execstack():
            clear_execstack(elf_files=elf_files)

        if self._build_attributes.no_patchelf():
            logger.warning(
                "The primed files for part {!r} will not be verified for "
                "correctness or patched: build-attributes: [no-patchelf] "
                "is set.".format(self.name)
            )
        else:
            part_patcher = PartPatcher(
                elf_files=elf_files,
                plugin=self.plugin,
                project=self._project_options,
                confinement=self._confinement,
                core_base=self._base,
                snap_base_path=self._snap_base_path,
                stagedir=self.stagedir,
                primedir=self.primedir,
                stage_packages=self._part_properties.get("stage-packages", []),
            )
            part_patcher.patch()

        return dependency_paths
Example #20
0
    def _handle_elf(self, snap_files: Sequence[str]) -> Set[str]:
        elf_files = elf.get_elf_files(self.primedir, snap_files)
        all_dependencies = set()
        core_path = common.get_core_path(self._base)

        # Clear the cache of all libs that aren't already in the primedir
        self._soname_cache.reset_except_root(self.primedir)
        for elf_file in elf_files:
            all_dependencies.update(
                elf_file.load_dependencies(
                    root_path=self.primedir,
                    core_base_path=core_path,
                    soname_cache=self._soname_cache,
                )
            )

        dependency_paths = self._handle_dependencies(all_dependencies)

        if not self._build_attributes.keep_execstack():
            clear_execstack(elf_files=elf_files)

        if self._build_attributes.no_patchelf():
            logger.warning(
                "The primed files for part {!r} will not be verified for "
                "correctness or patched: build-attributes: [no-patchelf] "
                "is set.".format(self.name)
            )
        else:
            part_patcher = PartPatcher(
                elf_files=elf_files,
                plugin=self.plugin,
                project=self._project_options,
                confinement=self._confinement,
                core_base=self._base,
                snap_base_path=self._snap_base_path,
                stagedir=self.stagedir,
                primedir=self.primedir,
                stage_packages=self._part_properties.get("stage-packages", []),
            )
            part_patcher.patch()

        return dependency_paths
Example #21
0
 def test_device_files(self):
     elf_files = elf.get_elf_files('/dev', {'null'})
     self.assertThat(elf_files, Equals(set()))
Example #22
0
 def test_elf_without_execstack(self):
     elf_files = elf.get_elf_files(self.fake_elf.root_path,
                                   {'fake_elf-2.23'})
     elf_file = set(elf_files).pop()
     self.assertThat(elf_file.execstack_set, Equals(False))
Example #23
0
 def test_elf_with_execstack(self):
     elf_files = elf.get_elf_files(self.fake_elf.root_path,
                                   {'fake_elf-with-execstack'})
     elf_file = set(elf_files).pop()
     self.assertThat(elf_file.execstack_set, Equals(True))
Example #24
0
 def test_no_find_dependencies_statically_linked(self):
     elf_files = elf.get_elf_files(self.fake_elf.root_path,
                                   {'fake_elf-static'})
     self.assertThat(elf_files, Equals(set()))
Example #25
0
    def prime(self, force=False) -> None:
        self.makedirs()
        self.notify_part_progress('Priming')
        snap_files, snap_dirs = self.migratable_fileset_for('prime')
        _migrate_files(snap_files, snap_dirs, self.stagedir, self.primedir)

        elf_files = elf.get_elf_files(self.primedir, snap_files)
        all_dependencies = set()
        for elf_file in elf_files:
            all_dependencies.update(elf_file.load_dependencies())

        # Split the necessary dependencies into their corresponding location.
        # We'll both migrate and track the system dependencies, but we'll only
        # track the part and staged dependencies, since they should have
        # already been primed by other means, and migrating them again could
        # potentially override the `stage` or `snap` filtering.
        (in_part, staged, primed, system) = _split_dependencies(
            all_dependencies, self.installdir, self.stagedir, self.primedir)

        part_dependency_paths = {os.path.dirname(d) for d in in_part}
        staged_dependency_paths = {os.path.dirname(d) for d in staged}

        dependency_paths = part_dependency_paths | staged_dependency_paths

        if not self._build_attributes.no_system_libraries():
            system_dependency_paths = {os.path.dirname(d) for d in system}
            dependency_paths.update(system_dependency_paths)

            if system:
                # Lots of dependencies are linked with a symlink, so we need to
                # make sure we follow those symlinks when we migrate the
                # dependencies.
                _migrate_files(system, system_dependency_paths, '/',
                               self.primedir, follow_symlinks=True)

        # TODO: base snap support
        core_path = common.get_core_path()

        def mangle_library_path(library_path: str, elf_file_path: str) -> str:
            # If the path is is in the core snap, use the absolute path,
            # if the path is primed, use $ORIGIN, and last if the dependency
            # is not anywhere return an empty string.
            #
            # Once we move away from the system library grabbing logic
            # we can move to a smarter library capturing mechanism.
            library_path = library_path.replace(self.installdir, self.primedir)
            if library_path.startswith(core_path):
                return os.path.dirname(library_path)
            elif (library_path.startswith(self.primedir) and
                  os.path.exists(library_path)):
                rel_library_path = os.path.relpath(library_path, elf_file_path)
                rel_library_path_dir = os.path.dirname(rel_library_path)
                # return the dirname, with the first .. replace with $ORIGIN
                return rel_library_path_dir.replace('..', '$ORIGIN', 1)
            else:
                return ''

        if self._confinement == 'classic':
            core_rpaths = common.get_library_paths(
                core_path, self._project_options.arch_triplet,
                existing_only=False)
            dynamic_linker = self._project_options.get_core_dynamic_linker()
            elf_patcher = elf.Patcher(dynamic_linker=dynamic_linker,
                                      library_path_func=mangle_library_path,
                                      base_rpaths=core_rpaths)
            for elf_file in elf_files:
                elf_patcher.patch(elf_file=elf_file)

        self.mark_prime_done(snap_files, snap_dirs, dependency_paths)
Example #26
0
 def test_device_files(self):
     elf_files = elf.get_elf_files("/dev", {"null"})
     self.assertThat(elf_files, Equals(set()))
Example #27
0
    def prime(self, force=False) -> None:
        self.makedirs()
        self.notify_part_progress('Priming')
        snap_files, snap_dirs = self.migratable_fileset_for('prime')
        _migrate_files(snap_files, snap_dirs, self.stagedir, self.primedir)

        elf_files = elf.get_elf_files(self.primedir, snap_files)
        all_dependencies = set()
        # TODO: base snap support
        core_path = common.get_core_path()

        for elf_file in elf_files:
            all_dependencies.update(
                elf_file.load_dependencies(root_path=self.primedir,
                                           core_base_path=core_path))

        # Split the necessary dependencies into their corresponding location.
        # We'll both migrate and track the system dependencies, but we'll only
        # track the part and staged dependencies, since they should have
        # already been primed by other means, and migrating them again could
        # potentially override the `stage` or `snap` filtering.
        (in_part, staged, primed,
         system) = _split_dependencies(all_dependencies, self.installdir,
                                       self.stagedir, self.primedir)

        part_dependency_paths = {os.path.dirname(d) for d in in_part}
        staged_dependency_paths = {os.path.dirname(d) for d in staged}

        dependency_paths = part_dependency_paths | staged_dependency_paths

        if not self._build_attributes.no_system_libraries():
            system_dependency_paths = {os.path.dirname(d) for d in system}
            dependency_paths.update(system_dependency_paths)

            if system:
                # Lots of dependencies are linked with a symlink, so we need to
                # make sure we follow those symlinks when we migrate the
                # dependencies.
                _migrate_files(system,
                               system_dependency_paths,
                               '/',
                               self.primedir,
                               follow_symlinks=True)
                formatted_system = '\n'.join(sorted(system))
                logger.warning(
                    'Files from the build host were migrated into the snap to '
                    'satisfy dependencies that would otherwise not be met. '
                    'This feature will be removed in a future release. If '
                    'these libraries are needed in the final snap, ensure '
                    'that the following are either satisfied by a '
                    'stage-packages entry or through a part:\n{}'.format(
                        formatted_system))

        # TODO revisit if we need to support variations and permutations
        #  of this
        staged_patchelf_path = os.path.join(self.stagedir, 'bin', 'patchelf')
        if not os.path.exists(staged_patchelf_path):
            staged_patchelf_path = None
        # We need to verify now that the GLIBC version would be compatible
        # with that of the base.
        # TODO the linker version depends on the chosen base, but that
        # base may not be installed so we cannot depend on
        # get_core_dynamic_linker to resolve the final path for which
        # we resort to our only working base 16, ld-2.23.so.
        linker_compatible = (e.is_linker_compatible(linker='ld-2.23.so')
                             for e in elf_files)
        if not all((x for x in linker_compatible)):
            handle_glibc_mismatch(elf_files=elf_files,
                                  root_path=self.primedir,
                                  snap_base_path=self._snap_base_path,
                                  core_base_path=core_path,
                                  preferred_patchelf_path=staged_patchelf_path)
        elif self._confinement == 'classic':
            dynamic_linker = self._project_options.get_core_dynamic_linker()
            elf_patcher = elf.Patcher(
                dynamic_linker=dynamic_linker,
                root_path=self.primedir,
                preferred_patchelf_path=staged_patchelf_path)
            for elf_file in elf_files:
                elf_patcher.patch(elf_file=elf_file)

        self.mark_prime_done(snap_files, snap_dirs, dependency_paths)
Example #28
0
    def test_fifo(self):
        fifo_path = os.path.join(self.fake_elf.root_path, 'fifo')
        os.mkfifo(fifo_path)

        elf_files = elf.get_elf_files(self.fake_elf.root_path, {'fifo'})
        self.assertThat(elf_files, Equals(set()))
Example #29
0
    def prime(self, force=False) -> None:  # noqa: C901
        self.makedirs()
        self.notify_part_progress('Priming')
        snap_files, snap_dirs = self.migratable_fileset_for('prime')
        _migrate_files(snap_files, snap_dirs, self.stagedir, self.primedir)

        elf_files = elf.get_elf_files(self.primedir, snap_files)
        all_dependencies = set()
        # TODO: base snap support
        core_path = common.get_core_path()

        # Reset to take into account new data inside prime provided by other
        # parts.
        self._soname_cache.reset()
        for elf_file in elf_files:
            all_dependencies.update(
                elf_file.load_dependencies(root_path=self.primedir,
                                           core_base_path=core_path,
                                           soname_cache=self._soname_cache))

        dependency_paths = self._handle_dependencies(all_dependencies)

        if not self._build_attributes.keep_execstack():
            clear_execstack(elf_files=elf_files)

        # TODO revisit if we need to support variations and permutations
        #  of this
        staged_patchelf_path = os.path.join(self.stagedir, 'bin', 'patchelf')
        if not os.path.exists(staged_patchelf_path):
            staged_patchelf_path = None
        # We need to verify now that the GLIBC version would be compatible
        # with that of the base.
        # TODO the linker version depends on the chosen base, but that
        # base may not be installed so we cannot depend on
        # get_core_dynamic_linker to resolve the final path for which
        # we resort to our only working base 16, ld-2.23.so.
        linker_incompat = dict()  # type: Dict[str, str]
        for elf_file in elf_files:
            if not elf_file.is_linker_compatible(linker='ld-2.23.so'):
                linker_incompat[elf_file.path] = elf_file.get_required_glibc()
        # If libc6 is staged, to avoid symbol mixups we will resort to
        # glibc mangling.
        libc6_staged = 'libc6' in self._part_properties.get(
            'stage-packages', [])
        is_classic = self._confinement == 'classic'
        # classic confined snaps built on anything but a host supporting the
        # the target base will require glibc mangling.
        classic_mangling_needed = (
            is_classic
            and not self._project_options.is_host_compatible_with_base)
        if linker_incompat:
            formatted_items = [
                '- {} (requires GLIBC {})'.format(k, v)
                for k, v in linker_incompat.items()
            ]
            logger.warning(
                'The GLIBC version of the targeted core is 2.23. A newer '
                'libc will be required for the following files:\n{}'.format(
                    '\n'.join(formatted_items)))
        if (linker_incompat or libc6_staged or classic_mangling_needed):
            if not libc6_staged:
                raise errors.StagePackageMissingError(package='libc6')
            handle_glibc_mismatch(elf_files=elf_files,
                                  root_path=self.primedir,
                                  snap_base_path=self._snap_base_path,
                                  core_base_path=core_path,
                                  preferred_patchelf_path=staged_patchelf_path,
                                  soname_cache=self._soname_cache)
        elif is_classic:
            dynamic_linker = self._project_options.get_core_dynamic_linker()
            elf_patcher = elf.Patcher(
                dynamic_linker=dynamic_linker,
                root_path=self.primedir,
                preferred_patchelf_path=staged_patchelf_path)
            for elf_file in elf_files:
                elf_patcher.patch(elf_file=elf_file)

        self.mark_prime_done(snap_files, snap_dirs, dependency_paths)
Example #30
0
    def test_invalid_elf_file(self):
        invalid_elf = os.path.join(self.path, "invalid-elf")
        open(invalid_elf, "wb").write(b"\x7fELF\x00")

        elf_files = elf.get_elf_files(self.path, ["invalid-elf"])
        self.assertThat(elf_files, Equals(set()))