PageRenderTime 20ms CodeModel.GetById 8ms app.highlight 7ms RepoModel.GetById 2ms app.codeStats 0ms

/src/rt/arch/i386/context.cpp

http://github.com/jruderman/rust
C++ | 73 lines | 48 code | 17 blank | 8 comment | 1 complexity | af0b2bcaa4d23a78716b22e0e9b824d9 MD5 | raw file
 1
 2#include "context.h"
 3#include "../../rust_globals.h"
 4
 5extern "C" uint32_t CDECL swap_registers(registers_t *oregs,
 6                                         registers_t *regs)
 7  asm ("swap_registers");
 8
 9context::context()
10{
11    assert((void*)&regs == (void*)this);
12}
13
14void context::swap(context &out)
15{
16  swap_registers(&out.regs, &regs);
17}
18
19void context::call(void *f, void *arg, void *stack) {
20  // Get the current context, which we will then modify to call the
21  // given function.
22  swap(*this);
23
24  // set up the trampoline frame
25  uint32_t *sp = (uint32_t *)stack;
26
27  // Shift the stack pointer so the alignment works out right.
28  sp = align_down(sp) - 3;
29  *--sp = (uint32_t)arg;
30  // The final return address. 0 indicates the bottom of the stack
31  *--sp = 0;
32
33  regs.esp = (uint32_t)sp;
34  regs.eip = (uint32_t)f;
35
36  // Last base pointer on the stack should be 0
37  regs.ebp = 0;
38}
39
40#if 0
41// This is some useful code to check how the registers struct got
42// layed out in memory.
43int main() {
44  registers_t regs;
45
46  printf("Register offsets\n");
47
48#define REG(r) \
49  printf("  %6s: +%ld\n", #r, (intptr_t)&regs.r - (intptr_t)&regs);
50
51  REG(eax);
52  REG(ebx);
53  REG(ecx);
54  REG(edx);
55  REG(ebp);
56  REG(esi);
57  REG(edi);
58  REG(esp);
59
60  REG(cs);
61  REG(ds);
62  REG(ss);
63  REG(es);
64  REG(fs);
65  REG(gs);
66
67  REG(eflags);
68
69  REG(eip);
70
71  return 0;
72}
73#endif