/* * Description: * Calls fetch and dispatches an instruction at the same cycle (if possible) * Inputs: * trace: instruction trace with all the instructions executed * current_cycle: the cycle we are at * Returns: * None */ void fetch_To_dispatch(instruction_trace_t* trace, int current_cycle) { /* ECE552: YOUR CODE GOES HERE */ /* ECE552 Assignment 3 - BEGIN CODE */ if(instr_queue_size < INSTR_QUEUE_SIZE && fetch_index <= sim_num_insn){ instruction_t *currInstr = get_instr(trace, fetch_index); while(currInstr && (IS_TRAP(currInstr->op))){ fetch_index++; currInstr = get_instr(trace, fetch_index); } if(currInstr){ currInstr->tom_dispatch_cycle = current_cycle; fetch(trace); } } //Resolve target and source operand dependence //Set map table of r_out to tag which reservation //station will produce the result if(instr_front() && USES_FP_FU(instr_front()->op)){ int i; for(i = 0; i < RESERV_FP_SIZE; i++){ if(!reservFP[i]){ reservFP[i] = instr_front(); //Make sure we mark the existing raw dependences //BEFORE updating the map table with my target regs markRAWDependence(reservFP[i]); updateMapTable(reservFP[i]); instr_pop(); break; } } } else if(instr_front() && (USES_INT_FU(instr_front()->op) || instr_front()->op == 0)){ int i; for(i = 0; i < RESERV_INT_SIZE; i++){ if(!reservINT[i]){ reservINT[i] = instr_front(); markRAWDependence(reservINT[i]); updateMapTable(reservINT[i]); instr_pop(); break; } } } else if(instr_front() && (IS_COND_CTRL(instr_front()->op) || IS_UNCOND_CTRL(instr_front()->op))) { instr_pop(); } return; /* ECE552 Assignment 3 - END CODE */ }
/* * The function looks through the trace and finds the next non trap instruction. */ instruction_t* get_next_non_trap_instr (instruction_trace_t* trace) { instruction_t* ret = NULL; while (fetch_index <= 1000000 && IS_TRAP(get_instr(trace, fetch_index)->op)) { fetch_index++; } if (fetch_index <= 1000000) { ret = get_instr(trace, fetch_index); } return ret; }
int main() { while(scanf("%s",mem),mem[0]!='8'){ A = B = 0; ip = 0; while(get_instr(),instr!=8){ switch(instr){ case 0:f0(); break; case 1:f1(); break; case 2:f2(); break; case 3:f3(); break; case 4:f4(); break; case 5:f5(); break; case 6:f6(); break; case 7:f7(); break; } } printf("%s\n",mem); } return 0; }
/* * Write an ASCII disassembly of one instruction at "pc" * in "RAM" into "line" (max length "max_line"), return * number of bytes consumed. */ int arch_pdp11_disasm_instr(cpu_t *cpu, addr_t pc, char *line, unsigned int max_line) { uint16_t opcode = cpu->RAM[pc]; char line2[8]; int addmode = get_addmode(opcode); if (addmode == ADDMODE_BRA) { snprintf(line2, sizeof(line2), "$%02" PRIX64, pc+2 + (int8_t)cpu->RAM[pc+1]); } else { switch (get_length(addmode)) { case 1: snprintf(line2, sizeof(line2), addmode_template[addmode], 0); break; case 2: snprintf(line2, sizeof(line2), addmode_template[addmode], cpu->RAM[pc+1]); break; case 3: snprintf(line2, sizeof(line2), addmode_template[addmode], cpu->RAM[pc+1] | cpu->RAM[pc+2]<<8); break; default: printf("Table error at %s:%d\n", __FILE__, __LINE__); exit(1); } } snprintf(line, max_line, "%s %s", mnemo[get_instr(opcode)], line2); return get_length(get_addmode(cpu->RAM[pc])); }
/* * Description: * Grabs an instruction from the instruction trace (if possible) * Inputs: * trace: instruction trace with all the instructions executed * Returns: * None */ void fetch(instruction_trace_t* trace) { /* ECE552: YOUR CODE GOES HERE */ /* ECE552 Assignment 3 - BEGIN CODE */ //I have valid index instruction_t *currInstr = get_instr(trace, fetch_index); instr_push(currInstr); fetch_index++; //REMOVE THIS BEFORE SUBMISSION /* ECE552 Assignment 3 - END CODE */ }
int execute_instruction(ARCH arch, uint word) { int c; if ((c = get_instr(word)) == NO_MATCH) return NO_MATCH; DESC_ARRAY[c].execute(arch, word); return MATCH; }
int display_instruction(ARCH arch, uint word, FILE* stream) { int c; if ((c = get_instr(word)) == NO_MATCH) return NO_MATCH; DESC_ARRAY[c].display(word, stream, arch); return MATCH; }
Value * arch_pdp11_translate_cond(cpu_t *cpu, addr_t pc, BasicBlock *bb) { uint16_t opcode = cpu->RAM[pc]; LOG("%s:%d pc=%" PRIx64 " opcode=%x\n", __func__, __LINE__, pc, opcode); switch (get_instr(opcode)) { // Sort it out. case INSTR_BEQ: /* Z */ return CC_EQ; case INSTR_BNE: /* !Z */ return CC_NE; case INSTR_BCS: /* C */ return CC_CS; case INSTR_BCC: /* !C */ return CC_CC; case INSTR_BMI: /* N */ return CC_MI; case INSTR_BPL: /* !N */ return CC_PL; case INSTR_BVS: /* V */ return CC_VS; case INSTR_BVC: /* !V */ return CC_VC; default: return NULL; /* no condition; should not be reached */ } }
int arch_6502_tag_instr(cpu_t *cpu, addr_t pc, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { uint8_t opcode = cpu->RAM[pc]; switch (get_instr(opcode)) { case INSTR_BRK: *tag = TAG_TRAP; break; case INSTR_RTS: *tag = TAG_RET; break; case INSTR_JMP: if (get_addmode(opcode) == ADDMODE_ABS) *new_pc = cpu->RAM[pc+1] | cpu->RAM[pc+2]<<8; else *new_pc = NEW_PC_NONE; /* jmp indirect */ *tag = TAG_BRANCH; break; case INSTR_JSR: *new_pc = cpu->RAM[pc+1] | cpu->RAM[pc+2]<<8; *tag = TAG_CALL; break; case INSTR_BCC: case INSTR_BCS: case INSTR_BEQ: case INSTR_BMI: case INSTR_BNE: case INSTR_BPL: case INSTR_BVC: case INSTR_BVS: *new_pc = pc+2 + (int8_t)cpu->RAM[pc+1]; *tag = TAG_COND_BRANCH; break; default: //XXX only known instrunctions should be TAG_CONTINUE, //XXX all others should be TAG_TRAP *tag = TAG_CONTINUE; break; } int length = get_length(get_addmode(opcode)); *next_pc = pc + length; return length; }
int arch_pdp11_translate_instr(cpu_t *cpu, addr_t pc, BasicBlock *bb) { uint16_t opcode = cpu->RAM[pc]; //LOG("%s:%d PC=$%04X\n", __func__, __LINE__, pc); switch (get_instr(opcode)) { /* flags */ case INSTR_CLC: LET1(cpu->ptr_C, FALSE); break; case INSTR_CLD: LET1(ptr_D, FALSE); break; case INSTR_CLI: LET1(ptr_I, FALSE); break; case INSTR_CLV: LET1(cpu->ptr_V, FALSE); break; case INSTR_SEC: LET1(cpu->ptr_C, TRUE); break; case INSTR_SED: LET1(ptr_D, TRUE); break; case INSTR_SEI: LET1(ptr_I, TRUE); break; /* register transfer */ case INSTR_TAX: SET_NZ(LET(X,R(A))); break; case INSTR_TAY: SET_NZ(LET(Y,R(A))); break; case INSTR_TXA: SET_NZ(LET(A,R(X))); break; case INSTR_TYA: SET_NZ(LET(A,R(Y))); break; case INSTR_TSX: SET_NZ(LET(X,R(S))); break; case INSTR_TXS: SET_NZ(LET(S,R(X))); break; /* load */ case INSTR_LDA: SET_NZ(LET(A,OPERAND)); break; case INSTR_LDX: SET_NZ(LET(X,OPERAND)); break; case INSTR_LDY: SET_NZ(LET(Y,OPERAND)); break; /* store */ case INSTR_STA: STORE(R(A),LOPERAND); break; case INSTR_STX: STORE(R(X),LOPERAND); break; case INSTR_STY: STORE(R(Y),LOPERAND); break; /* stack */ case INSTR_PHA: PUSH(R(A)); break; case INSTR_PHP: PUSH(arch_flags_encode(cpu, bb)); break; case INSTR_PLA: SET_NZ(LET(A,PULL)); break; case INSTR_PLP: arch_flags_decode(cpu, PULL, bb); break; /* shift */ case INSTR_ASL: SET_NZ(SHIFTROTATE(LOPERAND, LOPERAND, true, false)); break; case INSTR_LSR: SET_NZ(SHIFTROTATE(LOPERAND, LOPERAND, false, false)); break; case INSTR_ROL: SET_NZ(SHIFTROTATE(LOPERAND, LOPERAND, true, true)); break; case INSTR_ROR: SET_NZ(SHIFTROTATE(LOPERAND, LOPERAND, false, true)); break; /* bit logic */ case INSTR_AND: SET_NZ(LET(A,AND(R(A),OPERAND))); break; case INSTR_ORA: SET_NZ(LET(A,OR(R(A),OPERAND))); break; case INSTR_EOR: SET_NZ(LET(A,XOR(R(A),OPERAND))); break; case INSTR_BIT: SET_NZ(OPERAND); break; /* arithmetic */ case INSTR_ADC: SET_NZ(ADC(ptr_A, ptr_A, OPERAND, true, false)); break; case INSTR_SBC: SET_NZ(ADC(ptr_A, ptr_A, COM(OPERAND), true, false)); break; case INSTR_CMP: SET_NZ(ADC(NULL, ptr_A, COM(OPERAND), false, true)); break; case INSTR_CPX: SET_NZ(ADC(NULL, ptr_X, COM(OPERAND), false, true)); break; case INSTR_CPY: SET_NZ(ADC(NULL, ptr_Y, COM(OPERAND), false, true)); break; /* increment/decrement */ case INSTR_INX: SET_NZ(LET(X,INC(R(X)))); break; case INSTR_INY: SET_NZ(LET(Y,INC(R(Y)))); break; case INSTR_DEX: SET_NZ(LET(X,DEC(R(X)))); break; case INSTR_DEY: SET_NZ(LET(Y,DEC(R(Y)))); break; case INSTR_INC: SET_NZ(STORE(INC(OPERAND),LOPERAND)); break; case INSTR_DEC: SET_NZ(STORE(DEC(OPERAND),LOPERAND)); break; /* control flow */ case INSTR_JMP: if (get_addmode(opcode) == ADDMODE_IND) { Value *v = LOAD_RAM16(CONST32(OPERAND_16)); new StoreInst(v, cpu->ptr_PC, bb); } break; case INSTR_JSR: PUSH16(pc+2); break; case INSTR_RTS: STORE(ADD(PULL16, CONST16(1)), cpu->ptr_PC); break; /* branch */ case INSTR_BEQ: case INSTR_BNE: case INSTR_BCS: case INSTR_BCC: case INSTR_BMI: case INSTR_BPL: case INSTR_BVS: case INSTR_BVC: break; /* other */ case INSTR_NOP: break; case INSTR_BRK: arch_6502_trap(cpu, pc, bb); break; case INSTR_RTI: arch_6502_trap(cpu, pc, bb); break; case INSTR_XXX: arch_6502_trap(cpu, pc, bb); break; } return get_length(get_addmode(opcode)); }
int main(int argc, char *argv[]) { if (argc < 2) { usage(argv[0]); } if ((fin = fopen(argv[1], "rb")) == 0) { fprintf(stderr, "Error: could not open file\n"); exit(1); } BYTE *fbuf = (BYTE *) malloc(16 * sizeof(BYTE)); pe = (PESTRUCT *) malloc(sizeof(PESTRUCT)); parse_pe_header(); printf("EP RVA: %.8X\n", pe->rvaep); printf("Code section RVA: %.8X\n", pe->rvacode); printf("Data section RVA: %.8X\n", pe->rvadata); printf("Image base: %.8X\n", pe->imagebase); printf("Size of code section: %.8X\n", pe->codesize); /* Get size of headers to know where code section starts */ fseek(fin, pe->offset + 84, SEEK_SET); fgets(fbuf, 4, fin); pe->codeoffset = lendian(fbuf, 4); printf("Code section offset: %.8X\n", pe->codeoffset); /* Get OEP address */ pe->oep = pe->imagebase + pe->rvacode; printf("OEP address: %.8X\n", pe->oep); printf("\n"); // Formatting /* Get max offset from total file size */ fseek(fin, 0L, SEEK_END); pe->maxoffset = ftell(fin); fseek(fin, pe->codeoffset, SEEK_SET); // Go to start of code section DWORD len; DWORD cur_addr = pe->oep; // First instruction at OEP DWORD addr; int i; int quit = 0; /* Start parsing and outputting 50 instructions at a time, waiting for user input after each block */ while (!feof(fin) && !quit) { printf(":"); /* Wait for user input */ int ch = _getch(); printf("\b"); // Erase character switch (ch) { case KEY_ESC: // Quit case 'q': quit = 1; break; case 'n': // Next instruction print_instr(&cur_addr); break; case ' ': // Next 32 instructions print_ninstr(&cur_addr, 50); break; case 'o': // Go back to OEP printf("\r \n"); // Clear line printf("EP RVA: %.8X\n", pe->rvaep); printf("Code section RVA: %.8X\n", pe->rvacode); printf("Data section RVA: %.8X\n", pe->rvadata); printf("Image base: %.8X\n", pe->imagebase); printf("Size of code section: %.8X\n", pe->codesize); printf("Code section offset: %.8X\n", pe->codeoffset); printf("OEP address: %.8X\n", pe->oep); printf("\n"); fseek(fin, pe->codeoffset, SEEK_SET); cur_addr = pe->oep; break; case 'g': { // Go to specific address printf("\r \n"); // Clear line printf("Go to address: "); char getaddr[32]; fgets(getaddr, sizeof(getaddr), stdin); // Get input if (getaddr[0] == '\n' || getaddr[0] == '\r') { printf("\n"); break; } // Blank input (cancel instruction) addr = strtol(getaddr, NULL, 16); // Parse input address if (!print_instr(&addr)) break; // Print the first instruction cur_addr = addr; break; } case 'f': { // Follow instruction at specific address printf("\r \n"); // Clear line printf("Address of instruction to follow: "); char addrstr[32]; fgets(addrstr, sizeof(addrstr), stdin); // Get input if (addrstr[0] == '\n' || addrstr[0] == '\r') { printf("\n"); break; } // Blank input (cancel instruction) addr = strtol(addrstr, NULL, 16); char *instr = get_instr(addr); if (!instr) break; // Error printf("%.8X\t%s\n", addr, instr); // Print instruction to follow printf("\t\tv\n"); addr = parse_addr(instr); if (!print_instr(&addr)) break; cur_addr = addr; free(instr); break; } case 'd': { // Dump data at specific address printf("\r \n"); // Clear line printf("Address to dump: "); char addrstr[32]; fgets(addrstr, sizeof(addrstr), stdin); // Get input if (addrstr[0] == '\n' || addrstr[0] == '\r') { printf("\n"); break; } // Blank input (cancel instruction) addr = strtol(addrstr, NULL, 16); if (!valid_addr(addr)) { printf("Address out of bounds\n"); break; } printf("Number of bytes to dump (default 16): "); char bytesstr[3]; fgets(bytesstr, sizeof(bytesstr), stdin); int bytes = strtol(bytesstr, NULL, 10); if (bytes == 0) bytes = 16; if (bytes > DUMP_MAX) { printf("Too high\n"); break; } print_dump(addr, bytes); printf("\n"); // Formatting break; } case 's': { // Search for a string in .data, .rdata, and .rsrc sections (no unicode support) printf("\r \n"); // Clear line printf("Search for string: "); char searchstr[STRLEN_MAX]; fgets(searchstr, sizeof(searchstr), stdin); // Get input if (searchstr[0] == '\n' || searchstr[0] == '\r') { printf("\n"); break; } // Blank input (cancel instruction) addr = find_string_addr(searchstr); // Find address of string if (addr == 0) { printf("String not found\n"); } else { print_dump_str(addr); // Print dump of matched string } printf("\n"); // Formatting break; } case 'e': { // Edit binary printf("\r \n"); // Clear line printf("Starting address for editing: "); char addrstr[32]; fgets(addrstr, sizeof(addrstr), stdin); // Get input if (addrstr[0] == '\n' || addrstr[0] == '\r') { printf("\n"); break; } // Blank input (cancel instruction) addr = strtol(addrstr, NULL, 16); if (!valid_addr(addr)) { printf("Address out of bounds\n"); break; } printf("Input hex bytes: "); char bytestr[STRLEN_MAX]; fgets(bytestr, sizeof(bytestr), stdin); // Get input char *edit_file = (char *) calloc(strlen(argv[1]) + 6, sizeof(char)); strncpy(edit_file, argv[1], strlen(argv[1]) - 4); strcat(edit_file, "_edit.exe"); // Edited file name: inputfilename_edit.exe save_edits_to_file(fin, edit_file, addr, bytestr); printf("Edited file %s saved\n\n", edit_file); free(edit_file); break; } case 'h': // Show help case '?': print_help(); break; // Special keys case SPECIAL_KEY: ch = _getch(); switch (ch) { case KEY_DOWN: // Next instruction print_instr(&cur_addr); break; case KEY_PGDN: // Next 32 instructions print_ninstr(&cur_addr, 50); break; case KEY_HOME: // Go back to OEP printf("\r \n"); // Clear line printf("EP RVA: %.8X\n", pe->rvaep); printf("Code section RVA: %.8X\n", pe->rvacode); printf("Data section RVA: %.8X\n", pe->rvadata); printf("Image base: %.8X\n", pe->imagebase); printf("Size of code section: %.8X\n", pe->codesize); printf("Code section offset: %.8X\n", pe->codeoffset); printf("OEP address: %.8X\n", pe->oep); printf("\n"); fseek(fin, pe->codeoffset, SEEK_SET); cur_addr = pe->oep; break; default: //printf("0x%X\n", ch); // DEBUGGING break; } break; default: //printf("0x%X\n", ch); // DEBUGGING break; } fflush(stdin); } free(fbuf); free(pe); fclose(fin); return 0; }
TEST(FirstPass, get_instr) { char a[] = "NAME: .string \"Linus\""; char b[] = ".data +7,-57, 17 , 9"; char c[] = "DATA: .data +7,-57, 17 , 9"; char d[] = ".entry HELLO"; char e[] = ".extern HELLO"; char f[] = "some nonsense and white bears "; char g[] = "MOV ax, 125"; EXPECT_EQ(get_instr(a), string); EXPECT_EQ(get_instr(a), string); EXPECT_EQ(get_instr(b), data); EXPECT_EQ(get_instr(b), data); EXPECT_EQ(get_instr(c), data); EXPECT_EQ(get_instr(c), data); EXPECT_EQ(get_instr(d), entry); EXPECT_EQ(get_instr(e), extrn); EXPECT_EQ(get_instr(f), NONE); EXPECT_EQ(get_instr(f), NONE); EXPECT_EQ(get_instr(g), NONE); EXPECT_EQ(get_instr(g), NONE); }
/* XXX Note, this fuction does not currently handle faults from * vmalloc/vmaped'd memory. That should probably be in a separate * function anyway. */ int l4_do_page_fault(unsigned long address, long access, struct pt_regs *regs) { struct vm_area_struct * vma; struct mm_struct *mm = current->mm; int fault, si_code = SEGV_MAPERR; siginfo_t info; /* If we're in an interrupt context, or have no user context, we must not take the fault. */ if (!mm) /* || in_interrupt()) */ goto bad_area_nosemaphore; down_read(&mm->mmap_sem); vma = find_vma(mm, address); if (!vma) goto bad_area; if (vma->vm_start <= address) goto good_area; if (!(vma->vm_flags & VM_GROWSDOWN)) goto bad_area; if (expand_stack(vma, address)) goto bad_area; /* Ok, we have a good vm_area for this memory access, so we can handle it. */ good_area: si_code = SEGV_ACCERR; if (/* LOAD */ access & 0x4) { /* Allow reads even for write/execute-only mappings */ if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC))) goto bad_area; } else if (/* FETCH */ access & 0x1) { if (!(vma->vm_flags & VM_EXEC)) goto bad_area; } else { if (!(vma->vm_flags & VM_WRITE)) goto bad_area; } survive: /* If for any reason at all we couldn't handle the fault, make sure we exit gracefully rather than endlessly redo the fault. */ fault = handle_mm_fault(mm, vma, address, access & 0x2); up_read(&mm->mmap_sem); switch (fault) { case VM_FAULT_MINOR: current->min_flt++; break; case VM_FAULT_MAJOR: current->maj_flt++; break; case VM_FAULT_SIGBUS: goto do_sigbus; case VM_FAULT_OOM: goto out_of_memory; #if 0 /* * Well, it's a good idea to have this here, but apparently * handle_mm_fault() can return all sorts of weird stuff, which * makes it unsuitable to put BUG() here. -gl */ default: BUG(); #endif } return 0; /* Something tried to access memory that isn't in our memory map. Fix it, but check if it's kernel or user first. */ bad_area: up_read(&mm->mmap_sem); /* Check if it is at TASK_SIG_BASE */ #ifdef CONFIG_ARCH_ARM /* * Binary patching for NPTL * * XXX ??? Better place this thing? */ if (user_mode(regs) && ((address & PAGE_MASK) == 0xffff0000)) { #if 0 printk("Fault at address 0x%lx pc = 0x%lx, " "need rewrite\n", address, L4_MsgWord(¤t_regs()->msg, 1)); #endif if (address == 0xffff0fe0) { L4_Msg_t msg; unsigned long pc = L4_MsgWord(¤t_regs()->msg, 1); unsigned long lr, fpc; unsigned long instr, r; long offs; if (pc != 0xffff0fe0) goto bad_area_nosemaphore; L4_Copy_regs_to_mrs(task_thread_info(current)->user_tid); L4_StoreMRs(0, 16, &msg.msg[0]); lr = msg.msg[14]; fpc = lr - 4; L4_CacheFlushAll(); instr = get_instr(fpc); if (instr == -1UL) goto bad_area_nosemaphore; if ((instr & 0x0f000000) == 0x0b000000) { offs = instr << 8; offs = offs >> 6; /* ASR */ fpc = (fpc + 8) + offs; instr = get_instr(fpc); if (instr == -1UL) goto bad_area_nosemaphore; if ((instr & 0xffffffff) == 0xe3e00a0f) { /* mvn r0, 0xf000 */ /* * Rewrite to load the * kernel_reserved[0] from the * utcb. * * This requires L4 to cooperate * with the ExReg() syscall. */ /* mov r0, #0xff000000 */ r = set_instr(fpc, 0xe3a004ff); if (r == -1UL) goto bad_area_nosemaphore; fpc += 4; /* ldr r0, [r0, #0xff0] */ r = set_instr(fpc, 0xe5900ff0); if (r == -1UL) goto bad_area_nosemaphore; fpc += 4; /* ldr r0, [r0, #56] */ r = set_instr(fpc, 0xe5900038); if (r == -1UL) goto bad_area_nosemaphore; fpc += 4; /* mov pc, lr */ r = set_instr(fpc, 0xe1a0f00e); if (r == -1UL) goto bad_area_nosemaphore; L4_CacheFlushAll(); msg.msg[0] = current_thread_info()->tp_value; msg.msg[15] = lr; L4_LoadMRs(0, 16, &msg.msg[0]); L4_Copy_mrs_to_regs( task_thread_info(current)->user_tid); L4_MsgPutWord(¤t_regs()->msg, 1, lr); return 0; } } else if (instr == 0xe240f01f) {