From 6a4bd8b0b3ba84db02b5884c40758828642946e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Valur=20J=C3=B3nsson?= Date: Sun, 16 Nov 2025 15:17:39 +0000 Subject: [PATCH 01/11] Add macOS platform support (darwin_x86_64 and darwin_arm64) - Add platform detection for macOS in platform.h using __APPLE__ - Create separate macos.yml workflow for testing both x86_64 and ARM64 - Use darwin_x86_64 and darwin_arm64 ABI names for macOS libraries - Reuse existing AAPCS64/System V assembly implementations --- .github/workflows/buildcommit.yml | 80 ++++++++++++++++++++++++++++++- .github/workflows/macos.yml | 45 +++++++++++++++++ README.md | 19 ++++++-- stackman/platforms/platform.h | 16 +++++++ 4 files changed, 155 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/macos.yml diff --git a/.github/workflows/buildcommit.yml b/.github/workflows/buildcommit.yml index d858b1f..a82562f 100644 --- a/.github/workflows/buildcommit.yml +++ b/.github/workflows/buildcommit.yml @@ -3,6 +3,8 @@ name: build test and commit on: push: branches: [ master, dev ] + tags: + - 'v*.*.*' pull_request: branches: [ master ] @@ -91,7 +93,7 @@ jobs: commit-artifacts: runs-on: ubuntu-latest needs: [build-linux-gnu, build-windows] - if: ${{ github.event_name == 'push' }} + if: ${{ github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/') }} steps: - uses: actions/checkout@v4 - uses: actions/download-artifact@v4 @@ -106,3 +108,79 @@ jobs: git status git diff-index --quiet HEAD || git commit -m "Automated build" git push + + create-release: + runs-on: ubuntu-latest + needs: [build-linux-gnu, build-windows] + if: startsWith(github.ref, 'refs/tags/v') + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Create release archive + run: | + mkdir -p release/lib + # Copy all libraries to release/lib maintaining directory structure + cp -r artifacts/sysv_amd64/* release/lib/ 2>/dev/null || true + cp -r artifacts/sysv_i386/* release/lib/ 2>/dev/null || true + cp -r artifacts/arm32/* release/lib/ 2>/dev/null || true + cp -r artifacts/aarch64/* release/lib/ 2>/dev/null || true + cp -r artifacts/win_x86/* release/lib/ 2>/dev/null || true + cp -r artifacts/win_x64/* release/lib/ 2>/dev/null || true + cp -r artifacts/win_arm/* release/lib/ 2>/dev/null || true + cp -r artifacts/win_arm64/* release/lib/ 2>/dev/null || true + + # Copy headers and documentation + cp -r stackman release/ + cp README.md LICENSE release/ + + # Create version-specific archive + VERSION=${GITHUB_REF#refs/tags/v} + cd release + tar -czf ../stackman-${VERSION}-all-platforms.tar.gz . + cd .. + + - name: Extract version from tag + id: get_version + run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT + + - name: Create GitHub Release + uses: softprops/action-gh-release@v1 + with: + files: | + stackman-${{ steps.get_version.outputs.VERSION }}-all-platforms.tar.gz + artifacts/sysv_amd64/libstackman.a + artifacts/sysv_i386/libstackman.a + artifacts/arm32/libstackman.a + artifacts/aarch64/libstackman.a + artifacts/win_x86/stackman.lib + artifacts/win_x64/stackman.lib + artifacts/win_arm/stackman.lib + artifacts/win_arm64/stackman.lib + body: | + ## stackman ${{ steps.get_version.outputs.VERSION }} + + Pre-built libraries for all supported platforms. + + ### Platforms Included: + - **Linux**: AMD64, i386, ARM32, ARM64 (aarch64) + - **Windows**: x86, x64, ARM, ARM64 + + ### Download Options: + - **All platforms**: `stackman-${{ steps.get_version.outputs.VERSION }}-all-platforms.tar.gz` (includes headers + all libraries) + - **Individual libraries**: Download specific platform library files below + + ### Usage: + 1. Download the archive or specific library for your platform + 2. Include `stackman/stackman.h` in your code + 3. Link with the appropriate library file + + See [README.md](https://github.com/${{ github.repository }}/blob/${{ github.ref_name }}/README.md) for complete documentation. + draft: false + prerelease: false diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml new file mode 100644 index 0000000..3863c03 --- /dev/null +++ b/.github/workflows/macos.yml @@ -0,0 +1,45 @@ +name: macOS build and test + +on: + push: + pull_request: + branches: [ master ] + +jobs: + + build-macos: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [macos-13, macos-14] # macos-13 = x86_64, macos-14 = ARM64 (M1) + include: + - os: macos-13 + arch: x86_64 + abi: darwin_x86_64 + - os: macos-14 + arch: arm64 + abi: darwin_arm64 + + steps: + - uses: actions/checkout@v4 + + - name: Show system info + run: | + uname -a + uname -m + cc --version + + - name: Build library + run: make all + + - name: Run tests + run: make test + + - name: Show ABI name + run: make abiname + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.abi }} + path: lib/${{ matrix.abi }}/libstackman.a diff --git a/README.md b/README.md index e1c9331..e13b165 100644 --- a/README.md +++ b/README.md @@ -155,9 +155,10 @@ There are two basic ways to add the library to your project: Using a static libr ### static library (preferred) - - Link with the `libstackman.a` or `stackman.lib` libraries provided for your platform in the `lib/` directory. - - Pre-built libraries are available for all supported platforms (8 ABIs total). - - Libraries are automatically rebuilt by CI and committed to the repository for easy integration. + - Download pre-built libraries from the [Releases page](https://github.com/kristjanvalur/stackman/releases) for your platform + - Alternatively, link with the `libstackman.a` or `stackman.lib` libraries in the `lib/` directory if you've cloned the repository + - Pre-built libraries are available for all supported platforms (8 ABIs total) + - Libraries are automatically rebuilt by CI and committed to the repository for easy integration ### inlined code @@ -173,7 +174,17 @@ over separate assembly language source. The project uses GitHub Actions to automatically: - Build libraries for all 8 supported platforms (Linux: AMD64, i386, ARM32, ARM64; Windows: x86, x64, ARM, ARM64) - Run test suites on all platforms (using QEMU emulation for ARM on Linux) -- Commit updated libraries back to the repository on successful builds +- Commit updated libraries back to the repository on successful builds (for development branches) +- Create GitHub Releases with downloadable libraries when version tags are pushed + +### Releases + +Tagged versions (e.g., `v1.0.0`) automatically trigger: +- Build of all platforms +- Creation of a GitHub Release +- Upload of individual library files and a combined archive containing all platforms + headers + +Download stable releases from: https://github.com/kristjanvalur/stackman/releases See `.github/workflows/buildcommit.yml` for the complete CI configuration. diff --git a/stackman/platforms/platform.h b/stackman/platforms/platform.h index b797de9..007b852 100644 --- a/stackman/platforms/platform.h +++ b/stackman/platforms/platform.h @@ -53,7 +53,11 @@ #if defined(__amd64__) #include "switch_x86_64_gcc.h" /* gcc on amd64 */ #define _STACKMAN_PLATFORM x86_64_clang +#ifdef __APPLE__ +#define _STACKMAN_ABI darwin_x86_64 +#else #define _STACKMAN_ABI sysv_amd64 +#endif #elif defined(__i386__) #include "switch_x86_gcc.h" /* gcc on X86 */ #define _STACKMAN_PLATFORM x86_clang @@ -65,8 +69,12 @@ #elif defined(__ARM_ARCH_ISA_A64) #include "switch_aarch64_gcc.h" /* gcc using arm aarch64*/ #define _STACKMAN_PLATFORM aarch64_clang +#ifdef __APPLE__ +#define _STACKMAN_ABI darwin_arm64 +#else #define _STACKMAN_ABI aarch64 #endif +#endif #endif /* __clang__ */ #if defined(__GNUC__) && !defined(__clang__) @@ -74,7 +82,11 @@ #if defined(__amd64__) #include "switch_x86_64_gcc.h" /* gcc on amd64 */ #define _STACKMAN_PLATFORM x86_64_gcc +#ifdef __APPLE__ +#define _STACKMAN_ABI darwin_x86_64 +#else #define _STACKMAN_ABI sysv_amd64 +#endif #elif defined(__i386__) #include "switch_x86_gcc.h" /* gcc on X86 */ #define _STACKMAN_PLATFORM x86_gcc @@ -86,8 +98,12 @@ #elif defined(__ARM_ARCH_ISA_A64) #include "switch_aarch64_gcc.h" /* gcc using arm aarch64*/ #define _STACKMAN_PLATFORM aarch64_gcc +#ifdef __APPLE__ +#define _STACKMAN_ABI darwin_arm64 +#else #define _STACKMAN_ABI aarch64 #endif +#endif #endif /* __GNUC__ */ /* set STACKMAN_PLATFORM and optionally report */ From 207339285ecfd111924718ae000bb54f4f82b2d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Valur=20J=C3=B3nsson?= Date: Sun, 16 Nov 2025 15:20:24 +0000 Subject: [PATCH 02/11] Update to non-deprecated macOS runners (macos-15-intel and macos-latest) --- .github/workflows/macos.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 3863c03..ae13349 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -11,12 +11,12 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [macos-13, macos-14] # macos-13 = x86_64, macos-14 = ARM64 (M1) + os: [macos-15-intel, macos-latest] # macos-15-intel = x86_64, macos-latest = ARM64 include: - - os: macos-13 + - os: macos-15-intel arch: x86_64 abi: darwin_x86_64 - - os: macos-14 + - os: macos-latest arch: arm64 abi: darwin_arm64 From 6bed237ecabf9a40f8537d160076c0f05dab02b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Valur=20J=C3=B3nsson?= Date: Sun, 16 Nov 2025 15:22:06 +0000 Subject: [PATCH 03/11] Make ARM64 and x86_64 assembly compatible with macOS Mach-O format - Add conditional macros for Mach-O vs ELF directives - macOS requires leading underscore for C symbols (_stackman_switch) - Replace .type, .size, .section directives with macros that expand appropriately - Fixes build errors on macOS runners --- stackman/platforms/switch_aarch64_gcc.S | 32 ++++++++++++++++------- stackman/platforms/switch_x86_64_gcc.S | 34 +++++++++++++++++-------- 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/stackman/platforms/switch_aarch64_gcc.S b/stackman/platforms/switch_aarch64_gcc.S index 5b0406a..c2c6239 100644 --- a/stackman/platforms/switch_aarch64_gcc.S +++ b/stackman/platforms/switch_aarch64_gcc.S @@ -9,13 +9,28 @@ * and then copying the code from gen_asm.s into this file. * */ + +/* Mach-O (macOS) vs ELF (Linux) compatibility macros */ +#ifdef __APPLE__ +#define FUNCTION(name) .globl _##name +#define LABEL(name) _##name: +#define TYPE_FUNCTION(name) +#define SIZE_FUNCTION(name) +#define GNU_STACK +#else +#define FUNCTION(name) .global name ; .type name, %function +#define LABEL(name) name: +#define TYPE_FUNCTION(name) .type name, %function +#define SIZE_FUNCTION(name) .size name, .-name +#define GNU_STACK .section .note.GNU-stack,"",@progbits +#endif + .arch armv8-a .file "gen_asm.c" .text .align 2 - .global stackman_switch - .type stackman_switch, %function -stackman_switch: + FUNCTION(stackman_switch) +LABEL(stackman_switch) .LFB0: .cfi_startproc stp x29, x30, [sp, -160]! @@ -104,11 +119,10 @@ stackman_switch: ret .cfi_endproc .LFE0: - .size stackman_switch, .-stackman_switch + SIZE_FUNCTION(stackman_switch) .align 2 - .global stackman_call - .type stackman_call, %function -stackman_call: + FUNCTION(stackman_call) +LABEL(stackman_call) .LFB1: .cfi_startproc stp x29, x30, [sp, -32]! @@ -152,6 +166,6 @@ stackman_call: ret .cfi_endproc .LFE1: - .size stackman_call, .-stackman_call + SIZE_FUNCTION(stackman_call) .ident "GCC: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0" - .section .note.GNU-stack,"",@progbits + GNU_STACK diff --git a/stackman/platforms/switch_x86_64_gcc.S b/stackman/platforms/switch_x86_64_gcc.S index aca7168..a8429a5 100644 --- a/stackman/platforms/switch_x86_64_gcc.S +++ b/stackman/platforms/switch_x86_64_gcc.S @@ -9,11 +9,26 @@ * and then copying the code from gen_asm.s into this file. * */ + +/* Mach-O (macOS) vs ELF (Linux) compatibility macros */ +#ifdef __APPLE__ +#define FUNCTION(name) .globl _##name +#define LABEL(name) _##name: +#define TYPE_FUNCTION(name) +#define SIZE_FUNCTION(name) +#define GNU_STACK +#else +#define FUNCTION(name) .globl name ; .type name, @function +#define LABEL(name) name: +#define TYPE_FUNCTION(name) .type name, @function +#define SIZE_FUNCTION(name) .size name, .-name +#define GNU_STACK .section .note.GNU-stack,"",@progbits +#endif + .file "gen_asm.c" .text - .globl stackman_switch - .type stackman_switch, @function -stackman_switch: + FUNCTION(stackman_switch) +LABEL(stackman_switch) .LFB0: .cfi_startproc pushq %r15 @@ -93,10 +108,9 @@ stackman_switch: ret .cfi_endproc .LFE0: - .size stackman_switch, .-stackman_switch - .globl stackman_call - .type stackman_call, @function -stackman_call: + SIZE_FUNCTION(stackman_switch) + FUNCTION(stackman_call) +LABEL(stackman_call) .LFB1: .cfi_startproc pushq %rbp @@ -136,10 +150,10 @@ stackman_call: addq $8, %rsp popq %rbx popq %rbp - .cfi_def_cfa 7, 8 + .cfi_def_cfa_offset 8 ret .cfi_endproc .LFE1: - .size stackman_call, .-stackman_call + SIZE_FUNCTION(stackman_call) .ident "GCC: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0" - .section .note.GNU-stack,"",@progbits + GNU_STACK From 555a82d155c323dabbfc7a5249c7c9c042eeb21b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Valur=20J=C3=B3nsson?= Date: Sun, 16 Nov 2025 15:24:34 +0000 Subject: [PATCH 04/11] Disable CFI directives on macOS - macOS assembler has different CFI semantics causing errors - Add CFI_* macros that expand to nothing on macOS - CFI directives are for debugging/unwinding, not critical for functionality - Fixes 'invalid CFI advance_loc expression' errors --- stackman/platforms/switch_aarch64_gcc.S | 119 +++++++++++++----------- stackman/platforms/switch_x86_64_gcc.S | 67 +++++++------ 2 files changed, 104 insertions(+), 82 deletions(-) diff --git a/stackman/platforms/switch_aarch64_gcc.S b/stackman/platforms/switch_aarch64_gcc.S index c2c6239..65fde25 100644 --- a/stackman/platforms/switch_aarch64_gcc.S +++ b/stackman/platforms/switch_aarch64_gcc.S @@ -17,12 +17,23 @@ #define TYPE_FUNCTION(name) #define SIZE_FUNCTION(name) #define GNU_STACK +/* Disable CFI directives on macOS - they have different semantics */ +#define CFI_STARTPROC +#define CFI_ENDPROC +#define CFI_DEF_CFA_OFFSET(x) +#define CFI_OFFSET(r,o) +#define CFI_RESTORE(r) #else #define FUNCTION(name) .global name ; .type name, %function #define LABEL(name) name: #define TYPE_FUNCTION(name) .type name, %function #define SIZE_FUNCTION(name) .size name, .-name #define GNU_STACK .section .note.GNU-stack,"",@progbits +#define CFI_STARTPROC CFI_STARTPROC +#define CFI_ENDPROC CFI_ENDPROC +#define CFI_DEF_CFA_OFFSET(x) CFI_DEF_CFA_OFFSET()x +#define CFI_OFFSET(r,o) .cfi_offset r, o +#define CFI_RESTORE(r) CFI_RESTORE()r #endif .arch armv8-a @@ -32,11 +43,11 @@ FUNCTION(stackman_switch) LABEL(stackman_switch) .LFB0: - .cfi_startproc + CFI_STARTPROC stp x29, x30, [sp, -160]! - .cfi_def_cfa_offset 160 - .cfi_offset 29, -160 - .cfi_offset 30, -152 + CFI_DEF_CFA_OFFSET(160) + CFI_OFFSET(29,-160) + CFI_OFFSET(30,-152) mov x29, sp stp x19, x20, [sp, 16] stp x21, x22, [sp, 32] @@ -47,24 +58,24 @@ LABEL(stackman_switch) stp d10, d11, [sp, 112] stp d12, d13, [sp, 128] stp d14, d15, [sp, 144] - .cfi_offset 19, -144 - .cfi_offset 20, -136 - .cfi_offset 21, -128 - .cfi_offset 22, -120 - .cfi_offset 23, -112 - .cfi_offset 24, -104 - .cfi_offset 25, -96 - .cfi_offset 26, -88 - .cfi_offset 27, -80 - .cfi_offset 28, -72 - .cfi_offset 72, -64 - .cfi_offset 73, -56 - .cfi_offset 74, -48 - .cfi_offset 75, -40 - .cfi_offset 76, -32 - .cfi_offset 77, -24 - .cfi_offset 78, -16 - .cfi_offset 79, -8 + CFI_OFFSET(19,-144) + CFI_OFFSET(20,-136) + CFI_OFFSET(21,-128) + CFI_OFFSET(22,-120) + CFI_OFFSET(23,-112) + CFI_OFFSET(24,-104) + CFI_OFFSET(25,-96) + CFI_OFFSET(26,-88) + CFI_OFFSET(27,-80) + CFI_OFFSET(28,-72) + CFI_OFFSET(72,-64) + CFI_OFFSET(73,-56) + CFI_OFFSET(74,-48) + CFI_OFFSET(75,-40) + CFI_OFFSET(76,-32) + CFI_OFFSET(77,-24) + CFI_OFFSET(78,-16) + CFI_OFFSET(79,-8) mov x3, x0 mov x0, x1 #APP @@ -95,43 +106,43 @@ LABEL(stackman_switch) ldp d12, d13, [sp, 128] ldp d14, d15, [sp, 144] ldp x29, x30, [sp], 160 - .cfi_restore 30 - .cfi_restore 29 - .cfi_restore 78 - .cfi_restore 79 - .cfi_restore 76 - .cfi_restore 77 - .cfi_restore 74 - .cfi_restore 75 - .cfi_restore 72 - .cfi_restore 73 - .cfi_restore 27 - .cfi_restore 28 - .cfi_restore 25 - .cfi_restore 26 - .cfi_restore 23 - .cfi_restore 24 - .cfi_restore 21 - .cfi_restore 22 - .cfi_restore 19 - .cfi_restore 20 - .cfi_def_cfa_offset 0 + CFI_RESTORE(30) + CFI_RESTORE(29) + CFI_RESTORE(78) + CFI_RESTORE(79) + CFI_RESTORE(76) + CFI_RESTORE(77) + CFI_RESTORE(74) + CFI_RESTORE(75) + CFI_RESTORE(72) + CFI_RESTORE(73) + CFI_RESTORE(27) + CFI_RESTORE(28) + CFI_RESTORE(25) + CFI_RESTORE(26) + CFI_RESTORE(23) + CFI_RESTORE(24) + CFI_RESTORE(21) + CFI_RESTORE(22) + CFI_RESTORE(19) + CFI_RESTORE(20) + CFI_DEF_CFA_OFFSET(0) ret - .cfi_endproc + CFI_ENDPROC .LFE0: SIZE_FUNCTION(stackman_switch) .align 2 FUNCTION(stackman_call) LABEL(stackman_call) .LFB1: - .cfi_startproc + CFI_STARTPROC stp x29, x30, [sp, -32]! - .cfi_def_cfa_offset 32 - .cfi_offset 29, -32 - .cfi_offset 30, -24 + CFI_DEF_CFA_OFFSET(32) + CFI_OFFSET(29,-32) + CFI_OFFSET(30,-24) mov x29, sp str x19, [sp, 16] - .cfi_offset 19, -16 + CFI_OFFSET(19,-16) mov x4, x0 mov x0, x1 mov x3, x2 @@ -159,12 +170,12 @@ LABEL(stackman_call) #NO_APP ldr x19, [sp, 16] ldp x29, x30, [sp], 32 - .cfi_restore 30 - .cfi_restore 29 - .cfi_restore 19 - .cfi_def_cfa_offset 0 + CFI_RESTORE(30) + CFI_RESTORE(29) + CFI_RESTORE(19) + CFI_DEF_CFA_OFFSET(0) ret - .cfi_endproc + CFI_ENDPROC .LFE1: SIZE_FUNCTION(stackman_call) .ident "GCC: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0" diff --git a/stackman/platforms/switch_x86_64_gcc.S b/stackman/platforms/switch_x86_64_gcc.S index a8429a5..7930892 100644 --- a/stackman/platforms/switch_x86_64_gcc.S +++ b/stackman/platforms/switch_x86_64_gcc.S @@ -17,12 +17,23 @@ #define TYPE_FUNCTION(name) #define SIZE_FUNCTION(name) #define GNU_STACK +/* Disable CFI directives on macOS - they have different semantics */ +#define CFI_STARTPROC +#define CFI_ENDPROC +#define CFI_DEF_CFA_OFFSET(x) +#define CFI_OFFSET(r,o) +#define CFI_RESTORE(r) #else #define FUNCTION(name) .globl name ; .type name, @function #define LABEL(name) name: #define TYPE_FUNCTION(name) .type name, @function #define SIZE_FUNCTION(name) .size name, .-name #define GNU_STACK .section .note.GNU-stack,"",@progbits +#define CFI_STARTPROC CFI_STARTPROC +#define CFI_ENDPROC CFI_ENDPROC +#define CFI_DEF_CFA_OFFSET(x) CFI_DEF_CFA_OFFSET()x +#define CFI_OFFSET(r,o) .cfi_offset r, o +#define CFI_RESTORE(r) CFI_RESTORE()r #endif .file "gen_asm.c" @@ -30,27 +41,27 @@ FUNCTION(stackman_switch) LABEL(stackman_switch) .LFB0: - .cfi_startproc + CFI_STARTPROC pushq %r15 - .cfi_def_cfa_offset 16 - .cfi_offset 15, -16 + CFI_DEF_CFA_OFFSET(16) + CFI_OFFSET(15,-16) pushq %r14 - .cfi_def_cfa_offset 24 - .cfi_offset 14, -24 + CFI_DEF_CFA_OFFSET(24) + CFI_OFFSET(14,-24) pushq %r13 - .cfi_def_cfa_offset 32 - .cfi_offset 13, -32 + CFI_DEF_CFA_OFFSET(32) + CFI_OFFSET(13,-32) pushq %r12 - .cfi_def_cfa_offset 40 - .cfi_offset 12, -40 + CFI_DEF_CFA_OFFSET(40) + CFI_OFFSET(12,-40) pushq %rbp - .cfi_def_cfa_offset 48 - .cfi_offset 6, -48 + CFI_DEF_CFA_OFFSET(48) + CFI_OFFSET(6,-48) pushq %rbx - .cfi_def_cfa_offset 56 - .cfi_offset 3, -56 + CFI_DEF_CFA_OFFSET(56) + CFI_OFFSET(3,-56) subq $24, %rsp - .cfi_def_cfa_offset 80 + CFI_DEF_CFA_OFFSET(80) movq %rdi, %rax movq %rsi, %rcx #APP @@ -92,35 +103,35 @@ LABEL(stackman_switch) # 0 "" 2 #NO_APP addq $24, %rsp - .cfi_def_cfa_offset 56 + CFI_DEF_CFA_OFFSET(56) popq %rbx - .cfi_def_cfa_offset 48 + CFI_DEF_CFA_OFFSET(48) popq %rbp - .cfi_def_cfa_offset 40 + CFI_DEF_CFA_OFFSET(40) popq %r12 - .cfi_def_cfa_offset 32 + CFI_DEF_CFA_OFFSET(32) popq %r13 - .cfi_def_cfa_offset 24 + CFI_DEF_CFA_OFFSET(24) popq %r14 - .cfi_def_cfa_offset 16 + CFI_DEF_CFA_OFFSET(16) popq %r15 - .cfi_def_cfa_offset 8 + CFI_DEF_CFA_OFFSET(8) ret - .cfi_endproc + CFI_ENDPROC .LFE0: SIZE_FUNCTION(stackman_switch) FUNCTION(stackman_call) LABEL(stackman_call) .LFB1: - .cfi_startproc + CFI_STARTPROC pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset 6, -16 + CFI_DEF_CFA_OFFSET(16) + CFI_OFFSET(6,-16) movq %rsp, %rbp .cfi_def_cfa_register 6 pushq %rbx subq $8, %rsp - .cfi_offset 3, -24 + CFI_OFFSET(3,-24) movq %rdi, %rax movq %rsi, %rdi #APP @@ -150,9 +161,9 @@ LABEL(stackman_call) addq $8, %rsp popq %rbx popq %rbp - .cfi_def_cfa_offset 8 + CFI_DEF_CFA_OFFSET(8) ret - .cfi_endproc + CFI_ENDPROC .LFE1: SIZE_FUNCTION(stackman_call) .ident "GCC: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0" From dc117572240f246e95ae5e2b7bf431a64d4ec0be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Valur=20J=C3=B3nsson?= Date: Sun, 16 Nov 2025 15:26:36 +0000 Subject: [PATCH 05/11] Fix mktemp issue on macOS in abiname.sh - Clean up stale temp files before creating new ones - Prevents 'File exists' error from mktemp on macOS --- tools/abiname.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/abiname.sh b/tools/abiname.sh index e899f05..258182c 100644 --- a/tools/abiname.sh +++ b/tools/abiname.sh @@ -11,6 +11,8 @@ set -eu here=$(dirname "$0") mkdir -p "${here}/tmp" +# Clean up any stale temp files first +rm -f "${here}/tmp"/abiname*.c "${here}/tmp"/abiname*.c.out tmp=$(mktemp "${here}/tmp/abinameXXX.c") #1 create the preprocessed file From 0c8010c7c038c4aeb74fa4268393eb9e9d5461ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Valur=20J=C3=B3nsson?= Date: Sun, 16 Nov 2025 15:27:52 +0000 Subject: [PATCH 06/11] Disable static linking on macOS - macOS doesn't support -static flag (no crt0.o available) - Detect Darwin and skip -static flag - Tests will link dynamically on macOS, statically on Linux --- Makefile | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 20518c2..1df4c23 100644 --- a/Makefile +++ b/Makefile @@ -50,6 +50,12 @@ clean: DEBUG = #-DDEBUG_DUMP +# macOS doesn't support static linking +STATIC_FLAG := -static +ifeq ($(shell uname -s),Darwin) + STATIC_FLAG := +endif + .PHONY: test tests test: tests @@ -66,13 +72,13 @@ tests: bin/test_asm tests: LDLIBS := -lstackman bin/test: tests/test.o $(LIB)/libstackman.a - $(CC) $(LDFLAGS) -static -o $@ $< ${DEBUG} $(LDLIBS) + $(CC) $(LDFLAGS) $(STATIC_FLAG) -o $@ $< ${DEBUG} $(LDLIBS) bin/test_cc: tests/test_cc.o $(LIB)/libstackman.a - $(CXX) $(LDFLAGS) -static -o $@ $< ${DEBUG} $(LDLIBS) + $(CXX) $(LDFLAGS) $(STATIC_FLAG) -o $@ $< ${DEBUG} $(LDLIBS) bin/test_static: tests/test_static.o - $(CC) $(LDFLAGS) -static -o $@ $^ ${DEBUG} + $(CC) $(LDFLAGS) $(STATIC_FLAG) -o $@ $^ ${DEBUG} bin/test_asm: tests/test_asm.o tests/test_asm_s.o - $(CC) $(LDFLAGS) -static -o $@ $^ ${DEBUG} + $(CC) $(LDFLAGS) $(STATIC_FLAG) -o $@ $^ ${DEBUG} From 7473aae7752d34156dd78647f8e1c337dd74b616 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Valur=20J=C3=B3nsson?= Date: Sun, 16 Nov 2025 15:29:46 +0000 Subject: [PATCH 07/11] Add missing CFI_DEF_CFA_REGISTER macro for x86_64 - Fix .cfi_def_cfa_register directive on macOS - Properly define macro to expand to nothing on Apple platforms --- stackman/platforms/switch_x86_64_gcc.S | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/stackman/platforms/switch_x86_64_gcc.S b/stackman/platforms/switch_x86_64_gcc.S index 7930892..d4e2191 100644 --- a/stackman/platforms/switch_x86_64_gcc.S +++ b/stackman/platforms/switch_x86_64_gcc.S @@ -21,6 +21,7 @@ #define CFI_STARTPROC #define CFI_ENDPROC #define CFI_DEF_CFA_OFFSET(x) +#define CFI_DEF_CFA_REGISTER(x) #define CFI_OFFSET(r,o) #define CFI_RESTORE(r) #else @@ -29,11 +30,12 @@ #define TYPE_FUNCTION(name) .type name, @function #define SIZE_FUNCTION(name) .size name, .-name #define GNU_STACK .section .note.GNU-stack,"",@progbits -#define CFI_STARTPROC CFI_STARTPROC -#define CFI_ENDPROC CFI_ENDPROC -#define CFI_DEF_CFA_OFFSET(x) CFI_DEF_CFA_OFFSET()x +#define CFI_STARTPROC .cfi_startproc +#define CFI_ENDPROC .cfi_endproc +#define CFI_DEF_CFA_OFFSET(x) .cfi_def_cfa_offset x +#define CFI_DEF_CFA_REGISTER(x) .cfi_def_cfa_register x #define CFI_OFFSET(r,o) .cfi_offset r, o -#define CFI_RESTORE(r) CFI_RESTORE()r +#define CFI_RESTORE(r) .cfi_restore r #endif .file "gen_asm.c" @@ -128,7 +130,7 @@ LABEL(stackman_call) CFI_DEF_CFA_OFFSET(16) CFI_OFFSET(6,-16) movq %rsp, %rbp - .cfi_def_cfa_register 6 + CFI_DEF_CFA_REGISTER(6) pushq %rbx subq $8, %rsp CFI_OFFSET(3,-24) From b6dd92bd830950b0188e02d959dd3b45b4ea9cec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Valur=20J=C3=B3nsson?= Date: Sun, 16 Nov 2025 16:54:50 +0000 Subject: [PATCH 08/11] Add macOS builds to main workflow - Added build-macos job with darwin_x86_64 and darwin_arm64 - Included macOS artifacts in release archives - Now builds 9 platforms total (4 Linux, 2 macOS, 3 Windows) --- .github/workflows/buildcommit.yml | 37 ++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/.github/workflows/buildcommit.yml b/.github/workflows/buildcommit.yml index 446c8a6..a2c4ce3 100644 --- a/.github/workflows/buildcommit.yml +++ b/.github/workflows/buildcommit.yml @@ -52,7 +52,34 @@ jobs: uses: actions/upload-artifact@v4 with: name: ${{ env.abiname }} - path: lib/${{ env.abiname }}/libstackman.a + path: lib/${{ env.abiname }}/libstackman.a + + build-macos: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [macos-15-intel, macos-latest] + include: + - os: macos-15-intel + abi: darwin_x86_64 + - os: macos-latest + abi: darwin_arm64 + + steps: + - uses: actions/checkout@v4 + + - name: Build library + run: make all + + - name: Run tests + run: make test + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.abi }} + path: lib/${{ matrix.abi }}/libstackman.a build-windows: runs-on: windows-latest @@ -89,7 +116,7 @@ jobs: commit-artifacts: runs-on: ubuntu-latest - needs: [build-linux-gnu, build-windows] + needs: [build-linux-gnu, build-macos, build-windows] if: false # Disabled - libraries no longer committed to repository steps: - uses: actions/checkout@v4 @@ -108,7 +135,7 @@ jobs: create-release: runs-on: ubuntu-latest - needs: [build-linux-gnu, build-windows] + needs: [build-linux-gnu, build-macos, build-windows] if: startsWith(github.ref, 'refs/tags/v') permissions: contents: write @@ -129,6 +156,8 @@ jobs: cp -r artifacts/sysv_i386 release/lib/ cp -r artifacts/arm32 release/lib/ cp -r artifacts/aarch64 release/lib/ + cp -r artifacts/darwin_x86_64 release/lib/ + cp -r artifacts/darwin_arm64 release/lib/ cp -r artifacts/win_x86 release/lib/ cp -r artifacts/win_x64 release/lib/ cp -r artifacts/win_arm64 release/lib/ @@ -168,6 +197,8 @@ jobs: sysv_i386/ - Linux x86 (32-bit) arm32/ - Linux ARM (32-bit, AAPCS) aarch64/ - Linux ARM64 (AAPCS64) + darwin_x86_64/ - macOS x86_64 (Intel) + darwin_arm64/ - macOS ARM64 (Apple Silicon) win_x86/ - Windows x86 (32-bit) win_x64/ - Windows x64 win_arm64/ - Windows ARM64 From 984fb8326e360e332c6ceb6184e296d9cad12b7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Valur=20J=C3=B3nsson?= Date: Sun, 16 Nov 2025 16:54:59 +0000 Subject: [PATCH 09/11] Remove separate macOS workflow (now integrated into main workflow) --- .github/workflows/macos.yml | 45 ------------------------------------- 1 file changed, 45 deletions(-) delete mode 100644 .github/workflows/macos.yml diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml deleted file mode 100644 index ae13349..0000000 --- a/.github/workflows/macos.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: macOS build and test - -on: - push: - pull_request: - branches: [ master ] - -jobs: - - build-macos: - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [macos-15-intel, macos-latest] # macos-15-intel = x86_64, macos-latest = ARM64 - include: - - os: macos-15-intel - arch: x86_64 - abi: darwin_x86_64 - - os: macos-latest - arch: arm64 - abi: darwin_arm64 - - steps: - - uses: actions/checkout@v4 - - - name: Show system info - run: | - uname -a - uname -m - cc --version - - - name: Build library - run: make all - - - name: Run tests - run: make test - - - name: Show ABI name - run: make abiname - - - name: Upload artifacts - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.abi }} - path: lib/${{ matrix.abi }}/libstackman.a From fc20a6d1cadf05ede356db9dc9d569741098b4a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Valur=20J=C3=B3nsson?= Date: Sun, 16 Nov 2025 16:56:08 +0000 Subject: [PATCH 10/11] Add changelog entry for macOS platform support --- CHANGELOG.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4da7072..71c21f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,37 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Added +- macOS platform support + - `darwin_x86_64` - macOS on Intel (x86_64) + - `darwin_arm64` - macOS on Apple Silicon (ARM64) +- Platform detection for macOS in `platforms/platform.h` using `__APPLE__` and `__aarch64__` macros +- Mach-O assembly compatibility for both x86_64 and ARM64 + - Conditional assembly macros for ELF vs Mach-O object formats + - Disabled CFI directives on macOS (different semantics than Linux) + - Symbol name mangling with leading underscore for Mach-O +- macOS build jobs in CI workflow (macos-15-intel and macos-latest runners) +- macOS libraries included in release archives + +### Changed +- Assembly files (`switch_x86_64_gcc.S`, `switch_aarch64_gcc.S`) now support both Linux (ELF) and macOS (Mach-O) +- `Makefile` detects Darwin and disables `-static` flag (not supported on macOS) +- `tools/abiname.sh` improved to handle stale temp files on macOS +- Release archives now contain 9 platform libraries (was 7) + +## [1.0.1] - 2025-11-16 + +### Changed +- Disabled automatic library commits to repository +- Pre-built libraries now available exclusively via [GitHub Releases](https://github.com/stackless-dev/stackman/releases) +- Added `lib/README.md` documenting deprecation timeline + +### Deprecated +- `lib/` directory in repository - will be removed in v2.0.0 +- Committing binary library files to git (causes bloat and merge conflicts) + ## [1.0.0] - 2025-11-16 ### Added From b537c4443da4c21e5f38417f5215fe5fc10372a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Valur=20J=C3=B3nsson?= Date: Sun, 16 Nov 2025 16:57:09 +0000 Subject: [PATCH 11/11] Update README with macOS platform support - Updated version to 1.0.1 - Added macOS platforms (darwin_x86_64, darwin_arm64) to supported platforms list - Reorganized platform list by OS for clarity - Updated platform counts (9 ABIs total) --- README.md | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 634dfe1..ba34019 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # stackman -**Version 1.0.0** +**Version 1.0.1** Simple low-level stack manipulation API and implementation for common platforms @@ -75,13 +75,18 @@ The current code is distilled out of other work, with the aim of simplifying and standardizing the api. A number of ABI specifications is supported, meaning architecture and calling convention, plus archive format: - - win_x86 (32 bits) - - win_x64 - - win_arm64 (64 bit ARM) - - sysv_i386 (linux) - - sysv_amd64 (linux) - - AAPCS (32 bit arm - linux) - - AAPCS64 (64 bit arm - linux) + - **Linux (System V ABI)** + - sysv_i386 (32-bit x86) + - sysv_amd64 (64-bit x86_64) + - arm32 (32-bit ARM, AAPCS) + - aarch64 (64-bit ARM, AAPCS64) + - **macOS (Darwin)** + - darwin_x86_64 (Intel) + - darwin_arm64 (Apple Silicon) + - **Windows** + - win_x86 (32-bit) + - win_x64 (64-bit) + - win_arm64 (64-bit ARM) All platforms are automatically built and tested by GitHub Actions CI on every commit. @@ -156,7 +161,7 @@ There are two basic ways to add the library to your project: Using a static libr - Download pre-built libraries from the [Releases page](https://github.com/kristjanvalur/stackman/releases) for your platform - Alternatively, link with the `libstackman.a` or `stackman.lib` libraries in the `lib/` directory if you've cloned the repository - - Pre-built libraries are available for all supported platforms (8 ABIs total) + - Pre-built libraries are available for all supported platforms (9 ABIs total: 4 Linux, 2 macOS, 3 Windows) - Libraries are automatically rebuilt by CI and committed to the repository for easy integration ### inlined code @@ -171,7 +176,7 @@ over separate assembly language source. ## Continuous Integration The project uses GitHub Actions to automatically: -- Build libraries for all 8 supported platforms (Linux: AMD64, i386, ARM32, ARM64; Windows: x86, x64, ARM, ARM64) +- Build libraries for all 9 supported platforms (Linux: AMD64, i386, ARM32, ARM64; macOS: x86_64, ARM64; Windows: x86, x64, ARM64) - Run test suites on all platforms (using QEMU emulation for ARM on Linux) - Commit updated libraries back to the repository on successful builds (for development branches) - Create GitHub Releases with downloadable libraries when version tags are pushed