1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-18 12:33:17 +01:00

Resolved struct packing error and crash on OS X

This commit is contained in:
LRFLEW
2015-12-08 21:06:21 -06:00
parent af382b1884
commit c9be2e1bc9
3 changed files with 70 additions and 23 deletions

View File

@@ -90,6 +90,12 @@ extern "C" {
#define ioctlsocket ioctl
#endif // _WIN32
// Fixes issues on OS X
#if defined(_RCT2_H_) && !defined(_MSC_VER)
// use similar struct packing as MSVC for our structs
#pragma pack(1)
#endif
#ifdef __cplusplus
#include <list>

View File

@@ -40,14 +40,14 @@
#include "util/util.h"
#include "world/mapgen.h"
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
#if defined(__unix__)
#include <sys/mman.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
#endif // defined(__unix__)
int gOpenRCT2StartupAction = STARTUP_ACTION_TITLE;
utf8 gOpenRCT2StartupActionPath[512] = { 0 };
@@ -59,11 +59,11 @@ bool gOpenRCT2Headless = false;
bool gOpenRCT2ShowChangelog;
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
//unsigned char __attribute__((section ("rct2_text,__text"))) gTextSegment[0x004A3000];
//unsigned char __attribute__((section ("rct2_data,__data"))) gDataSegment[0x01429000 - 0x8a4000];
#if defined(__unix__)
void *gDataSegment;
void *gTextSegment;
int gExeFd;
#endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
#endif // defined(__unix__)
/** If set, will end the OpenRCT2 game loop. Intentially private to this module so that the flag can not be set back to 0. */
int _finished;
@@ -471,8 +471,8 @@ static bool openrct2_setup_rct2_segment()
{
// POSIX OSes will run OpenRCT2 as a native application and then load in the Windows PE, mapping the appropriate addresses as
// necessary. Windows does not need to do this as OpenRCT2 runs as a DLL loaded from the Windows PE.
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
/*#define RDATA_OFFSET 0x004A4000
#if defined(__unix__)
#define RDATA_OFFSET 0x004A4000
#define DATASEG_OFFSET 0x005E2000
const char *exepath = "openrct2.exe";
@@ -551,23 +551,22 @@ static bool openrct2_setup_rct2_segment()
log_error("Found already mapped pages in region we want to claim. This means something accessed memory before we got to and following mmap (or next malloc) call will likely fail.");
}
// section: rw data
void* asdf = mmap((void *)0x8a4000, len, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANON | MAP_SHARED, 0, 0);
if (asdf != (void *)0x8a4000) {
log_fatal("mmap failed to get required offset for data segment! got %p, expected %p, errno = %d", gDataSegment, (void *)(0x8a4000), errno);
exit(1);
gDataSegment = mmap((void *)0x8a4000, len, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS | MAP_SHARED, 0, 0);
if (gDataSegment != (void *)0x8a4000) {
log_fatal("mmap failed to get required offset for data segment! got %p, expected %p, errno = %d", gDataSegment, (void *)(0x8a4000), errno);
exit(1);
}
len = 0x004A3000;
// section: text
void* ffaa = mmap((void *)(0x401000), len, PROT_EXEC | PROT_WRITE | PROT_READ, MAP_FIXED | MAP_PRIVATE, gExeFd, 0x1000);
if (ffaa != (void *)(0x401000))
gTextSegment = mmap((void *)(0x401000), len, PROT_EXEC | PROT_WRITE | PROT_READ, MAP_FIXED | MAP_PRIVATE, gExeFd, 0x1000);
if (gTextSegment != (void *)(0x401000))
{
log_fatal("mmap failed to get required offset for text segment! got %p, expected %p, errno = %d", gTextSegment, (void *)(0x401000), errno);
exit(1);
log_fatal("mmap failed to get required offset for text segment! got %p, expected %p, errno = %d", gTextSegment, (void *)(0x401000), errno);
exit(1);
}
void *fbase = mmap(NULL, file_size, PROT_READ, MAP_PRIVATE | MAP_FILE, gExeFd, 0);
void *fbase = mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, gExeFd, 0);
err = errno;
log_warning("mmapped file to %p", fbase);
if (fbase == MAP_FAILED)
@@ -585,8 +584,8 @@ static bool openrct2_setup_rct2_segment()
{
err = errno;
log_error("Failed to unmap file! errno = %d", err);
}*/
#endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
}
#endif // defined(__unix__)
// Check that the expected data is at various addresses.
// Start at 0x9a6000, which is start of .data, to skip the region containing addresses to DLL
@@ -610,8 +609,32 @@ static bool openrct2_setup_rct2_segment()
static bool openrct2_release_rct2_segment()
{
bool result = true;
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
#endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
#if defined(__unix__)
int len = 0x01429000 - 0x8a4000; // 0xB85000, 12079104 bytes or around 11.5MB
int err;
err = munmap(gDataSegment, len);
if (err != 0)
{
err = errno;
log_error("Failed to unmap data segment! errno = %d", err);
result = false;
}
len = 0x004A3000;
err = munmap(gTextSegment, len);
if (err != 0)
{
err = errno;
log_error("Failed to unmap text segment! errno = %d", err);
result = false;
}
err = close(gExeFd);
if (err != 0)
{
err = errno;
log_error("Failed to close file! errno = %d", err);
result = false;
}
#endif // defined(__unix__)
return result;
}