Author: trasz
Date: Tue Apr  9 15:24:38 2019
New Revision: 346053
URL: https://svnweb.freebsd.org/changeset/base/346053

Log:
  Factor out section loading into a separate function.
  
  Reviewed by:  kib
  MFC after:    2 weeks
  Sponsored by: DARPA, AFRL
  Differential Revision:        https://reviews.freebsd.org/D19846

Modified:
  head/sys/kern/imgact_elf.c

Modified: head/sys/kern/imgact_elf.c
==============================================================================
--- head/sys/kern/imgact_elf.c  Tue Apr  9 13:54:08 2019        (r346052)
+++ head/sys/kern/imgact_elf.c  Tue Apr  9 15:24:38 2019        (r346053)
@@ -649,6 +649,45 @@ __elfN(load_section)(struct image_params *imgp, vm_oof
        return (0);
 }
 
+static int
+__elfN(load_sections)(struct image_params *imgp, const Elf_Ehdr *hdr,
+    const Elf_Phdr *phdr, u_long rbase, u_long *base_addrp)
+{
+       vm_prot_t prot;
+       u_long base_addr;
+       bool first;
+       int error, i;
+
+       base_addr = 0;
+       first = true;
+
+       for (i = 0; i < hdr->e_phnum; i++) {
+               if (phdr[i].p_type != PT_LOAD || phdr[i].p_memsz == 0)
+                       continue;
+
+               /* Loadable segment */
+               prot = __elfN(trans_prot)(phdr[i].p_flags);
+               error = __elfN(load_section)(imgp, phdr[i].p_offset,
+                   (caddr_t)(uintptr_t)phdr[i].p_vaddr + rbase,
+                   phdr[i].p_memsz, phdr[i].p_filesz, prot);
+               if (error != 0)
+                       return (error);
+
+               /*
+                * Establish the base address if this is the first segment.
+                */
+               if (first) {
+                       base_addr = trunc_page(phdr[i].p_vaddr + rbase);
+                       first = false;
+               }
+       }
+
+       if (base_addrp != NULL)
+               *base_addrp = base_addr;
+
+       return (0);
+}
+
 /*
  * Load the file "file" into memory.  It may be either a shared object
  * or an executable.
@@ -675,10 +714,9 @@ __elfN(load_file)(struct proc *p, const char *file, u_
        struct nameidata *nd;
        struct vattr *attr;
        struct image_params *imgp;
-       vm_prot_t prot;
        u_long rbase;
        u_long base_addr = 0;
-       int error, i, numsegs;
+       int error;
 
 #ifdef CAPABILITY_MODE
        /*
@@ -756,25 +794,10 @@ __elfN(load_file)(struct proc *p, const char *file, u_
                goto fail;
        }
 
-       for (i = 0, numsegs = 0; i < hdr->e_phnum; i++) {
-               if (phdr[i].p_type == PT_LOAD && phdr[i].p_memsz != 0) {
-                       /* Loadable segment */
-                       prot = __elfN(trans_prot)(phdr[i].p_flags);
-                       error = __elfN(load_section)(imgp, phdr[i].p_offset,
-                           (caddr_t)(uintptr_t)phdr[i].p_vaddr + rbase,
-                           phdr[i].p_memsz, phdr[i].p_filesz, prot);
-                       if (error != 0)
-                               goto fail;
-                       /*
-                        * Establish the base address if this is the
-                        * first segment.
-                        */
-                       if (numsegs == 0)
-                               base_addr = trunc_page(phdr[i].p_vaddr +
-                                   rbase);
-                       numsegs++;
-               }
-       }
+       error = __elfN(load_sections)(imgp, hdr, phdr, rbase, &base_addr);
+       if (error != 0)
+               goto fail;
+
        *addr = base_addr;
        *entry = (unsigned long)hdr->e_entry + rbase;
 
@@ -998,7 +1021,6 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
        char *interp;
        Elf_Brandinfo *brand_info;
        struct sysentvec *sv;
-       vm_prot_t prot;
        u_long addr, baddr, et_dyn_addr, entry, proghdr;
        u_long maxalign, mapsz, maxv, maxv1;
        uint32_t fctl0;
@@ -1055,6 +1077,17 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
                                maxalign = phdr[i].p_align;
                        mapsz += phdr[i].p_memsz;
                        n++;
+
+                       /*
+                        * If this segment contains the program headers,
+                        * remember their virtual address for the AT_PHDR
+                        * aux entry. Static binaries don't usually include
+                        * a PT_PHDR entry.
+                        */
+                       if (phdr[i].p_offset == 0 &&
+                           hdr->e_phoff + hdr->e_phnum * hdr->e_phentsize
+                               <= phdr[i].p_filesz)
+                               proghdr = phdr[i].p_vaddr + hdr->e_phoff;
                        break;
                case PT_INTERP:
                        /* Path to interpreter */
@@ -1074,6 +1107,9 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
                                    __elfN(trans_prot)(phdr[i].p_flags);
                        imgp->stack_sz = phdr[i].p_memsz;
                        break;
+               case PT_PHDR:   /* Program header table info */
+                       proghdr = phdr[i].p_vaddr;
+                       break;
                }
        }
 
@@ -1174,38 +1210,10 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
        if (error != 0)
                goto ret;
 
-       for (i = 0; i < hdr->e_phnum; i++) {
-               switch (phdr[i].p_type) {
-               case PT_LOAD:   /* Loadable segment */
-                       if (phdr[i].p_memsz == 0)
-                               break;
-                       prot = __elfN(trans_prot)(phdr[i].p_flags);
-                       error = __elfN(load_section)(imgp, phdr[i].p_offset,
-                           (caddr_t)(uintptr_t)phdr[i].p_vaddr + et_dyn_addr,
-                           phdr[i].p_memsz, phdr[i].p_filesz, prot);
-                       if (error != 0)
-                               goto ret;
+       error = __elfN(load_sections)(imgp, hdr, phdr, et_dyn_addr, NULL);
+       if (error != 0)
+               goto ret;
 
-                       /*
-                        * If this segment contains the program headers,
-                        * remember their virtual address for the AT_PHDR
-                        * aux entry. Static binaries don't usually include
-                        * a PT_PHDR entry.
-                        */
-                       if (phdr[i].p_offset == 0 &&
-                           hdr->e_phoff + hdr->e_phnum * hdr->e_phentsize
-                               <= phdr[i].p_filesz)
-                               proghdr = phdr[i].p_vaddr + hdr->e_phoff +
-                                   et_dyn_addr;
-                       break;
-               case PT_PHDR:   /* Program header table info */
-                       proghdr = phdr[i].p_vaddr + et_dyn_addr;
-                       break;
-               default:
-                       break;
-               }
-       }
-
        error = __elfN(enforce_limits)(imgp, hdr, phdr, et_dyn_addr);
        if (error != 0)
                goto ret;
@@ -1253,7 +1261,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
         */
        elf_auxargs = malloc(sizeof(Elf_Auxargs), M_TEMP, M_WAITOK);
        elf_auxargs->execfd = -1;
-       elf_auxargs->phdr = proghdr;
+       elf_auxargs->phdr = proghdr + et_dyn_addr;
        elf_auxargs->phent = hdr->e_phentsize;
        elf_auxargs->phnum = hdr->e_phnum;
        elf_auxargs->pagesz = PAGE_SIZE;
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to