diff options
Diffstat (limited to 'arch/mips/include/asm/elf.h')
| -rw-r--r-- | arch/mips/include/asm/elf.h | 32 | 
1 files changed, 29 insertions, 3 deletions
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index cf3ae2480b1..d4144056e92 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h @@ -36,6 +36,7 @@  #define EF_MIPS_ABI2		0x00000020  #define EF_MIPS_OPTIONS_FIRST	0x00000080  #define EF_MIPS_32BITMODE	0x00000100 +#define EF_MIPS_FP64		0x00000200  #define EF_MIPS_ABI		0x0000f000  #define EF_MIPS_ARCH		0xf0000000 @@ -176,6 +177,18 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];  #ifdef CONFIG_32BIT  /* + * In order to be sure that we don't attempt to execute an O32 binary which + * requires 64 bit FP (FR=1) on a system which does not support it we refuse + * to execute any binary which has bits specified by the following macro set + * in its ELF header flags. + */ +#ifdef CONFIG_MIPS_O32_FP64_SUPPORT +# define __MIPS_O32_FP64_MUST_BE_ZERO	0 +#else +# define __MIPS_O32_FP64_MUST_BE_ZERO	EF_MIPS_FP64 +#endif + +/*   * This is used to ensure we don't load something for the wrong architecture.   */  #define elf_check_arch(hdr)						\ @@ -192,6 +205,8 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];  	if (((__h->e_flags & EF_MIPS_ABI) != 0) &&			\  	    ((__h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32))		\  		__res = 0;						\ +	if (__h->e_flags & __MIPS_O32_FP64_MUST_BE_ZERO)		\ +		__res = 0;						\  									\  	__res;								\  }) @@ -249,6 +264,11 @@ extern struct mips_abi mips_abi_n32;  #define SET_PERSONALITY(ex)						\  do {									\ +	if ((ex).e_flags & EF_MIPS_FP64)				\ +		clear_thread_flag(TIF_32BIT_FPREGS);			\ +	else								\ +		set_thread_flag(TIF_32BIT_FPREGS);			\ +									\  	if (personality(current->personality) != PER_LINUX)		\  		set_personality(PER_LINUX);				\  									\ @@ -271,14 +291,18 @@ do {									\  #endif  #ifdef CONFIG_MIPS32_O32 -#define __SET_PERSONALITY32_O32()					\ +#define __SET_PERSONALITY32_O32(ex)					\  	do {								\  		set_thread_flag(TIF_32BIT_REGS);			\  		set_thread_flag(TIF_32BIT_ADDR);			\ +									\ +		if (!((ex).e_flags & EF_MIPS_FP64))			\ +			set_thread_flag(TIF_32BIT_FPREGS);		\ +									\  		current->thread.abi = &mips_abi_32;			\  	} while (0)  #else -#define __SET_PERSONALITY32_O32()					\ +#define __SET_PERSONALITY32_O32(ex)					\  	do { } while (0)  #endif @@ -289,7 +313,7 @@ do {									\  	     ((ex).e_flags & EF_MIPS_ABI) == 0)				\  		__SET_PERSONALITY32_N32();				\  	else								\ -		__SET_PERSONALITY32_O32();				\ +		__SET_PERSONALITY32_O32(ex);                            \  } while (0)  #else  #define __SET_PERSONALITY32(ex) do { } while (0) @@ -300,6 +324,7 @@ do {									\  	unsigned int p;							\  									\  	clear_thread_flag(TIF_32BIT_REGS);				\ +	clear_thread_flag(TIF_32BIT_FPREGS);				\  	clear_thread_flag(TIF_32BIT_ADDR);				\  									\  	if ((ex).e_ident[EI_CLASS] == ELFCLASS32)			\ @@ -331,6 +356,7 @@ extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);  #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs)			\  	dump_task_fpu(tsk, elf_fpregs) +#define CORE_DUMP_USE_REGSET  #define ELF_EXEC_PAGESIZE	PAGE_SIZE  /* This yields a mask that user programs can use to figure out what  | 
