• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "runtime/fibers/arch/asm_macros.h"
17#include "runtime/fibers/arch/amd64/context_layout.h"
18
19.extern abort
20
21LOCAL_FUNCTION_START(FiberExitBridge)
22    // indicate abnormal exit by calling exit(-1)
23    // because fibers should not return from FiberProc
24    // movq $-1, %rax
25    // call exit
26
27    // let's make the exit more violent than exit(-1) for now
28    // TODO(konstanting, #I67QXC): revert to exit() when everything is tested and works
29    call    abort@plt
30FUNCTION_END(FiberExitBridge)
31
32
33#define GPR_O(reg) FCTX_GPR_OFFSET_BYTES_ ## reg
34#define FP_O(reg) FCTX_FP_OFFSET_BYTES_ ## reg
35
36/**
37 * arguments:
38 * rdi: uint8_t* ctx_memory
39 * rsi: void (*func)(void*)
40 * rdx: void* argument
41 * rcx: uint8_t* stack
42 * r8:  size_t stack_size_bytes
43 */
44FUNCTION_START(UpdateContext)
45    // context->RIP = func
46    movq    %rsi, GPR_O(RIP)(%rdi)
47    // context->RDI = argument
48    movq    %rdx, GPR_O(RDI)(%rdi)
49
50    /**
51     * %rax will hold the new RSP value:
52     * NEW_RSP = align((stack + stack_size), 16B) - sizeof(trampoline_ptr)
53     */
54
55    // %rax = stack + stack_size_bytes
56    movq    %rcx, %rax
57    addq    %r8, %rax
58    // %rax = align(%rax, 16B) - 8B
59    andq    $-16, %rax
60    subq    $8, %rax
61    // context->RSP = %rax
62    movq    %rax, GPR_O(RSP)(%rdi)
63    // put FiberExitBridge as the return address for the FiberProc
64    leaq    FiberExitBridge(%rip), %r10
65    movq    %r10, (%rax)
66
67    // return success
68    xorq    %rax, %rax
69    ret
70FUNCTION_END(UpdateContext)
71
72/**
73 * arguments:
74 * rdi: uint8_t* ctx_memory
75 * rsi: void (*func)(void*)
76 * rdx: void* argument
77 */
78FUNCTION_START(UpdateContextKeepStack)
79    // (use %rax, %r10 as temporaries)
80    // %r10 = context->RIP
81    movq    GPR_O(RIP)(%rdi), %r10
82    // context->RIP = func
83    movq    %rsi, GPR_O(RIP)(%rdi)
84    // context->RDI = argument
85    movq    %rdx, GPR_O(RDI)(%rdi)
86
87    // pretend that we called the func(), i.e. push context's RIP to context's stack:
88    // %rax = context->RSP
89    movq    GPR_O(RSP)(%rdi), %rax
90    // %rax -= 8
91    subq    $8, %rax
92    // M[%rax] = %r10
93    movq    (%rax), %r10
94    // context->RSP = %rax
95    movq    %rax, GPR_O(RSP)(%rdi)
96
97    // return success
98    xorq    %rax, %rax
99    ret
100FUNCTION_END(UpdateContextKeepStack)
101
102#undef GPR_O
103#undef FP_O
104
105// we don't need executable stack.
106.section .note.GNU-stack,"",%progbits