123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- $OpenBSD: patch-rpython_rlib_rmmap_py,v 1.1 2016/08/15 09:16:40 edd Exp $
- Make the CPython bootstrap W^X compatible.
- --- rpython/rlib/rmmap.py.orig Tue Jun 14 08:46:04 2016
- +++ rpython/rlib/rmmap.py Thu Aug 11 08:49:22 2016
- @@ -155,6 +155,9 @@ if _POSIX:
- c_mremap, _ = external('mremap',
- [PTR, size_t, size_t, rffi.ULONG], PTR)
-
- + c_mprotect, _ = external('mprotect',
- + [PTR, size_t, rffi.INT], rffi.INT)
- +
- # this one is always safe
- _pagesize = rffi_platform.getintegerfunctionresult('getpagesize',
- includes=includes)
- @@ -694,11 +697,29 @@ if _POSIX:
- def alloc_hinted(hintp, map_size):
- flags = MAP_PRIVATE | MAP_ANONYMOUS
- prot = PROT_EXEC | PROT_READ | PROT_WRITE
- +
- if we_are_translated():
- flags = NonConstant(flags)
- prot = NonConstant(prot)
- return c_mmap_safe(hintp, map_size, prot, flags, -1, 0)
-
- + def alloc_hinted_noexec(hintp, map_size):
- + """Same as alloc_hinted, but allocates pages non-executable.
- + Duplicated because of constancy constraints on prot."""
- +
- + flags = MAP_PRIVATE | MAP_ANONYMOUS
- + prot = PROT_READ | PROT_WRITE
- +
- + if we_are_translated():
- + flags = NonConstant(flags)
- + prot = NonConstant(prot)
- + return c_mmap_safe(hintp, map_size, prot, flags, -1, 0)
- +
- + def set_pages_executable(addr, size):
- + rv = c_mprotect(addr, size, PROT_EXEC)
- + if rv < 0:
- + debug.fatalerror_notb("set_pages_executable failed")
- +
- def clear_large_memory_chunk_aligned(addr, map_size):
- addr = rffi.cast(PTR, addr)
- flags = MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS
- @@ -714,10 +735,10 @@ if _POSIX:
- pos = -0x4fff0000 # for reproducible results
- hint = Hint()
-
- - def alloc(map_size):
- + def alloc(map_size, no_exec=False):
- """Allocate memory. This is intended to be used by the JIT,
- - so the memory has the executable bit set and gets allocated
- - internally in case of a sandboxed process.
- + so the memory has the executable bit set (unless no_exec=True)
- + and gets allocated internally in case of a sandboxed process.
- """
- from errno import ENOMEM
- from rpython.rlib import debug
- @@ -730,11 +751,17 @@ if _POSIX:
- if res == rffi.cast(PTR, 0):
- raise MemoryError
- return res
- - res = alloc_hinted(rffi.cast(PTR, hint.pos), map_size)
- + if no_exec:
- + res = alloc_hinted_noexec(rffi.cast(PTR, hint.pos), map_size)
- + else:
- + res = alloc_hinted(rffi.cast(PTR, hint.pos), map_size)
- if res == rffi.cast(PTR, -1):
- # some systems (some versions of OS/X?) complain if they
- # are passed a non-zero address. Try again.
- - res = alloc_hinted(rffi.cast(PTR, 0), map_size)
- + if no_exec:
- + res = alloc_hinted_noexec(rffi.cast(PTR, 0), map_size)
- + else:
- + res = alloc_hinted(rffi.cast(PTR, 0), map_size)
- if res == rffi.cast(PTR, -1):
- # ENOMEM simply raises MemoryError, but other errors are fatal
- if rposix.get_saved_errno() != ENOMEM:
- @@ -748,7 +775,7 @@ if _POSIX:
- else:
- hint.pos += map_size
- return res
- - alloc._annenforceargs_ = (int,)
- + alloc._annenforceargs_ = (int, bool)
-
- if _CYGWIN:
- free = c_free_safe
- @@ -886,11 +913,13 @@ elif _MS_WINDOWS:
- hint = Hint()
- # XXX this has no effect on windows
-
- - def alloc(map_size):
- + def alloc(map_size, no_exec=False):
- """Allocate memory. This is intended to be used by the JIT,
- so the memory has the executable bit set.
- XXX implement me: it should get allocated internally in
- case of a sandboxed process
- +
- + XXX no_exec ignored on windows.
- """
- null = lltype.nullptr(rffi.VOIDP.TO)
- res = VirtualAlloc_safe(null, map_size, MEM_COMMIT | MEM_RESERVE,
- @@ -902,7 +931,7 @@ elif _MS_WINDOWS:
- lltype.free(arg, flavor='raw')
- # ignore errors, just try
- return res
- - alloc._annenforceargs_ = (int,)
- + alloc._annenforceargs_ = (int, bool)
-
- def free(ptr, map_size):
- VirtualFree_safe(ptr, 0, MEM_RELEASE)
|