1#ifndef COROUTINE_ARM64_CONTEXT_H
2#define COROUTINE_ARM64_CONTEXT_H 1
19#define COROUTINE __attribute__((noreturn)) void
20#define COROUTINE_DECL COROUTINE
22#define COROUTINE __declspec(noreturn) void
23#define COROUTINE_DECL void
27#define TEB_OFFSET 0x20
29#define TEB_OFFSET 0x00
32enum {COROUTINE_REGISTERS = (0xa0 + TEB_OFFSET) / 8};
34#if defined(__SANITIZE_ADDRESS__)
35 #define COROUTINE_SANITIZE_ADDRESS
36#elif defined(__has_feature)
37 #if __has_feature(address_sanitizer)
38 #define COROUTINE_SANITIZE_ADDRESS
42#if defined(COROUTINE_SANITIZE_ADDRESS)
43#include <sanitizer/common_interface_defs.h>
44#include <sanitizer/asan_interface.h>
52#if defined(COROUTINE_SANITIZE_ADDRESS)
62 context->stack_pointer = NULL;
65static inline void *ptrauth_sign_instruction_addr(
void *addr,
void *modifier) {
66#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT != 0
68 register void *r17 __asm(
"r17") = addr;
69 register void *r16 __asm(
"r16") = modifier;
71 __asm (
"hint #8;" :
"+r"(r17) :
"r"(r16));
79static inline void coroutine_initialize(
81 coroutine_start start,
85 assert(start && stack && size >= 1024);
87#if defined(COROUTINE_SANITIZE_ADDRESS)
88 context->fake_stack = NULL;
89 context->stack_base = stack;
90 context->stack_size = size;
94 char * top = (
char*)stack + size;
95 top = (
char *)((uintptr_t)top & ~0xF);
96 context->stack_pointer = (
void**)top;
98 context->stack_pointer -= COROUTINE_REGISTERS;
99 memset(context->stack_pointer, 0,
sizeof(
void*) * COROUTINE_REGISTERS);
101 void *addr = (
void*)(uintptr_t)start;
102 context->stack_pointer[(0x98 + TEB_OFFSET) / 8] = ptrauth_sign_instruction_addr(addr, (
void*)top);
105 context->stack_pointer[0x00 / 8] = (
char*)stack + size;
107 context->stack_pointer[0x08 / 8] = stack;
108 context->stack_pointer[0x10 / 8] = stack;