lang/pypy: Fix build for W^X and update to 5.3.1.

Note that the W^X patch only makes the CPython-based no_bootstrap build work,
and that the PyPy JIT itself is still not W^X compliant. This will require more
work.

OK jca@, thanks.
This commit is contained in:
edd 2016-08-15 09:16:40 +00:00
parent e8da246299
commit dc750b461a
6 changed files with 151 additions and 37 deletions

View File

@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.24 2016/06/13 08:44:17 edd Exp $
# $OpenBSD: Makefile,v 1.25 2016/08/15 09:16:40 edd Exp $
ONLY_FOR_ARCHS = amd64
@ -18,7 +18,7 @@ COMMENT = fast implementation of the Python language
# You can use the no_bootstrap FLAVOR to make a new bootstrap. This uses
# CPython to build PyPy instead. Note this is slower.
V = 5.3.0
V = 5.3.1
BOOTSTRAP_V = ${V}
DISTNAME = pypy2-v${V}-src
PKGNAME = pypy-${V}
@ -95,7 +95,8 @@ do-build:
pypy --jit loop_longevity=300 \
../../rpython/bin/rpython --source --opt=jit
.endif
cd ${WRKDIR}/usession/testing_1 && ${SETENV} ${MAKE_ENV} ${MAKE_PROGRAM}
cd ${WRKDIR}/usession/testing_1 && ${SETENV} ${MAKE_ENV} \
${MAKE_PROGRAM} LDFLAGS_LINK="-Wl,-z,wxneeded -pthread"
PYPY_INST_LIB_DIR = ${PREFIX}/pypy/lib
PYPY_LD_LIBRARY_PATH = LD_LIBRARY_PATH=${PYPY_INST_LIB_DIR}

View File

@ -1,4 +1,4 @@
SHA256 (pypy/pypy-bootstrap-amd64-5.3.0.tar.xz) = edy2uGOHyc3D9NndGeSZ86szEvpiJmFSQdAC/wtLBpg=
SHA256 (pypy/pypy2-v5.3.0-src.tar.bz2) = QULrj0A4ELyIpJEXkrtaUC4VLflYBuM+aQUMgozRYNU=
SIZE (pypy/pypy-bootstrap-amd64-5.3.0.tar.xz) = 21976516
SIZE (pypy/pypy2-v5.3.0-src.tar.bz2) = 17361429
SHA256 (pypy/pypy-bootstrap-amd64-5.3.1.tar.xz) = J8lRGufV48uBbJu302zRSAf3RdXxjEokruugShyOJ0U=
SHA256 (pypy/pypy2-v5.3.1-src.tar.bz2) = MaUrq1hKvzoPDe/Rv5opEx2rCN9DiF5+7d/H3Jtxg24=
SIZE (pypy/pypy-bootstrap-amd64-5.3.1.tar.xz) = 22269372
SIZE (pypy/pypy2-v5.3.1-src.tar.bz2) = 17361760

View File

@ -0,0 +1,30 @@
$OpenBSD: patch-rpython_jit_backend_x86_detect_feature_py,v 1.1 2016/08/15 09:16:40 edd Exp $
Make the CPython bootstrap W^X compatible.
--- rpython/jit/backend/x86/detect_feature.py.orig Tue Jun 14 08:46:04 2016
+++ rpython/jit/backend/x86/detect_feature.py Thu Aug 11 08:49:22 2016
@@ -1,17 +1,20 @@
import sys
import struct
from rpython.rtyper.lltypesystem import lltype, rffi
-from rpython.rlib.rmmap import alloc, free
+from rpython.rlib.rmmap import alloc, free, set_pages_executable
+CPU_INFO_SZ = 4096
+
def cpu_info(instr):
- data = alloc(4096)
+ data = alloc(CPU_INFO_SZ, no_exec=True)
pos = 0
for c in instr:
data[pos] = c
pos += 1
fnptr = rffi.cast(lltype.Ptr(lltype.FuncType([], lltype.Signed)), data)
+ set_pages_executable(data, CPU_INFO_SZ)
code = fnptr()
- free(data, 4096)
+ free(data, CPU_INFO_SZ)
return code
def detect_sse2():

View File

@ -0,0 +1,113 @@
$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)

View File

@ -1,18 +0,0 @@
$OpenBSD: patch-rpython_rlib_rvmprof_src_vmprof_config_h,v 1.2 2016/06/13 08:44:17 edd Exp $
--- rpython/rlib/rvmprof/src/vmprof_config.h.orig Sun Jun 5 16:45:04 2016
+++ rpython/rlib/rvmprof/src/vmprof_config.h Sun Jun 5 16:47:15 2016
@@ -1,10 +1,14 @@
+#if !defined(__OpenBSD__)
#define HAVE_SYS_UCONTEXT_H
+#endif
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#ifdef __i386__
#define PC_FROM_UCONTEXT uc_mcontext.mc_eip
#else
#define PC_FROM_UCONTEXT uc_mcontext.mc_rip
#endif
+#elif defined(__OpenBSD__)
+#define PC_FROM_UCONTEXT sc_rip
#elif defined( __APPLE__)
#if ((ULONG_MAX) == (UINT_MAX))
#define PC_FROM_UCONTEXT uc_mcontext->__ss.__eip

View File

@ -1,12 +0,0 @@
$OpenBSD: patch-rpython_rlib_rvmprof_src_vmprof_getpc_h,v 1.2 2016/06/13 08:44:17 edd Exp $
--- rpython/rlib/rvmprof/src/vmprof_getpc.h.orig Sun Apr 24 05:08:33 2016
+++ rpython/rlib/rvmprof/src/vmprof_getpc.h Sun Jun 5 16:43:26 2016
@@ -65,6 +65,8 @@
#elif defined(HAVE_CYGWIN_SIGNAL_H)
#include <cygwin/signal.h>
typedef ucontext ucontext_t;
+#elif defined(__OpenBSD__)
+#include <signal.h>
#endif