int main(int argc, char * const argv[]) { // Save original stack ptr. long st_ptr; GetSP(st_ptr); // Move the stack ptr to where we want it. SetSP(MyStack + STACK_SZ); // Get address of MyStack. The address where we start // unprotecting is the nearest lowest page boundary address. // If MyStack spans a page boundary, protect two pages. long start = (long)MyStack; start = (start / PAGESIZE) * PAGESIZE; size_t amount = ((long)(MyStack + STACK_SZ)) - start; if(mprotect((void*)start, amount, PROT_READ|PROT_WRITE|PROT_EXEC) < 0) { perror("mprotect"); exit(1); } // This is definitely not malicious code. Nope, nothing to see here. // Carry on. get_input(); // Set the stack ptr back to the original location. SetSP(st_ptr); return 0; }
void lwp_start() { SAVE_STATE(); GetSP(original_stack_pointer); /* make sure we have threads to run */ if (lwp_procs == 0) { SetSP(original_stack_pointer); RESTORE_STATE(); /* dont do anything if we have no jobs */ return; } /* pick a proc */ setRunning(); /* switch to new stack */ SetSP(lwp_ptable[lwp_running].sp); RESTORE_STATE(); return; }
void lwp_yield() { /* push everything onto our stack */ SAVE_STATE(); /* save our stack pointer in our process table */ GetSP(lwp_ptable[lwp_running].sp); /* now we grab the new process */ setRunning(); SetSP(lwp_ptable[lwp_running].sp); RESTORE_STATE(); return; }
/* * lwp_exit * * we build */ void lwp_exit() { lwp_procs--; /* saved into global so we can access after sp changes */ stackToFree = lwp_ptable[lwp_running].stack; if (lwp_procs == 0) { SetSP(original_stack_pointer); /* free the stack of the last lwp */ freeStack(); lwp_stop(); } /* cleanup sets new running proc */ /* and it accounts for the missing proc */ cleanup(); /*SetSP(original_stack_pointer);*/ freeStack(); SetSP(lwp_ptable[lwp_running].sp); RESTORE_STATE(); return; }
void lwp_stop() { SAVE_STATE(); if (lwp_procs) { GetSP(lwp_ptable[lwp_running].sp); } else { /* oops no more procs */ RESTORE_STATE(); } /* get back to "system" stack */ SetSP(original_stack_pointer); RESTORE_STATE(); return; }
// Assuming pContext is a plain generic call-site, adjust it to look like // it called into TailCallHelperStub, and is at the point of the call. TailCallFrame * TailCallFrame::AdjustContextForTailCallHelperStub(CONTEXT * pContext, size_t cbNewArgArea, Thread * pThread) { TailCallFrame * pNewFrame = (TailCallFrame *) (GetSP(pContext) - sizeof(TailCallFrame)); // The return addres for the pseudo-call pContext->Lr = (DWORD_PTR)JIT_TailCallHelperStub_ReturnAddress; // The R11/ETW chain 'frame' pointer pContext->R11 = GetSP(pContext) - (2 * sizeof(DWORD)); // LR & R11 // The unwind data frame pointer pContext->R7 = pContext->R11 - (7 * sizeof(DWORD)); // r4-R10 non-volatile registers // for the args and the remainder of the FrameWithCookie<TailCallFrame> SetSP(pContext, (size_t) pNewFrame - (cbNewArgArea + sizeof(GSCookie))); // For popping the Frame, store the Thread pContext->R6 = (DWORD_PTR)pThread; // And the current head/top pContext->R5 = (DWORD_PTR)pThread->GetFrame(); return pNewFrame; }