[PATCH] libwine: Use getsegmentdata(3) on Mac OS to find the __DATA segment.
Chip Davis
cdavis at codeweavers.com
Tue Jul 31 12:05:15 CDT 2018
Don't assume it starts 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.
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.
Signed-off-by: Chip Davis <cdavis at codeweavers.com>
---
libs/wine/loader.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/libs/wine/loader.c b/libs/wine/loader.c
index c07042a583e6..e757a59cd682 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
@@ -392,6 +393,10 @@ static void *map_dll( const IMAGE_NT_HEADERS *nt_descr )
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)
@@ -424,8 +429,15 @@ static void *map_dll( const IMAGE_NT_HEADERS *nt_descr )
delta = (const BYTE *)nt_descr - addr;
code_start = page_size;
+#ifdef __APPLE__
+ /* Need the mach_header, not the PE header, to give to getsegmentdata(3) */
+ dladdr(addr, &dli);
+ data_start = getsegmentdata(dli.dli_fbase, "__DATA", &data_size) - addr;
+ data_end = (data_start + data_size + page_mask) & ~page_mask;
+#else
data_start = delta & ~page_mask;
data_end = (nt->OptionalHeader.SizeOfImage + delta + page_mask) & ~page_mask;
+#endif
fixup_rva_ptrs( &nt->OptionalHeader.AddressOfEntryPoint, addr, 1 );
--
2.18.0
More information about the wine-devel
mailing list