diff options
Diffstat (limited to 'coroutine/amd64')
| -rw-r--r-- | coroutine/amd64/Context.S | 86 | ||||
| -rw-r--r-- | coroutine/amd64/Context.h | 37 |
2 files changed, 99 insertions, 24 deletions
diff --git a/coroutine/amd64/Context.S b/coroutine/amd64/Context.S index ac986b2aa5..4b94d31f30 100644 --- a/coroutine/amd64/Context.S +++ b/coroutine/amd64/Context.S @@ -2,45 +2,87 @@ ## This file is part of the "Coroutine" project and released under the MIT License. ## ## Created by Samuel Williams on 10/5/2018. -## Copyright, 2018, by Samuel Williams. All rights reserved. +## Copyright, 2018, by Samuel Williams. ## +/* Important - do _not_ include <cet.h> in this file; doing so will + * cause an incorrect .note.gnu.property section to be emitted. We have + * one at the bottom of this file */ + #define TOKEN_PASTE(x,y) x##y -#define PREFIXED_SYMBOL(prefix,name) TOKEN_PASTE(prefix,name) .text -.globl PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer) -PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer): +.globl PREFIXED_SYMBOL(coroutine_transfer) +PREFIXED_SYMBOL(coroutine_transfer): + +#if defined(__CET__) && (__CET__ & 0x01) != 0 + /* IBT landing pad */ + endbr64 +#endif + + # Make space on the stack for 6 registers: + subq $48, %rsp - # Save caller state - pushq %rbp - pushq %rbx - pushq %r12 - pushq %r13 - pushq %r14 - pushq %r15 + # Save caller state: + movq %rbp, 40(%rsp) + movq %rbx, 32(%rsp) + movq %r12, 24(%rsp) + movq %r13, 16(%rsp) + movq %r14, 8(%rsp) + movq %r15, (%rsp) - # Save caller stack pointer + # Save caller stack pointer: movq %rsp, (%rdi) - # Restore callee stack pointer + # Restore callee stack pointer: movq (%rsi), %rsp # Restore callee state - popq %r15 - popq %r14 - popq %r13 - popq %r12 - popq %rbx - popq %rbp - - # Put the first argument into the return value + movq 40(%rsp), %rbp + movq 32(%rsp), %rbx + movq 24(%rsp), %r12 + movq 16(%rsp), %r13 + movq 8(%rsp), %r14 + movq (%rsp), %r15 + + # Adjust stack pointer back: + addq $48, %rsp + + # Put the first argument into the return value: movq %rdi, %rax # We pop the return address and jump to it ret -#if defined(__linux__) && defined(__ELF__) +#if (defined(__linux__) || defined(__FreeBSD__)) && defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif + +#if defined(__ELF__) + +#if defined(__CET__) && (__CET__ & 0x01) != 0 +# define IBT_FLAG 0x01 +#else +# define IBT_FLAG 0x00 +#endif + +/* We do _NOT_ support CET shadow-stack. Do _not_ add the property for + * this to the Context.o object. If you require CET shadow-stack support, + * for now, consider building with --with-coroutine=ucontext */ +#define SHSTK_FLAG 0x00 + +.pushsection .note.gnu.property, "a" +.p2align 3 +.long 0x4 /* Name size ("GNU\0") */ +.long 0x10 /* Descriptor size */ +.long 0x5 /* Type: NT_GNU_PROPERTY_TYPE_0 */ +.asciz "GNU" /* Name */ +# Begin descriptor +.long 0xc0000002 /* Property type: GNU_PROPERTY_X86_FEATURE_1_AND */ +.long 0x4 /* Property size */ +.long (IBT_FLAG | SHSTK_FLAG) +.long 0x0 /* 8-byte alignment padding */ +/* End descriptor */ +.popsection +#endif diff --git a/coroutine/amd64/Context.h b/coroutine/amd64/Context.h index 8fe323c1a1..65aa638304 100644 --- a/coroutine/amd64/Context.h +++ b/coroutine/amd64/Context.h @@ -1,22 +1,47 @@ +#ifndef COROUTINE_AMD64_CONTEXT_H +#define COROUTINE_AMD64_CONTEXT_H 1 + /* * This file is part of the "Coroutine" project and released under the MIT License. * * Created by Samuel Williams on 10/5/2018. - * Copyright, 2018, by Samuel Williams. All rights reserved. + * Copyright, 2018, by Samuel Williams. */ #pragma once #include <assert.h> +#include <stddef.h> +#include <stdint.h> #include <string.h> #define COROUTINE __attribute__((noreturn)) void enum {COROUTINE_REGISTERS = 6}; +#if defined(__SANITIZE_ADDRESS__) + #define COROUTINE_SANITIZE_ADDRESS +#elif defined(__has_feature) + #if __has_feature(address_sanitizer) + #define COROUTINE_SANITIZE_ADDRESS + #endif +#endif + +#if defined(COROUTINE_SANITIZE_ADDRESS) +#include <sanitizer/common_interface_defs.h> +#include <sanitizer/asan_interface.h> +#endif + struct coroutine_context { void **stack_pointer; + void *argument; + +#if defined(COROUTINE_SANITIZE_ADDRESS) + void *fake_stack; + void *stack_base; + size_t stack_size; +#endif }; typedef COROUTINE(* coroutine_start)(struct coroutine_context *from, struct coroutine_context *self); @@ -33,12 +58,18 @@ static inline void coroutine_initialize( ) { assert(start && stack && size >= 1024); +#if defined(COROUTINE_SANITIZE_ADDRESS) + context->fake_stack = NULL; + context->stack_base = stack; + context->stack_size = size; +#endif + // Stack grows down. Force 16-byte alignment. char * top = (char*)stack + size; context->stack_pointer = (void**)((uintptr_t)top & ~0xF); *--context->stack_pointer = NULL; - *--context->stack_pointer = (void*)start; + *--context->stack_pointer = (void*)(uintptr_t)start; context->stack_pointer -= COROUTINE_REGISTERS; memset(context->stack_pointer, 0, sizeof(void*) * COROUTINE_REGISTERS); @@ -50,3 +81,5 @@ static inline void coroutine_destroy(struct coroutine_context * context) { context->stack_pointer = NULL; } + +#endif /* COROUTINE_AMD64_CONTEXT_H */ |
