/src/rt/arch/i386/context.cpp
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*)®s == (void*)this); 12} 13 14void context::swap(context &out) 15{ 16 swap_registers(&out.regs, ®s); 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)®s.r - (intptr_t)®s); 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