#endif
 
 static int
-create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
-               unsigned long load_addr, unsigned long interp_load_addr)
+create_elf_tables(struct linux_binprm *bprm, const struct elfhdr *exec,
+               unsigned long load_addr, unsigned long interp_load_addr,
+               unsigned long e_entry)
 {
        unsigned long p = bprm->p;
        int argc = bprm->argc;
        NEW_AUX_ENT(AT_PHNUM, exec->e_phnum);
        NEW_AUX_ENT(AT_BASE, interp_load_addr);
        NEW_AUX_ENT(AT_FLAGS, 0);
-       NEW_AUX_ENT(AT_ENTRY, exec->e_entry);
+       NEW_AUX_ENT(AT_ENTRY, e_entry);
        NEW_AUX_ENT(AT_UID, from_kuid_munged(cred->user_ns, cred->uid));
        NEW_AUX_ENT(AT_EUID, from_kuid_munged(cred->user_ns, cred->euid));
        NEW_AUX_ENT(AT_GID, from_kgid_munged(cred->user_ns, cred->gid));
        int bss_prot = 0;
        int retval, i;
        unsigned long elf_entry;
+       unsigned long e_entry;
        unsigned long interp_load_addr = 0;
        unsigned long start_code, end_code, start_data, end_data;
        unsigned long reloc_func_desc __maybe_unused = 0;
        int executable_stack = EXSTACK_DEFAULT;
+       struct elfhdr *elf_ex = (struct elfhdr *)bprm->buf;
        struct {
-               struct elfhdr elf_ex;
                struct elfhdr interp_elf_ex;
        } *loc;
        struct arch_elf_state arch_state = INIT_ARCH_ELF_STATE;
                retval = -ENOMEM;
                goto out_ret;
        }
-       
-       /* Get the exec-header */
-       loc->elf_ex = *((struct elfhdr *)bprm->buf);
 
        retval = -ENOEXEC;
        /* First of all, some simple consistency checks */
-       if (memcmp(loc->elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
+       if (memcmp(elf_ex->e_ident, ELFMAG, SELFMAG) != 0)
                goto out;
 
-       if (loc->elf_ex.e_type != ET_EXEC && loc->elf_ex.e_type != ET_DYN)
+       if (elf_ex->e_type != ET_EXEC && elf_ex->e_type != ET_DYN)
                goto out;
-       if (!elf_check_arch(&loc->elf_ex))
+       if (!elf_check_arch(elf_ex))
                goto out;
-       if (elf_check_fdpic(&loc->elf_ex))
+       if (elf_check_fdpic(elf_ex))
                goto out;
        if (!bprm->file->f_op->mmap)
                goto out;
 
-       elf_phdata = load_elf_phdrs(&loc->elf_ex, bprm->file);
+       elf_phdata = load_elf_phdrs(elf_ex, bprm->file);
        if (!elf_phdata)
                goto out;
 
        elf_ppnt = elf_phdata;
-       for (i = 0; i < loc->elf_ex.e_phnum; i++, elf_ppnt++) {
+       for (i = 0; i < elf_ex->e_phnum; i++, elf_ppnt++) {
                char *elf_interpreter;
 
                if (elf_ppnt->p_type != PT_INTERP)
        }
 
        elf_ppnt = elf_phdata;
-       for (i = 0; i < loc->elf_ex.e_phnum; i++, elf_ppnt++)
+       for (i = 0; i < elf_ex->e_phnum; i++, elf_ppnt++)
                switch (elf_ppnt->p_type) {
                case PT_GNU_STACK:
                        if (elf_ppnt->p_flags & PF_X)
                        break;
 
                case PT_LOPROC ... PT_HIPROC:
-                       retval = arch_elf_pt_proc(&loc->elf_ex, elf_ppnt,
+                       retval = arch_elf_pt_proc(elf_ex, elf_ppnt,
                                                  bprm->file, false,
                                                  &arch_state);
                        if (retval)
         * still possible to return an error to the code that invoked
         * the exec syscall.
         */
-       retval = arch_check_elf(&loc->elf_ex,
+       retval = arch_check_elf(elf_ex,
                                !!interpreter, &loc->interp_elf_ex,
                                &arch_state);
        if (retval)
 
        /* Do this immediately, since STACK_TOP as used in setup_arg_pages
           may depend on the personality.  */
-       SET_PERSONALITY2(loc->elf_ex, &arch_state);
-       if (elf_read_implies_exec(loc->elf_ex, executable_stack))
+       SET_PERSONALITY2(*elf_ex, &arch_state);
+       if (elf_read_implies_exec(*elf_ex, executable_stack))
                current->personality |= READ_IMPLIES_EXEC;
 
        if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
        /* Now we do a little grungy work by mmapping the ELF image into
           the correct location in memory. */
        for(i = 0, elf_ppnt = elf_phdata;
-           i < loc->elf_ex.e_phnum; i++, elf_ppnt++) {
+           i < elf_ex->e_phnum; i++, elf_ppnt++) {
                int elf_prot, elf_flags;
                unsigned long k, vaddr;
                unsigned long total_size = 0;
                 * If we are loading ET_EXEC or we have already performed
                 * the ET_DYN load_addr calculations, proceed normally.
                 */
-               if (loc->elf_ex.e_type == ET_EXEC || load_addr_set) {
+               if (elf_ex->e_type == ET_EXEC || load_addr_set) {
                        elf_flags |= MAP_FIXED;
-               } else if (loc->elf_ex.e_type == ET_DYN) {
+               } else if (elf_ex->e_type == ET_DYN) {
                        /*
                         * This logic is run once for the first LOAD Program
                         * Header for ET_DYN binaries to calculate the
                        load_bias = ELF_PAGESTART(load_bias - vaddr);
 
                        total_size = total_mapping_size(elf_phdata,
-                                                       loc->elf_ex.e_phnum);
+                                                       elf_ex->e_phnum);
                        if (!total_size) {
                                retval = -EINVAL;
                                goto out_free_dentry;
                if (!load_addr_set) {
                        load_addr_set = 1;
                        load_addr = (elf_ppnt->p_vaddr - elf_ppnt->p_offset);
-                       if (loc->elf_ex.e_type == ET_DYN) {
+                       if (elf_ex->e_type == ET_DYN) {
                                load_bias += error -
                                             ELF_PAGESTART(load_bias + vaddr);
                                load_addr += load_bias;
                }
        }
 
-       loc->elf_ex.e_entry += load_bias;
+       e_entry = elf_ex->e_entry + load_bias;
        elf_bss += load_bias;
        elf_brk += load_bias;
        start_code += load_bias;
                allow_write_access(interpreter);
                fput(interpreter);
        } else {
-               elf_entry = loc->elf_ex.e_entry;
+               elf_entry = e_entry;
                if (BAD_ADDR(elf_entry)) {
                        retval = -EINVAL;
                        goto out_free_dentry;
                goto out;
 #endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */
 
-       retval = create_elf_tables(bprm, &loc->elf_ex,
-                         load_addr, interp_load_addr);
+       retval = create_elf_tables(bprm, elf_ex,
+                         load_addr, interp_load_addr, e_entry);
        if (retval < 0)
                goto out;
        current->mm->end_code = end_code;
                 * growing down), and into the unused ELF_ET_DYN_BASE region.
                 */
                if (IS_ENABLED(CONFIG_ARCH_HAS_ELF_RANDOMIZE) &&
-                   loc->elf_ex.e_type == ET_DYN && !interpreter)
+                   elf_ex->e_type == ET_DYN && !interpreter)
                        current->mm->brk = current->mm->start_brk =
                                ELF_ET_DYN_BASE;