//set the JMP void JMP::set(int type, intptr_t val) { if (type == TCONSTANT || type == TINSTRUCTION || type == TINSTRUCTIONRELATIVE) setjump(type, val, "\xEB", "\xE9"); else if (type == TREG32 || type == TDWORDPTR) setregptr(type, val, "\xFF", "", "", 0x20); else if (isdataptr(type)) setdataptr(type, val); }
//set a jump instruction using the given bytes void AssemblyInstruction::setjump(int type, intptr_t val, string ocsmall, string oclarge) { if (type == TCONSTANT) { if (val >= -128 && val <= 127) bytes.assign(ocsmall).append(1, (char)(val)); else bytes.assign(oclarge).append(to4bytes(val)); } else if (type == TINSTRUCTION) { setjump(TCONSTANT, 0, ocsmall, oclarge); tag = TAGJMPINSTRUCTIONSHORT; tag2 = val; } else if (type == TINSTRUCTIONRELATIVE) { setjump(TCONSTANT, 0, ocsmall, oclarge); tag = TAGJMPINSTRUCTIONSHORTRELATIVE; tag2 = val; } }
void dwthread_yield() { /* * 1. save the context of caller */ // we do this before all other works // to keep registers untouched volatile dwt_reg_t eax, ebx, ecx, edx, esi, edi; __asm__("movl %%eax, %0\n\t" "movl %%ebx, %1\n\t" "movl %%ecx, %2\n\t" "movl %%edx, %3\n\t" "movl %%esi, %4\n\t" "movl %%edi, %5\n\t" :"=m"(eax), "=m"(ebx), "=m"(ecx), "=m"(edx), "=m"(esi), "=m"(edi)); dwt_tid_t cur_tid = dwthread_get_tid(); dwt_task_t *cur_task = dw_find(cur_tid); // TODO: for the first task, init its task_t if (cur_task == NULL) { cur_task = malloc(sizeof(dwt_task_t)); cur_task->tid = current_tid; cur_task->statue = DWT_STATUE_RUNNING; dw_inqueue(cur_task); } /* * 2. set jump and schedule() */ if (setjump(&cur_task->context.jmp_restorer) == 0) { schedule(); }else { // long jump from schedule(), run the task // restore registers __asm__("movl %0, %%eax\n\t" "movl %1, %%ebx\n\t" "movl %2, %%ecx\n\t" "movl %3, %%edx\n\t" "movl %4, %%esi\n\t" "movl %5, %%edi\n\t" ::"m"(eax), "m"(ebx), "m"(ecx), "m"(edx), "m"(esi), "m"(edi)); } return; }
//set the JGE void JGE::set(int type, intptr_t val) { setjump(type, val, "\x7D", "\x0F\x8D"); }
//set the JG void JG::set(int type, intptr_t val) { setjump(type, val, "\x7F", "\x0F\x8F"); }
//set the JLE void JLE::set(int type, intptr_t val) { setjump(type, val, "\x7E", "\x0F\x8E"); }
//set the JL void JL::set(int type, intptr_t val) { setjump(type, val, "\x7C", "\x0F\x8C"); }
//set the JNE void JNE::set(int type, intptr_t val) { setjump(type, val, "\x75", "\x0F\x85"); }
//set the JE void JE::set(int type, intptr_t val) { setjump(type, val, "\x74", "\x0F\x84"); }