svn commit: r346053 - head/sys/kern

2019-09-03 Thread Edward Tomasz Napierala
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, _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);
  

svn commit: r346053 - head/sys/kern

2019-04-09 Thread Edward Tomasz Napierala
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, _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);