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"
|
LIBRACKET_DEP="${LIBRACKET_DEP} libmzgc.la"
|
||||||
fi
|
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 ################
|
############## platform tests ################
|
||||||
|
|
||||||
# for flags we don't want to use in config tests:
|
# for flags we don't want to use in config tests:
|
||||||
|
@ -4047,6 +4054,7 @@ case "$host_os" in
|
||||||
EXE_SUFFIX=".exe"
|
EXE_SUFFIX=".exe"
|
||||||
COLLECTS_PATH="collects"
|
COLLECTS_PATH="collects"
|
||||||
skip_iconv_check=yes
|
skip_iconv_check=yes
|
||||||
|
check_for_mprotect=no
|
||||||
|
|
||||||
cat >>confdefs.h <<\_ACEOF
|
cat >>confdefs.h <<\_ACEOF
|
||||||
#define HAVE_STDINT_H 1
|
#define HAVE_STDINT_H 1
|
||||||
|
@ -5531,6 +5539,72 @@ echo "${ECHO_T}$have_libffi" >&6; }
|
||||||
fi
|
fi
|
||||||
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
|
if test "${enable_backtrace}" = "yes" ; then
|
||||||
GC2OPTIONS="$GC2OPTIONS -DMZ_GC_BACKTRACE"
|
GC2OPTIONS="$GC2OPTIONS -DMZ_GC_BACKTRACE"
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -469,6 +469,13 @@ if test "${enable_shared}" = "yes" ; then
|
||||||
LIBRACKET_DEP="${LIBRACKET_DEP} libmzgc.la"
|
LIBRACKET_DEP="${LIBRACKET_DEP} libmzgc.la"
|
||||||
fi
|
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 ################
|
############## platform tests ################
|
||||||
|
|
||||||
# for flags we don't want to use in config tests:
|
# for flags we don't want to use in config tests:
|
||||||
|
@ -578,6 +585,7 @@ case "$host_os" in
|
||||||
EXE_SUFFIX=".exe"
|
EXE_SUFFIX=".exe"
|
||||||
COLLECTS_PATH="collects"
|
COLLECTS_PATH="collects"
|
||||||
skip_iconv_check=yes
|
skip_iconv_check=yes
|
||||||
|
check_for_mprotect=no
|
||||||
AC_DEFINE(HAVE_STDINT_H,1,[Have stdint.h])
|
AC_DEFINE(HAVE_STDINT_H,1,[Have stdint.h])
|
||||||
if `which ${host}-windres > /dev/null` ; then
|
if `which ${host}-windres > /dev/null` ; then
|
||||||
WINDRES="${host}-windres"
|
WINDRES="${host}-windres"
|
||||||
|
@ -976,6 +984,24 @@ if test "${enable_libffi}" = "yes" ; then
|
||||||
fi
|
fi
|
||||||
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
|
if test "${enable_backtrace}" = "yes" ; then
|
||||||
GC2OPTIONS="$GC2OPTIONS -DMZ_GC_BACKTRACE"
|
GC2OPTIONS="$GC2OPTIONS -DMZ_GC_BACKTRACE"
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -61,6 +61,9 @@ typedef unsigned long uintptr_t;
|
||||||
#undef HAVE_EPOLL_SYSCALL
|
#undef HAVE_EPOLL_SYSCALL
|
||||||
#undef HAVE_KQUEUE_SYSCALL
|
#undef HAVE_KQUEUE_SYSCALL
|
||||||
|
|
||||||
|
/* When mmap() and mprotect() are available: */
|
||||||
|
#undef HAVE_MMAP_MPROTECT
|
||||||
|
|
||||||
/* Enable futures: */
|
/* Enable futures: */
|
||||||
#undef MZ_USE_FUTURES
|
#undef MZ_USE_FUTURES
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,11 @@
|
||||||
# define MALLOC malloc
|
# define MALLOC malloc
|
||||||
#endif
|
#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 <unistd.h>
|
||||||
# include <sys/mman.h>
|
# include <sys/mman.h>
|
||||||
# ifndef MAP_ANON
|
# 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);
|
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;
|
static int fd, fd_created;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LOG_CODE_MALLOC(lvl, s) /* if (lvl > 1) s */
|
#define LOG_CODE_MALLOC(lvl, s) /* if (lvl > 1) s */
|
||||||
#define CODE_PAGE_OF(p) ((void *)(((uintptr_t)p) & ~(page_size - 1)))
|
#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 {
|
struct free_list_entry {
|
||||||
intptr_t size; /* size of elements in this bucket */
|
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)
|
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;
|
intptr_t size2, bucket, sz, page_size;
|
||||||
void *p, *pg, *prev;
|
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
|
/* allocate code that will never be freed and that can be used
|
||||||
in multiple places */
|
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;
|
void *p;
|
||||||
intptr_t page_size;
|
intptr_t page_size;
|
||||||
|
|
||||||
|
@ -1148,7 +1152,7 @@ void *scheme_malloc_permanent_code(intptr_t size)
|
||||||
|
|
||||||
void scheme_free_code(void *p)
|
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;
|
intptr_t size, size2, bucket, page_size;
|
||||||
int per_page, n;
|
int per_page, n;
|
||||||
void *prev;
|
void *prev;
|
||||||
|
@ -1234,7 +1238,7 @@ void scheme_free_code(void *p)
|
||||||
|
|
||||||
void scheme_free_all_code(void)
|
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;
|
void *p, *next;
|
||||||
intptr_t page_size;
|
intptr_t page_size;
|
||||||
|
|
||||||
|
@ -1260,7 +1264,7 @@ void scheme_free_all_code(void)
|
||||||
currently takes advantage of that combination, so we support it
|
currently takes advantage of that combination, so we support it
|
||||||
with scheme_malloc_gcable_code() --- but only in CGC mode. */
|
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;
|
static uintptr_t jit_prev_page = 0, jit_prev_length = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1269,7 +1273,7 @@ void *scheme_malloc_gcable_code(intptr_t size)
|
||||||
void *p;
|
void *p;
|
||||||
p = scheme_malloc(size);
|
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.] */
|
/* [This chunk of code moved from our copy of GNU lightning to here.] */
|
||||||
uintptr_t page, length, page_size;
|
uintptr_t page, length, page_size;
|
||||||
|
@ -1324,7 +1328,7 @@ void *scheme_malloc_gcable_code(intptr_t size)
|
||||||
|
|
||||||
void scheme_notify_code_gc()
|
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_page = 0;
|
||||||
jit_prev_length = 0;
|
jit_prev_length = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user