summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuta Saito <kateinoigakukun@gmail.com>2023-12-22 08:52:20 +0900
committerYuta Saito <kateinoigakukun@gmail.com>2023-12-22 11:30:00 +0900
commitfa0f7522c41bd2a71117b2428bc6fbb0bbcc9699 (patch)
tree98e38bfa4b03a2b39a2f139af66e7069bddf197e
parent2d004decde80566c5b004c5b832e8a1ab007965f (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.S19
-rw-r--r--coroutine/arm64/Context.h4
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);