diff --git a/CMakeLists.txt b/CMakeLists.txt index f2c70e9..98e5ab8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,8 @@ cmake_minimum_required(VERSION 3.5...3.16) project(boost_context VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX) +list(APPEND CMAKE_MODULE_PATH ${boost_context_SOURCE_DIR}/cmake) + # Build features ## Binary format @@ -27,10 +29,10 @@ unset(_default_binfmt) math(EXPR _bits "${CMAKE_SIZEOF_VOID_P}*8") -if(WIN32) - set(_default_abi ms) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") +if(CMAKE_SYSTEM_PROCESSOR MATCHES "^[Aa][Rr][Mm]" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") set(_default_abi aapcs) +elseif(WIN32) + set(_default_abi ms) elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips") if(_bits EQUAL 32) set(_default_abi o32) @@ -54,7 +56,7 @@ set(_all_archs arm arm64 loongarch64 mips32 mips64 ppc32 ppc64 riscv64 s390x i38 if(CMAKE_SYSTEM_PROCESSOR IN_LIST _all_archs) set(_default_arch ${CMAKE_SYSTEM_PROCESSOR}) elseif(_bits EQUAL 32) - if(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") + if(CMAKE_SYSTEM_PROCESSOR MATCHES "^[Aa][Rr][Mm]") set(_default_arch arm) elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips") set(_default_arch mips32) @@ -63,7 +65,7 @@ elseif(_bits EQUAL 32) endif() else() if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" OR - CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") # armv8 + CMAKE_SYSTEM_PROCESSOR MATCHES "^[Aa][Rr][Mm]") # armv8 set(_default_arch arm64) elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips") set(_default_arch mips64) @@ -82,7 +84,11 @@ unset(_default_arch) ## Assembler type if(MSVC) - set(_default_asm masm) + if(BOOST_CONTEXT_ARCHITECTURE STREQUAL arm64 OR BOOST_CONTEXT_ARCHITECTURE STREQUAL arm) + set(_default_asm armasm) + else() + set(_default_asm masm) + endif() else() set(_default_asm gas) endif() @@ -135,6 +141,8 @@ if(BOOST_CONTEXT_IMPLEMENTATION STREQUAL "fcontext") else() enable_language(ASM) endif() + elseif(BOOST_CONTEXT_ASSEMBLER STREQUAL armasm) + enable_language(ASM_ARMASM) else() enable_language(ASM_MASM) endif() diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 index 9df8f0a..a56fb28 100644 --- a/build/Jamfile.v2 +++ b/build/Jamfile.v2 @@ -229,6 +229,19 @@ alias asm_sources darwin ; +# ARM/AAPCS/PE +alias asm_sources + : asm/make_arm64_aapcs_pe_armasm.asm + asm/jump_arm64_aapcs_pe_armasm.asm + asm/ontop_arm64_aapcs_pe_armasm.asm + untested.cpp + : aapcs + 64 + arm + pe + msvc + ; + # LOONGARCH64 # LOONGARCH64/SYSV/ELF alias asm_sources diff --git a/cmake/CMakeASM_ARMASMInformation.cmake b/cmake/CMakeASM_ARMASMInformation.cmake new file mode 100644 index 0000000..ff44539 --- /dev/null +++ b/cmake/CMakeASM_ARMASMInformation.cmake @@ -0,0 +1,17 @@ + +# for the armasm assembler, armasm or armasm64 + +set(ASM_DIALECT "_ARMASM") + +set(CMAKE_ASM${ASM_DIALECT}_SOURCE_FILE_EXTENSIONS asm) + +set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT " -o ") + +# The ASM_ARMASM compiler id for this compiler is "MSVC", so fill out the runtime library table. +set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded "") +set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL "") +set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug "") +set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL "") + +include(CMakeASMInformation) +set(ASM_DIALECT) diff --git a/cmake/CMakeDetermineASM_ARMASMCompiler.cmake b/cmake/CMakeDetermineASM_ARMASMCompiler.cmake new file mode 100644 index 0000000..d7687b3 --- /dev/null +++ b/cmake/CMakeDetermineASM_ARMASMCompiler.cmake @@ -0,0 +1,15 @@ + +# Find the armasm assembler, armasm or armasm64 + +set(ASM_DIALECT "_ARMASM") + +# if we are using the 64bit cl compiler, assume we also want the 64bit assembler +if(";${CMAKE_VS_PLATFORM_NAME};${MSVC_C_ARCHITECTURE_ID};${MSVC_CXX_ARCHITECTURE_ID};" + MATCHES ";ARM64;") + set(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT armasm64) +else() + set(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT armasm) +endif() + +include(CMakeDetermineASMCompiler) +set(ASM_DIALECT) diff --git a/cmake/CMakeTestASM_ARMASMCompiler.cmake b/cmake/CMakeTestASM_ARMASMCompiler.cmake new file mode 100644 index 0000000..ddaf928 --- /dev/null +++ b/cmake/CMakeTestASM_ARMASMCompiler.cmake @@ -0,0 +1,13 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + + +# This file is used by EnableLanguage in cmGlobalGenerator to +# determine that the selected ASM_MASM "compiler" (should be masm or masm64) +# works. For assembler this can only check whether the compiler has been found, +# because otherwise there would have to be a separate assembler source file +# for each assembler on every architecture. + +set(ASM_DIALECT "_ARMASM") +include(CMakeTestASMCompiler) +set(ASM_DIALECT) diff --git a/src/asm/jump_arm64_aapcs_pe_armasm.asm b/src/asm/jump_arm64_aapcs_pe_armasm.asm new file mode 100644 index 0000000..20550ec --- /dev/null +++ b/src/asm/jump_arm64_aapcs_pe_armasm.asm @@ -0,0 +1,110 @@ +; Copyright Edward Nevill + Oliver Kowalke 2015 +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) + +;******************************************************* +;* * +;* ------------------------------------------------- * +;* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * +;* ------------------------------------------------- * +;* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * +;* ------------------------------------------------- * +;* | d8 | d9 | d10 | d11 | * +;* ------------------------------------------------- * +;* ------------------------------------------------- * +;* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * +;* ------------------------------------------------- * +;* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * +;* ------------------------------------------------- * +;* | d12 | d13 | d14 | d15 | * +;* ------------------------------------------------- * +;* ------------------------------------------------- * +;* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * +;* ------------------------------------------------- * +;* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * +;* ------------------------------------------------- * +;* | x19 | x20 | x21 | x22 | * +;* ------------------------------------------------- * +;* ------------------------------------------------- * +;* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * +;* ------------------------------------------------- * +;* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * +;* ------------------------------------------------- * +;* | x23 | x24 | x25 | x26 | * +;* ------------------------------------------------- * +;* ------------------------------------------------- * +;* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * +;* ------------------------------------------------- * +;* | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * +;* ------------------------------------------------- * +;* | x27 | x28 | FP | LR | * +;* ------------------------------------------------- * +;* ------------------------------------------------- * +;* | 40 | 41 | 42 | 43 | | | * +;* ------------------------------------------------- * +;* | 0xa0| 0xa4| 0xa8| 0xac| | | * +;* ------------------------------------------------- * +;* | PC | align | | | * +;* ------------------------------------------------- * +;* * +;******************************************************* + + AREA |.text|, CODE, READONLY, ALIGN=4, CODEALIGN + EXPORT jump_fcontext + +jump_fcontext proc + ; prepare stack for GP + FPU + sub sp, sp, #0xb0 + + ; save d8 - d15 + stp d8, d9, [sp, #0x00] + stp d10, d11, [sp, #0x10] + stp d12, d13, [sp, #0x20] + stp d14, d15, [sp, #0x30] + + ; save x19-x30 + stp x19, x20, [sp, #0x40] + stp x21, x22, [sp, #0x50] + stp x23, x24, [sp, #0x60] + stp x25, x26, [sp, #0x70] + stp x27, x28, [sp, #0x80] + stp x29, x30, [sp, #0x90] + + ; save LR as PC + str x30, [sp, #0xa0] + + ; store RSP (pointing to context-data) in X0 + mov x4, sp + + ; restore RSP (pointing to context-data) from X1 + mov sp, x0 + + ; load d8 - d15 + ldp d8, d9, [sp, #0x00] + ldp d10, d11, [sp, #0x10] + ldp d12, d13, [sp, #0x20] + ldp d14, d15, [sp, #0x30] + + ; load x19-x30 + ldp x19, x20, [sp, #0x40] + ldp x21, x22, [sp, #0x50] + ldp x23, x24, [sp, #0x60] + ldp x25, x26, [sp, #0x70] + ldp x27, x28, [sp, #0x80] + ldp x29, x30, [sp, #0x90] + + ; return transfer_t from jump + ; pass transfer_t as first arg in context function + ; X0 == FCTX, X1 == DATA + mov x0, x4 + + ; load pc + ldr x4, [sp, #0xa0] + + ; restore stack from GP + FPU + add sp, sp, #0xb0 + + ret x4 + ENDP + END \ No newline at end of file diff --git a/src/asm/make_arm64_aapcs_pe_armasm.asm b/src/asm/make_arm64_aapcs_pe_armasm.asm new file mode 100644 index 0000000..44efdba --- /dev/null +++ b/src/asm/make_arm64_aapcs_pe_armasm.asm @@ -0,0 +1,81 @@ +; Copyright Edward Nevill + Oliver Kowalke 2015 +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) + +;******************************************************* +;* * +;* ------------------------------------------------- * +;* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * +;* ------------------------------------------------- * +;* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * +;* ------------------------------------------------- * +;* | d8 | d9 | d10 | d11 | * +;* ------------------------------------------------- * +;* ------------------------------------------------- * +;* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * +;* ------------------------------------------------- * +;* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * +;* ------------------------------------------------- * +;* | d12 | d13 | d14 | d15 | * +;* ------------------------------------------------- * +;* ------------------------------------------------- * +;* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * +;* ------------------------------------------------- * +;* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * +;* ------------------------------------------------- * +;* | x19 | x20 | x21 | x22 | * +;* ------------------------------------------------- * +;* ------------------------------------------------- * +;* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * +;* ------------------------------------------------- * +;* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * +;* ------------------------------------------------- * +;* | x23 | x24 | x25 | x26 | * +;* ------------------------------------------------- * +;* ------------------------------------------------- * +;* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * +;* ------------------------------------------------- * +;* | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * +;* ------------------------------------------------- * +;* | x27 | x28 | FP | LR | * +;* ------------------------------------------------- * +;* ------------------------------------------------- * +;* | 40 | 41 | 42 | 43 | | | * +;* ------------------------------------------------- * +;* | 0xa0| 0xa4| 0xa8| 0xac| | | * +;* ------------------------------------------------- * +;* | PC | align | | | * +;* ------------------------------------------------- * +;* * +;******************************************************* + + AREA |.text|, CODE, READONLY, ALIGN=4, CODEALIGN + EXPORT make_fcontext + IMPORT _exit + +make_fcontext proc + ; shift address in x0 (allocated stack) to lower 16 byte boundary + and x0, x0, ~0xF + + ; reserve space for context-data on context-stack + sub x0, x0, #0xb0 + + ; third arg of make_fcontext() == address of context-function + ; store address as a PC to jump in + str x2, [x0, #0xa0] + + ; save address of finish as return-address for context-function + ; will be entered after context-function returns (LR register) + adr x1, finish + str x1, [x0, #0x98] + + ret x30 ; return pointer to context-data (x0) + +finish + ; exit code is zero + mov x0, #0 + ; exit application + bl _exit + ENDP + END diff --git a/src/asm/ontop_arm64_aapcs_pe_armasm.asm b/src/asm/ontop_arm64_aapcs_pe_armasm.asm new file mode 100644 index 0000000..cdbc8a9 --- /dev/null +++ b/src/asm/ontop_arm64_aapcs_pe_armasm.asm @@ -0,0 +1,109 @@ +; Copyright Edward Nevill + Oliver Kowalke 2015 +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) + +;******************************************************* +;* * +;* ------------------------------------------------- * +;* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * +;* ------------------------------------------------- * +;* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * +;* ------------------------------------------------- * +;* | d8 | d9 | d10 | d11 | * +;* ------------------------------------------------- * +;* ------------------------------------------------- * +;* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * +;* ------------------------------------------------- * +;* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * +;* ------------------------------------------------- * +;* | d12 | d13 | d14 | d15 | * +;* ------------------------------------------------- * +;* ------------------------------------------------- * +;* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * +;* ------------------------------------------------- * +;* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * +;* ------------------------------------------------- * +;* | x19 | x20 | x21 | x22 | * +;* ------------------------------------------------- * +;* ------------------------------------------------- * +;* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * +;* ------------------------------------------------- * +;* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * +;* ------------------------------------------------- * +;* | x23 | x24 | x25 | x26 | * +;* ------------------------------------------------- * +;* ------------------------------------------------- * +;* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * +;* ------------------------------------------------- * +;* | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * +;* ------------------------------------------------- * +;* | x27 | x28 | FP | LR | * +;* ------------------------------------------------- * +;* ------------------------------------------------- * +;* | 40 | 41 | 42 | 43 | | | * +;* ------------------------------------------------- * +;* | 0xa0| 0xa4| 0xa8| 0xac| | | * +;* ------------------------------------------------- * +;* | PC | align | | | * +;* ------------------------------------------------- * +;* * +;******************************************************* + + AREA |.text|, CODE, READONLY, ALIGN=4, CODEALIGN + EXPORT ontop_fcontext + +ontop_fcontext proc BOOST_CONTEXT_EXPORT + ; prepare stack for GP + FPU + sub sp, sp, #0xb0 + + ; save d8 - d15 + stp d8, d9, [sp, #0x00] + stp d10, d11, [sp, #0x10] + stp d12, d13, [sp, #0x20] + stp d14, d15, [sp, #0x30] + + ; save x19-x30 + stp x19, x20, [sp, #0x40] + stp x21, x22, [sp, #0x50] + stp x23, x24, [sp, #0x60] + stp x25, x26, [sp, #0x70] + stp x27, x28, [sp, #0x80] + stp x29, x30, [sp, #0x90] + + ; save LR as PC + str x30, [sp, #0xa0] + + ; store RSP (pointing to context-data) in X5 + mov x4, sp + + ; restore RSP (pointing to context-data) from X1 + mov sp, x0 + + ; load d8 - d15 + ldp d8, d9, [sp, #0x00] + ldp d10, d11, [sp, #0x10] + ldp d12, d13, [sp, #0x20] + ldp d14, d15, [sp, #0x30] + + ; load x19-x30 + ldp x19, x20, [sp, #0x40] + ldp x21, x22, [sp, #0x50] + ldp x23, x24, [sp, #0x60] + ldp x25, x26, [sp, #0x70] + ldp x27, x28, [sp, #0x80] + ldp x29, x30, [sp, #0x90] + + ; return transfer_t from jump + ; pass transfer_t as first arg in context function + ; X0 == FCTX, X1 == DATA + mov x0, x4 + + ; skip pc + ; restore stack from GP + FPU + add sp, sp, #0xb0 + + ; jump to ontop-function + ret x2 + ENDP + END