svn commit: r198284 - in stable/8/sys: . amd64/include/xen
cddl/contrib/opensolaris contrib/dev/acpica contrib/pf
dev/xen/xenpci kern
Konstantin Belousov
kib at FreeBSD.org
Tue Oct 20 13:34:42 UTC 2009
Author: kib
Date: Tue Oct 20 13:34:41 2009
New Revision: 198284
URL: http://svn.freebsd.org/changeset/base/198284
Log:
MFC r197934:
Map PIE binaries at non-zero base address.
MFC r198202:
Honour non-zero mapbase for PIE binaries. Inform interpreter-less PIE
binary about its relocbase.
Approved by: re (kensmith)
Modified:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/xen/xenpci/ (props changed)
stable/8/sys/kern/imgact_elf.c
Modified: stable/8/sys/kern/imgact_elf.c
==============================================================================
--- stable/8/sys/kern/imgact_elf.c Tue Oct 20 13:32:28 2009 (r198283)
+++ stable/8/sys/kern/imgact_elf.c Tue Oct 20 13:34:41 2009 (r198284)
@@ -685,9 +685,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, 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;
@@ -716,14 +716,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;
}
}
@@ -733,9 +741,19 @@ __CONCAT(exec_, __elfN(imgact))(struct i
hdr->e_ident[EI_OSABI]);
return (ENOEXEC);
}
- if (hdr->e_type == ET_DYN &&
- (brand_info->flags & BI_CAN_EXEC_DYN) == 0)
- return (ENOEXEC);
+ if (hdr->e_type == ET_DYN) {
+ if ((brand_info->flags & BI_CAN_EXEC_DYN) == 0)
+ return (ENOEXEC);
+ /*
+ * 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;
if (interp != NULL && brand_info->interp_newpath != NULL)
newinterp = brand_info->interp_newpath;
@@ -783,7 +801,7 @@ __CONCAT(exec_, __elfN(imgact))(struct i
if ((error = __elfN(load_section)(vmspace,
imgp->object, phdr[i].p_offset,
- (caddr_t)(uintptr_t)phdr[i].p_vaddr,
+ (caddr_t)(uintptr_t)phdr[i].p_vaddr + et_dyn_addr,
phdr[i].p_memsz, phdr[i].p_filesz, prot,
sv->sv_pagesize)) != 0)
return (error);
@@ -797,11 +815,12 @@ __CONCAT(exec_, __elfN(imgact))(struct i
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;
+ proghdr = phdr[i].p_vaddr + hdr->e_phoff +
+ et_dyn_addr;
- seg_addr = trunc_page(phdr[i].p_vaddr);
+ seg_addr = trunc_page(phdr[i].p_vaddr + et_dyn_addr);
seg_size = round_page(phdr[i].p_memsz +
- phdr[i].p_vaddr - seg_addr);
+ phdr[i].p_vaddr + et_dyn_addr - seg_addr);
/*
* Is this .text or .data? We can't use
@@ -823,7 +842,7 @@ __CONCAT(exec_, __elfN(imgact))(struct i
phdr[i].p_memsz)) {
text_size = seg_size;
text_addr = seg_addr;
- entry = (u_long)hdr->e_entry;
+ entry = (u_long)hdr->e_entry + et_dyn_addr;
} else {
data_size = seg_size;
data_addr = seg_addr;
@@ -831,7 +850,7 @@ __CONCAT(exec_, __elfN(imgact))(struct i
total_size += seg_size;
break;
case PT_PHDR: /* Program header table info */
- proghdr = phdr[i].p_vaddr;
+ proghdr = phdr[i].p_vaddr + et_dyn_addr;
break;
default:
break;
@@ -903,7 +922,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-8
mailing list