Index: sys/machine/pc32/include/vmparam.h =================================================================== RCS file: /home/dcvs/src/sys/machine/pc32/include/vmparam.h,v retrieving revision 1.9 diff -u -r1.9 vmparam.h --- sys/machine/pc32/include/vmparam.h 28 Dec 2006 18:29:06 -0000 1.9 +++ sys/machine/pc32/include/vmparam.h 11 Jan 2007 17:37:58 -0000 @@ -50,6 +50,9 @@ #define VM_PROT_READ_IS_EXEC /* if you can read -- then you can exec */ +/* I386 has a line where all code is executable: 0 - I386_MAX_EXE_ADDR */ +#define I386_MAX_EXE_ADDR 0x20000000 /* exec line */ + /* * Virtual memory related constants, all in bytes */ Index: sys/sys/mman.h =================================================================== RCS file: /home/dcvs/src/sys/sys/mman.h,v retrieving revision 1.8 diff -u -r1.8 mman.h --- sys/sys/mman.h 27 Dec 2006 20:43:09 -0000 1.8 +++ sys/sys/mman.h 11 Jan 2007 17:37:58 -0000 @@ -76,6 +76,7 @@ #define MAP_HASSEMAPHORE 0x0200 /* region may contain semaphores */ #define MAP_STACK 0x0400 /* region grows down, like a stack */ #define MAP_NOSYNC 0x0800 /* page to but do not sync underlying file */ +#define MAP_TRYFIXED 0x1000 /* attempt hint address, even within heap */ #ifdef _P1003_1B_VISIBLE /* Index: sys/vm/vm_map.c =================================================================== RCS file: /home/dcvs/src/sys/vm/vm_map.c,v retrieving revision 1.55 diff -u -r1.55 vm_map.c --- sys/vm/vm_map.c 7 Jan 2007 08:37:37 -0000 1.55 +++ sys/vm/vm_map.c 13 Jan 2007 12:59:26 -0000 @@ -94,6 +94,8 @@ #include +#include + /* * Virtual memory maps provide for the mapping, protection, * and sharing of virtual memory objects. In addition, @@ -3419,6 +3421,32 @@ } /* + * vm_map_hint: return the beginning of the best area suitable for + * creating a new mapping with "prot" protection. + */ +vm_offset_t +vm_map_hint(struct proc *p, vm_prot_t prot) +{ + vm_offset_t addr; + +#ifdef __i386__ + /* + * If executable skip first two pages, otherwise start + * after data + heap region. + */ + if ((prot & VM_PROT_EXECUTE) && + ((vm_offset_t)p->p_vmspace->vm_daddr >= I386_MAX_EXE_ADDR)) { + addr = (PAGE_SIZE*2) + + (karc4random() & (I386_MAX_EXE_ADDR / 2 - 1)); + return (round_page(addr)); + } +#endif + addr = (vm_offset_t)p->p_vmspace->vm_daddr + MAXDSIZ; + addr += karc4random() & (MIN((256 * 1024 * 1024), MAXDSIZ) - 1); + + return (round_page(addr)); +} +/* * vm_map_lookup_done: * * Releases locks acquired by a vm_map_lookup Index: sys/vm/vm_map.h =================================================================== RCS file: /home/dcvs/src/sys/vm/vm_map.h,v retrieving revision 1.29 diff -u -r1.29 vm_map.h --- sys/vm/vm_map.h 11 Jan 2007 10:15:21 -0000 1.29 +++ sys/vm/vm_map.h 11 Jan 2007 17:37:58 -0000 @@ -438,6 +438,7 @@ vm_prot_t, vm_prot_t, int); int vm_map_findspace (vm_map_t, vm_offset_t, vm_size_t, vm_offset_t, vm_offset_t *); +vm_offset_t vm_map_hint(struct proc *, vm_prot_t); int vm_map_inherit (vm_map_t, vm_offset_t, vm_offset_t, vm_inherit_t); void vm_map_init (struct vm_map *, vm_offset_t, vm_offset_t, pmap_t); int vm_map_insert (vm_map_t, int *, vm_object_t, vm_ooffset_t, Index: sys/vm/vm_mmap.c =================================================================== RCS file: /home/dcvs/src/sys/vm/vm_mmap.c,v retrieving revision 1.37 diff -u -r1.37 vm_mmap.c --- sys/vm/vm_mmap.c 28 Dec 2006 18:29:08 -0000 1.37 +++ sys/vm/vm_mmap.c 13 Jan 2007 10:17:31 -0000 @@ -238,10 +238,17 @@ * There should really be a pmap call to determine a reasonable * location. */ - else if (addr == 0 || - (addr >= round_page((vm_offset_t)vms->vm_taddr) && - addr < round_page((vm_offset_t)vms->vm_daddr + maxdsiz))) - addr = round_page((vm_offset_t)vms->vm_daddr + maxdsiz); + else { + /* + * not fixed: make sure we skip over the largest possible heap. + * we will refine our guess later (e.g. to account for VAC, etc) + */ + if (addr == 0) + addr = vm_map_hint(p, prot); + else if (!(flags & MAP_TRYFIXED) && + addr < (vm_offset_t)p->p_vmspace->vm_daddr) + addr = vm_map_hint(p, prot); + } if (flags & MAP_ANON) { /*