ELF_PAGESTART(cmds[first_idx].p_vaddr);
 }
 
+/**
+ * load_elf_phdrs() - load ELF program headers
+ * @elf_ex:   ELF header of the binary whose program headers should be loaded
+ * @elf_file: the opened ELF binary file
+ *
+ * Loads ELF program headers from the binary file elf_file, which has the ELF
+ * header pointed to by elf_ex, into a newly allocated array. The caller is
+ * responsible for freeing the allocated data. Returns an ERR_PTR upon failure.
+ */
+static struct elf_phdr *load_elf_phdrs(struct elfhdr *elf_ex,
+                                      struct file *elf_file)
+{
+       struct elf_phdr *elf_phdata = NULL;
+       int retval, size, err = -1;
+
+       /*
+        * If the size of this structure has changed, then punt, since
+        * we will be doing the wrong thing.
+        */
+       if (elf_ex->e_phentsize != sizeof(struct elf_phdr))
+               goto out;
+
+       /* Sanity check the number of program headers... */
+       if (elf_ex->e_phnum < 1 ||
+               elf_ex->e_phnum > 65536U / sizeof(struct elf_phdr))
+               goto out;
+
+       /* ...and their total size. */
+       size = sizeof(struct elf_phdr) * elf_ex->e_phnum;
+       if (size > ELF_MIN_ALIGN)
+               goto out;
+
+       elf_phdata = kmalloc(size, GFP_KERNEL);
+       if (!elf_phdata)
+               goto out;
+
+       /* Read in the program headers */
+       retval = kernel_read(elf_file, elf_ex->e_phoff,
+                            (char *)elf_phdata, size);
+       if (retval != size) {
+               err = (retval < 0) ? retval : -EIO;
+               goto out;
+       }
+
+       /* Success! */
+       err = 0;
+out:
+       if (err) {
+               kfree(elf_phdata);
+               elf_phdata = NULL;
+       }
+       return elf_phdata;
+}
 
 /* This is much more generalized than the library routine read function,
    so we keep this separate.  Technically the library read function
        unsigned long last_bss = 0, elf_bss = 0;
        unsigned long error = ~0UL;
        unsigned long total_size;
-       int retval, i, size;
+       int i;
 
        /* First of all, some simple consistency checks */
        if (interp_elf_ex->e_type != ET_EXEC &&
        if (!interpreter->f_op->mmap)
                goto out;
 
-       /*
-        * If the size of this structure has changed, then punt, since
-        * we will be doing the wrong thing.
-        */
-       if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr))
-               goto out;
-       if (interp_elf_ex->e_phnum < 1 ||
-               interp_elf_ex->e_phnum > 65536U / sizeof(struct elf_phdr))
-               goto out;
-
-       /* Now read in all of the header information */
-       size = sizeof(struct elf_phdr) * interp_elf_ex->e_phnum;
-       if (size > ELF_MIN_ALIGN)
-               goto out;
-       elf_phdata = kmalloc(size, GFP_KERNEL);
+       elf_phdata = load_elf_phdrs(interp_elf_ex, interpreter);
        if (!elf_phdata)
                goto out;
 
-       retval = kernel_read(interpreter, interp_elf_ex->e_phoff,
-                            (char *)elf_phdata, size);
-       error = -EIO;
-       if (retval != size) {
-               if (retval < 0)
-                       error = retval; 
-               goto out_close;
-       }
-
        total_size = total_mapping_size(elf_phdata, interp_elf_ex->e_phnum);
        if (!total_size) {
                error = -EINVAL;
        struct elf_phdr *elf_ppnt, *elf_phdata;
        unsigned long elf_bss, elf_brk;
        int retval, i;
-       unsigned int size;
        unsigned long elf_entry;
        unsigned long interp_load_addr = 0;
        unsigned long start_code, end_code, start_data, end_data;
        if (!bprm->file->f_op->mmap)
                goto out;
 
-       /* Now read in all of the header information */
-       if (loc->elf_ex.e_phentsize != sizeof(struct elf_phdr))
-               goto out;
-       if (loc->elf_ex.e_phnum < 1 ||
-               loc->elf_ex.e_phnum > 65536U / sizeof(struct elf_phdr))
-               goto out;
-       size = loc->elf_ex.e_phnum * sizeof(struct elf_phdr);
-       retval = -ENOMEM;
-       elf_phdata = kmalloc(size, GFP_KERNEL);
+       elf_phdata = load_elf_phdrs(&loc->elf_ex, bprm->file);
        if (!elf_phdata)
                goto out;
 
-       retval = kernel_read(bprm->file, loc->elf_ex.e_phoff,
-                            (char *)elf_phdata, size);
-       if (retval != size) {
-               if (retval >= 0)
-                       retval = -EIO;
-               goto out_free_ph;
-       }
-
        elf_ppnt = elf_phdata;
        elf_bss = 0;
        elf_brk = 0;