svn commit: r202646 - stable/7/sys/kern
Konstantin Belousov
kib at FreeBSD.org
Tue Jan 19 19:59:04 UTC 2010
Author: kib
Date: Tue Jan 19 19:59:03 2010
New Revision: 202646
URL: http://svn.freebsd.org/changeset/base/202646
Log:
MFC r198202:
If ET_DYN binary has non-zero base address for some reason, honour it
and do not relocate the binary to ET_DYN_LOAD_ADDR. Communicate the
relocation bias of the mapping for interpeter-less ET_DYN binary.
Tested by: Mykola Dzham <i levsha me>
Modified:
stable/7/sys/kern/imgact_elf.c
Directory Properties:
stable/7/sys/ (props changed)
stable/7/sys/cddl/contrib/opensolaris/ (props changed)
stable/7/sys/contrib/dev/acpica/ (props changed)
stable/7/sys/contrib/pf/ (props changed)
Modified: stable/7/sys/kern/imgact_elf.c
==============================================================================
--- stable/7/sys/kern/imgact_elf.c Tue Jan 19 19:56:50 2010 (r202645)
+++ stable/7/sys/kern/imgact_elf.c Tue Jan 19 19:59:03 2010 (r202646)
@@ -692,9 +692,9 @@ __CONCAT(exec_, __elfN(imgact))(struct i
u_long text_size = 0, data_size = 0, total_size = 0;
u_long text_addr = 0, data_addr = 0;
u_long seg_size, seg_addr;
- u_long addr, et_dyn_addr, entry = 0, proghdr = 0;
+ u_long addr, baddr, et_dyn_addr, entry = 0, proghdr = 0;
int32_t osrel = 0;
- int error = 0, i;
+ int error = 0, i, n;
const char *interp = NULL, *newinterp = NULL;
Elf_Brandinfo *brand_info;
char *path;
@@ -724,14 +724,22 @@ __CONCAT(exec_, __elfN(imgact))(struct i
phdr = (const Elf_Phdr *)(imgp->image_header + hdr->e_phoff);
if (!aligned(phdr, Elf_Addr))
return (ENOEXEC);
+ n = 0;
+ baddr = 0;
for (i = 0; i < hdr->e_phnum; i++) {
+ if (phdr[i].p_type == PT_LOAD) {
+ if (n == 0)
+ baddr = phdr[i].p_vaddr;
+ n++;
+ continue;
+ }
if (phdr[i].p_type == PT_INTERP) {
/* Path to interpreter */
if (phdr[i].p_filesz > MAXPATHLEN ||
phdr[i].p_offset + phdr[i].p_filesz > PAGE_SIZE)
return (ENOEXEC);
interp = imgp->image_header + phdr[i].p_offset;
- break;
+ continue;
}
}
@@ -744,7 +752,14 @@ __CONCAT(exec_, __elfN(imgact))(struct i
if (hdr->e_type == ET_DYN) {
if ((brand_info->flags & BI_CAN_EXEC_DYN) == 0)
return (ENOEXEC);
- et_dyn_addr = ET_DYN_LOAD_ADDR;
+ /*
+ * Honour the base load address from the dso if it is
+ * non-zero for some reason.
+ */
+ if (baddr == 0)
+ et_dyn_addr = ET_DYN_LOAD_ADDR;
+ else
+ et_dyn_addr = 0;
} else
et_dyn_addr = 0;
sv = brand_info->sysvec;
@@ -915,7 +930,7 @@ __CONCAT(exec_, __elfN(imgact))(struct i
return (error);
}
} else
- addr = 0;
+ addr = et_dyn_addr;
/*
* Construct auxargs table (used by the fixup routine)
More information about the svn-src-stable-7
mailing list