add `configure' test for mmap() and mprotect()
Use the test to enable execute permission on memory that is allocated for code, including FFI callbacks.
This commit is contained in:
parent
a948f1b40d
commit
ba973a317f
74
src/configure
vendored
74
src/configure
vendored
|
@ -3938,6 +3938,13 @@ if test "${enable_shared}" = "yes" ; then
|
|||
LIBRACKET_DEP="${LIBRACKET_DEP} libmzgc.la"
|
||||
fi
|
||||
|
||||
if test "${enable_foreign}" = "yes" ; then
|
||||
check_for_mprotect=yes
|
||||
fi
|
||||
if test "${enable_jit}" = "yes" ; then
|
||||
check_for_mprotect=yes
|
||||
fi
|
||||
|
||||
############## platform tests ################
|
||||
|
||||
# for flags we don't want to use in config tests:
|
||||
|
@ -4047,6 +4054,7 @@ case "$host_os" in
|
|||
EXE_SUFFIX=".exe"
|
||||
COLLECTS_PATH="collects"
|
||||
skip_iconv_check=yes
|
||||
check_for_mprotect=no
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_STDINT_H 1
|
||||
|
@ -5531,6 +5539,72 @@ echo "${ECHO_T}$have_libffi" >&6; }
|
|||
fi
|
||||
fi
|
||||
|
||||
if test "${check_for_mprotect}" = "yes" ; then
|
||||
msg="for mmap and mprotect"
|
||||
{ echo "$as_me:$LINENO: checking $msg" >&5
|
||||
echo $ECHO_N "checking $msg... $ECHO_C" >&6; }
|
||||
if test "$cross_compiling" = yes; then
|
||||
use_mprotect=no
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
int main() {
|
||||
void *p;
|
||||
p = mmap(0, 2 << 16, PROT_READ | PROT_WRITE, MAP_PRIVATE, open("/dev/zero", O_RDWR), 0);
|
||||
mprotect(p, 2 << 16, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest$ac_exeext
|
||||
if { (ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_link") 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && { ac_try='./conftest$ac_exeext'
|
||||
{ (case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_try") 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
use_mprotect=yes
|
||||
else
|
||||
echo "$as_me: program exited with status $ac_status" >&5
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
( exit $ac_status )
|
||||
use_mprotect=no
|
||||
fi
|
||||
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
|
||||
|
||||
{ echo "$as_me:$LINENO: result: $use_mprotect" >&5
|
||||
echo "${ECHO_T}$use_mprotect" >&6; }
|
||||
if test "${use_mprotect}" = "yes" ; then
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_MMAP_MPROTECT 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "${enable_backtrace}" = "yes" ; then
|
||||
GC2OPTIONS="$GC2OPTIONS -DMZ_GC_BACKTRACE"
|
||||
fi
|
||||
|
|
|
@ -469,6 +469,13 @@ if test "${enable_shared}" = "yes" ; then
|
|||
LIBRACKET_DEP="${LIBRACKET_DEP} libmzgc.la"
|
||||
fi
|
||||
|
||||
if test "${enable_foreign}" = "yes" ; then
|
||||
check_for_mprotect=yes
|
||||
fi
|
||||
if test "${enable_jit}" = "yes" ; then
|
||||
check_for_mprotect=yes
|
||||
fi
|
||||
|
||||
############## platform tests ################
|
||||
|
||||
# for flags we don't want to use in config tests:
|
||||
|
@ -578,6 +585,7 @@ case "$host_os" in
|
|||
EXE_SUFFIX=".exe"
|
||||
COLLECTS_PATH="collects"
|
||||
skip_iconv_check=yes
|
||||
check_for_mprotect=no
|
||||
AC_DEFINE(HAVE_STDINT_H,1,[Have stdint.h])
|
||||
if `which ${host}-windres > /dev/null` ; then
|
||||
WINDRES="${host}-windres"
|
||||
|
@ -976,6 +984,24 @@ if test "${enable_libffi}" = "yes" ; then
|
|||
fi
|
||||
fi
|
||||
|
||||
if test "${check_for_mprotect}" = "yes" ; then
|
||||
[ msg="for mmap and mprotect" ]
|
||||
AC_MSG_CHECKING($msg)
|
||||
AC_TRY_RUN(
|
||||
[ #include <sys/mman.h> ]
|
||||
[ #include <fcntl.h> ]
|
||||
int main() {
|
||||
void *p;
|
||||
p = mmap(0, 2 << 16, PROT_READ | PROT_WRITE, MAP_PRIVATE, open("/dev/zero", O_RDWR), 0);
|
||||
mprotect(p, 2 << 16, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
return 0;
|
||||
}, use_mprotect=yes, use_mprotect=no, use_mprotect=no)
|
||||
AC_MSG_RESULT($use_mprotect)
|
||||
if test "${use_mprotect}" = "yes" ; then
|
||||
AC_DEFINE(HAVE_MMAP_MPROTECT,1,[Have mmap and mprotect])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "${enable_backtrace}" = "yes" ; then
|
||||
GC2OPTIONS="$GC2OPTIONS -DMZ_GC_BACKTRACE"
|
||||
fi
|
||||
|
|
|
@ -61,6 +61,9 @@ typedef unsigned long uintptr_t;
|
|||
#undef HAVE_EPOLL_SYSCALL
|
||||
#undef HAVE_KQUEUE_SYSCALL
|
||||
|
||||
/* When mmap() and mprotect() are available: */
|
||||
#undef HAVE_MMAP_MPROTECT
|
||||
|
||||
/* Enable futures: */
|
||||
#undef MZ_USE_FUTURES
|
||||
|
||||
|
|
|
@ -39,7 +39,11 @@
|
|||
# define MALLOC malloc
|
||||
#endif
|
||||
|
||||
#ifdef MZ_JIT_USE_MPROTECT
|
||||
#if defined(MZ_JIT_USE_MPROTECT) || defined(HAVE_MMAP_MPROTECT)
|
||||
# define MZ_CODE_ALLOC_USE_MPROTECT
|
||||
#endif
|
||||
|
||||
#ifdef MZ_CODE_ALLOC_USE_MPROTECT
|
||||
# include <unistd.h>
|
||||
# include <sys/mman.h>
|
||||
# ifndef MAP_ANON
|
||||
|
@ -851,14 +855,14 @@ THREAD_LOCAL_DECL(static void *code_allocation_page_list);
|
|||
|
||||
THREAD_LOCAL_DECL(intptr_t scheme_code_page_total);
|
||||
|
||||
#if defined(MZ_JIT_USE_MPROTECT) && !defined(MAP_ANON)
|
||||
#if defined(MZ_CODE_ALLOC_USE_MPROTECT) && !defined(MAP_ANON)
|
||||
static int fd, fd_created;
|
||||
#endif
|
||||
|
||||
#define LOG_CODE_MALLOC(lvl, s) /* if (lvl > 1) s */
|
||||
#define CODE_PAGE_OF(p) ((void *)(((uintptr_t)p) & ~(page_size - 1)))
|
||||
|
||||
#if defined(MZ_JIT_USE_MPROTECT) || defined(MZ_JIT_USE_WINDOWS_VIRTUAL_ALLOC)
|
||||
#if defined(MZ_CODE_ALLOC_USE_MPROTECT) || defined(MZ_JIT_USE_WINDOWS_VIRTUAL_ALLOC)
|
||||
|
||||
struct free_list_entry {
|
||||
intptr_t size; /* size of elements in this bucket */
|
||||
|
@ -1030,7 +1034,7 @@ static intptr_t free_list_find_bucket(intptr_t size)
|
|||
|
||||
void *scheme_malloc_code(intptr_t size)
|
||||
{
|
||||
#if defined(MZ_JIT_USE_MPROTECT) || defined(MZ_JIT_USE_WINDOWS_VIRTUAL_ALLOC)
|
||||
#if defined(MZ_CODE_ALLOC_USE_MPROTECT) || defined(MZ_JIT_USE_WINDOWS_VIRTUAL_ALLOC)
|
||||
|
||||
intptr_t size2, bucket, sz, page_size;
|
||||
void *p, *pg, *prev;
|
||||
|
@ -1109,7 +1113,7 @@ void *scheme_malloc_permanent_code(intptr_t size)
|
|||
/* allocate code that will never be freed and that can be used
|
||||
in multiple places */
|
||||
{
|
||||
#if defined(MZ_USE_PLACES) && (defined(MZ_JIT_USE_MPROTECT) || defined(MZ_JIT_USE_WINDOWS_VIRTUAL_ALLOC))
|
||||
#if defined(MZ_USE_PLACES) && (defined(MZ_CODE_ALLOC_USE_MPROTECT) || defined(MZ_JIT_USE_WINDOWS_VIRTUAL_ALLOC))
|
||||
void *p;
|
||||
intptr_t page_size;
|
||||
|
||||
|
@ -1148,7 +1152,7 @@ void *scheme_malloc_permanent_code(intptr_t size)
|
|||
|
||||
void scheme_free_code(void *p)
|
||||
{
|
||||
#if defined(MZ_JIT_USE_MPROTECT) || defined(MZ_JIT_USE_WINDOWS_VIRTUAL_ALLOC)
|
||||
#if defined(MZ_CODE_ALLOC_USE_MPROTECT) || defined(MZ_JIT_USE_WINDOWS_VIRTUAL_ALLOC)
|
||||
intptr_t size, size2, bucket, page_size;
|
||||
int per_page, n;
|
||||
void *prev;
|
||||
|
@ -1234,7 +1238,7 @@ void scheme_free_code(void *p)
|
|||
|
||||
void scheme_free_all_code(void)
|
||||
{
|
||||
#if defined(MZ_JIT_USE_MPROTECT) || defined(MZ_JIT_USE_WINDOWS_VIRTUAL_ALLOC)
|
||||
#if defined(MZ_CODE_ALLOC_USE_MPROTECT) || defined(MZ_JIT_USE_WINDOWS_VIRTUAL_ALLOC)
|
||||
void *p, *next;
|
||||
intptr_t page_size;
|
||||
|
||||
|
@ -1260,7 +1264,7 @@ void scheme_free_all_code(void)
|
|||
currently takes advantage of that combination, so we support it
|
||||
with scheme_malloc_gcable_code() --- but only in CGC mode. */
|
||||
|
||||
#if defined(MZ_JIT_USE_MPROTECT) || defined(MZ_JIT_USE_WINDOWS_VIRTUAL_ALLOC)
|
||||
#if defined(MZ_CODE_ALLOC_USE_MPROTECT) || defined(MZ_JIT_USE_WINDOWS_VIRTUAL_ALLOC)
|
||||
static uintptr_t jit_prev_page = 0, jit_prev_length = 0;
|
||||
#endif
|
||||
|
||||
|
@ -1269,7 +1273,7 @@ void *scheme_malloc_gcable_code(intptr_t size)
|
|||
void *p;
|
||||
p = scheme_malloc(size);
|
||||
|
||||
#if defined(MZ_JIT_USE_MPROTECT) || defined(MZ_JIT_USE_WINDOWS_VIRTUAL_ALLOC)
|
||||
#if defined(MZ_CODE_ALLOC_USE_MPROTECT) || defined(MZ_JIT_USE_WINDOWS_VIRTUAL_ALLOC)
|
||||
{
|
||||
/* [This chunk of code moved from our copy of GNU lightning to here.] */
|
||||
uintptr_t page, length, page_size;
|
||||
|
@ -1324,7 +1328,7 @@ void *scheme_malloc_gcable_code(intptr_t size)
|
|||
|
||||
void scheme_notify_code_gc()
|
||||
{
|
||||
#if defined(MZ_JIT_USE_MPROTECT) || defined(MZ_JIT_USE_WINDOWS_VIRTUAL_ALLOC)
|
||||
#if defined(MZ_CODE_ALLOC_USE_MPROTECT) || defined(MZ_JIT_USE_WINDOWS_VIRTUAL_ALLOC)
|
||||
jit_prev_page = 0;
|
||||
jit_prev_length = 0;
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue
Block a user