2011-07-22 18:58:34 +04:00
# include <linux/export.h>
2008-09-07 20:16:54 +04:00
# include <linux/sched.h>
# include <linux/personality.h>
# include <linux/binfmts.h>
# include <linux/elf.h>
int elf_check_arch ( const struct elf32_hdr * x )
{
unsigned int eflags ;
/* Make sure it's an ARM executable */
if ( x - > e_machine ! = EM_ARM )
return 0 ;
/* Make sure the entry address is reasonable */
if ( x - > e_entry & 1 ) {
if ( ! ( elf_hwcap & HWCAP_THUMB ) )
return 0 ;
} else if ( x - > e_entry & 3 )
return 0 ;
eflags = x - > e_flags ;
if ( ( eflags & EF_ARM_EABI_MASK ) = = EF_ARM_EABI_UNKNOWN ) {
2008-11-02 12:16:50 +03:00
unsigned int flt_fmt ;
2008-09-07 20:16:54 +04:00
/* APCS26 is only allowed if the CPU supports it */
if ( ( eflags & EF_ARM_APCS_26 ) & & ! ( elf_hwcap & HWCAP_26BIT ) )
return 0 ;
2008-11-02 12:16:50 +03:00
flt_fmt = eflags & ( EF_ARM_VFP_FLOAT | EF_ARM_SOFT_FLOAT ) ;
2008-09-07 20:16:54 +04:00
/* VFP requires the supporting code */
2008-11-02 12:16:50 +03:00
if ( flt_fmt = = EF_ARM_VFP_FLOAT & & ! ( elf_hwcap & HWCAP_VFP ) )
2008-09-07 20:16:54 +04:00
return 0 ;
}
return 1 ;
}
EXPORT_SYMBOL ( elf_check_arch ) ;
void elf_set_personality ( const struct elf32_hdr * x )
{
unsigned int eflags = x - > e_flags ;
2011-04-13 07:59:36 +04:00
unsigned int personality = current - > personality & ~ PER_MASK ;
/*
* We only support Linux ELF executables , so always set the
* personality to LINUX .
*/
personality | = PER_LINUX ;
2008-09-07 20:16:54 +04:00
/*
* APCS - 26 is only valid for OABI executables
*/
2011-04-13 07:59:36 +04:00
if ( ( eflags & EF_ARM_EABI_MASK ) = = EF_ARM_EABI_UNKNOWN & &
( eflags & EF_ARM_APCS_26 ) )
personality & = ~ ADDR_LIMIT_32BIT ;
else
personality | = ADDR_LIMIT_32BIT ;
2008-09-07 20:16:54 +04:00
set_personality ( personality ) ;
/*
* Since the FPA coprocessor uses CP1 and CP2 , and iWMMXt uses CP0
* and CP1 , we only enable access to the iWMMXt coprocessor if the
* binary is EABI or softfloat ( and thus , guaranteed not to use
* FPA instructions . )
*/
if ( elf_hwcap & HWCAP_IWMMXT & &
eflags & ( EF_ARM_EABI_MASK | EF_ARM_SOFT_FLOAT ) ) {
set_thread_flag ( TIF_USING_IWMMXT ) ;
} else {
clear_thread_flag ( TIF_USING_IWMMXT ) ;
}
}
EXPORT_SYMBOL ( elf_set_personality ) ;
/*
* Set READ_IMPLIES_EXEC if :
* - the binary requires an executable stack
* - we ' re running on a CPU which doesn ' t support NX .
*/
int arm_elf_read_implies_exec ( const struct elf32_hdr * x , int executable_stack )
{
2009-02-19 17:34:59 +03:00
if ( executable_stack ! = EXSTACK_DISABLE_X )
2008-09-07 20:16:54 +04:00
return 1 ;
2009-02-19 17:34:59 +03:00
if ( cpu_architecture ( ) < CPU_ARCH_ARMv6 )
2008-09-07 20:16:54 +04:00
return 1 ;
return 0 ;
}
EXPORT_SYMBOL ( arm_elf_read_implies_exec ) ;