Hack to load code below 4GB, and to make 32-bit vm allocates work.

This commit is contained in:
Dan Sumorok 2013-07-06 17:09:37 -04:00
parent 1c99d52b91
commit c01bd008db
3 changed files with 38 additions and 22 deletions

View File

@ -772,18 +772,20 @@ if [[ "x$WANT_SDL" = "xyes" ]]; then
EXTRASYSSRCS="$EXTRASYSSRCS ../SDL/SDLMain.m"
fi
fi
AC_MSG_CHECKING([whether __LP64__ is defined])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#if !defined(__LP64__)
# error __LP64__ not defined
#endif
]])],
[AC_MSG_RESULT(yes); LP64_DEFINED=yes],
[AC_MSG_RESULT(no)])
if [[ "x$WANT_SDL_VIDEO" = "xyes" ]]; then
AC_DEFINE(USE_SDL_VIDEO, 1, [Define to enable SDL video graphics support])
VIDEOSRCS="../SDL/video_sdl.cpp"
KEYCODES="../SDL/keycodes"
if [[ "x$ac_cv_framework_Carbon" = "xyes" ]]; then
AC_MSG_CHECKING([whether __LP64__ is defined])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#if !defined(__LP64__)
# error __LP64__ not defined
#endif
]])],
[AC_MSG_RESULT(yes); LP64_DEFINED=yes],
[AC_MSG_RESULT(no)])
if [[ "x$LP64_DEFINED" = "xyes" ]]; then
EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/clip_macosx64.mm ../pict.c"
else
@ -1774,6 +1776,16 @@ if [[ "x$HAVE_IPA" = "xyes" ]]; then
LDFLAGS="$LDFLAGS -O3 -OPT:Olimit=0 -IPA"
fi
if [[ "x$LP64_DEFINED" = "xyes" ] && [ "x$have_mach_vm" = "xyes" ]]; then
LIBS+=" -Wl,-pagezero_size,0x20000000"
LIBS+=" -Wl,-segaddr,__TEXT,0x60000000"
LIBS+=" -Wl,-segaddr,__PAGEZERO,0x20000000"
fi
if [[ ${OS_TYPE} = darwin ]]; then
LIBS+=" -Wl,-no_pie"
fi
dnl Generate Makefile.
AC_SUBST(DEFINES)
AC_SUBST(SYSSRCS)

View File

@ -106,7 +106,7 @@ extern "C" {
#define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&SIP->thr_state.MACH_FIELD_NAME(rax)) /* RAX is the first GPR we consider */
#endif
#ifdef __x86_64__
#define SIGSEGV_FAULT_ADDRESS_FAST (((uint64_t)code[1])|0x100000000)
#define SIGSEGV_FAULT_ADDRESS_FAST code[1]
#else
#define SIGSEGV_FAULT_ADDRESS_FAST code[1]
#endif

View File

@ -221,6 +221,9 @@ void vm_exit(void)
/* Allocate zero-filled memory of SIZE bytes. The mapping is private
and default protection bits are read / write. The return value
is the actual mapping address chosen or VM_MAP_FAILED for errors. */
#if defined(HAVE_MACH_VM)
static void *last_alloc = NULL;
#endif
void * vm_acquire(size_t size, int options)
{
@ -238,24 +241,18 @@ void * vm_acquire(size_t size, int options)
#endif
#if defined(HAVE_MACH_VM)
static size_t addrOffset = 0x80000000;
static size_t addrOffset = 0x20000000;
kern_return_t ret_code;
static uint8 *base32 = NULL;
if(options & VM_MAP_32BIT) {
#ifdef __LP64__
if((size < 0x08000000) && (addrOffset < 0x100000000ULL) && (base32 != NULL)) {
addr = (void *)(base32 + addrOffset);
ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr,
size, VM_FLAGS_FIXED);
addrOffset += 0x08000000;
} else {
ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr,
size, VM_FLAGS_ANYWHERE);
if((ret_code == KERN_SUCCESS) && (base32 == NULL)) {
base32 = (uint8_t *)addr;
}
addr = base32 + addrOffset;
ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr,
size, VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE);
if(ret_code == KERN_SUCCESS) {
last_alloc = addr;
base32 = base32 + size;
}
#else
// vm_allocate() returns a zero-filled memory region
@ -325,9 +322,16 @@ int vm_acquire_fixed(void * addr, size_t size, int options)
#if defined(HAVE_MACH_VM)
// vm_allocate() returns a zero-filled memory region
#ifdef __LP64__
kern_return_t ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, size,
if(addr != last_alloc) {
return -1;
}
kern_return_t ret_code = vm_allocate(mach_task_self(),
(vm_address_t *)&addr, size,
VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE);
#else
kern_return_t ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, size,
VM_FLAGS_FIXED);