Skip to content

Commit cd75c9c

Browse files
committed
rt: Implement part of the 64-bit __morestack
1 parent 92f1e9f commit cd75c9c

File tree

2 files changed

+57
-20
lines changed

2 files changed

+57
-20
lines changed

src/rt/arch/x86_64/morestack.S

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
// prolog when we run out.
77

88
#if defined(__APPLE__) || defined(_WIN32)
9-
#define RUST_NEW_STACK _rust_new_stack
9+
#define RUST_NEW_STACK2 _rust_new_stack2
1010
#define RUST_DEL_STACK _rust_del_stack
11+
#define UPCALL_CALL_C _upcall_call_shim_on_c_stack
1112
#define MORESTACK ___morestack
1213
#else
13-
#define RUST_NEW_STACK rust_new_stack
14+
#define RUST_NEW_STACK2 rust_new_stack2
1415
#define RUST_DEL_STACK rust_del_stack
16+
#define UPCALL_CALL_C upcall_call_shim_on_c_stack
1517
#define MORESTACK __morestack
1618
#endif
1719

@@ -28,31 +30,51 @@
2830
# define ARG2 %rdx
2931
#endif
3032

31-
.globl RUST_NEW_STACK
33+
.globl RUST_NEW_STACK2
3234
.globl RUST_DEL_STACK
33-
35+
.globl UPCALL_CALL_C
3436
.globl MORESTACK
3537

38+
#ifdef __ELF__
39+
.type MORESTACK,@function
40+
#endif
41+
3642
MORESTACK:
37-
// Hastily and probably incorrectly ported from i386 version.
38-
// Actually this calling convention doens't make so much sense
39-
// for x86_64...
40-
mov %rcx, ARG0 // param 0: amount of space needed
41-
mov %rdx, ARG2 // param 2: size of arguments
42-
lea 8(%rsp),ARG1
43-
call rust_new_stack_sym
43+
.cfi_startproc
44+
45+
# Set up a normal backtrace
46+
pushq %rbp
47+
.cfi_def_cfa_offset 16
48+
.cfi_offset %rbp, -16
49+
movq %rsp, %rbp
50+
.cfi_def_cfa_register %rbp
4451

52+
// Save argument registers
53+
pushq %rdi
54+
pushq %rsi
55+
pushq %rdx
56+
pushq %rcx
57+
pushq %r8
58+
pushq %r9
59+
60+
// Calculate the address of the stack arguments
61+
movq %rbp, %rcx
62+
addq $16, %rcx // Add the saved %rbp, and return address
63+
addq %r11, %rcx // Add the size of stack arguments
64+
65+
pushq %r10 // The amount of stack needed
66+
pushq %rcx // Address of stack arguments
67+
pushq %r11 // Size of stack arguments
68+
pushq %rbp // Save the Rust stack pointer
69+
70+
// FIXME: Don't understand why I have to use the PLT here
71+
lea RUST_NEW_STACK2@PLT(%rip), %rsi
72+
lea 24(%rsp), %rdi
73+
call UPCALL_CALL_C@PLT
74+
4575
mov (%rsp),%rdx // Grab the return pointer.
4676
inc %rdx // Skip past the `ret`.
4777
mov %rax,%rsp // Switch to the new stack.
4878
call *%rdx // Enter the new function.
4979

50-
// Now the function that called us has returned, so we need to delete the
51-
// old stack space.
52-
call rust_new_stack_sym
53-
mov %rax,%rsp // Switch back to the old stack.
54-
ret
55-
56-
// This is totally broken
57-
rust_new_stack_sym:
58-
rust_del_stack_sym:
80+
.cfi_endproc

src/rt/rust_task.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,21 @@ rust_new_stack(size_t stk_sz, void *args_addr, size_t args_sz,
8686
return new_sp;
8787
}
8888

89+
struct rust_new_stack2_args {
90+
size_t stk_sz;
91+
void *args_addr;
92+
size_t args_sz;
93+
uintptr_t current_sp;
94+
};
95+
96+
// A new stack function suitable for calling through
97+
// upcall_call_shim_on_c_stack
98+
extern "C" void *
99+
rust_new_stack2(struct rust_new_stack2_args *args) {
100+
return rust_new_stack(args->stk_sz, args->args_addr,
101+
args->args_sz, args->current_sp);
102+
}
103+
89104
extern "C" void
90105
rust_del_stack() {
91106
rust_task *task = rust_scheduler::get_task();

0 commit comments

Comments
 (0)