loader: On Mac, reserve an area starting at 4GB to force Rosetta's allocations higher.
On Apple Silicon, Rosetta allocates memory starting at 0x100000000
(the 4GB line) before the preloader runs.
The .NET 3.5 installer and DirectX Jun2010 redistributable both contain
non-relocatable EXEs with that base address, which fail to run.
The workaround is to create an empty linker section at that address,
which is mapped by the kernel before Rosetta runs and forces Rosetta's
allocations higher in memory.
The linker section runs from 0x100000000-0x114000000.
Rosetta's allocations are ~132MB, and should end below 0x120000000.
This is not an exact science: a non-relocatable EXE with base address
between 0x114000000-0x120000000 will fail to run. If one is discovered,
the section size will need to be changed.
Signed-off-by: Brendan Shanks <bshanks@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
(cherry picked from commit 307f5d00f1
)
Signed-off-by: Michael Stefaniuc <mstefani@winehq.org>
This commit is contained in:
parent
497025d144
commit
f1a7cae5cb
|
@ -8722,7 +8722,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 :
|
||||
|
|
|
@ -745,7 +745,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],,
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue