summaryrefslogtreecommitdiffstats
path: root/sys/kern/exec_elf.c
diff options
context:
space:
mode:
authorariane <ariane@openbsd.org>2011-05-24 15:27:36 +0000
committerariane <ariane@openbsd.org>2011-05-24 15:27:36 +0000
commit4e3da9ea5c5c5f4e31e57e65a6f97720cfa2a93f (patch)
treed9bb5c2f86c9031ede4e5ba19468f965cd1ce33e /sys/kern/exec_elf.c
parentMerge pf_scrub_ip() and pf_scrub_ip6() into a single function. Call (diff)
downloadwireguard-openbsd-4e3da9ea5c5c5f4e31e57e65a6f97720cfa2a93f.tar.xz
wireguard-openbsd-4e3da9ea5c5c5f4e31e57e65a6f97720cfa2a93f.zip
Reimplement uvm/uvm_map.
vmmap is designed to perform address space randomized allocations, without letting fragmentation of the address space go through the roof. Some highlights: - kernel address space randomization - proper implementation of guardpages - roughly 10% system time reduction during kernel build Tested by alot of people on tech@ and developers. Theo's machines are still happy.
Diffstat (limited to 'sys/kern/exec_elf.c')
-rw-r--r--sys/kern/exec_elf.c24
1 files changed, 13 insertions, 11 deletions
diff --git a/sys/kern/exec_elf.c b/sys/kern/exec_elf.c
index 980f49431ed..d4bdfd1ba7e 100644
--- a/sys/kern/exec_elf.c
+++ b/sys/kern/exec_elf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: exec_elf.c,v 1.81 2011/04/18 21:44:56 guenther Exp $ */
+/* $OpenBSD: exec_elf.c,v 1.82 2011/05/24 15:27:36 ariane Exp $ */
/*
* Copyright (c) 1996 Per Fogelstrom
@@ -333,6 +333,7 @@ ELFNAME(load_file)(struct proc *p, char *path, struct exec_package *epp,
int nload, idx = 0;
Elf_Addr pos = *last;
int file_align;
+ int loop;
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p);
if ((error = namei(&nd)) != 0) {
@@ -389,6 +390,7 @@ ELFNAME(load_file)(struct proc *p, char *path, struct exec_package *epp,
pos = ELF_ROUND(pos, file_align);
*last = epp->ep_interp_pos = pos;
+ loop = 0;
for (i = 0; i < nload;/**/) {
vaddr_t addr;
struct uvm_object *uobj;
@@ -416,17 +418,17 @@ ELFNAME(load_file)(struct proc *p, char *path, struct exec_package *epp,
addr = round_page((vaddr_t)p->p_vmspace->vm_daddr +
BRKSIZ);
- vm_map_lock(&p->p_vmspace->vm_map);
- if (uvm_map_findspace(&p->p_vmspace->vm_map, addr, size,
- &addr, uobj, uoff, 0, UVM_FLAG_FIXED) == NULL) {
- if (uvm_map_findspace(&p->p_vmspace->vm_map, addr, size,
- &addr, uobj, uoff, 0, 0) == NULL) {
- error = ENOMEM; /* XXX */
- vm_map_unlock(&p->p_vmspace->vm_map);
- goto bad1;
+ if (uvm_map_mquery(&p->p_vmspace->vm_map, &addr, size,
+ (i == 0 ? uoff : UVM_UNKNOWN_OFFSET), 0) != 0) {
+ if (loop == 0) {
+ loop = 1;
+ i = 0;
+ *last = epp->ep_interp_pos = pos = 0;
+ continue;
}
- }
- vm_map_unlock(&p->p_vmspace->vm_map);
+ error = ENOMEM;
+ goto bad1;
+ }
if (addr != pos + loadmap[i].vaddr) {
/* base changed. */
pos = addr - trunc_page(loadmap[i].vaddr);