Change the setup so that rust_activate_glue returns to rust_exit_task_glue
and rust_exit_task_glue calls the rust main. This is simpler since we only need to setup one frame. It also matches what ld.so does, so gdb is happy and stops a backtrace at rust_exit_task_glue instead of continuing past whatever function happened to be before rust_exit_task_glue is the object file. This is the rt part and should be merged after the rust0 part.
This commit is contained in:
committed by
Graydon Hoare
parent
d85260bcc5
commit
d6deeffd95
@@ -254,9 +254,9 @@ rust_task::start_rustboot(uintptr_t exit_task_glue,
|
|||||||
|
|
||||||
void
|
void
|
||||||
rust_task::start_rustc(uintptr_t exit_task_glue,
|
rust_task::start_rustc(uintptr_t exit_task_glue,
|
||||||
uintptr_t spawnee_fn,
|
uintptr_t spawnee_fn,
|
||||||
uintptr_t args,
|
uintptr_t args,
|
||||||
size_t callsz)
|
size_t callsz)
|
||||||
{
|
{
|
||||||
LOGPTR(dom, "exit-task glue", exit_task_glue);
|
LOGPTR(dom, "exit-task glue", exit_task_glue);
|
||||||
LOGPTR(dom, "from spawnee", spawnee_fn);
|
LOGPTR(dom, "from spawnee", spawnee_fn);
|
||||||
@@ -271,27 +271,18 @@ rust_task::start_rustc(uintptr_t exit_task_glue,
|
|||||||
// see: "Mac OS X ABI Function Call Guide"
|
// see: "Mac OS X ABI Function Call Guide"
|
||||||
|
|
||||||
|
|
||||||
// Begin synthesizing frames. There are two: a "fully formed"
|
// Begin synthesizing the exit_task_glue frame. We will return to
|
||||||
// exit-task frame at the top of the stack -- that pretends to be
|
// exit_task_glue and it is responsible for calling the user code
|
||||||
// mid-execution -- and a just-starting frame beneath it that
|
// and passing the value returned by the user to the system
|
||||||
// starts executing the first instruction of the spawnee. The
|
// exit routine.
|
||||||
// spawnee *thinks* it was called by the exit-task frame above
|
|
||||||
// it. It wasn't; we put that fake frame in place here, but the
|
|
||||||
// illusion is enough for the spawnee to return to the exit-task
|
|
||||||
// frame when it's done, and exit.
|
|
||||||
uintptr_t *spp = (uintptr_t *)rust_sp;
|
uintptr_t *spp = (uintptr_t *)rust_sp;
|
||||||
|
|
||||||
|
uintptr_t dummy_ret = (uintptr_t) spp--;
|
||||||
|
|
||||||
// The exit_task_glue frame we synthesize above the frame we activate:
|
uintptr_t args_size = callsz - 3*sizeof(uintptr_t);
|
||||||
make_aligned_room_for_bytes(spp, 2 * sizeof(uintptr_t));
|
uintptr_t frame_size = args_size + 4*sizeof(uintptr_t);
|
||||||
*spp-- = (uintptr_t) 0; // closure-or-obj
|
|
||||||
*spp-- = (uintptr_t) this; // task
|
|
||||||
I(dom, spp == align_down(spp));
|
|
||||||
*spp-- = (uintptr_t) 0x0; // output
|
|
||||||
*spp-- = (uintptr_t) 0x0; // retpc
|
|
||||||
|
|
||||||
I(dom, args);
|
make_aligned_room_for_bytes(spp, frame_size);
|
||||||
make_aligned_room_for_bytes(spp, callsz - 3 * sizeof(uintptr_t));
|
|
||||||
|
|
||||||
// Copy args from spawner to spawnee.
|
// Copy args from spawner to spawnee.
|
||||||
uintptr_t *src = (uintptr_t *)args;
|
uintptr_t *src = (uintptr_t *)args;
|
||||||
@@ -299,29 +290,19 @@ rust_task::start_rustc(uintptr_t exit_task_glue,
|
|||||||
src += 1; // spawn-call task slot
|
src += 1; // spawn-call task slot
|
||||||
src += 1; // spawn-call closure-or-obj slot
|
src += 1; // spawn-call closure-or-obj slot
|
||||||
|
|
||||||
// Undo previous sp-- so we're pointing at the last word pushed.
|
*spp-- = (uintptr_t) *src; // vec
|
||||||
++spp;
|
*spp-- = (uintptr_t) 0x0; // closure-or-obj
|
||||||
|
*spp-- = (uintptr_t) this; // task
|
||||||
|
*spp-- = (uintptr_t) dummy_ret; // output address
|
||||||
|
|
||||||
// Memcpy all but the task, output and env pointers
|
*spp-- = (uintptr_t) (uintptr_t) spawnee_fn;
|
||||||
callsz -= (3 * sizeof(uintptr_t));
|
|
||||||
spp = (uintptr_t*) (((uintptr_t)spp) - callsz);
|
|
||||||
memcpy(spp, src, callsz);
|
|
||||||
|
|
||||||
// Move sp down to point to last implicit-arg cell (env).
|
I(dom, spp == align_down(spp));
|
||||||
spp--;
|
|
||||||
|
|
||||||
// The *implicit* incoming args to the spawnee frame we're
|
*spp-- = (uintptr_t) 0x0; // retp
|
||||||
// activating:
|
|
||||||
*spp-- = (uintptr_t) 0x0; // closure-or-obj
|
|
||||||
|
|
||||||
// in FASTCALL mode we don't, the outptr will be in ecx and the task
|
*spp-- = (uintptr_t) exit_task_glue;
|
||||||
// in edx, and the activate_glue will make sure to set that up.
|
|
||||||
|
|
||||||
I(dom, spp+1 == align_down(spp+1));
|
|
||||||
*spp-- = (uintptr_t) exit_task_glue; // retpc
|
|
||||||
|
|
||||||
// The context the activate_glue needs to switch stack.
|
|
||||||
*spp-- = (uintptr_t) spawnee_fn; // instruction to start at
|
|
||||||
for (size_t j = 0; j < n_callee_saves; ++j) {
|
for (size_t j = 0; j < n_callee_saves; ++j) {
|
||||||
*spp-- = (uintptr_t)NULL;
|
*spp-- = (uintptr_t)NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user