mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-19 22:02:57 +01:00
Resolved struct packing error and crash on OS X
This commit is contained in:
@@ -65,7 +65,7 @@ if (UNIX)
|
|||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32 -std=gnu++11 -fno-omit-frame-pointer -fno-pie")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32 -std=gnu++11 -fno-omit-frame-pointer -fno-pie")
|
||||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32")
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32")
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -sectcreate rct2_text __text /Users/kkirbatski/Desktop/openrct2_text -sectcreate rct2_data __data /Users/kkirbatski/Desktop/openrct2_data -segaddr rct2_data 0x8a4000 -segprot rct2_data rwx rwx -segaddr rct2_text 0x4010000 -segprot rct2_text rwx rwx -fno-pie -read_only_relocs suppress")
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -sectcreate rct2_text __text ${CMAKE_CURRENT_SOURCE_DIR}/build/openrct2_text -sectcreate rct2_data __data ${CMAKE_CURRENT_SOURCE_DIR}/build/openrct2_data -segaddr rct2_data 0x8a4000 -segprot rct2_data rwx rwx -segaddr rct2_text 0x401000 -segprot rct2_text rwx rwx -fno-pie -read_only_relocs suppress")
|
||||||
endif (APPLE)
|
endif (APPLE)
|
||||||
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS})
|
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS})
|
||||||
endif (UNIX)
|
endif (UNIX)
|
||||||
@@ -104,6 +104,24 @@ if (APPLE)
|
|||||||
TARGET_LINK_LIBRARIES(${PROJECT} ${ICONV_LIBRARIES})
|
TARGET_LINK_LIBRARIES(${PROJECT} ${ICONV_LIBRARIES})
|
||||||
endif (APPLE)
|
endif (APPLE)
|
||||||
|
|
||||||
|
# handle creating the rct2 text and data files on OS X
|
||||||
|
if (APPLE)
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT openrct2_text
|
||||||
|
COMMAND dd if=${CMAKE_CURRENT_SOURCE_DIR}/openrct2.exe of=${CMAKE_BINARY_DIR}/openrct2_text bs=4096 skip=1 count=1187
|
||||||
|
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/openrct2.exe
|
||||||
|
)
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT openrct2_data
|
||||||
|
COMMAND dd if=${CMAKE_CURRENT_SOURCE_DIR}/openrct2.exe of=${CMAKE_BINARY_DIR}/openrct2_data bs=4096 skip=1188 count=318
|
||||||
|
COMMAND dd if=/dev/zero of=${CMAKE_BINARY_DIR}/openrct2_data bs=4096 seek=318 count=2630 conv=notrunc
|
||||||
|
COMMAND dd if=${CMAKE_CURRENT_SOURCE_DIR}/openrct2.exe of=${CMAKE_BINARY_DIR}/openrct2_data bs=4096 skip=1506 seek=2948 count=1 conv=notrunc
|
||||||
|
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/openrct2.exe
|
||||||
|
)
|
||||||
|
add_custom_target(segfiles DEPENDS openrct2_text openrct2_data)
|
||||||
|
add_dependencies(${PROJECT} segfiles)
|
||||||
|
endif (APPLE)
|
||||||
|
|
||||||
# install into ${CMAKE_INSTALL_PREFIX}/bin/
|
# install into ${CMAKE_INSTALL_PREFIX}/bin/
|
||||||
#install (TARGETS ${PROJECT} DESTINATION bin)
|
#install (TARGETS ${PROJECT} DESTINATION bin)
|
||||||
|
|
||||||
|
|||||||
@@ -90,6 +90,12 @@ extern "C" {
|
|||||||
#define ioctlsocket ioctl
|
#define ioctlsocket ioctl
|
||||||
#endif // _WIN32
|
#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
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|||||||
@@ -40,14 +40,14 @@
|
|||||||
#include "util/util.h"
|
#include "util/util.h"
|
||||||
#include "world/mapgen.h"
|
#include "world/mapgen.h"
|
||||||
|
|
||||||
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
#if defined(__unix__)
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
#endif // defined(__unix__)
|
||||||
|
|
||||||
int gOpenRCT2StartupAction = STARTUP_ACTION_TITLE;
|
int gOpenRCT2StartupAction = STARTUP_ACTION_TITLE;
|
||||||
utf8 gOpenRCT2StartupActionPath[512] = { 0 };
|
utf8 gOpenRCT2StartupActionPath[512] = { 0 };
|
||||||
@@ -59,11 +59,11 @@ bool gOpenRCT2Headless = false;
|
|||||||
|
|
||||||
bool gOpenRCT2ShowChangelog;
|
bool gOpenRCT2ShowChangelog;
|
||||||
|
|
||||||
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
#if defined(__unix__)
|
||||||
//unsigned char __attribute__((section ("rct2_text,__text"))) gTextSegment[0x004A3000];
|
void *gDataSegment;
|
||||||
//unsigned char __attribute__((section ("rct2_data,__data"))) gDataSegment[0x01429000 - 0x8a4000];
|
void *gTextSegment;
|
||||||
int gExeFd;
|
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. */
|
/** 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;
|
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
|
// 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.
|
// 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__))
|
#if defined(__unix__)
|
||||||
/*#define RDATA_OFFSET 0x004A4000
|
#define RDATA_OFFSET 0x004A4000
|
||||||
#define DATASEG_OFFSET 0x005E2000
|
#define DATASEG_OFFSET 0x005E2000
|
||||||
|
|
||||||
const char *exepath = "openrct2.exe";
|
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.");
|
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
|
// section: rw data
|
||||||
|
gDataSegment = mmap((void *)0x8a4000, len, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS | MAP_SHARED, 0, 0);
|
||||||
void* asdf = mmap((void *)0x8a4000, len, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANON | MAP_SHARED, 0, 0);
|
if (gDataSegment != (void *)0x8a4000) {
|
||||||
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);
|
||||||
log_fatal("mmap failed to get required offset for data segment! got %p, expected %p, errno = %d", gDataSegment, (void *)(0x8a4000), errno);
|
exit(1);
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
len = 0x004A3000;
|
len = 0x004A3000;
|
||||||
// section: text
|
// section: text
|
||||||
void* ffaa = mmap((void *)(0x401000), len, PROT_EXEC | PROT_WRITE | PROT_READ, MAP_FIXED | MAP_PRIVATE, gExeFd, 0x1000);
|
gTextSegment = mmap((void *)(0x401000), len, PROT_EXEC | PROT_WRITE | PROT_READ, MAP_FIXED | MAP_PRIVATE, gExeFd, 0x1000);
|
||||||
if (ffaa != (void *)(0x401000))
|
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);
|
log_fatal("mmap failed to get required offset for text segment! got %p, expected %p, errno = %d", gTextSegment, (void *)(0x401000), errno);
|
||||||
exit(1);
|
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;
|
err = errno;
|
||||||
log_warning("mmapped file to %p", fbase);
|
log_warning("mmapped file to %p", fbase);
|
||||||
if (fbase == MAP_FAILED)
|
if (fbase == MAP_FAILED)
|
||||||
@@ -585,8 +584,8 @@ static bool openrct2_setup_rct2_segment()
|
|||||||
{
|
{
|
||||||
err = errno;
|
err = errno;
|
||||||
log_error("Failed to unmap file! errno = %d", err);
|
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.
|
// 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
|
// 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()
|
static bool openrct2_release_rct2_segment()
|
||||||
{
|
{
|
||||||
bool result = true;
|
bool result = true;
|
||||||
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
#if defined(__unix__)
|
||||||
#endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user