diff options
author | Yuta Saito <kateinoigakukun@gmail.com> | 2023-12-22 08:52:20 +0900 |
---|---|---|
committer | Yuta Saito <kateinoigakukun@gmail.com> | 2023-12-22 11:30:00 +0900 |
commit | fa0f7522c41bd2a71117b2428bc6fbb0bbcc9699 (patch) | |
tree | 98e38bfa4b03a2b39a2f139af66e7069bddf197e | |
parent | 2d004decde80566c5b004c5b832e8a1ab007965f (diff) |
coroutine/arm64: Skip saving/restoring x30 twice and use `autiasp`
We don't need to save/restore x30 twice, and we can just use `ret`,
which uses x30 as return address register instead of explicit `ret <reg>`
instruction. This also allows us to use `autiasp` instead of `autia1716`
and we can skip setting SP/LR to x16/x17.
Also the size of register save area is shrunk by 16 bytes due to the
removal of extra x30 save/restore.
-rw-r--r-- | coroutine/arm64/Context.S | 19 | ||||
-rw-r--r-- | coroutine/arm64/Context.h | 4 |
2 files changed, 8 insertions, 15 deletions
diff --git a/coroutine/arm64/Context.S b/coroutine/arm64/Context.S index cdcc6ca6dd..eeb0f774a3 100644 --- a/coroutine/arm64/Context.S +++ b/coroutine/arm64/Context.S @@ -36,7 +36,7 @@ PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer): hint #34 #endif # Make space on the stack for caller registers - sub sp, sp, 0xb0 + sub sp, sp, 0xa0 # Save caller registers stp d8, d9, [sp, 0x00] @@ -50,9 +50,6 @@ PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer): stp x27, x28, [sp, 0x80] stp x29, x30, [sp, 0x90] - # Save return address - str x30, [sp, 0xa0] - # Save stack pointer to x0 (first argument) mov x2, sp str x2, [x0, 0] @@ -73,20 +70,16 @@ PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer): ldp x27, x28, [sp, 0x80] ldp x29, x30, [sp, 0x90] - # Load return address into x17 - ldr x17, [sp, 0xa0] - # Pop stack frame - add sp, sp, 0xb0 + add sp, sp, 0xa0 #if defined(__ARM_FEATURE_PAC_DEFAULT) && (__ARM_FEATURE_PAC_DEFAULT != 0) - mov x16, sp - # autia1716 - hint #12 + # autiasp: Authenticate x30 (LR) with SP and key A + hint #29 #endif - # Jump to return address (in x17) - ret x17 + # Jump to return address (in x30) + ret #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/coroutine/arm64/Context.h b/coroutine/arm64/Context.h index 168ec18c4a..1819fa5be9 100644 --- a/coroutine/arm64/Context.h +++ b/coroutine/arm64/Context.h @@ -17,7 +17,7 @@ #define COROUTINE __attribute__((noreturn)) void -enum {COROUTINE_REGISTERS = 0xb0 / 8}; +enum {COROUTINE_REGISTERS = 0xa0 / 8}; #if defined(__SANITIZE_ADDRESS__) #define COROUTINE_SANITIZE_ADDRESS @@ -89,7 +89,7 @@ static inline void coroutine_initialize( context->stack_pointer -= COROUTINE_REGISTERS; memset(context->stack_pointer, 0, sizeof(void*) * COROUTINE_REGISTERS); - context->stack_pointer[0xa0 / 8] = ptrauth_sign_instruction_addr((void*)start, (void*)top); + context->stack_pointer[0x98 / 8] = ptrauth_sign_instruction_addr((void*)start, (void*)top); } struct coroutine_context * coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target); |