diff --git a/CMakeLists.txt b/CMakeLists.txt index bf5d954..811cd17 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -200,6 +200,8 @@ if (FUNCHOOK_CPU STREQUAL "arm64") if (MSVC) enable_language(ASM_MARMASM) set(FUNCHOOK_SOURCES ${FUNCHOOK_SOURCES} src/prehook-arm64-ms.asm) + elseif (APPLE) + set(FUNCHOOK_SOURCES ${FUNCHOOK_SOURCES} src/prehook-arm64-gas_mac.S) else () set(FUNCHOOK_SOURCES ${FUNCHOOK_SOURCES} src/prehook-arm64-gas.S) endif () diff --git a/src/prehook-arm64-gas_mac.S b/src/prehook-arm64-gas_mac.S new file mode 100644 index 0000000..dbdb717 --- /dev/null +++ b/src/prehook-arm64-gas_mac.S @@ -0,0 +1,85 @@ + .arch armv8-a + .text + .globl _funchook_hook_caller_asm + ; .type _funchook_hook_caller_asm, %function +_funchook_hook_caller_asm: + .cfi_startproc + // save frame pointer (x29) and link register (x30). + stp x29, x30, [sp, -0xe0]! + .cfi_def_cfa_offset 0xe0 + .cfi_offset 29, -0xe0 + .cfi_offset 30, -0xd8 + // set frame pointer + mov x29, sp + // save integer or pointer arguments passed in registers. + stp x0, x1, [sp, 0x10] + .cfi_offset 0, -0xd0 + .cfi_offset 1, -0xc8 + stp x2, x3, [sp, 0x20] + .cfi_offset 2, -0xc0 + .cfi_offset 3, -0xb8 + stp x4, x5, [sp, 0x30] + .cfi_offset 4, -0xb0 + .cfi_offset 5, -0xa8 + stp x6, x7, [sp, 0x40] + .cfi_offset 6, -0xa0 + .cfi_offset 7, -0x98 + // save indirect return value address and platform register. + stp x8, x18, [sp, 0x50] + .cfi_offset 8, -0x90 + .cfi_offset 18, -0x88 + // save floating-point registers used as arguments. + stp q0, q1, [sp, 0x60] + .cfi_offset q0, -0x80 + .cfi_offset q1, -0x70 + stp q2, q3, [sp, 0x80] + .cfi_offset q2, -0x60 + .cfi_offset q3, -0x50 + stp q4, q5, [sp, 0xa0] + .cfi_offset q4, -0x40 + .cfi_offset q5, -0x30 + stp q6, q7, [sp, 0xc0] + .cfi_offset q6, -0x20 + .cfi_offset q7, -0x10 + // 1st arg: the start address of transit. Note: x10 is set by transit-aarch64.s. + mov x0, x10 + // 2nd arg: frame pointer + mov x1, x29 + // call funchook_hook_caller + bl _funchook_hook_caller + mov x9, x0 + // restore registers + ldp x0, x1, [sp, 0x10] + .cfi_restore 0 + .cfi_restore 1 + ldp x2, x3, [sp, 0x20] + .cfi_restore 2 + .cfi_restore 3 + ldp x4, x5, [sp, 0x30] + .cfi_restore 4 + .cfi_restore 5 + ldp x6, x7, [sp, 0x40] + .cfi_restore 6 + .cfi_restore 7 + ldp x8, x18, [sp, 0x50] + .cfi_restore 8 + .cfi_restore 18 + ldp q0, q1, [sp, 0x60] + .cfi_restore q0 + .cfi_restore q1 + ldp q2, q3, [sp, 0x80] + .cfi_restore q2 + .cfi_restore q3 + ldp q4, q5, [sp, 0xa0] + .cfi_restore q4 + .cfi_restore q5 + ldp q6, q7, [sp, 0xc0] + .cfi_restore q6 + .cfi_restore q7 + ldp x29, x30, [sp], 0xe0 + .cfi_restore 29 + .cfi_restore 30 + .cfi_def_cfa_offset 0 + // jump to hook_func + br x9 + .cfi_endproc diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7d0f23b..c9e9056 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -27,14 +27,28 @@ if (FUNCHOOK_CPU STREQUAL x86) endif () -if (NOT MSVC) - set(FUNCHOOK_ASM_SUFFIX _gas.S) -elseif (FUNCHOOK_CPU MATCHES "^x86") - enable_language(ASM_MASM) - set(FUNCHOOK_ASM_SUFFIX _masm.asm) +# if (NOT MSVC) +# set(FUNCHOOK_ASM_SUFFIX _gas.S) +# elseif (FUNCHOOK_CPU MATCHES "^x86") +# enable_language(ASM_MASM) +# set(FUNCHOOK_ASM_SUFFIX _masm.asm) +# else () +# set(FUNCHOOK_CPU noasm) +# set(FUNCHOOK_ASM_SUFFIX .c) +# endif () + +if (MSVC) + if (FUNCHOOK_CPU MATCHES "^x86") + enable_language(ASM_MASM) + set(FUNCHOOK_ASM_SUFFIX _masm.asm) + else () + set(FUNCHOOK_CPU noasm) + set(FUNCHOOK_ASM_SUFFIX .c) + endif () +elseif (APPLE AND FUNCHOOK_CPU STREQUAL aarch64) + set(FUNCHOOK_ASM_SUFFIX _gas_mac.S) else () - set(FUNCHOOK_CPU noasm) - set(FUNCHOOK_ASM_SUFFIX .c) + set(FUNCHOOK_ASM_SUFFIX _gas.S) endif () add_library(funchook_test SHARED libfunchook_test.c libfunchook_test_cpp.cpp libfunchook_test_${FUNCHOOK_CPU}${FUNCHOOK_ASM_SUFFIX}) diff --git a/test/libfunchook_test_aarch64_gas_mac.S b/test/libfunchook_test_aarch64_gas_mac.S new file mode 100644 index 0000000..3655f21 --- /dev/null +++ b/test/libfunchook_test_aarch64_gas_mac.S @@ -0,0 +1,139 @@ + .arch armv8-a + .file "libfunchook_test_aarch64_gas_mac.S" + .text + .align 2 + .p2align 3,,7 + +test_data: + .8byte 0x1020304050607080, 0x0102030405060708 + +_call_get_val_in_dll: + .global _call_get_val_in_dll + ; .type call_get_val_in_dll, %function + stp x29, x30, [sp, -16]! + bl _get_val_in_dll + ldp x29, x30, [sp], 16 + ret + +_jump_get_val_in_dll: + .global _jump_get_val_in_dll + ; .type jump_get_val_in_dll, %function + b _get_val_in_dll + +_arm64_test_adr: + .global _arm64_test_adr + ; .type arm64_test_adr, %function + adr x9, test_data + ldr x9, [x9] + add x0, x0, x9 + ret + +_arm64_test_beq: + .global _arm64_test_beq + ; .type arm64_test_beq, %function + adds x0, x0, 1 + beq 1f + sub x0, x0, 2 +1: + ret + +_arm64_test_bne: + .global _arm64_test_bne + ; .type arm64_test_bne, %function + adds x0, x0, 1 + bne 1f + sub x0, x0, 2 +1: + ret + + +_arm64_test_cbnz: + .global _arm64_test_cbnz + ; .type arm64_test_cbnz, %function + cbnz x0, 1f + add x0, x0, 2 +1: + sub x0, x0, 1 + ret + +_arm64_test_cbz: + .global _arm64_test_cbz + ; .type arm64_test_cbz, %function + cbz x0, 1f + add x0, x0, 2 +1: + sub x0, x0, 1 + ret + +_arm64_test_ldr_w: + .global _arm64_test_ldr_w + ; .type arm64_test_ldr_w, %function + ldr w9, test_data + add x0, x0, x9 + ret + +_arm64_test_ldr_x: + .global _arm64_test_ldr_x + ; .type arm64_test_ldr_x, %function + ldr x9, test_data + add x0, x0, x9 + ret + +_arm64_test_ldr_s: + .global _arm64_test_ldr_s + ; .type arm64_test_ldr_s, %function + ldr s16, test_data + mov w9, v16.s[0] + add x0, x0, x9 + ret + +_arm64_test_ldr_d: + .global _arm64_test_ldr_d + ; .type arm64_test_ldr_d, %function + ldr d16, test_data + mov x9, v16.d[0] + add x0, x0, x9 + ret + +_arm64_test_ldr_q: + .global _arm64_test_ldr_q + ; .type arm64_test_ldr_q, %function + ldr q16, test_data + mov x9, v16.d[0] + add x0, x0, x9 + mov x9, v16.d[1] + add x0, x0, x9 + ret + +_arm64_test_prfm: + .global _arm64_test_prfm + ; .type arm64_test_prfm, %function + prfm pldl1keep, test_data + ldr x9, test_data + add x0, x0, x9 + ret + +_arm64_test_ldrsw: + .global _arm64_test_ldrsw + ; .type arm64_test_ldrsw, %function + ldrsw x9, 1f + add x0, x0, x9 + ret + +_arm64_test_tbnz: + .global _arm64_test_tbnz + ; .type arm64_test_tbnz, %function + tbnz x0, 32, 1f + add x0, x0, 2 +1: + sub x0, x0, 1 + ret + +_arm64_test_tbz: + .global _arm64_test_tbz + ; .type arm64_test_tbz, %function + tbz x0, 32, 1f + add x0, x0, 2 +1: + sub x0, x0, 1 + ret