GitLab will be upgraded on June 2nd 2020 at 2.00 pm (AEDT) to 3.00 pm (AEDT) due to Critical Security Patch Availability. During the update, GitLab and Mattermost services will not be available. If you have any concerns with this, please talk to local Gitlab admin team.

swap_stack_x64_sysv.S 3.34 KB
Newer Older
Kunshan Wang's avatar
Kunshan Wang committed
1 2
#include "asm_common.S.inc"

3 4
# swap_stack_to(new_sp: Address, entry: Address, old_sp_loc: Address)
#               %rdi             %rsi            %rdx
Kunshan Wang's avatar
Kunshan Wang committed
5
begin_func swap_to_mu_stack
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
          # -- on old stack --
          # C calling convention
          pushq %rbp
          movq %rsp, %rbp

          # other callee-saved registers
          pushq %rbx
          pushq %r12
          pushq %r13
          pushq %r14
          pushq %r15

          # save sp to %rbx
          movq %rsp, 0(%rdx)

          # switch to new stack
          movq %rdi, %rsp
          # save entry function in %rax
          movq %rsi, %rax

          # -- on new stack --
          # arguments (reverse order of thread.rs - runtime_load_args)
          popq %r9
          popq %r8
          popq %rcx
          popq %rdx
          popq %rsi
          popq %rdi
          movsd 0(%rsp), %xmm7
          movsd 8(%rsp), %xmm6
          movsd 16(%rsp), %xmm5
          movsd 24(%rsp), %xmm4
          movsd 32(%rsp), %xmm3
          movsd 40(%rsp), %xmm2
          add $48, %rsp
          # at this point new stack is clean (no intermediate values)

          movq %rsp, %rbp

          # push an empty pointer to stack, if entry fucntion tries to return, it causes a segfault
          pushq $0
          # push entry function and start it
          pushq %rax
          ret
Kunshan Wang's avatar
Kunshan Wang committed
50
end_func swap_to_mu_stack
51 52 53

# _swap_back_to_native_stack(sp_loc: Address)
#                            %rdi
Kunshan Wang's avatar
Kunshan Wang committed
54
begin_func muentry_swap_back_to_native_stack
55 56 57 58 59 60 61 62 63 64
          movq 0(%rdi), %rsp

          popq %r15
          popq %r14
          popq %r13
          popq %r12
          popq %rbx

          popq %rbp
          ret
Kunshan Wang's avatar
Kunshan Wang committed
65
end_func muentry_swap_back_to_native_stack
66 67

# _get_current_frame_rbp() -> Address
Kunshan Wang's avatar
Kunshan Wang committed
68
begin_func get_current_frame_rbp
69 70
          movq %rbp, %rax
          ret
Kunshan Wang's avatar
Kunshan Wang committed
71
end_func get_current_frame_rbp
qinsoon's avatar
qinsoon committed
72

73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
# muentry_throw_exception(obj: Address)
#                         %rdi
begin_func muentry_throw_exception
         # save all callee-saved
         pushq %r15
         pushq %r14
         pushq %r13
         pushq %r12
         pushq %rbp
         pushq %rbx

         # %rsp points to %rbx, pass this as 2nd argument
         movq  %rsp, %rsi

         jmp CNAME(throw_exception_internal)
         # won't return

qinsoon's avatar
qinsoon committed
90
# _exception_restore(dest: Address, callee_saved: *const Word, rsp: Address) -> !
91
#                    %rdi           %rsi                       %rdx
qinsoon's avatar
qinsoon committed
92
# callee_saved: [rbx, rbp, r12, r13, r14, r15]
Kunshan Wang's avatar
Kunshan Wang committed
93
begin_func exception_restore
qinsoon's avatar
qinsoon committed
94 95 96 97 98 99 100 101 102
          movq 0(%rsi), %rbx
          movq 8(%rsi), %rbp
          movq 16(%rsi),%r12
          movq 24(%rsi),%r13
          movq 32(%rsi),%r14
          movq 40(%rsi),%r15

          movq %rdx, %rsp
          jmpq *%rdi
Kunshan Wang's avatar
Kunshan Wang committed
103
end_func exception_restore
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130

# fake_swap_mu_thread(old_sp_loc: Address)
#                     %rdi
# (we do not actually swap stack, but we make the stack the same
# as if they are native stack that have been swapped out, so that
# when THREADEXIT (swap_back_to_native_stack) is called, we won't panic

# this function is untested!!!
begin_func fake_swap_mu_thread
    # save return address
    movq (%rsp), %rax

    pushq %rbp
    movq %rsp, %rbp

    pushq %rbx
    pushq %r12
    pushq %r13
    pushq %r14
    pushq %r15

    # save old sp to thread field
    movq %rsp, 0(%rdi)

    # return to caller, but preserve those pushed values (since THREADEXIT will pick them up)
    pushq %rax
    ret