summaryrefslogtreecommitdiff
path: root/libraries/ghci/GHCi
diff options
context:
space:
mode:
authorMoritz Angermann <moritz.angermann@gmail.com>2021-02-13 16:44:19 +0800
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-03-29 17:25:49 -0400
commite754ff7f178a629a2261cba77a29d9510391aebd (patch)
tree77aca9f315288b52efbc9d410a57300a4029279d /libraries/ghci/GHCi
parent4421fb34b3a70db1323833337c94ac4364824124 (diff)
downloadhaskell-e754ff7f178a629a2261cba77a29d9510391aebd.tar.gz
Allocate Adjustors and mark them readable in two steps
This drops allocateExec for darwin, and replaces it with a alloc, write, mark executable strategy instead. This prevents us from trying to allocate an executable range and then write to it, which X^W will prohibit on darwin. This will *only* work if we can use mmap.
Diffstat (limited to 'libraries/ghci/GHCi')
-rw-r--r--libraries/ghci/GHCi/InfoTable.hsc18
1 files changed, 18 insertions, 0 deletions
diff --git a/libraries/ghci/GHCi/InfoTable.hsc b/libraries/ghci/GHCi/InfoTable.hsc
index 2fe35ee927..fce2c653f2 100644
--- a/libraries/ghci/GHCi/InfoTable.hsc
+++ b/libraries/ghci/GHCi/InfoTable.hsc
@@ -318,7 +318,11 @@ sizeOfEntryCode tables_next_to_code
-- Note: Must return proper pointer for use in a closure
newExecConItbl :: Bool -> StgInfoTable -> ByteString -> IO (FunPtr ())
newExecConItbl tables_next_to_code obj con_desc
+#if RTS_LINKER_USE_MMAP && MIN_VERSION_rts(1,0,1)
+ = do
+#else
= alloca $ \pcode -> do
+#endif
sz0 <- sizeOfEntryCode tables_next_to_code
let lcon_desc = BS.length con_desc + 1{- null terminator -}
-- SCARY
@@ -328,8 +332,13 @@ newExecConItbl tables_next_to_code obj con_desc
-- table, because on a 64-bit platform we reference this string
-- with a 32-bit offset relative to the info table, so if we
-- allocated the string separately it might be out of range.
+#if RTS_LINKER_USE_MMAP && MIN_VERSION_rts(1,0,1)
+ wr_ptr <- _allocateWrite (sz + fromIntegral lcon_desc)
+ let ex_ptr = wr_ptr
+#else
wr_ptr <- _allocateExec (sz + fromIntegral lcon_desc) pcode
ex_ptr <- peek pcode
+#endif
let cinfo = StgConInfoTable { conDesc = ex_ptr `plusPtr` fromIntegral sz
, infoTable = obj }
pokeConItbl tables_next_to_code wr_ptr ex_ptr cinfo
@@ -338,6 +347,9 @@ newExecConItbl tables_next_to_code obj con_desc
let null_off = fromIntegral sz + fromIntegral (BS.length con_desc)
poke (castPtr wr_ptr `plusPtr` null_off) (0 :: Word8)
_flushExec sz ex_ptr -- Cache flush (if needed)
+#if RTS_LINKER_USE_MMAP && MIN_VERSION_rts(1,0,1)
+ _markExec (sz + fromIntegral lcon_desc) ex_ptr
+#endif
pure $ if tables_next_to_code
then castPtrToFunPtr $ ex_ptr `plusPtr` conInfoTableSizeB
else castPtrToFunPtr ex_ptr
@@ -348,6 +360,12 @@ foreign import ccall unsafe "allocateExec"
foreign import ccall unsafe "flushExec"
_flushExec :: CUInt -> Ptr a -> IO ()
+#if RTS_LINKER_USE_MMAP && MIN_VERSION_rts(1,0,1)
+foreign import ccall unsafe "allocateWrite"
+ _allocateWrite :: CUInt -> IO (Ptr a)
+foreign import ccall unsafe "markExec"
+ _markExec :: CUInt -> Ptr a -> IO ()
+#endif
-- -----------------------------------------------------------------------------
-- Constants and config