| Paul Gortmaker | ecea4ab | 2011-07-22 10:58:34 -0400 | [diff] [blame] | 1 | #include <linux/export.h> | 
| Russell King | 8ec5366 | 2008-09-07 17:16:54 +0100 | [diff] [blame] | 2 | #include <linux/sched.h> | 
 | 3 | #include <linux/personality.h> | 
 | 4 | #include <linux/binfmts.h> | 
 | 5 | #include <linux/elf.h> | 
| David Howells | 9f97da7 | 2012-03-28 18:30:01 +0100 | [diff] [blame] | 6 | #include <asm/system_info.h> | 
| Russell King | 8ec5366 | 2008-09-07 17:16:54 +0100 | [diff] [blame] | 7 |  | 
 | 8 | int elf_check_arch(const struct elf32_hdr *x) | 
 | 9 | { | 
 | 10 | 	unsigned int eflags; | 
 | 11 |  | 
 | 12 | 	/* Make sure it's an ARM executable */ | 
 | 13 | 	if (x->e_machine != EM_ARM) | 
 | 14 | 		return 0; | 
 | 15 |  | 
 | 16 | 	/* Make sure the entry address is reasonable */ | 
 | 17 | 	if (x->e_entry & 1) { | 
 | 18 | 		if (!(elf_hwcap & HWCAP_THUMB)) | 
 | 19 | 			return 0; | 
 | 20 | 	} else if (x->e_entry & 3) | 
 | 21 | 		return 0; | 
 | 22 |  | 
 | 23 | 	eflags = x->e_flags; | 
 | 24 | 	if ((eflags & EF_ARM_EABI_MASK) == EF_ARM_EABI_UNKNOWN) { | 
| Russell King | d2ed5cb | 2008-11-02 09:16:50 +0000 | [diff] [blame] | 25 | 		unsigned int flt_fmt; | 
 | 26 |  | 
| Russell King | 8ec5366 | 2008-09-07 17:16:54 +0100 | [diff] [blame] | 27 | 		/* APCS26 is only allowed if the CPU supports it */ | 
 | 28 | 		if ((eflags & EF_ARM_APCS_26) && !(elf_hwcap & HWCAP_26BIT)) | 
 | 29 | 			return 0; | 
 | 30 |  | 
| Russell King | d2ed5cb | 2008-11-02 09:16:50 +0000 | [diff] [blame] | 31 | 		flt_fmt = eflags & (EF_ARM_VFP_FLOAT | EF_ARM_SOFT_FLOAT); | 
 | 32 |  | 
| Russell King | 8ec5366 | 2008-09-07 17:16:54 +0100 | [diff] [blame] | 33 | 		/* VFP requires the supporting code */ | 
| Russell King | d2ed5cb | 2008-11-02 09:16:50 +0000 | [diff] [blame] | 34 | 		if (flt_fmt == EF_ARM_VFP_FLOAT && !(elf_hwcap & HWCAP_VFP)) | 
| Russell King | 8ec5366 | 2008-09-07 17:16:54 +0100 | [diff] [blame] | 35 | 			return 0; | 
 | 36 | 	} | 
 | 37 | 	return 1; | 
 | 38 | } | 
 | 39 | EXPORT_SYMBOL(elf_check_arch); | 
 | 40 |  | 
 | 41 | void elf_set_personality(const struct elf32_hdr *x) | 
 | 42 | { | 
 | 43 | 	unsigned int eflags = x->e_flags; | 
| Nicolas Pitre | 5e14343 | 2011-04-13 04:59:36 +0100 | [diff] [blame] | 44 | 	unsigned int personality = current->personality & ~PER_MASK; | 
 | 45 |  | 
 | 46 | 	/* | 
 | 47 | 	 * We only support Linux ELF executables, so always set the | 
 | 48 | 	 * personality to LINUX. | 
 | 49 | 	 */ | 
 | 50 | 	personality |= PER_LINUX; | 
| Russell King | 8ec5366 | 2008-09-07 17:16:54 +0100 | [diff] [blame] | 51 |  | 
 | 52 | 	/* | 
 | 53 | 	 * APCS-26 is only valid for OABI executables | 
 | 54 | 	 */ | 
| Nicolas Pitre | 5e14343 | 2011-04-13 04:59:36 +0100 | [diff] [blame] | 55 | 	if ((eflags & EF_ARM_EABI_MASK) == EF_ARM_EABI_UNKNOWN && | 
 | 56 | 	    (eflags & EF_ARM_APCS_26)) | 
 | 57 | 		personality &= ~ADDR_LIMIT_32BIT; | 
 | 58 | 	else | 
 | 59 | 		personality |= ADDR_LIMIT_32BIT; | 
| Russell King | 8ec5366 | 2008-09-07 17:16:54 +0100 | [diff] [blame] | 60 |  | 
 | 61 | 	set_personality(personality); | 
 | 62 |  | 
 | 63 | 	/* | 
 | 64 | 	 * Since the FPA coprocessor uses CP1 and CP2, and iWMMXt uses CP0 | 
 | 65 | 	 * and CP1, we only enable access to the iWMMXt coprocessor if the | 
 | 66 | 	 * binary is EABI or softfloat (and thus, guaranteed not to use | 
 | 67 | 	 * FPA instructions.) | 
 | 68 | 	 */ | 
 | 69 | 	if (elf_hwcap & HWCAP_IWMMXT && | 
 | 70 | 	    eflags & (EF_ARM_EABI_MASK | EF_ARM_SOFT_FLOAT)) { | 
 | 71 | 		set_thread_flag(TIF_USING_IWMMXT); | 
 | 72 | 	} else { | 
 | 73 | 		clear_thread_flag(TIF_USING_IWMMXT); | 
 | 74 | 	} | 
 | 75 | } | 
 | 76 | EXPORT_SYMBOL(elf_set_personality); | 
 | 77 |  | 
 | 78 | /* | 
 | 79 |  * Set READ_IMPLIES_EXEC if: | 
 | 80 |  *  - the binary requires an executable stack | 
 | 81 |  *  - we're running on a CPU which doesn't support NX. | 
 | 82 |  */ | 
 | 83 | int arm_elf_read_implies_exec(const struct elf32_hdr *x, int executable_stack) | 
 | 84 | { | 
| Makito SHIOKAWA | 9da616f | 2009-02-19 15:34:59 +0100 | [diff] [blame] | 85 | 	if (executable_stack != EXSTACK_DISABLE_X) | 
| Russell King | 8ec5366 | 2008-09-07 17:16:54 +0100 | [diff] [blame] | 86 | 		return 1; | 
| Makito SHIOKAWA | 9da616f | 2009-02-19 15:34:59 +0100 | [diff] [blame] | 87 | 	if (cpu_architecture() < CPU_ARCH_ARMv6) | 
| Russell King | 8ec5366 | 2008-09-07 17:16:54 +0100 | [diff] [blame] | 88 | 		return 1; | 
 | 89 | 	return 0; | 
| Russell King | 8ec5366 | 2008-09-07 17:16:54 +0100 | [diff] [blame] | 90 | } | 
 | 91 | EXPORT_SYMBOL(arm_elf_read_implies_exec); |