summaryrefslogtreecommitdiffstats
path: root/fs/binfmt_elf_fdpic.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2008-10-15 22:04:15 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-16 11:21:46 -0700
commitec23847d6cfe445ba9a1a5ec513297f4cc0ada53 (patch)
tree3c4dbdec1546023cc87ab058355e01a7c817e1af /fs/binfmt_elf_fdpic.c
parent758222f84261a6a808c4d1dcd443f90c1baaa875 (diff)
downloadlinux-ec23847d6cfe445ba9a1a5ec513297f4cc0ada53.tar.bz2
binfmt_elf_fdpic: support auxvec base platform string
Commit 483fad1c3fa1060d7e6710e84a065ad514571739 ("ELF loader support for auxvec base platform string") introduced AT_BASE_PLATFORM, but only implemented it for binfmt_elf. Given that AT_VECTOR_SIZE_BASE is unconditionally enlarged for us, and it's only optionally added in for the platforms that set ELF_BASE_PLATFORM, wire it up for binfmt_elf_fdpic, too. Signed-off-by: Paul Mundt <lethal@linux-sh.org> Acked-by: David Howells <dhowells@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/binfmt_elf_fdpic.c')
-rw-r--r--fs/binfmt_elf_fdpic.c50
1 files changed, 43 insertions, 7 deletions
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 80c1f952ef78..e4eb472558ca 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -455,6 +455,16 @@ error_kill:
}
/*****************************************************************************/
+
+#ifndef ELF_BASE_PLATFORM
+/*
+ * AT_BASE_PLATFORM indicates the "real" hardware/microarchitecture.
+ * If the arch defines ELF_BASE_PLATFORM (in asm/elf.h), the value
+ * will be copied to the user stack in the same manner as AT_PLATFORM.
+ */
+#define ELF_BASE_PLATFORM NULL
+#endif
+
/*
* present useful information to the program
*/
@@ -466,8 +476,8 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
unsigned long sp, csp, nitems;
elf_caddr_t __user *argv, *envp;
size_t platform_len = 0, len;
- char *k_platform;
- char __user *u_platform, *p;
+ char *k_platform, *k_base_platform;
+ char __user *u_platform, *u_base_platform, *p;
long hwcap;
int loop;
int nr; /* reset for each csp adjustment */
@@ -483,11 +493,14 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
return -EFAULT;
#endif
- /* get hold of platform and hardware capabilities masks for the machine
- * we are running on. In some cases (Sparc), this info is impossible
- * to get, in others (i386) it is merely difficult.
- */
hwcap = ELF_HWCAP;
+
+ /*
+ * If this architecture has a platform capability string, copy it
+ * to userspace. In some cases (Sparc), this info is impossible
+ * for userspace to get any other way, in others (i386) it is
+ * merely difficult.
+ */
k_platform = ELF_PLATFORM;
u_platform = NULL;
@@ -499,6 +512,21 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
return -EFAULT;
}
+ /*
+ * If this architecture has a "base" platform capability
+ * string, copy it to userspace.
+ */
+ k_base_platform = ELF_BASE_PLATFORM;
+ u_base_platform = NULL;
+
+ if (k_base_platform) {
+ platform_len = strlen(k_base_platform) + 1;
+ sp -= platform_len;
+ u_base_platform = (char __user *) sp;
+ if (__copy_to_user(u_base_platform, k_base_platform, platform_len) != 0)
+ return -EFAULT;
+ }
+
#if defined(__i386__) && defined(CONFIG_SMP)
/* in some cases (e.g. Hyper-Threading), we want to avoid L1 evictions
* by the processes running on the same package. One thing we can do is
@@ -543,7 +571,8 @@ 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) + AT_VECTOR_SIZE_ARCH;
+ nitems = 1 + DLINFO_ITEMS + (k_platform ? 1 : 0) +
+ (k_base_platform ? 1 : 0) + AT_VECTOR_SIZE_ARCH;
csp = sp;
sp -= nitems * 2 * sizeof(unsigned long);
@@ -575,6 +604,13 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
(elf_addr_t) (unsigned long) u_platform);
}
+ if (k_base_platform) {
+ nr = 0;
+ csp -= 2 * sizeof(unsigned long);
+ NEW_AUX_ENT(AT_BASE_PLATFORM,
+ (elf_addr_t) (unsigned long) u_base_platform);
+ }
+
nr = 0;
csp -= DLINFO_ITEMS * 2 * sizeof(unsigned long);
NEW_AUX_ENT(AT_HWCAP, hwcap);