Пример #1
0
static boolean_t
elf32_arm_abi_supported(struct image_params *imgp)
{
	const Elf_Ehdr *hdr = (const Elf_Ehdr *)imgp->image_header;

	/*
	 * When configured for EABI, FreeBSD supports EABI vesions 4 and 5.
	 */
	if (EF_ARM_EABI_VERSION(hdr->e_flags) < EF_ARM_EABI_FREEBSD_MIN) {
		if (bootverbose)
			uprintf("Attempting to execute non EABI binary (rev %d) image %s",
			    EF_ARM_EABI_VERSION(hdr->e_flags), imgp->args->fname);
		return (FALSE);
	}
	return (TRUE);
}
Пример #2
0
static int
is_executable(const char *fname, int fd, int *is_shlib, int *type)
{
	union {
#ifdef AOUT_SUPPORTED
		struct exec aout;
#endif
#if __ELF_WORD_SIZE > 32 && defined(ELF32_SUPPORTED)
		Elf32_Ehdr elf32;
#endif
		Elf_Ehdr elf;
	} hdr;
	int n;

	*is_shlib = 0;
	*type = TYPE_UNKNOWN;

	if ((n = read(fd, &hdr, sizeof(hdr))) == -1) {
		warn("%s: can't read program header", fname);
		return (0);
	}

#ifdef AOUT_SUPPORTED
	if ((size_t)n >= sizeof(hdr.aout) && !N_BADMAG(hdr.aout)) {
		/* a.out file */
		if ((N_GETFLAG(hdr.aout) & EX_DPMASK) != EX_DYNAMIC
#if 1 /* Compatibility */
		    || hdr.aout.a_entry < __LDPGSZ
#endif
			) {
			warnx("%s: not a dynamic executable", fname);
			return (0);
		}
		*type = TYPE_AOUT;
		return (1);
	}
#endif

#if __ELF_WORD_SIZE > 32 && defined(ELF32_SUPPORTED)
	if ((size_t)n >= sizeof(hdr.elf32) && IS_ELF(hdr.elf32) &&
	    hdr.elf32.e_ident[EI_CLASS] == ELFCLASS32) {
		/* Handle 32 bit ELF objects */
		Elf32_Phdr phdr;
		int dynamic, i;

		dynamic = 0;
		*type = TYPE_ELF32;

		if (lseek(fd, hdr.elf32.e_phoff, SEEK_SET) == -1) {
			warnx("%s: header too short", fname);
			return (0);
		}
		for (i = 0; i < hdr.elf32.e_phnum; i++) {
			if (read(fd, &phdr, hdr.elf32.e_phentsize) !=
			    sizeof(phdr)) {
				warnx("%s: can't read program header", fname);
				return (0);
			}
			if (phdr.p_type == PT_DYNAMIC) {
				dynamic = 1;
				break;
			}
		}

		if (!dynamic) {
			warnx("%s: not a dynamic ELF executable", fname);
			return (0);
		}
		if (hdr.elf32.e_type == ET_DYN) {
			if (hdr.elf32.e_ident[EI_OSABI] == ELFOSABI_FREEBSD) {
				*is_shlib = 1;
				return (1);
			}
			warnx("%s: not a FreeBSD ELF shared object", fname);
			return (0);
		}

		return (1);
	}
#endif

	if ((size_t)n >= sizeof(hdr.elf) && IS_ELF(hdr.elf) &&
	    hdr.elf.e_ident[EI_CLASS] == ELF_TARG_CLASS) {
		/* Handle default ELF objects on this architecture */
		Elf_Phdr phdr;
		int dynamic, i;

		dynamic = 0;
		*type = TYPE_ELF;

		if (lseek(fd, hdr.elf.e_phoff, SEEK_SET) == -1) {
			warnx("%s: header too short", fname);
			return (0);
		}
		for (i = 0; i < hdr.elf.e_phnum; i++) {
			if (read(fd, &phdr, hdr.elf.e_phentsize)
			   != sizeof(phdr)) {
				warnx("%s: can't read program header", fname);
				return (0);
			}
			if (phdr.p_type == PT_DYNAMIC) {
				dynamic = 1;
				break;
			}
		}

		if (!dynamic) {
			warnx("%s: not a dynamic ELF executable", fname);
			return (0);
		}
		if (hdr.elf.e_type == ET_DYN) {
			switch (hdr.elf.e_ident[EI_OSABI]) {
			case ELFOSABI_FREEBSD:
				*is_shlib = 1;
				return (1);
#ifdef __ARM_EABI__
			case ELFOSABI_NONE:
				if (hdr.elf.e_machine != EM_ARM)
					break;
				if (EF_ARM_EABI_VERSION(hdr.elf.e_flags) <
				    EF_ARM_EABI_FREEBSD_MIN)
					break;
				*is_shlib = 1;
				return (1);
#endif
			}
			warnx("%s: not a FreeBSD ELF shared object", fname);
			return (0);
		}

		return (1);
	}

	warnx("%s: not a dynamic executable", fname);
	return (0);
}