1#ifndef COROUTINE_ARM64_CONTEXT_H
2#define COROUTINE_ARM64_CONTEXT_H 1
18#define COROUTINE __attribute__((noreturn)) void
20enum {COROUTINE_REGISTERS = 0xa0 / 8};
22#if defined(__SANITIZE_ADDRESS__)
23 #define COROUTINE_SANITIZE_ADDRESS
24#elif defined(__has_feature)
25 #if __has_feature(address_sanitizer)
26 #define COROUTINE_SANITIZE_ADDRESS
30#if defined(COROUTINE_SANITIZE_ADDRESS)
31#include <sanitizer/common_interface_defs.h>
32#include <sanitizer/asan_interface.h>
40#if defined(COROUTINE_SANITIZE_ADDRESS)
50 context->stack_pointer = NULL;
53#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT != 0
55static inline void *ptrauth_sign_instruction_addr(
void *addr,
void *modifier) {
56 register void *r17 __asm(
"r17") = addr;
57 register void *r16 __asm(
"r16") = modifier;
59 asm (
"hint #8;" :
"+r"(r17) :
"r"(r16));
65static inline void *ptrauth_sign_instruction_addr(
void *addr,
void *modifier) {
70static inline void coroutine_initialize(
72 coroutine_start start,
76 assert(start && stack && size >= 1024);
78#if defined(COROUTINE_SANITIZE_ADDRESS)
79 context->fake_stack = NULL;
80 context->stack_base = stack;
81 context->stack_size = size;
85 char * top = (
char*)stack + size;
86 top = (
char *)((uintptr_t)top & ~0xF);
87 context->stack_pointer = (
void**)top;
89 context->stack_pointer -= COROUTINE_REGISTERS;
90 memset(context->stack_pointer, 0,
sizeof(
void*) * COROUTINE_REGISTERS);
92 context->stack_pointer[0x98 / 8] = ptrauth_sign_instruction_addr((
void*)start, (
void*)top);