Skip to content

Commit 03efeda

Browse files
committed
Backport MAP_JIT fixes from PCRE2 10.33
This is intended to fix the primary issue from bug #77260. Prior to macOS 10.14 multiple MAP_JIT segments were not permitted, leading to mmap failures and corresponding "no more memory" errors on macOS 10.13.
1 parent 409e9ea commit 03efeda

File tree

1 file changed

+43
-3
lines changed

1 file changed

+43
-3
lines changed

ext/pcre/pcre2lib/sljit/sljitExecAllocator.c

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,46 @@ static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
9494

9595
#else
9696

97+
#ifdef __APPLE__
98+
/* Configures TARGET_OS_OSX when appropriate */
99+
#include <TargetConditionals.h>
100+
101+
#if TARGET_OS_OSX && defined(MAP_JIT)
102+
#include <sys/utsname.h>
103+
#endif /* TARGET_OS_OSX && MAP_JIT */
104+
105+
#ifdef MAP_JIT
106+
107+
static SLJIT_INLINE int get_map_jit_flag()
108+
{
109+
#if TARGET_OS_OSX
110+
/* On macOS systems, returns MAP_JIT if it is defined _and_ we're running on a version
111+
of macOS where it's OK to have more than one JIT block. On non-macOS systems, returns
112+
MAP_JIT if it is defined. */
113+
static int map_jit_flag = -1;
114+
115+
/* The following code is thread safe because multiple initialization
116+
sets map_jit_flag to the same value and the code has no side-effects.
117+
Changing the kernel version witout system restart is (very) unlikely. */
118+
if (map_jit_flag == -1) {
119+
struct utsname name;
120+
121+
uname(&name);
122+
123+
/* Kernel version for 10.14.0 (Mojave) */
124+
map_jit_flag = (atoi(name.release) >= 18) ? MAP_JIT : 0;
125+
}
126+
127+
return map_jit_flag;
128+
#else /* !TARGET_OS_OSX */
129+
return MAP_JIT;
130+
#endif /* TARGET_OS_OSX */
131+
}
132+
133+
#endif /* MAP_JIT */
134+
135+
#endif /* __APPLE__ */
136+
97137
static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
98138
{
99139
void *retval;
@@ -103,17 +143,17 @@ static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
103143
int flags = MAP_PRIVATE | MAP_ANON;
104144

105145
#ifdef MAP_JIT
106-
flags |= MAP_JIT;
146+
flags |= get_map_jit_flag();
107147
#endif
108148

109149
retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, flags, -1, 0);
110-
#else
150+
#else /* !MAP_ANON */
111151
if (dev_zero < 0) {
112152
if (open_dev_zero())
113153
return NULL;
114154
}
115155
retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, dev_zero, 0);
116-
#endif
156+
#endif /* MAP_ANON */
117157

118158
return (retval != MAP_FAILED) ? retval : NULL;
119159
}

0 commit comments

Comments
 (0)