I have made a final patch (as of now) and linked it from:
http://www.tux.org/~mayer/cygwin/pypy/index.html

See the bottom third of the page, the patch against the trunk of the mercurial 
repository is
http://www.tux.org/~mayer/cygwin/pypy/pypy-pypy-ac392fb76904.patch

With this pypy builds under Cygwin, and os.fork() works.
It would be good if this could get merged into the trunk.
--Uwe


----- Original Message -----
From: Uwe F. Mayer <uwe_f_ma...@yahoo.com>
To: Armin Rigo <ar...@tunes.org>; Amaury Forgeot d'Arc <amaur...@gmail.com>
Cc: Matti Picus <matti.pi...@gmail.com>; "pypy-dev@python.org" 
<pypy-dev@python.org>
Sent: Monday, June 11, 2012 10:27 AM
Subject: Re: [pypy-dev] Patches for Pypy under cygwin

> ----- Original Message -----
> From: Armin Rigo <ar...@tunes.org>
> Sent: Monday, June 11, 2012 4:59 AM
> >>On Sun, Jun 10, 2012 at 11:12 AM, Amaury Forgeot d'Arc <amaur...@gmail.com> 
> >>wrote:
> >> I think memory allocated for JIT must be marked with PROT_EXEC (it contains
> >> machine code), so malloc() is not an option.
> Exactly.  On Linux it would work, because you can use mprotect() to
> make even malloc()ed memory executable, but I doubt this non-Posix
> extension works on cygwin.  What might work instead would be using the
> Windows API instead of the POSIX one.  In pypy/rlib/rmmap.py, look for
> "def alloc" and "def free": there are the two versions.


Cygwin implements the POSIX API on top of the Windows API, and some things are 
tricky to implement, and memory handling and permissions tend to be part of 
those. To see if it may just work, I modified rmmap.pyto use malloc() and 
free(), and indeed pypy seems to work just fine. Following up on this email I 
also added an mprotect() call, which does exist under Cygwin. However, POSIX 
says that the behavior of mprotect() is unspecified if it is applied to a 
region of memory that was not obtained via mmap(2), and indeed this fails.

Here's the patch that works, using malloc() and free(), and not using 
mprotect().

*** pypy/pypy/rlib/rmmap.pyMon Jun 11 10:18:55 2012
--- pypy/pypy/rlib/rmmap.pyMon Jun 11 10:16:12 2012
***************
*** 14,19 ****
--- 14,20 ----
  _MS_WINDOWS = os.name == "nt"
  _LINUX = "linux" in sys.platform
  _64BIT = "64bit" in platform.architecture()[0]
+ _CYGWIN = "cygwin" == sys.platform
  
  class RValueError(Exception):
      def __init__(self, message):
***************
*** 115,120 ****
--- 116,126 ----
  
  PTR = rffi.CCHARP
  
+ if _CYGWIN:
+     c_malloc, _ = external('malloc', [size_t], PTR)
+     #c_mprotect, _ = external('mprotect', [PTR, size_t, rffi.INT], rffi.INT)
+     c_free, _ = external('free', [PTR], lltype.Void)
+ 
  c_memmove, _ = external('memmove', [PTR, PTR, size_t], lltype.Void)
  
  if _POSIX:
***************
*** 692,714 ****
          so the memory has the executable bit set and gets allocated
          internally in case of a sandboxed process.
          """
!         flags = MAP_PRIVATE | MAP_ANONYMOUS
!         prot = PROT_EXEC | PROT_READ | PROT_WRITE
!         hintp = rffi.cast(PTR, hint.pos)
!         res = c_mmap_safe(hintp, map_size, prot, flags, -1, 0)
!         if res == rffi.cast(PTR, -1):
!             # some systems (some versions of OS/X?) complain if they
!             # are passed a non-zero address.  Try again.
!             hintp = rffi.cast(PTR, 0)
!             res = c_mmap_safe(hintp, map_size, prot, flags, -1, 0)
!             if res == rffi.cast(PTR, -1):
                  raise MemoryError
          else:
!             hint.pos += map_size
          return res
      alloc._annenforceargs_ = (int,)
  
!     free = c_munmap_safe
  
  elif _MS_WINDOWS:
      def mmap(fileno, length, tagname="", access=_ACCESS_DEFAULT, offset=0):
--- 698,739 ----
          so the memory has the executable bit set and gets allocated
          internally in case of a sandboxed process.
          """
!         if _CYGWIN:
!             # XXX: JIT memory should be using mmap MAP_PRIVATE with
!             #      PROT_EXEC but Cygwin's fork() fails
!             res = c_malloc(map_size)
!             if res == rffi.cast(PTR, 0):
                  raise MemoryError
+             # XXX POSIX says that the behavior of mprotect() is unspecified
+             # if it is applied to a region of memory that was not obtained
+             # via mmap(2), and indeed it does not work here.
+             # prot = PROT_EXEC | PROT_READ | PROT_WRITE
+             # res2 = c_mprotect(res, map_size, prot)
+             # if res2 == -1:
+             #     errno = rposix.get_errno()
+             #     raise OSError(errno, os.strerror(errno))
          else:
!             flags = MAP_PRIVATE | MAP_ANONYMOUS
!             prot = PROT_EXEC | PROT_READ | PROT_WRITE
!             hintp = rffi.cast(PTR, hint.pos)
!             res = c_mmap_safe(hintp, map_size, prot, flags, -1, 0)
!             if res == rffi.cast(PTR, -1):
!                 # some systems (some versions of OS/X?) complain if they
!                 # are passed a non-zero address.  Try again.
!                 hintp = rffi.cast(PTR, 0)
!                 res = c_mmap_safe(hintp, map_size, prot, flags, -1, 0)
!                 if res == rffi.cast(PTR, -1):
!                     raise MemoryError
!             else:
!                 hint.pos += map_size
          return res
+ 
      alloc._annenforceargs_ = (int,)
  
!     if _CYGWIN:
!         free = c_free
!     else:
!         free = c_munmap_safe
  
  elif _MS_WINDOWS:
      def mmap(fileno, length, tagname="", access=_ACCESS_DEFAULT, offset=0):

_______________________________________________
pypy-dev mailing list
pypy-dev@python.org
http://mail.python.org/mailman/listinfo/pypy-dev

Reply via email to