|
@@ -131,6 +131,15 @@ static int padzero(unsigned long elf_bss)
|
|
|
#define STACK_ALLOC(sp, len) ({ sp -= len ; sp; })
|
|
|
#endif
|
|
|
|
|
|
+#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
|
|
|
+
|
|
|
static int
|
|
|
create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
|
|
|
unsigned long load_addr, unsigned long interp_load_addr)
|
|
@@ -142,7 +151,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
|
|
|
elf_addr_t __user *envp;
|
|
|
elf_addr_t __user *sp;
|
|
|
elf_addr_t __user *u_platform;
|
|
|
+ elf_addr_t __user *u_base_platform;
|
|
|
const char *k_platform = ELF_PLATFORM;
|
|
|
+ const char *k_base_platform = ELF_BASE_PLATFORM;
|
|
|
int items;
|
|
|
elf_addr_t *elf_info;
|
|
|
int ei_index = 0;
|
|
@@ -172,6 +183,19 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
|
|
|
return -EFAULT;
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * If this architecture has a "base" platform capability
|
|
|
+ * string, copy it to userspace.
|
|
|
+ */
|
|
|
+ u_base_platform = NULL;
|
|
|
+ if (k_base_platform) {
|
|
|
+ size_t len = strlen(k_base_platform) + 1;
|
|
|
+
|
|
|
+ u_base_platform = (elf_addr_t __user *)STACK_ALLOC(p, len);
|
|
|
+ if (__copy_to_user(u_base_platform, k_base_platform, len))
|
|
|
+ return -EFAULT;
|
|
|
+ }
|
|
|
+
|
|
|
/* Create the ELF interpreter info */
|
|
|
elf_info = (elf_addr_t *)current->mm->saved_auxv;
|
|
|
/* update AT_VECTOR_SIZE_BASE if the number of NEW_AUX_ENT() changes */
|
|
@@ -209,6 +233,10 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
|
|
|
NEW_AUX_ENT(AT_PLATFORM,
|
|
|
(elf_addr_t)(unsigned long)u_platform);
|
|
|
}
|
|
|
+ if (k_base_platform) {
|
|
|
+ NEW_AUX_ENT(AT_BASE_PLATFORM,
|
|
|
+ (elf_addr_t)(unsigned long)u_base_platform);
|
|
|
+ }
|
|
|
if (bprm->interp_flags & BINPRM_FLAGS_EXECFD) {
|
|
|
NEW_AUX_ENT(AT_EXECFD, bprm->interp_data);
|
|
|
}
|