diff --git a/configure b/configure index 4cb23101f4c..42596bbb9c8 100755 --- a/configure +++ b/configure @@ -8727,7 +8727,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu WINELOADER_LDFLAGS="-Wl,-pie,-pagezero_size,0x1000,-sectcreate,__TEXT,__info_plist,loader/wine_info.plist" wine_can_build_preloader=yes - WINEPRELOADER_LDFLAGS="-nostartfiles -nodefaultlibs -e _start -ldylib1.o -Wl,-image_base,0x7d400000,-pagezero_size,0x1000,-sectcreate,__TEXT,__info_plist,loader/wine_info.plist" + WINEPRELOADER_LDFLAGS="-nostartfiles -nodefaultlibs -e _start -ldylib1.o -Wl,-image_base,0x7d400000,-pagezero_size,0x1000,-sectcreate,__TEXT,__info_plist,loader/wine_info.plist,-segaddr,WINE_4GB_RESERVE,0x100000000" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports -Wl,-no_new_main -e _main" >&5 $as_echo_n "checking whether the compiler supports -Wl,-no_new_main -e _main... " >&6; } if ${ac_cv_cflags__Wl__no_new_main__e__main+:} false; then : diff --git a/configure.ac b/configure.ac index 0f8b9f6c080..a9003523700 100644 --- a/configure.ac +++ b/configure.ac @@ -753,7 +753,7 @@ case $host_os in WINELOADER_LDFLAGS="-Wl,-pie,-pagezero_size,0x1000,-sectcreate,__TEXT,__info_plist,loader/wine_info.plist" wine_can_build_preloader=yes - WINEPRELOADER_LDFLAGS="-nostartfiles -nodefaultlibs -e _start -ldylib1.o -Wl,-image_base,0x7d400000,-pagezero_size,0x1000,-sectcreate,__TEXT,__info_plist,loader/wine_info.plist" + WINEPRELOADER_LDFLAGS="-nostartfiles -nodefaultlibs -e _start -ldylib1.o -Wl,-image_base,0x7d400000,-pagezero_size,0x1000,-sectcreate,__TEXT,__info_plist,loader/wine_info.plist,-segaddr,WINE_4GB_RESERVE,0x100000000" WINE_TRY_CFLAGS([-Wl,-no_new_main -e _main], [WINEPRELOADER_LDFLAGS="-Wl,-no_new_main $WINEPRELOADER_LDFLAGS" WINE_TRY_CFLAGS([-Wl,-no_new_main -e _main -nostartfiles -nodefaultlibs],, diff --git a/loader/preloader_mac.c b/loader/preloader_mac.c index d86675538bb..fc07b7da0ed 100644 --- a/loader/preloader_mac.c +++ b/loader/preloader_mac.c @@ -54,6 +54,17 @@ #include "wine/asm.h" #include "main.h" +/* Rosetta on Apple Silicon allocates memory starting at 0x100000000 (the 4GB line) + * before the preloader runs, which prevents any nonrelocatable EXEs with that + * base address from running. + * + * This empty linker section forces Rosetta's allocations (currently ~132 MB) + * to start at 0x114000000, and they should end below 0x120000000. + */ +#if defined(__x86_64__) +__asm__(".zerofill WINE_4GB_RESERVE,WINE_4GB_RESERVE,___wine_4gb_reserve,0x14000000"); +#endif + #ifndef LC_MAIN #define LC_MAIN 0x80000028 struct entry_point_command @@ -79,6 +90,7 @@ static struct wine_preload_info preload_info[] = { (void *)0x000000010000, 0x00100000 }, /* DOS area */ { (void *)0x000000110000, 0x67ef0000 }, /* low memory area */ { (void *)0x00007ff00000, 0x000f0000 }, /* shared user data */ + { (void *)0x000100000000, 0x14000000 }, /* WINE_4GB_RESERVE section */ { (void *)0x7ffd00000000, 0x01ff0000 }, /* top-down allocations + virtual heap */ #endif /* __i386__ */ { 0, 0 }, /* PE exe range set with WINEPRELOADRESERVE */ @@ -395,6 +407,10 @@ static int preloader_overlaps_range( const void *start, const void *end ) struct target_segment_command *seg = (struct target_segment_command*)cmd; const void *seg_start = (const void*)(seg->vmaddr + slide); const void *seg_end = (const char*)seg_start + seg->vmsize; + static const char reserved_segname[] = "WINE_4GB_RESERVE"; + + if (!wld_strncmp( seg->segname, reserved_segname, sizeof(reserved_segname)-1 )) + continue; if (end > seg_start && start <= seg_end) {