Hi, The diff below works in my tests. It allows OpenBSD to use the PROT_GROWSUP and PROT_GROWSDOWN flags for mprotect under Linux emulation. Cherrypicked from http://marc.info/?l=openbsd-misc&m=118277676431920 with minor modifications.
Please comment/help, as I'd like to have it in so I can update print/acroread to the latest version... Ciao, David Index: linux_misc.c =================================================================== RCS file: /cvs/src/sys/compat/linux/linux_misc.c,v retrieving revision 1.76 diff -u -p -r1.76 linux_misc.c --- linux_misc.c 22 Apr 2012 05:43:14 -0000 1.76 +++ linux_misc.c 30 Apr 2012 08:43:50 -0000 @@ -1449,11 +1449,62 @@ linux_sys_sysinfo(p, v, retval) int linux_sys_mprotect(struct proc *p, void *v, register_t *retval) { - struct sys_mprotect_args *uap = v; + 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; - if (SCARG(uap, prot) & (PROT_WRITE | PROT_EXEC)) - SCARG(uap, prot) |= PROT_READ; - return (sys_mprotect(p, uap, retval)); + 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_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); } int Index: linux_mmap.h =================================================================== RCS file: /cvs/src/sys/compat/linux/linux_mmap.h,v retrieving revision 1.3 diff -u -p -r1.3 linux_mmap.h --- linux_mmap.h 5 Apr 2011 22:54:30 -0000 1.3 +++ linux_mmap.h 30 Apr 2012 08:43:50 -0000 @@ -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 Index: syscalls.master =================================================================== RCS file: /cvs/src/sys/compat/linux/syscalls.master,v retrieving revision 1.66 diff -u -p -r1.66 syscalls.master --- syscalls.master 14 Dec 2011 08:33:18 -0000 1.66 +++ syscalls.master 30 Apr 2012 08:43:51 -0000 @@ -222,7 +222,8 @@ 123 STD { int linux_sys_modify_ldt(void); } #endif 124 STD { int linux_sys_adjtimex(void); } -125 STD { int linux_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); } [demime 1.01d removed an attachment of type application/octet-stream]