> I have successfully ported the relevant material from the NetBSD patches
>
>
> http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/compat/linux/common/linux_misc.c.diff?r1=1.140&r2=1.141
>
>
> http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/compat/linux/common/linux_mmap.h.diff?r1=1.16&r2=1.17
>
> http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/compat/linux/arch/i386/syscalls.master.diff?r1=1.61&r2=1.62
>
> to OpenBSD. The OpenBSD patch is given at the end of this message. Be
There have been requests that I resubmit the patch as a unified
diff, rather than a context diff. The patch is given below. Remember to
run the make file at /usr/src/sys/compat/linux/ after applying the patch.
--- /usr/src/sys/compat/linux/linux_misc.c.orig Wed Feb 14 18:07:51 2007
+++ /usr/src/sys/compat/linux/linux_misc.c Mon Jun 25 00:13:42 2007
@@ -718,6 +718,70 @@
}
+int
+linux_sys_mprotect(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct linux_sys_mprotect_args /* {
+ syscallarg(const void *) start;
+ syscallarg(unsigned long) len;
+ syscallarg(int) prot;
+ } */ *uap = v;
+ struct vm_map_entry *entry;
+ struct vm_map *map;
+ vaddr_t end, start, len, stacklim;
+ int prot, grows;
+
+ start = (vaddr_t)SCARG(uap, start);
+ len = round_page(SCARG(uap, len));
+ prot = SCARG(uap, prot);
+ grows = prot & (LINUX_PROT_GROWSDOWN | LINUX_PROT_GROWSUP);
+ prot &= ~grows;
+ end = start + len;
+
+ if (start & PAGE_MASK)
+ return EINVAL;
+ if (end < start)
+ return EINVAL;
+ if (end == start)
+ return 0;
+
+ if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
+ return EINVAL;
+ if (grows == (LINUX_PROT_GROWSDOWN | LINUX_PROT_GROWSUP))
+ return EINVAL;
+
+ map = &p->p_vmspace->vm_map;
+ vm_map_lock(map);
+ if (!uvm_map_lookup_entry(map, start, &entry) || entry->start > start) {
+ vm_map_unlock(map);
+ return ENOMEM;
+ }
+
+ /*
+ * Approximate the behaviour of PROT_GROWS{DOWN,UP}.
+ */
+
+ stacklim = (vaddr_t)p->p_limit->pl_rlimit[RLIMIT_STACK].rlim_cur;
+ if (grows & LINUX_PROT_GROWSDOWN) {
+ if (USRSTACK - stacklim <= start && start < USRSTACK) {
+ start = USRSTACK - stacklim;
+ } else {
+ start = entry->start;
+ }
+ } else if (grows & LINUX_PROT_GROWSUP) {
+ if (USRSTACK <= end && end < USRSTACK + stacklim) {
+ end = USRSTACK + stacklim;
+ } else {
+ end = entry->end;
+ }
+ }
+ vm_map_unlock(map);
+ return uvm_map_protect(map, start, end, prot, FALSE);
+}
+
/*
* This code is partly stolen from src/lib/libc/gen/times.c
* XXX - CLK_TCK isn't declared in /sys, just in <time.h>, done here
--- /usr/src/sys/compat/linux/linux_mmap.h.orig Wed Apr 17 05:23:56 1996
+++ /usr/src/sys/compat/linux/linux_mmap.h Mon Jun 25 00:13:42 2007
@@ -38,6 +38,8 @@
#define LINUX_PROT_READ 0x01
#define LINUX_PROT_WRITE 0x02
#define LINUX_PROT_EXEC 0x04
+#define LINUX_PROT_GROWSDOWN 0x01000000
+#define LINUX_PROT_GROWSUP 0x02000000
#define LINUX_MAP_SHARED 0x0001
#define LINUX_MAP_PRIVATE 0x0002
--- /usr/src/sys/compat/linux/syscalls.master.orig Wed Oct 27 13:23:38 2004
+++ /usr/src/sys/compat/linux/syscalls.master Mon Jun 25 00:13:42 2007
@@ -223,7 +223,8 @@
123 STD { int linux_sys_modify_ldt(void); }
#endif
124 STD { int linux_sys_adjtimex(void); }
-125 NOARGS { int sys_mprotect(caddr_t addr, int len, int prot); }
+125 STD { int linux_sys_mprotect(const void *start, \
+ unsigned long len, int prot); }
126 STD { int linux_sys_sigprocmask(int how, \
linux_old_sigset_t *set, linux_old_sigset_t *oset);
}
127 STD { int linux_sys_create_module(void); }