From 531e528c6154edb185cdeabda1b21c0a30288802 Mon Sep 17 00:00:00 2001 From: Jacob Coby Date: Wed, 17 Apr 2024 09:09:22 -0400 Subject: [PATCH 1/3] Apple M-Series Fixes * Adds portable debug_break (https://github.com/scottt/debugbreak/) * Adds Brewfile for Homebrew deps * use isfinite() instead of finite() * Stub int3 code in mveasm --- Brewfile | 8 ++ CMakeLists.txt | 3 - lib/debug.h | 26 +------ lib/debugbreak.h | 174 ++++++++++++++++++++++++++++++++++++++++++ lib/linux/linux_fix.h | 5 ++ libmve/mveasm.cpp | 4 +- 6 files changed, 191 insertions(+), 29 deletions(-) create mode 100644 Brewfile create mode 100644 lib/debugbreak.h diff --git a/Brewfile b/Brewfile new file mode 100644 index 000000000..e9116ff1d --- /dev/null +++ b/Brewfile @@ -0,0 +1,8 @@ +# Homebrew dependencies to build Descent3 + +# XQuartz required for OpenGL and glx.h (not included in Xcode) +brew "xquartz" + +# SDL +brew "sdl12_compat" +brew "sdl2_image" diff --git a/CMakeLists.txt b/CMakeLists.txt index c02bc8c91..939764568 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,9 +5,6 @@ MARK_AS_ADVANCED(CMAKE_BACKWARDS_COMPATIBILITY) # allow more human readable "if then else" constructs SET( CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS TRUE ) -# TODO: Apple Silicon (arm64) later -SET( CMAKE_OSX_ARCHITECTURES x86_64 CACHE STRING "" FORCE) - PROJECT(Descent3) diff --git a/lib/debug.h b/lib/debug.h index 1839b23b9..72e0a275c 100644 --- a/lib/debug.h +++ b/lib/debug.h @@ -153,37 +153,13 @@ void Debug_ConsoleRedirectMessages(int virtual_window, int physical_window); // DEBUGGING MACROS // Break into the debugger, if this feature was enabled in Debug_init() #if !defined(RELEASE) +#include "debugbreak.h" #if defined(WIN32) -#define debug_break() \ - do { \ - if (Debug_break) \ - __asm int 3 \ - } while (0) #elif defined(__LINUX__) void ddio_InternalKeyClose(); -// #define debug_break() do{__asm__ __volatile__ ( "int $3" );}while(0) -#ifndef MACOSXPPC -#define debug_break() \ - do { \ - ddio_InternalKeyClose(); \ - __asm__ __volatile__("int $3"); \ - } while (0) -#else -#define debug_break() \ - do { \ - ddio_InternalKeyClose(); /*nop*/ \ - } while (0) -#endif #elif defined(MACINTOSH) extern void SuspendControls(); extern void ResumeControls(); -#define debug_break() \ - do { \ - if (Debug_break) \ - SuspendControls(); \ - Debugger(); \ - ResumeControls(); \ - } while (0) #else #define debug_break() #endif diff --git a/lib/debugbreak.h b/lib/debugbreak.h new file mode 100644 index 000000000..c37236e48 --- /dev/null +++ b/lib/debugbreak.h @@ -0,0 +1,174 @@ +/* Copyright (c) 2011-2021, Scott Tsai + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef DEBUG_BREAK_H +#define DEBUG_BREAK_H + +#ifdef _MSC_VER + +#define debug_break __debugbreak + +#else + +#ifdef __cplusplus +extern "C" { +#endif + +#define DEBUG_BREAK_USE_TRAP_INSTRUCTION 1 +#define DEBUG_BREAK_USE_BULTIN_TRAP 2 +#define DEBUG_BREAK_USE_SIGTRAP 3 + +#if defined(__i386__) || defined(__x86_64__) + #define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_TRAP_INSTRUCTION +__inline__ static void trap_instruction(void) +{ + __asm__ volatile("int $0x03"); +} +#elif defined(__thumb__) + #define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_TRAP_INSTRUCTION +/* FIXME: handle __THUMB_INTERWORK__ */ +__attribute__((always_inline)) +__inline__ static void trap_instruction(void) +{ + /* See 'arm-linux-tdep.c' in GDB source. + * Both instruction sequences below work. */ +#if 1 + /* 'eabi_linux_thumb_le_breakpoint' */ + __asm__ volatile(".inst 0xde01"); +#else + /* 'eabi_linux_thumb2_le_breakpoint' */ + __asm__ volatile(".inst.w 0xf7f0a000"); +#endif + + /* Known problem: + * After a breakpoint hit, can't 'stepi', 'step', or 'continue' in GDB. + * 'step' would keep getting stuck on the same instruction. + * + * Workaround: use the new GDB commands 'debugbreak-step' and + * 'debugbreak-continue' that become available + * after you source the script from GDB: + * + * $ gdb -x debugbreak-gdb.py <... USUAL ARGUMENTS ...> + * + * 'debugbreak-step' would jump over the breakpoint instruction with + * roughly equivalent of: + * (gdb) set $instruction_len = 2 + * (gdb) tbreak *($pc + $instruction_len) + * (gdb) jump *($pc + $instruction_len) + */ +} +#elif defined(__arm__) && !defined(__thumb__) + #define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_TRAP_INSTRUCTION +__attribute__((always_inline)) +__inline__ static void trap_instruction(void) +{ + /* See 'arm-linux-tdep.c' in GDB source, + * 'eabi_linux_arm_le_breakpoint' */ + __asm__ volatile(".inst 0xe7f001f0"); + /* Known problem: + * Same problem and workaround as Thumb mode */ +} +#elif defined(__aarch64__) && defined(__APPLE__) + #define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_BULTIN_DEBUGTRAP +#elif defined(__aarch64__) + #define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_TRAP_INSTRUCTION +__attribute__((always_inline)) +__inline__ static void trap_instruction(void) +{ + /* See 'aarch64-tdep.c' in GDB source, + * 'aarch64_default_breakpoint' */ + __asm__ volatile(".inst 0xd4200000"); +} +#elif defined(__powerpc__) + /* PPC 32 or 64-bit, big or little endian */ + #define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_TRAP_INSTRUCTION +__attribute__((always_inline)) +__inline__ static void trap_instruction(void) +{ + /* See 'rs6000-tdep.c' in GDB source, + * 'rs6000_breakpoint' */ + __asm__ volatile(".4byte 0x7d821008"); + + /* Known problem: + * After a breakpoint hit, can't 'stepi', 'step', or 'continue' in GDB. + * 'step' stuck on the same instruction ("twge r2,r2"). + * + * The workaround is the same as ARM Thumb mode: use debugbreak-gdb.py + * or manually jump over the instruction. */ +} +#elif defined(__riscv) + /* RISC-V 32 or 64-bit, whether the "C" extension + * for compressed, 16-bit instructions are supported or not */ + #define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_TRAP_INSTRUCTION +__attribute__((always_inline)) +__inline__ static void trap_instruction(void) +{ + /* See 'riscv-tdep.c' in GDB source, + * 'riscv_sw_breakpoint_from_kind' */ + __asm__ volatile(".4byte 0x00100073"); +} +#else + #define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_SIGTRAP +#endif + + +#ifndef DEBUG_BREAK_IMPL +#error "debugbreak.h is not supported on this target" +#elif DEBUG_BREAK_IMPL == DEBUG_BREAK_USE_TRAP_INSTRUCTION +__attribute__((always_inline)) +__inline__ static void debug_break(void) +{ + trap_instruction(); +} +#elif DEBUG_BREAK_IMPL == DEBUG_BREAK_USE_BULTIN_DEBUGTRAP +__attribute__((always_inline)) +__inline__ static void debug_break(void) +{ + __builtin_debugtrap(); +} +#elif DEBUG_BREAK_IMPL == DEBUG_BREAK_USE_BULTIN_TRAP +__attribute__((always_inline)) +__inline__ static void debug_break(void) +{ + __builtin_trap(); +} +#elif DEBUG_BREAK_IMPL == DEBUG_BREAK_USE_SIGTRAP +#include +__attribute__((always_inline)) +__inline__ static void debug_break(void) +{ + raise(SIGTRAP); +} +#else +#error "invalid DEBUG_BREAK_IMPL value" +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ifdef _MSC_VER */ + +#endif /* ifndef DEBUG_BREAK_H */ diff --git a/lib/linux/linux_fix.h b/lib/linux/linux_fix.h index 18f5d8cfe..23a3123e9 100644 --- a/lib/linux/linux_fix.h +++ b/lib/linux/linux_fix.h @@ -2,6 +2,7 @@ #define __LINUX_FIX_H_ #include +#include #define LOKI_VERSION "" @@ -46,7 +47,11 @@ inline int _filelength(int fd) { #define strcmpi(a, b) stricmp(a, b) #define strcmpni(a, b, c) strnicmp(a, b, c) #define _chmod(a, b) chmod(a, b) +#if defined(__arm64__) +#define _finite(a) isfinite(a) +#else #define _finite(a) finite(a) +#endif #define _min(a, b) min(a, b) #define _max(a, b) max(a, b) #define __min(a, b) min(a, b) diff --git a/libmve/mveasm.cpp b/libmve/mveasm.cpp index c1acf2e12..af28d2ebf 100644 --- a/libmve/mveasm.cpp +++ b/libmve/mveasm.cpp @@ -2054,7 +2054,9 @@ void MVE_gfxWaitRetrace(int state); void MVE_gfxSetSplit(unsigned line); #if defined(__LINUX__) -#ifndef MACOSXPPC + +#if !defined(MACOSXPPC) && !defined(__arm64__) + #define int3 __asm__ __volatile__("int $3"); #else #define int3 From 1413cfa74b4009cc08c6539aac7a4a4180c91f18 Mon Sep 17 00:00:00 2001 From: Jacob Coby Date: Wed, 17 Apr 2024 09:24:47 -0400 Subject: [PATCH 2/3] Ignore formatting for debugbreak.h --- .clang-format-ignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .clang-format-ignore diff --git a/.clang-format-ignore b/.clang-format-ignore new file mode 100644 index 000000000..653f6bde7 --- /dev/null +++ b/.clang-format-ignore @@ -0,0 +1,2 @@ +# 3rd party libs +lib/debugbreak.h From 55e29c23a6569d63297c59280611cab12b9163fd Mon Sep 17 00:00:00 2001 From: Jacob Coby Date: Wed, 17 Apr 2024 11:10:36 -0400 Subject: [PATCH 3/3] Use brew bundle to install dependencies --- .github/workflows/build.yml | 6 ++---- Brewfile | 7 ++++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0fc60808d..b1e83a5fe 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,10 +23,8 @@ jobs: - name: Install macOS dependencies if: ${{ matrix.os.preset == 'mac' }} run: | - # Note this is x86_64 Homebrew - /usr/local/bin/brew install sdl12-compat sdl2_image - curl --output-dir /tmp -fsSLO https://github.com/XQuartz/XQuartz/releases/download/XQuartz-2.8.5/XQuartz-2.8.5.pkg - sudo installer -pkg /tmp/XQuartz-2.8.5.pkg -target LocalSystem + # Install packages from Homebrew + brew bundle install - name: Configure CMake run: cmake --preset ${{matrix.os.preset}} -B ${{github.workspace}}/build diff --git a/Brewfile b/Brewfile index e9116ff1d..f2a1b2351 100644 --- a/Brewfile +++ b/Brewfile @@ -1,8 +1,9 @@ # Homebrew dependencies to build Descent3 # XQuartz required for OpenGL and glx.h (not included in Xcode) -brew "xquartz" +tap "homebrew/cask" +cask "xquartz" -# SDL -brew "sdl12_compat" +# SDL +brew "sdl12-compat" brew "sdl2_image"