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
This commit is contained in:
parent
cef38d45bb
commit
9bcd7482b2
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=346053
@ -649,6 +649,45 @@ __elfN(load_section)(struct image_params *imgp, vm_ooffset_t offset,
|
|||||||
return (0);
|
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
|
* Load the file "file" into memory. It may be either a shared object
|
||||||
* or an executable.
|
* or an executable.
|
||||||
@ -675,10 +714,9 @@ __elfN(load_file)(struct proc *p, const char *file, u_long *addr,
|
|||||||
struct nameidata *nd;
|
struct nameidata *nd;
|
||||||
struct vattr *attr;
|
struct vattr *attr;
|
||||||
struct image_params *imgp;
|
struct image_params *imgp;
|
||||||
vm_prot_t prot;
|
|
||||||
u_long rbase;
|
u_long rbase;
|
||||||
u_long base_addr = 0;
|
u_long base_addr = 0;
|
||||||
int error, i, numsegs;
|
int error;
|
||||||
|
|
||||||
#ifdef CAPABILITY_MODE
|
#ifdef CAPABILITY_MODE
|
||||||
/*
|
/*
|
||||||
@ -756,25 +794,10 @@ __elfN(load_file)(struct proc *p, const char *file, u_long *addr,
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0, numsegs = 0; i < hdr->e_phnum; i++) {
|
error = __elfN(load_sections)(imgp, hdr, phdr, rbase, &base_addr);
|
||||||
if (phdr[i].p_type == PT_LOAD && phdr[i].p_memsz != 0) {
|
if (error != 0)
|
||||||
/* Loadable segment */
|
goto fail;
|
||||||
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++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*addr = base_addr;
|
*addr = base_addr;
|
||||||
*entry = (unsigned long)hdr->e_entry + rbase;
|
*entry = (unsigned long)hdr->e_entry + rbase;
|
||||||
|
|
||||||
@ -998,7 +1021,6 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
|
|||||||
char *interp;
|
char *interp;
|
||||||
Elf_Brandinfo *brand_info;
|
Elf_Brandinfo *brand_info;
|
||||||
struct sysentvec *sv;
|
struct sysentvec *sv;
|
||||||
vm_prot_t prot;
|
|
||||||
u_long addr, baddr, et_dyn_addr, entry, proghdr;
|
u_long addr, baddr, et_dyn_addr, entry, proghdr;
|
||||||
u_long maxalign, mapsz, maxv, maxv1;
|
u_long maxalign, mapsz, maxv, maxv1;
|
||||||
uint32_t fctl0;
|
uint32_t fctl0;
|
||||||
@ -1055,6 +1077,17 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
|
|||||||
maxalign = phdr[i].p_align;
|
maxalign = phdr[i].p_align;
|
||||||
mapsz += phdr[i].p_memsz;
|
mapsz += phdr[i].p_memsz;
|
||||||
n++;
|
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;
|
break;
|
||||||
case PT_INTERP:
|
case PT_INTERP:
|
||||||
/* Path to interpreter */
|
/* Path to interpreter */
|
||||||
@ -1074,6 +1107,9 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
|
|||||||
__elfN(trans_prot)(phdr[i].p_flags);
|
__elfN(trans_prot)(phdr[i].p_flags);
|
||||||
imgp->stack_sz = phdr[i].p_memsz;
|
imgp->stack_sz = phdr[i].p_memsz;
|
||||||
break;
|
break;
|
||||||
|
case PT_PHDR: /* Program header table info */
|
||||||
|
proghdr = phdr[i].p_vaddr;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1174,37 +1210,9 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
|
|||||||
if (error != 0)
|
if (error != 0)
|
||||||
goto ret;
|
goto ret;
|
||||||
|
|
||||||
for (i = 0; i < hdr->e_phnum; i++) {
|
error = __elfN(load_sections)(imgp, hdr, phdr, et_dyn_addr, NULL);
|
||||||
switch (phdr[i].p_type) {
|
if (error != 0)
|
||||||
case PT_LOAD: /* Loadable segment */
|
goto ret;
|
||||||
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;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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);
|
error = __elfN(enforce_limits)(imgp, hdr, phdr, et_dyn_addr);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
@ -1253,7 +1261,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
|
|||||||
*/
|
*/
|
||||||
elf_auxargs = malloc(sizeof(Elf_Auxargs), M_TEMP, M_WAITOK);
|
elf_auxargs = malloc(sizeof(Elf_Auxargs), M_TEMP, M_WAITOK);
|
||||||
elf_auxargs->execfd = -1;
|
elf_auxargs->execfd = -1;
|
||||||
elf_auxargs->phdr = proghdr;
|
elf_auxargs->phdr = proghdr + et_dyn_addr;
|
||||||
elf_auxargs->phent = hdr->e_phentsize;
|
elf_auxargs->phent = hdr->e_phentsize;
|
||||||
elf_auxargs->phnum = hdr->e_phnum;
|
elf_auxargs->phnum = hdr->e_phnum;
|
||||||
elf_auxargs->pagesz = PAGE_SIZE;
|
elf_auxargs->pagesz = PAGE_SIZE;
|
||||||
|
Loading…
Reference in New Issue
Block a user