diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 35e093e73..d00b88824 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,6 +11,11 @@ include( FindPkgConfig ) option( NO_ASM "Disable assembly code" ) if( CMAKE_COMPILER_IS_GNUCXX ) option( NO_STRIP "Do not strip Release or MinSizeRel builds" ) + # At least some versions of Xcode fail if you strip with the linker + # instead of the separate strip utility. + if( APPLE ) + set( NO_STRIP ON ) + endif( APPLE ) endif( CMAKE_COMPILER_IS_GNUCXX ) if( CMAKE_SIZEOF_VOID_P MATCHES "8" ) @@ -232,13 +237,6 @@ endif( FMOD_LIBRARY ) # Search for NASM -if( CMAKE_SYSTEM_PROCESSOR MATCHES powerpc OR CMAKE_OSX_ARCHITECTURES MATCHES ppc) - if( NOT NO_ASM ) - message( STATUS "Disabling assembly code for PowerPC." ) - set( NO_ASM ON ) - endif( NOT NO_ASM ) -endif( CMAKE_SYSTEM_PROCESSOR MATCHES powerpc OR CMAKE_OSX_ARCHITECTURES MATCHES ppc ) - if( NOT NO_ASM ) if( UNIX AND X64 ) find_program( GAS_PATH as ) @@ -297,7 +295,12 @@ if( NOT NO_ASM ) set( ASM_FLAGS ) set( ASM_SOURCE_EXTENSION .s ) else( X64 ) - set( ASM_FLAGS -f elf -DM_TARGET_LINUX -i${CMAKE_CURRENT_SOURCE_DIR}/ ) + if( APPLE ) + set( ASM_FLAGS -fmacho -DM_TARGET_MACHO ) + else( APPLE ) + set( ASM_FLAGS -felf ) + endif( APPLE ) + set( ASM_FLAGS "${ASM_FLAGS}" -DM_TARGET_LINUX -i${CMAKE_CURRENT_SOURCE_DIR}/ ) set( ASM_SOURCE_EXTENSION .asm ) endif( X64 ) else( UNIX ) diff --git a/src/asm_ia32/a.asm b/src/asm_ia32/a.asm index 196e8317a..07b00fe25 100644 --- a/src/asm_ia32/a.asm +++ b/src/asm_ia32/a.asm @@ -93,7 +93,16 @@ setupvlineasm: selfmod premach3a, machvsh8+6 ret +%ifdef M_TARGET_MACHO + SECTION .text align=64 +%else SECTION .rtext progbits alloc exec write align=64 +%endif + +%ifdef M_TARGET_MACHO +GLOBAL rtext_a_start +rtext_a_start: +%endif ;eax = xscale ;ebx = palookupoffse @@ -538,3 +547,8 @@ ALIGN 16 mvcase0: jmp beginmvlineasm4 align 16 + +%ifdef M_TARGET_MACHO +GLOBAL rtext_a_end +rtext_a_end: +%endif diff --git a/src/asm_ia32/tmap.asm b/src/asm_ia32/tmap.asm index e4c477598..04b86d09d 100644 --- a/src/asm_ia32/tmap.asm +++ b/src/asm_ia32/tmap.asm @@ -285,7 +285,16 @@ R_SetSpanSize_ASM: aret: ret +%ifdef M_TARGET_MACHO + SECTION .text align=64 +%else SECTION .rtext progbits alloc exec write align=64 +%endif + +%ifdef M_TARGET_MACHO +GLOBAL rtext_tmap_start +rtext_tmap_start: +%endif rtext_start: @@ -1738,6 +1747,10 @@ ac4nil: pop edi ret rtext_end: +%ifdef M_TARGET_MACHO +GLOBAL rtext_tmap_end +rtext_tmap_end: +%endif align 16 ;************************ diff --git a/src/asm_ia32/tmap2.asm b/src/asm_ia32/tmap2.asm index 7f6ed82da..63eee0044 100644 --- a/src/asm_ia32/tmap2.asm +++ b/src/asm_ia32/tmap2.asm @@ -216,7 +216,13 @@ SetTiltedSpanSize: ret +%ifndef M_TARGET_MACHO SECTION .rtext progbits alloc exec write align=64 +%else + SECTION .text align=64 +GLOBAL rtext_tmap2_start +rtext_tmap2_start: +%endif rtext_start: @@ -628,3 +634,7 @@ fetch10 mov al,[ebp+esi+SPACEFILLER4] ret rtext_end: +%ifdef M_TARGET_MACHO +GLOBAL rtext_tmap2_end +rtext_tmap2_end: +%endif diff --git a/src/asm_ia32/tmap3.asm b/src/asm_ia32/tmap3.asm index 49444419c..3791b4ff0 100644 --- a/src/asm_ia32/tmap3.asm +++ b/src/asm_ia32/tmap3.asm @@ -80,7 +80,13 @@ setupvlinetallasm: selfmod shifter1, shift12+6 ret +%ifdef M_TARGET_MACHO + SECTION .text align=64 +GLOBAL rtext_tmap3_start +rtext_tmap3_start: +%else SECTION .rtext progbits alloc exec write align=64 +%endif ALIGN 16 @@ -331,3 +337,8 @@ shift12: shr ecx,16 pop ebx pop ebp ret + +%ifdef M_TARGET_MACHO +GLOBAL rtext_tmap3_end +rtext_tmap3_end: +%endif diff --git a/src/d_main.cpp b/src/d_main.cpp index 3b1e841a5..520127b9b 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -38,7 +38,7 @@ #endif #include -#ifdef unix +#if defined(unix) || defined(__APPLE__) #include #endif diff --git a/src/doomtype.h b/src/doomtype.h index 7757a3cc6..31f96d2ab 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -44,12 +44,6 @@ // Since this file is included by everything, it seems an appropriate place // to check the NOASM/USEASM macros. -#if defined(__APPLE__) -// The assembly code needs to be tweaked for Mach-O before enabled on Macs. -#ifndef NOASM -#define NOASM -#endif -#endif // There are three assembly-related macros: // diff --git a/src/p_acs.cpp b/src/p_acs.cpp index f1cbe4446..28217f663 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3495,7 +3495,7 @@ inline int getshort (int *&pc) #if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) inline int uallong(int &foo) { - return *foo; + return foo; } #else inline int uallong(int &foo) diff --git a/src/sdl/i_main.cpp b/src/sdl/i_main.cpp index 5650c0781..4305a07ca 100644 --- a/src/sdl/i_main.cpp +++ b/src/sdl/i_main.cpp @@ -44,6 +44,10 @@ #include #endif #include +#if defined(__MACH__) && !defined(NOASM) +#include +#include +#endif #include "doomerrors.h" #include "m_argv.h" @@ -201,6 +205,46 @@ static int DoomSpecificInfo (char *buffer, char *end) return p; } +#if defined(__MACH__) && !defined(NOASM) +// NASM won't let us create custom sections for Mach-O. Whether that's a limitation of NASM +// or of Mach-O, I don't know, but since we're using NASM for the assembly, it doesn't much +// matter. +extern "C" +{ + extern void *rtext_a_start, *rtext_a_end; + extern void *rtext_tmap_start, *rtext_tmap_end; + extern void *rtext_tmap2_start, *rtext_tmap2_end; + extern void *rtext_tmap3_start, *rtext_tmap3_end; +}; + +static void unprotect_pages(long pagesize, void *start, void *end) +{ + char *page = (char *)((intptr_t)start & ~(pagesize - 1)); + size_t len = (char *)end - (char *)start; + if (mprotect(page, len, PROT_READ|PROT_WRITE|PROT_EXEC) != 0) + { + fprintf(stderr, "mprotect failed\n"); + exit(1); + } +} + +static void unprotect_rtext() +{ + static void *const pages[] = + { + rtext_a_start, rtext_a_end, + rtext_tmap_start, rtext_tmap_end, + rtext_tmap2_start, rtext_tmap2_end, + rtext_tmap3_start, rtext_tmap3_end + }; + long pagesize = sysconf(_SC_PAGESIZE); + for (void *const *p = pages; p < &pages[countof(pages)]; p += 2) + { + unprotect_pages(pagesize, p[0], p[1]); + } +} +#endif + int main (int argc, char **argv) { printf(GAMENAME" v%s - SVN revision %s - SDL version\nCompiled on %s\n\n", @@ -214,6 +258,10 @@ int main (int argc, char **argv) seteuid (getuid ()); std::set_new_handler (NewFailure); +#if defined(__MACH__) && !defined(NOASM) + unprotect_rtext(); +#endif + #ifndef NO_GTK GtkAvailable = gtk_init_check (&argc, &argv); #endif