summaryrefslogtreecommitdiff
path: root/sys/uvm/uvm_map.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/uvm/uvm_map.c')
-rw-r--r--sys/uvm/uvm_map.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/sys/uvm/uvm_map.c b/sys/uvm/uvm_map.c
index a13a7ce92a6..338ec1fc99e 100644
--- a/sys/uvm/uvm_map.c
+++ b/sys/uvm/uvm_map.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_map.c,v 1.100 2008/06/09 20:30:23 miod Exp $ */
+/* $OpenBSD: uvm_map.c,v 1.101 2008/07/18 16:40:17 kurt Exp $ */
/* $NetBSD: uvm_map.c,v 1.86 2000/11/27 08:40:03 chs Exp $ */
/*
@@ -1100,6 +1100,45 @@ uvm_map_spacefits(struct vm_map *map, vaddr_t *phint, vsize_t length,
}
/*
+ * uvm_map_pie: return a random load address for a PIE executable
+ * properly aligned.
+ */
+
+#ifndef VM_PIE_MAX_ADDR
+#define VM_PIE_MAX_ADDR (VM_MAXUSER_ADDRESS / 4)
+#endif
+
+#ifndef VM_PIE_MIN_ADDR
+#define VM_PIE_MIN_ADDR VM_MIN_ADDRESS
+#endif
+
+#ifndef VM_PIE_MIN_ALIGN
+#define VM_PIE_MIN_ALIGN PAGE_SIZE
+#endif
+
+vaddr_t
+uvm_map_pie(vaddr_t align)
+{
+ vaddr_t addr, space, min;
+
+ align = MAX(align, VM_PIE_MIN_ALIGN);
+
+ /* round up to next alignment */
+ min = (VM_PIE_MIN_ADDR + align - 1) & ~(align - 1);
+
+ if (align >= VM_PIE_MAX_ADDR || min >= VM_PIE_MAX_ADDR)
+ return (align);
+
+ space = (VM_PIE_MAX_ADDR - min) / align;
+ space = MIN(space, (u_int32_t)-1);
+
+ addr = (vaddr_t)arc4random_uniform((u_int32_t)space) * align;
+ addr += min;
+
+ return (addr);
+}
+
+/*
* uvm_map_hint: return the beginning of the best area suitable for
* creating a new mapping with "prot" protection.
*/