0001
0002 #include <linux/export.h>
0003 #include <linux/sched.h>
0004 #include <linux/personality.h>
0005 #include <linux/binfmts.h>
0006 #include <linux/elf.h>
0007 #include <linux/elf-fdpic.h>
0008 #include <asm/system_info.h>
0009
0010 int elf_check_arch(const struct elf32_hdr *x)
0011 {
0012 unsigned int eflags;
0013
0014
0015 if (x->e_machine != EM_ARM)
0016 return 0;
0017
0018
0019 if (x->e_entry & 1) {
0020 if (!(elf_hwcap & HWCAP_THUMB))
0021 return 0;
0022 } else if (x->e_entry & 3)
0023 return 0;
0024
0025 eflags = x->e_flags;
0026 if ((eflags & EF_ARM_EABI_MASK) == EF_ARM_EABI_UNKNOWN) {
0027 unsigned int flt_fmt;
0028
0029
0030 if ((eflags & EF_ARM_APCS_26) && !(elf_hwcap & HWCAP_26BIT))
0031 return 0;
0032
0033 flt_fmt = eflags & (EF_ARM_VFP_FLOAT | EF_ARM_SOFT_FLOAT);
0034
0035
0036 if (flt_fmt == EF_ARM_VFP_FLOAT && !(elf_hwcap & HWCAP_VFP))
0037 return 0;
0038 }
0039 return 1;
0040 }
0041 EXPORT_SYMBOL(elf_check_arch);
0042
0043 void elf_set_personality(const struct elf32_hdr *x)
0044 {
0045 unsigned int eflags = x->e_flags;
0046 unsigned int personality = current->personality & ~PER_MASK;
0047
0048
0049
0050
0051
0052 personality |= PER_LINUX;
0053
0054
0055
0056
0057 if ((eflags & EF_ARM_EABI_MASK) == EF_ARM_EABI_UNKNOWN &&
0058 (eflags & EF_ARM_APCS_26))
0059 personality &= ~ADDR_LIMIT_32BIT;
0060 else
0061 personality |= ADDR_LIMIT_32BIT;
0062
0063 set_personality(personality);
0064
0065
0066
0067
0068
0069
0070
0071 if (elf_hwcap & HWCAP_IWMMXT &&
0072 eflags & (EF_ARM_EABI_MASK | EF_ARM_SOFT_FLOAT)) {
0073 set_thread_flag(TIF_USING_IWMMXT);
0074 } else {
0075 clear_thread_flag(TIF_USING_IWMMXT);
0076 }
0077 }
0078 EXPORT_SYMBOL(elf_set_personality);
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104 int arm_elf_read_implies_exec(int executable_stack)
0105 {
0106 if (executable_stack == EXSTACK_DEFAULT)
0107 return 1;
0108 if (cpu_architecture() < CPU_ARCH_ARMv6)
0109 return 1;
0110 return 0;
0111 }
0112 EXPORT_SYMBOL(arm_elf_read_implies_exec);
0113
0114 #if defined(CONFIG_MMU) && defined(CONFIG_BINFMT_ELF_FDPIC)
0115
0116 void elf_fdpic_arch_lay_out_mm(struct elf_fdpic_params *exec_params,
0117 struct elf_fdpic_params *interp_params,
0118 unsigned long *start_stack,
0119 unsigned long *start_brk)
0120 {
0121 elf_set_personality(&exec_params->hdr);
0122
0123 exec_params->load_addr = 0x8000;
0124 interp_params->load_addr = ELF_ET_DYN_BASE;
0125 *start_stack = TASK_SIZE - SZ_16M;
0126
0127 if ((exec_params->flags & ELF_FDPIC_FLAG_ARRANGEMENT) == ELF_FDPIC_FLAG_INDEPENDENT) {
0128 exec_params->flags &= ~ELF_FDPIC_FLAG_ARRANGEMENT;
0129 exec_params->flags |= ELF_FDPIC_FLAG_CONSTDISP;
0130 }
0131 }
0132
0133 #endif