예제 #1
0
static void test_match_chain(const int argc, char *argv[])
{
  t_upslst_item *flavor_list = NULL, *quals_list = NULL;
  t_upslst_item *vinst_list = NULL, *tinst_list = NULL;
  t_upslst_item *cinst_list = NULL;
  int need_unique = 0, i, num_matches;
  char *new_string = NULL;
  char *ups_db = "/usrdevel/s1/berman/upsdb";

  if (! strcmp(argv[1],"1")) {
    need_unique = 1;
  }

  for (i = 3; i < argc; i += 2) {
    new_string = get_ups_string(argv[i]);
    flavor_list = upslst_add(flavor_list, new_string);
    new_string = get_ups_string(argv[i+1]);
    quals_list = upslst_add(quals_list, new_string);
  }

  /* point back to the first elements of the list */
  flavor_list = upslst_first(flavor_list);
  quals_list = upslst_first(quals_list);

  num_matches = match_from_chain("tigger", argv[2], "*", (char *)NULL,
				 (char *)NULL, ups_db, need_unique, 
				 flavor_list, quals_list, &cinst_list,
				 &vinst_list, &tinst_list);
  printf("\nNumber of matches found in chain file is %d -\n",num_matches);
  print_inst(cinst_list);
  printf("\nNumber of matches found in version file is %d -\n",num_matches);
  print_inst(vinst_list);
  printf("\nNumber of matches found in table file is %d -\n",num_matches);
  print_inst(tinst_list);
}
예제 #2
0
static void test_get_instance(const int argc, char *argv[])
{
  char cfile[] = "/usrdevel/s1/berman/upsdb/tigger/current.chain";
  char vfile[] = "/usrdevel/s1/berman/upsdb/tigger/v2_0.version";
  char tfile[] = "/usrdevel/s1/berman/upsdb/tigger/v2_0.tbl";
  t_upslst_item *flavor_list = NULL, *quals_list = NULL, *inst_list = NULL;
  int need_unique = 0, i, num_matches;
  t_upstyp_product *product = NULL;
  char *new_string = NULL;

  if (! strcmp(argv[1],"1")) {
    need_unique = 1;
  }

  for (i = 2; i < argc; i += 2) {
    new_string = get_ups_string(argv[i]);
    flavor_list = upslst_add(flavor_list, new_string);
    new_string = get_ups_string(argv[i+1]);
    quals_list = upslst_add(quals_list, new_string);
  }

  /* point back to the first elements of the list */
  flavor_list = upslst_first(flavor_list);
  quals_list = upslst_first(quals_list);

  if ((product = upsfil_read_file(&cfile[0])) != NULL) {
    print_inst(product->instance_list);
    num_matches = get_instance(product->instance_list, flavor_list,
			       quals_list, need_unique, &inst_list);
    printf("\nNumber of matches found is %d, and they are -\n",num_matches);
    print_inst(inst_list);
  }
}
예제 #3
0
static void test_match_table(const int argc, char *argv[])
{
  t_upslst_item *flavor_list = NULL, *quals_list = NULL, *inst_list = NULL;
  int need_unique = 0, i, num_matches;
  char *new_string = NULL;

  if (! strcmp(argv[1],"1")) {
    need_unique = 1;
  }

  for (i = 7; i < argc; i += 2) {
    new_string = get_ups_string(argv[i]);
    flavor_list = upslst_add(flavor_list, new_string);
    new_string = get_ups_string(argv[i+1]);
    quals_list = upslst_add(quals_list, new_string);
  }

  /* point back to the first elements of the list */
  flavor_list = upslst_first(flavor_list);
  quals_list = upslst_first(quals_list);

  num_matches = match_from_table("tigger", (char *)argv[2], (char *)argv[3],
				 (char *)argv[4], (char *)argv[5],
				 (char *)argv[6], need_unique, 
				 flavor_list, quals_list, &inst_list);
  printf("\nNumber of matches found is %d, and they are -\n",num_matches);
  print_inst(inst_list);
}
예제 #4
0
파일: print_inst.cpp 프로젝트: jzeng4/top
static void print_func(FUNCTION *func)
{
	unsigned int start_pc = func->begin()->first;
#ifdef WINDOWS_FORMAT
	fprintf(output, "__asm{\n");
#else 
	fprintf(output, "__asm__ __volatile__(\n");
	fprintf(output, "\"leave\\n\\t\"\n");
#endif

#ifndef WINDOWS_NAKED
	print_prologue(start_pc);
#endif

	if(start_pc == g_main_pc){
#ifdef WINDOWS_FORMAT
		fprintf(output, "call  init_dependence_data\n");
#else
		fprintf(output, "\"call  init_dependence_data\\n\\t\"\n");
#endif
	}

	for(FUNCTION::iterator it = func->begin();
			it != func->end();it++){
		g_pc = it->first;
		fprintf(output, "//%x\n", g_pc);
		if(map_tmp.count(it->first) == 0 ){
			print_inst(it->second);
		}
		map_tmp[it->first] = 0;
	}
#ifndef WINDOWS_NAKED
	//print_epilogue(start_pc);
#endif

#ifdef WINDOWS_FORMAT
	fprintf(output, "L_ERROR_0x%x:\n", start_pc);
	fprintf(output, "}\n");
#else
	fprintf(output, "\"L_ERROR_0x%x:\\n\\t\"\n", start_pc);
	fprintf(output, "\"call safety_guard\\n\\t\"\n");
	fprintf(output, ":);\n");
#endif
}
예제 #5
0
int process_block(struct self_s *self, struct process_state_s *process_state, uint64_t inst_log_prev, uint64_t eip_offset_limit) {
	uint64_t offset = 0;
	int result;
	int n, m, l;
	int err;
	int found;
	struct inst_log_entry_s *inst_exe_prev;
	struct inst_log_entry_s *inst_exe;
	struct inst_log_entry_s *inst_log_entry = self->inst_log_entry;
	struct instruction_s *instruction = NULL;
	int instruction_offset = 0;
	int octets = 0;
	//struct memory_s *memory_text;
	//struct memory_s *memory_stack;
	struct memory_s *memory_reg;
	//struct memory_s *memory_data;
	struct dis_instructions_s dis_instructions;
	int *memory_used;
	struct entry_point_s *entry = self->entry_point;
	uint64_t list_length = self->entry_point_list_length;
	void *handle_void = self->handle_void;

	//memory_text = process_state->memory_text;
	//memory_stack = process_state->memory_stack;
	memory_reg = process_state->memory_reg;
	//memory_data = process_state->memory_data;
	memory_used = process_state->memory_used;

	debug_print(DEBUG_EXE, 1, "process_block entry\n");
	debug_print(DEBUG_EXE, 1, "inst_log=%"PRId64"\n", inst_log);
	debug_print(DEBUG_EXE, 1, "dis:Data at %p, size=0x%"PRIx64"\n", inst, inst_size);
	for (offset = 0; ;) {
	//for (offset = 0; offset < inst_size;
			//offset += dis_instructions.bytes_used) {
		/* Update EIP */
		offset = memory_reg[2].offset_value;
		if (offset >= eip_offset_limit) {
			debug_print(DEBUG_EXE, 1, "Over ran offset=0x%"PRIx64" >= eip_offset_limit=0x%"PRIx64" \n",
				offset, eip_offset_limit);
			return 1;
		}
		dis_instructions.instruction_number = 0;
		dis_instructions.bytes_used = 0;
		debug_print(DEBUG_EXE, 1, "eip=0x%"PRIx64", offset=0x%"PRIx64"\n",
			memory_reg[2].offset_value, offset);
		/* the calling program must define this function. This is a callback. */
		result = disassemble(self, &dis_instructions, inst, inst_size, offset);
		debug_print(DEBUG_EXE, 1, "bytes used = %d\n", dis_instructions.bytes_used);
		debug_print(DEBUG_EXE, 1, "eip=0x%"PRIx64", offset=0x%"PRIx64"\n",
			memory_reg[2].offset_value, offset);
		/* Memory not used yet */
		if (0 == memory_used[offset]) {
			debug_print(DEBUG_EXE, 1, "Memory not used yet\n");
			for (n = 0; n < dis_instructions.bytes_used; n++) {
				memory_used[offset + n] = -n;
				debug_print(DEBUG_EXE, 1, " 0x%02x\n", inst[offset + n]);
			}
			debug_print(DEBUG_EXE, 1, "\n");
			memory_used[offset] = inst_log;
		} else {
			int inst_this = memory_used[offset];
			if (inst_this < 0) {
				/* FIXME: What to do in this case? */
				/* problem caused by rep movs instruction */
				debug_print(DEBUG_EXE, 1, "process_block:line110:FIXME:Not a valid instuction %d at eip offset 0x%"PRIx64"\n", inst_this, offset);
			}
			/* If value == maxint, then it is the destination of a jump */
			/* But I need to separate the instruction flows */
			/* A jump/branch inst should create a new instruction tree */
			debug_print(DEBUG_EXE, 1, "Memory already used\n");
			inst_exe_prev = &inst_log_entry[inst_log_prev];
			inst_exe = &inst_log_entry[inst_this];
			debug_print(DEBUG_EXE, 1, "inst_exe_prev=%p, inst_exe=%p\n",
				inst_exe_prev, inst_exe);
			inst_exe->prev_size++;
			if (inst_exe->prev_size == 1) {
				inst_exe->prev = malloc(sizeof(inst_exe->prev));
			} else {
				inst_exe->prev = realloc(inst_exe->prev, sizeof(inst_exe->prev) * inst_exe->prev_size);
			}
			inst_exe->prev[inst_exe->prev_size - 1] = inst_log_prev;
			if (inst_exe_prev->next_size > 0) {
				debug_print(DEBUG_EXE, 1, "JCD8a: next_size = 0x%x\n", inst_exe_prev->next_size);
			}
			if (inst_exe_prev->next_size == 0) {
				inst_exe_prev->next_size++;
				inst_exe_prev->next = malloc(sizeof(inst_exe_prev->next));
				inst_exe_prev->next[inst_exe_prev->next_size - 1] = inst_this;
			} else {
				found = 0;
				for (l = 0; l < inst_exe_prev->next_size; l++) {
					if (inst_exe_prev->next[inst_exe_prev->next_size - 1] == inst_this) {
						found = 1;
						break;
					}
				}
				if (!found) {
					inst_exe_prev->next_size++;
					if (inst_exe_prev->next_size > 2) {
						debug_print(DEBUG_EXE, 1, "process_block: next_size = %d, inst = 0x%x\n", inst_exe_prev->next_size, inst_this);
					}
					inst_exe_prev->next = realloc(inst_exe_prev->next, sizeof(inst_exe_prev->next) * inst_exe_prev->next_size);
					inst_exe_prev->next[inst_exe_prev->next_size - 1] = inst_this;
				}
			}
			break;
		}	
		//debug_print(DEBUG_EXE, 1, "disassemble_fn\n");
		//disassemble_fn = disassembler (handle->bfd);
		//debug_print(DEBUG_EXE, 1, "disassemble_fn done\n");
		debug_print(DEBUG_EXE, 1, "disassemble att  : ");
		bf_disassemble_set_options(handle_void, "att");
		bf_disassemble_callback_start(handle_void);
		octets = bf_disassemble(handle_void, offset);
		bf_disassemble_callback_end(handle_void);
		debug_print(DEBUG_EXE, 1, "  octets=%d\n", octets);
		debug_print(DEBUG_EXE, 1, "disassemble intel: ");
		bf_disassemble_set_options(handle_void, "intel");
		bf_disassemble_callback_start(handle_void);
		octets = bf_disassemble(handle_void, offset);
		bf_disassemble_callback_end(handle_void);
		debug_print(DEBUG_EXE, 1, "  octets=%d\n", octets);
		if (dis_instructions.bytes_used != octets) {
			debug_print(DEBUG_EXE, 1, "Unhandled instruction. Length mismatch. Got %d, expected %d, Exiting\n", dis_instructions.bytes_used, octets);
			return 1;
		}
		/* Update EIP */
		memory_reg[2].offset_value += octets;

		debug_print(DEBUG_EXE, 1, "Number of RTL dis_instructions=%d\n",
			dis_instructions.instruction_number);
		if (result != 0) {
			debug_print(DEBUG_EXE, 1, "Unhandled instruction. Exiting\n");
			return 1;
		}
		if (dis_instructions.instruction_number == 0) {
			debug_print(DEBUG_EXE, 1, "NOP instruction. Get next inst\n");
			continue;
		}
		for (n = 0; n < dis_instructions.instruction_number; n++) {
			instruction = &dis_instructions.instruction[n];
			debug_print(DEBUG_EXE, 1,  "Printing inst1111:0x%x, 0x%x, 0x%"PRIx64"\n",instruction_offset, n, inst_log);
			err = print_inst(self, instruction, instruction_offset + n + 1, NULL);
			if (err) {
				debug_print(DEBUG_EXE, 1, "print_inst failed\n");
				return err;
			}
			inst_exe_prev = &inst_log_entry[inst_log_prev];
			inst_exe = &inst_log_entry[inst_log];
			memcpy(&(inst_exe->instruction), instruction, sizeof(struct instruction_s));
			err = execute_instruction(self, process_state, inst_exe);
			if (err) {
				debug_print(DEBUG_EXE, 1, "execute_intruction failed err=%d\n", err);
				return err;
			}
			inst_exe->prev_size++;
			if (inst_exe->prev_size == 1) {
				inst_exe->prev = malloc(sizeof(inst_exe->prev));
			} else {
				inst_exe->prev = realloc(inst_exe->prev, sizeof(inst_exe->prev) * inst_exe->prev_size);
			}
			inst_exe->prev[inst_exe->prev_size - 1] = inst_log_prev;
			inst_exe_prev->next_size++;
			if (inst_exe_prev->next_size > 2) {
				debug_print(DEBUG_EXE, 1, "process_block:line203: next_size = %d, inst = 0x%"PRIx64"\n", inst_exe_prev->next_size, inst_log);
			}
			if (inst_exe_prev->next_size > 1) {
				debug_print(DEBUG_EXE, 1, "JCD8b: next_size = 0x%x\n", inst_exe_prev->next_size);
			}
			if (inst_exe_prev->next_size == 1) {
				inst_exe_prev->next = malloc(sizeof(inst_exe_prev->next));
				inst_exe_prev->next[inst_exe_prev->next_size - 1] = inst_log;
			} else {
				inst_exe_prev->next = realloc(inst_exe_prev->next, sizeof(inst_exe_prev->next) * inst_exe_prev->next_size);
				inst_exe_prev->next[inst_exe_prev->next_size - 1] = inst_log;
			}
			inst_exe_prev->next[inst_exe_prev->next_size - 1] = inst_log;

			if (IF == instruction->opcode) {
				debug_print(DEBUG_EXE, 1, "IF FOUND\n");
				//debug_print(DEBUG_EXE, 1, "Breaking at IF\n");
				debug_print(DEBUG_EXE, 1, "IF: this EIP = 0x%"PRIx64"\n",
					memory_reg[2].offset_value);
				debug_print(DEBUG_EXE, 1, "IF: jump dst abs EIP = 0x%"PRIx64"\n",
					inst_exe->value3.offset_value);
				debug_print(DEBUG_EXE, 1, "IF: inst_log = %"PRId64"\n",
					inst_log);
				for (m = 0; m < list_length; m++ ) {
					if (0 == entry[m].used) {
						entry[m].esp_init_value = memory_reg[0].init_value;
						entry[m].esp_offset_value = memory_reg[0].offset_value;
						entry[m].ebp_init_value = memory_reg[1].init_value;
						entry[m].ebp_offset_value = memory_reg[1].offset_value;
						entry[m].eip_init_value = memory_reg[2].init_value;
						entry[m].eip_offset_value = memory_reg[2].offset_value;
						entry[m].previous_instuction = inst_log;
						entry[m].used = 1;
						debug_print(DEBUG_EXE, 1, "JCD:8 used 1\n");
						
						break;
					}
				}
				/* FIXME: Would starting a "m" be better here? */
				for (m = 0; m < list_length; m++ ) {
					if (0 == entry[m].used) {
						entry[m].esp_init_value = memory_reg[0].init_value;
						entry[m].esp_offset_value = memory_reg[0].offset_value;
						entry[m].ebp_init_value = memory_reg[1].init_value;
						entry[m].ebp_offset_value = memory_reg[1].offset_value;
						entry[m].eip_init_value = inst_exe->value3.init_value;
						entry[m].eip_offset_value = inst_exe->value3.offset_value;
						entry[m].previous_instuction = inst_log;
						entry[m].used = 1;
						debug_print(DEBUG_EXE, 1, "JCD:8 used 2\n");
						break;
					}
				}
			}
			if (JMPT == instruction->opcode) {
				/* FIXME: add the jump table detection here */
				uint64_t inst_base;
				int tmp;
				struct inst_log_entry_s *inst_exe_base;
				struct instruction_s *instruction = NULL;
				int relocation_area;
				uint64_t relocation_index;
				tmp = search_for_jump_table_base(self, inst_log, &inst_base);
				if (tmp) {
					debug_print(DEBUG_EXE, 1, "FIXME: JMPT reached..exiting %d 0x%"PRIx64"\n", tmp, inst_base);
					exit(1);
				}
				inst_exe_base = &inst_log_entry[inst_base];
				instruction = &(inst_exe_base->instruction);
				debug_print(DEBUG_EXE, 1, "Relocated = 0x%x\n", instruction->srcB.relocated);
				debug_print(DEBUG_EXE, 1, "Relocated_area = 0x%x\n", instruction->srcB.relocated_area);
				debug_print(DEBUG_EXE, 1, "Relocated_index = 0x%x\n", instruction->srcB.relocated_index);
				if (2 == instruction->srcB.relocated_area) {
					uint64_t index = instruction->srcB.relocated_index;
					tmp = 0;
					
					do {
						tmp = bf_find_relocation_rodata(handle_void, index, &relocation_area, &relocation_index);
						if (!tmp) {
							if (1 != relocation_area) {
								debug_print(DEBUG_EXE, 1, "JMPT Relocation area not to code\n");
								exit(1);
							}
							for (m = 0; m < list_length; m++ ) {
								if (0 == entry[m].used) {
									entry[m].esp_init_value = memory_reg[0].init_value;
									entry[m].esp_offset_value = memory_reg[0].offset_value;
									entry[m].ebp_init_value = memory_reg[1].init_value;
									entry[m].ebp_offset_value = memory_reg[1].offset_value;
									entry[m].eip_init_value = 0;
									entry[m].eip_offset_value = relocation_index;
									entry[m].previous_instuction = inst_log;
									entry[m].used = 1;
									debug_print(DEBUG_EXE, 1, "JMPT new entry \n");
									break;
								}
							}
						} else {
							debug_print(DEBUG_EXE, 1, "JMPT index, 0x%"PRIx64", not found in rodata relocation table\n", index);
						}
						index += 8;
					} while (!tmp);
				}
			}
			inst_log_prev = inst_log;
			inst_log++;
			if (0 == memory_reg[2].offset_value) {
				debug_print(DEBUG_EXE, 1, "Function exited\n");
				if (inst_exe_prev->instruction.opcode == NOP) {
					inst_exe_prev->instruction.opcode = RET;
				}
				break;
			}
			if (JMPT == instruction->opcode) {
				debug_print(DEBUG_EXE, 1, "Function exited. Temporary action for JMPT\n");
				break;
			}
		}
		instruction_offset += dis_instructions.instruction_number;
		if (0 == memory_reg[2].offset_value) {
			debug_print(DEBUG_EXE, 1, "Breaking\n");
			break;
		}
		if (instruction && (JMPT == instruction->opcode)) {
			debug_print(DEBUG_EXE, 1, "Function exited. Temporary action for JMPT\n");
			break;
		}
#if 0
		if (IF == instruction->opcode) {
			debug_print(DEBUG_EXE, 1, "Breaking at IF\n");
			debug_print(DEBUG_EXE, 1, "IF: this EIP = 0x%"PRIx64"\n",
				memory_reg[2].offset_value);
			debug_print(DEBUG_EXE, 1, "IF: jump dst abs EIP = 0x%"PRIx64"\n",
				inst_exe->value3.offset_value);
			debug_print(DEBUG_EXE, 1, "IF: inst_log = %"PRId64"\n",
				inst_log);
			for (n = 0; n < list_length; n++ ) {
				if (0 == entry[n].used) {
					entry[n].esp_init_value = memory_reg[0].init_value;
					entry[n].esp_offset_value = memory_reg[0].offset_value;
					entry[n].ebp_init_value = memory_reg[1].init_value;
					entry[n].ebp_offset_value = memory_reg[1].offset_value;
					entry[n].eip_init_value = memory_reg[2].init_value;
					entry[n].eip_offset_value = memory_reg[2].offset_value;
					entry[n].previous_instuction = inst_log - 1;
					entry[n].used = 1;
					break;
				}
			}
			/* FIXME: Would starting a "n" be better here? */
			for (n = 0; n < list_length; n++ ) {
				if (0 == entry[n].used) {
					entry[n].esp_init_value = memory_reg[0].init_value;
					entry[n].esp_offset_value = memory_reg[0].offset_value;
					entry[n].ebp_init_value = memory_reg[1].init_value;
					entry[n].ebp_offset_value = memory_reg[1].offset_value;
					entry[n].eip_init_value = inst_exe->value3.init_value;
					entry[n].eip_offset_value = inst_exe->value3.offset_value;
					entry[n].previous_instuction = inst_log - 1;
					entry[n].used = 1;
					break;
				}
			}
			break;
		}
#endif
	}
	return 0;
}
예제 #6
0
void simulate(FILE **oFile, word *regs, word *prog,
 word *mem, size *PC, size *GP) {
    size pc = 0,                    // current instruction
         gp = 0,                    // current mem location
         iType;                     // current instruction type
    Ibits curr_instr;               // current instr value
    
    
    //  This is the actual simulation. It will loop until either
    //     the program counter reaches the limit and thus exiting
    //     with an error code, or the proper exit command is made.
    //  This is done by translating op/func codes into calls to
    //     simulation functions. Notice that each function is
    //     passed the same parameters (save syscalls). While this
    //     could be prevented by using gloabl variables, the extra
    //     work is worth the encapsulation.
    //  Each simulation function will return the address to the
    //     next instruction. Thus each loop will start by grabbing
    //     the instruction from the instruction array. It will then
    //     store the encoding into a union to permit efficient
    //     memory usage, and easy bit field referencing.
    
    
    while(pc < *PC) {
        curr_instr.bits = prog[pc];               // get next instruction
        iType = get_iType(curr_instr.R.op, &pc);  // get instruction type
        print_inst(oFile, &curr_instr, &pc, 1);          // print instruction
        if(iType == 0) {                          // handle R-type
            switch(curr_instr.R.fn) {
                case 12: 
                    pc = sim_syscall(regs, mem, PC, &pc, GP, &gp);
                    if (pc == -1) return;
                    break;
                case 16: 
                    pc = sim_mfhi(&curr_instr, regs, mem, PC, &pc, GP, &gp);
                    break;
                case 18: 
                    pc = sim_mflo(&curr_instr, regs, mem, PC, &pc, GP, &gp);
                    break;
                case 24: 
                    pc = sim_mult(&curr_instr, regs, mem, PC, &pc, GP, &gp);
                    break;
                case 26: 
                    pc = sim_div(&curr_instr, regs, mem, PC, &pc, GP, &gp);
                    break;
                case 33: 
                    pc = sim_addu(&curr_instr, regs, mem, PC, &pc, GP, &gp);
                    break;
                case 35: 
                    pc = sim_subu(&curr_instr, regs, mem, PC, &pc, GP, &gp);
                    break;
                case 36: 
                    pc = sim_and(&curr_instr, regs, mem, PC, &pc, GP, &gp);
                    break;
                case 37: 
                    pc = sim_or(&curr_instr, regs, mem, PC, &pc, GP, &gp);
                    break;
                case 42: 
                    pc = sim_slt(&curr_instr, regs, mem, PC, &pc, GP, &gp);
                    break;
                default: 
                    fprintf(stderr,
                      "ERROR: Illegal function encoding - line %d\n", pc);
                    exit(1);
            }
        }
        else if (iType == 1) {                    // handle I-type
            switch(curr_instr.I.op) {
                case 9:  
                    pc = sim_addiu(&curr_instr, regs, mem, PC, &pc, GP, &gp);
                    break;
                case 4:  
                    pc = sim_beq(&curr_instr, regs, mem, PC, &pc, GP, &gp);
                    break;
                case 5:  
                    pc = sim_bne(&curr_instr, regs, mem, PC, &pc, GP, &gp);
                    break;
                case 35: 
                    pc = sim_lw(&curr_instr, regs, mem, PC, &pc, GP, &gp);
                    break;
                case 43: 
                    pc = sim_sw(&curr_instr, regs, mem, PC, &pc, GP, &gp);
                    break;
            }
        }
        else {                                    // handle J-type
            pc = sim_j(&curr_instr, regs, mem, PC, &pc, GP, &gp);
        }
        
        print_regs(oFile, regs);                         // status of regs
        print_mem(oFile, mem, GP);                       // status of mem
    }
    
}
예제 #7
0
void print_list(FILE *fptr, inst_t head) {
    while (head) {
        print_inst(fptr, head);
        head = head->next;
    }
}