mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-01-28 22:04:43 -08:00
7da7ae71d2
Patches directly from the mailing list with second sign-off if supplied.
92 lines
3.5 KiB
Diff
92 lines
3.5 KiB
Diff
From 1a3385427b0834c46a262959ed7da3f21b59d8bd Mon Sep 17 00:00:00 2001
|
|
From: Chip Davis <cdavis@codeweavers.com>
|
|
Date: Wed, 1 Aug 2018 15:46:09 -0500
|
|
Subject: [PATCH 20/24] libwine: Use getsegmentdata(3) on Mac OS to find the
|
|
end of the __TEXT segment.
|
|
|
|
Don't assume it ends with the fake PE header. This assumption doesn't
|
|
hold on Mac OS: the __data section where it was placed is located after
|
|
several other sections, all in the __DATA segment.
|
|
|
|
Unfortunately, this causes Wine, when DEP/NX is turned off, to override
|
|
the page protections for the start of the __DATA segment, removing write
|
|
permission from them, leading to a crash when winemac.drv attempted to
|
|
use an Objective-C class for the first time.
|
|
|
|
Also, be sure to include the zero-fill (i.e. BSS) sections in the total
|
|
size of the .data section. This should fix some tests that use large
|
|
uninitialized arrays.
|
|
|
|
Signed-off-by: Ken Thomases <ken@codeweavers.com>
|
|
Signed-off-by: Chip Davis <cdavis@codeweavers.com>
|
|
---
|
|
libs/wine/loader.c | 19 ++++++++++++++++---
|
|
1 file changed, 16 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/libs/wine/loader.c b/libs/wine/loader.c
|
|
index c07042a..0af3b8e 100644
|
|
--- a/libs/wine/loader.c
|
|
+++ b/libs/wine/loader.c
|
|
@@ -49,6 +49,7 @@
|
|
#undef LoadResource
|
|
#undef GetCurrentThread
|
|
#include <pthread.h>
|
|
+#include <mach-o/getsect.h>
|
|
#else
|
|
extern char **environ;
|
|
#endif
|
|
@@ -387,11 +388,15 @@ static void *map_dll( const IMAGE_NT_HEADERS *nt_descr )
|
|
IMAGE_NT_HEADERS *nt;
|
|
IMAGE_SECTION_HEADER *sec;
|
|
BYTE *addr;
|
|
- DWORD code_start, data_start, data_end;
|
|
+ DWORD code_start, code_end, data_start, data_end;
|
|
const size_t page_size = sysconf( _SC_PAGESIZE );
|
|
const size_t page_mask = page_size - 1;
|
|
int delta, nb_sections = 2; /* code + data */
|
|
unsigned int i;
|
|
+#ifdef __APPLE__
|
|
+ Dl_info dli;
|
|
+ unsigned long data_size;
|
|
+#endif
|
|
|
|
size_t size = (sizeof(IMAGE_DOS_HEADER)
|
|
+ sizeof(IMAGE_NT_HEADERS)
|
|
@@ -425,7 +430,15 @@ static void *map_dll( const IMAGE_NT_HEADERS *nt_descr )
|
|
delta = (const BYTE *)nt_descr - addr;
|
|
code_start = page_size;
|
|
data_start = delta & ~page_mask;
|
|
+#ifdef __APPLE__
|
|
+ /* Need the mach_header, not the PE header, to give to getsegmentdata(3) */
|
|
+ dladdr(addr, &dli);
|
|
+ code_end = getsegmentdata(dli.dli_fbase, "__DATA", &data_size) - addr;
|
|
+ data_end = (code_end + data_size + page_mask) & ~page_mask;
|
|
+#else
|
|
+ code_end = data_start;
|
|
data_end = (nt->OptionalHeader.SizeOfImage + delta + page_mask) & ~page_mask;
|
|
+#endif
|
|
|
|
fixup_rva_ptrs( &nt->OptionalHeader.AddressOfEntryPoint, addr, 1 );
|
|
|
|
@@ -434,7 +447,7 @@ static void *map_dll( const IMAGE_NT_HEADERS *nt_descr )
|
|
#ifndef _WIN64
|
|
nt->OptionalHeader.BaseOfData = data_start;
|
|
#endif
|
|
- nt->OptionalHeader.SizeOfCode = data_start - code_start;
|
|
+ nt->OptionalHeader.SizeOfCode = code_end - code_start;
|
|
nt->OptionalHeader.SizeOfInitializedData = data_end - data_start;
|
|
nt->OptionalHeader.SizeOfUninitializedData = 0;
|
|
nt->OptionalHeader.SizeOfImage = data_end;
|
|
@@ -443,7 +456,7 @@ static void *map_dll( const IMAGE_NT_HEADERS *nt_descr )
|
|
/* Build the code section */
|
|
|
|
memcpy( sec->Name, ".text", sizeof(".text") );
|
|
- sec->SizeOfRawData = data_start - code_start;
|
|
+ sec->SizeOfRawData = code_end - code_start;
|
|
sec->Misc.VirtualSize = sec->SizeOfRawData;
|
|
sec->VirtualAddress = code_start;
|
|
sec->PointerToRawData = code_start;
|
|
--
|
|
1.9.1
|
|
|