diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/Kconfig.binfmt | 2 | ||||
| -rw-r--r-- | fs/binfmt_elf_fdpic.c | 45 | 
2 files changed, 26 insertions, 21 deletions
| diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt index 3263084eef9e..4a551af6f3fc 100644 --- a/fs/Kconfig.binfmt +++ b/fs/Kconfig.binfmt @@ -30,7 +30,7 @@ config COMPAT_BINFMT_ELF  config BINFMT_ELF_FDPIC  	bool "Kernel support for FDPIC ELF binaries"  	default y -	depends on (FRV || BLACKFIN) +	depends on (FRV || BLACKFIN || (SUPERH32 && !MMU))  	help  	  ELF FDPIC binaries are based on ELF, but allow the individual load  	  segments of a binary to be located in memory independently of each diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index fdeadab2f18b..80c1f952ef78 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -470,6 +470,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,  	char __user *u_platform, *p;  	long hwcap;  	int loop; +	int nr;	/* reset for each csp adjustment */  	/* we're going to shovel a whole load of stuff onto the stack */  #ifdef CONFIG_MMU @@ -542,10 +543,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,  	/* force 16 byte _final_ alignment here for generality */  #define DLINFO_ITEMS 13 -	nitems = 1 + DLINFO_ITEMS + (k_platform ? 1 : 0); -#ifdef DLINFO_ARCH_ITEMS -	nitems += DLINFO_ARCH_ITEMS; -#endif +	nitems = 1 + DLINFO_ITEMS + (k_platform ? 1 : 0) + AT_VECTOR_SIZE_ARCH;  	csp = sp;  	sp -= nitems * 2 * sizeof(unsigned long); @@ -557,39 +555,46 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,  	sp -= sp & 15UL;  	/* put the ELF interpreter info on the stack */ -#define NEW_AUX_ENT(nr, id, val)					\ +#define NEW_AUX_ENT(id, val)						\  	do {								\  		struct { unsigned long _id, _val; } __user *ent;	\  									\  		ent = (void __user *) csp;				\  		__put_user((id), &ent[nr]._id);				\  		__put_user((val), &ent[nr]._val);			\ +		nr++;							\  	} while (0) +	nr = 0;  	csp -= 2 * sizeof(unsigned long); -	NEW_AUX_ENT(0, AT_NULL, 0); +	NEW_AUX_ENT(AT_NULL, 0);  	if (k_platform) { +		nr = 0;  		csp -= 2 * sizeof(unsigned long); -		NEW_AUX_ENT(0, AT_PLATFORM, +		NEW_AUX_ENT(AT_PLATFORM,  			    (elf_addr_t) (unsigned long) u_platform);  	} +	nr = 0;  	csp -= DLINFO_ITEMS * 2 * sizeof(unsigned long); -	NEW_AUX_ENT( 0, AT_HWCAP,	hwcap); -	NEW_AUX_ENT( 1, AT_PAGESZ,	PAGE_SIZE); -	NEW_AUX_ENT( 2, AT_CLKTCK,	CLOCKS_PER_SEC); -	NEW_AUX_ENT( 3, AT_PHDR,	exec_params->ph_addr); -	NEW_AUX_ENT( 4, AT_PHENT,	sizeof(struct elf_phdr)); -	NEW_AUX_ENT( 5, AT_PHNUM,	exec_params->hdr.e_phnum); -	NEW_AUX_ENT( 6,	AT_BASE,	interp_params->elfhdr_addr); -	NEW_AUX_ENT( 7, AT_FLAGS,	0); -	NEW_AUX_ENT( 8, AT_ENTRY,	exec_params->entry_addr); -	NEW_AUX_ENT( 9, AT_UID,		(elf_addr_t) current->uid); -	NEW_AUX_ENT(10, AT_EUID,	(elf_addr_t) current->euid); -	NEW_AUX_ENT(11, AT_GID,		(elf_addr_t) current->gid); -	NEW_AUX_ENT(12, AT_EGID,	(elf_addr_t) current->egid); +	NEW_AUX_ENT(AT_HWCAP,	hwcap); +	NEW_AUX_ENT(AT_PAGESZ,	PAGE_SIZE); +	NEW_AUX_ENT(AT_CLKTCK,	CLOCKS_PER_SEC); +	NEW_AUX_ENT(AT_PHDR,	exec_params->ph_addr); +	NEW_AUX_ENT(AT_PHENT,	sizeof(struct elf_phdr)); +	NEW_AUX_ENT(AT_PHNUM,	exec_params->hdr.e_phnum); +	NEW_AUX_ENT(AT_BASE,	interp_params->elfhdr_addr); +	NEW_AUX_ENT(AT_FLAGS,	0); +	NEW_AUX_ENT(AT_ENTRY,	exec_params->entry_addr); +	NEW_AUX_ENT(AT_UID,	(elf_addr_t) current->uid); +	NEW_AUX_ENT(AT_EUID,	(elf_addr_t) current->euid); +	NEW_AUX_ENT(AT_GID,	(elf_addr_t) current->gid); +	NEW_AUX_ENT(AT_EGID,	(elf_addr_t) current->egid);  #ifdef ARCH_DLINFO +	nr = 0; +	csp -= AT_VECTOR_SIZE_ARCH * 2 * sizeof(unsigned long); +  	/* ARCH_DLINFO must come last so platform specific code can enforce  	 * special alignment requirements on the AUXV if necessary (eg. PPC).  	 */ | 
