Skip to content
This repository has been archived by the owner on Mar 24, 2022. It is now read-only.

Commit

Permalink
[lucet-runtime-internals] terminate the stack correctly
Browse files Browse the repository at this point in the history
This places the pointers to the parent and child contexts _above_ the two zero words used to
terminate the call stack. This is the location where memory arguments are expected, which isn't
completely relevant since `lucet_context_backstop` is written in assembly, but it at least prevents
gdb and other unwinding tools from mistaking the pointers for return addresses.
  • Loading branch information
acfoltzer committed Jul 17, 2019
1 parent bc8aaef commit 9389a4c
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ _lucet_context_bootstrap:
.align 16
lucet_context_backstop:
_lucet_context_backstop:
mov -16(%rbp), %rdi /* parent context to arg 1 */
mov -8(%rbp), %rsi /* own context to arg 2 */
mov 16(%rbp), %rdi /* parent context to arg 1 */
mov 24(%rbp), %rsi /* own context to arg 2 */
mov %rax, (8*8 + 8*16 + 8*0)(%rdi) /* store return values before swapping back -- offset is offsetof(struct lucet_context, retvals) */
mov %rdx, (8*8 + 8*16 + 8*1)(%rdi)
movdqu %xmm0, (8*8 + 8*16 + 8*2)(%rdi) /* floating-point return value */
Expand Down
13 changes: 7 additions & 6 deletions lucet-runtime/lucet-runtime-internals/src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,22 +348,23 @@ impl Context {
// the guest function returns into lucet_context_backstop.
stack[sp + 2 - stack_start] = lucet_context_backstop as u64;

// Terminate the call chain.
stack[sp - 4] = 0;
stack[sp - 3] = 0;

// if fptr ever returns, it returns to the backstop func. backstop needs two arguments in
// its frame - first the context we are switching *out of* (which is also the one we are
// creating right now) and the ctx we switch back into. Note *parent might not be a valid
// ctx now, but it should be when this ctx is started.
stack[sp - 4] = child as *mut Context as u64;
stack[sp - 3] = parent as *mut Context as u64;
// Terminate the call chain.
stack[sp - 2] = 0;
stack[sp - 1] = 0;
stack[sp - 2] = child as *mut Context as u64;
stack[sp - 1] = parent as *mut Context as u64;

// RSP, RBP, and sigset still remain to be initialized.
// Stack pointer: this has the return address of the first function to be run on the swap.
child.gpr.rsp = &mut stack[sp - stack_start] as *mut u64 as u64;
// Frame pointer: this is only used by the backstop code. It uses it to locate the ctx and
// parent arguments set above.
child.gpr.rbp = &mut stack[sp - 2] as *mut u64 as u64;
child.gpr.rbp = &mut stack[sp - 4] as *mut u64 as u64;

// Read the sigprocmask to be restored if we ever need to jump out of a signal handler. If
// this isn't possible, die.
Expand Down

0 comments on commit 9389a4c

Please sign in to comment.