⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mips64.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器
💻 C
📖 第 1 页 / 共 2 页
字号:
   if (i == MIPS64_MAX_BREAKPOINTS)      return(-1);   mcpu->breakpoints[i] = pc;   mcpu->breakpoints_enabled = TRUE;   return(0);}/* Remove a virtual breakpoint */void mips64_remove_breakpoint(cpu_gen_t *cpu,m_uint64_t pc){      cpu_mips_t *mcpu = CPU_MIPS64(cpu);   int i,j;   for(i=0;i<MIPS64_MAX_BREAKPOINTS;i++)      if (mcpu->breakpoints[i] == pc)      {         for(j=i;j<MIPS64_MAX_BREAKPOINTS-1;j++)            mcpu->breakpoints[j] = mcpu->breakpoints[j+1];         mcpu->breakpoints[MIPS64_MAX_BREAKPOINTS-1] = 0;      }   for(i=0;i<MIPS64_MAX_BREAKPOINTS;i++)      if (mcpu->breakpoints[i] != 0)         return;   mcpu->breakpoints_enabled = FALSE;}/* Debugging for register-jump to address 0 */fastcall void mips64_debug_jr0(cpu_mips_t *cpu){   printf("MIPS64: cpu %p jumping to address 0...\n",cpu);   mips64_dump_regs(cpu->gen);}/* Set a register */void mips64_reg_set(cpu_gen_t *cpu,u_int reg,m_uint64_t val){   if (reg < MIPS64_GPR_NR)      CPU_MIPS64(cpu)->gpr[reg] = val;}/* Dump registers of a MIPS64 processor */void mips64_dump_regs(cpu_gen_t *cpu){    cpu_mips_t *mcpu = CPU_MIPS64(cpu);   mips_insn_t *ptr,insn;   char buffer[80];   int i;   printf("MIPS64 Registers:\n");   for(i=0;i<MIPS64_GPR_NR/2;i++) {      printf("  %s ($%2d) = 0x%16.16llx   %s ($%2d) = 0x%16.16llx\n",             mips64_gpr_reg_names[i*2], i*2, mcpu->gpr[i*2],             mips64_gpr_reg_names[(i*2)+1], (i*2)+1, mcpu->gpr[(i*2)+1]);   }   printf("  lo = 0x%16.16llx, hi = 0x%16.16llx\n", mcpu->lo, mcpu->hi);   printf("  pc = 0x%16.16llx, ll_bit = %u\n", mcpu->pc, mcpu->ll_bit);   /* Fetch the current instruction */    ptr = mcpu->mem_op_lookup(mcpu,mcpu->pc);   if (ptr) {      insn = vmtoh32(*ptr);      if (mips64_dump_insn(buffer,sizeof(buffer),1,mcpu->pc,insn) != -1)         printf("  Instruction: %s\n",buffer);   }   printf("\nCP0 Registers:\n");   for(i=0;i<MIPS64_CP0_REG_NR/2;i++) {      printf("  %-10s ($%2d) = 0x%16.16llx   %-10s ($%2d) = 0x%16.16llx\n",             mips64_cp0_reg_names[i*2], i*2,              mips64_cp0_get_reg(mcpu,i*2),             mips64_cp0_reg_names[(i*2)+1], (i*2)+1,             mips64_cp0_get_reg(mcpu,(i*2)+1));   }   printf("\n  IRQ count: %llu, IRQ false positives: %llu, "          "IRQ Pending: %u\n",          mcpu->irq_count,mcpu->irq_fp_count,mcpu->irq_pending);   printf("  Timer IRQ count: %llu, pending: %u, timer drift: %u\n\n",          mcpu->timer_irq_count,mcpu->timer_irq_pending,mcpu->timer_drift);   printf("  Device access count: %llu\n",cpu->dev_access_counter);   printf("\n");}/* Dump a memory block */void mips64_dump_memory(cpu_mips_t *cpu,m_uint64_t vaddr,u_int count){   void *haddr;   u_int i;   for(i=0;i<count;i++,vaddr+=4)    {      if ((i & 3) == 0)         printf("\n  0x%16.16llx: ",vaddr);      haddr = cpu->mem_op_lookup(cpu,vaddr);            if (haddr)         printf("0x%8.8x ",htovm32(*(m_uint32_t *)haddr));      else         printf("XXXXXXXXXX ");   }   printf("\n\n");}/* Dump the stack */void mips64_dump_stack(cpu_mips_t *cpu,u_int count){      printf("MIPS Stack Dump at 0x%16.16llx:",cpu->gpr[MIPS_GPR_SP]);   mips64_dump_memory(cpu,cpu->gpr[MIPS_GPR_SP],count);}/* Save the CPU state into a file */int mips64_save_state(cpu_mips_t *cpu,char *filename){   FILE *fd;   int i;   if (!(fd = fopen(filename,"w"))) {      perror("mips64_save_state: fopen");      return(-1);   }   /* pc, lo and hi */   fprintf(fd,"pc: %16.16llx\n",cpu->pc);   fprintf(fd,"lo: %16.16llx\n",cpu->lo);   fprintf(fd,"hi: %16.16llx\n",cpu->hi);   /* general purpose registers */   for(i=0;i<MIPS64_GPR_NR;i++)      fprintf(fd,"%s: %16.16llx\n",              mips64_gpr_reg_names[i],cpu->gpr[i]);   printf("\n");   /* cp0 registers */   for(i=0;i<MIPS64_CP0_REG_NR;i++)      fprintf(fd,"%s: %16.16llx\n",              mips64_cp0_reg_names[i],cpu->cp0.reg[i]);   printf("\n");   /* cp1 registers */   for(i=0;i<MIPS64_CP1_REG_NR;i++)      fprintf(fd,"fpu%d: %16.16llx\n",i,cpu->fpu.reg[i]);   printf("\n");   /* tlb entries */   for(i=0;i<cpu->cp0.tlb_entries;i++) {      fprintf(fd,"tlb%d_mask: %16.16llx\n",i,cpu->cp0.tlb[i].mask);      fprintf(fd,"tlb%d_hi: %16.16llx\n",i,cpu->cp0.tlb[i].hi);      fprintf(fd,"tlb%d_lo0: %16.16llx\n",i,cpu->cp0.tlb[i].lo0);      fprintf(fd,"tlb%d_lo1: %16.16llx\n",i,cpu->cp0.tlb[i].lo1);   }   fclose(fd);   return(0);}/* Read a 64-bit unsigned integer */static m_uint64_t mips64_hex_u64(char *str,int *err){   m_uint64_t res = 0;   u_char c;   /* remove leading spaces */   while((*str == ' ') || (*str == '\t'))      str++;   while(*str) {      c = *str;      if ((c >= '0') && (c <= '9'))         res = (res << 4) + (c - '0');      if ((c >= 'a') && (c <= 'f'))         res = (res << 4) + ((c - 'a') + 10);      if ((c >= 'A') && (c <= 'F'))         res = (res << 4) + ((c - 'A') + 10);      str++;   }   return(res);}/* Restore the CPU state from a file */int mips64_restore_state(cpu_mips_t *cpu,char *filename){   char buffer[4096],*sep,*value,*ep,*field;   size_t len;   FILE *fd;   int index;   if (!(fd = fopen(filename,"r"))) {      perror("mips64_restore_state: fopen");      return(-1);   }   while(!feof(fd))   {      *buffer = 0;      fgets(buffer,sizeof(buffer),fd);      len = strlen(buffer);      if (buffer[len-1] == '\n')         buffer[len-1] = 0;      sep = strchr(buffer,':');      if (!sep) continue;      value = sep + 1;      *sep = 0;      /* gpr ? */      if ((index = mips64_get_reg_index(buffer)) != -1) {         cpu->gpr[index] = mips64_hex_u64(value,NULL);         continue;      }      /* cp0 register ? */      if ((index = mips64_cp0_get_reg_index(buffer)) != -1) {         cpu->cp0.reg[index] = mips64_hex_u64(value,NULL);         continue;      }      /* cp1 register ? */      if ((len > 3) && (!strncmp(buffer,"fpu",3))) {         index = atoi(buffer+3);         cpu->fpu.reg[index] = mips64_hex_u64(value,NULL);              }      /* tlb entry ? */      if ((len > 3) && (!strncmp(buffer,"tlb",3))) {         ep = strchr(buffer,'_');         if (ep) {            index = atoi(buffer+3);            field = ep + 1;                        if (!strcmp(field,"mask")) {               cpu->cp0.tlb[index].mask = mips64_hex_u64(value,NULL);               continue;            }            if (!strcmp(field,"hi")) {               cpu->cp0.tlb[index].hi = mips64_hex_u64(value,NULL);               continue;            }            if (!strcmp(field,"lo0")) {               cpu->cp0.tlb[index].lo0 = mips64_hex_u64(value,NULL);               continue;            }            if (!strcmp(field,"lo1")) {               cpu->cp0.tlb[index].lo1 = mips64_hex_u64(value,NULL);               continue;            }         }      }            /* pc, lo, hi ? */      if (!strcmp(buffer,"pc")) {         cpu->pc = mips64_hex_u64(value,NULL);         continue;      }      if (!strcmp(buffer,"lo")) {         cpu->lo = mips64_hex_u64(value,NULL);         continue;      }      if (!strcmp(buffer,"hi")) {         cpu->hi = mips64_hex_u64(value,NULL);         continue;      }   }   mips64_cp0_map_all_tlb_to_mts(cpu);   mips64_dump_regs(cpu->gen);   mips64_tlb_dump(cpu->gen);   fclose(fd);   return(0);}/* Load a raw image into the simulated memory */int mips64_load_raw_image(cpu_mips_t *cpu,char *filename,m_uint64_t vaddr){      struct stat file_info;   size_t len,clen;   m_uint32_t remain;   void *haddr;   FILE *bfd;   if (!(bfd = fopen(filename,"r"))) {      perror("fopen");      return(-1);   }   if (fstat(fileno(bfd),&file_info) == -1) {      perror("stat");      return(-1);   }   len = file_info.st_size;   printf("Loading RAW file '%s' at virtual address 0x%llx (size=%lu)\n",          filename,vaddr,(u_long)len);   while(len > 0)   {      haddr = cpu->mem_op_lookup(cpu,vaddr);         if (!haddr) {         fprintf(stderr,"load_raw_image: invalid load address 0x%llx\n",                 vaddr);         return(-1);      }      if (len > MIPS_MIN_PAGE_SIZE)         clen = MIPS_MIN_PAGE_SIZE;      else         clen = len;      remain = MIPS_MIN_PAGE_SIZE;      remain -= (vaddr - (vaddr & MIPS_MIN_PAGE_MASK));            clen = m_min(clen,remain);      if (fread((u_char *)haddr,clen,1,bfd) != 1)         break;            vaddr += clen;      len -= clen;   }      fclose(bfd);   return(0);}/* Load an ELF image into the simulated memory */int mips64_load_elf_image(cpu_mips_t *cpu,char *filename,int skip_load,                          m_uint32_t *entry_point){   m_uint64_t vaddr;   m_uint32_t remain;   void *haddr;   Elf32_Ehdr *ehdr;   Elf32_Shdr *shdr;   Elf_Scn *scn;   Elf *img_elf;   size_t len,clen;   char *name;   int i,fd;   FILE *bfd;   if (!filename)      return(-1);#ifdef __CYGWIN__   fd = open(filename,O_RDONLY|O_BINARY);#else   fd = open(filename,O_RDONLY);#endif   if (fd == -1) {      perror("load_elf_image: open");      return(-1);   }   if (elf_version(EV_CURRENT) == EV_NONE) {      fprintf(stderr,"load_elf_image: library out of date\n");      return(-1);   }   if (!(img_elf = elf_begin(fd,ELF_C_READ,NULL))) {      fprintf(stderr,"load_elf_image: elf_begin: %s\n",              elf_errmsg(elf_errno()));      return(-1);   }   if (!(ehdr = elf32_getehdr(img_elf))) {      fprintf(stderr,"load_elf_image: invalid ELF file\n");      return(-1);   }   printf("Loading ELF file '%s'...\n",filename);   bfd = fdopen(fd,"rb");   if (!bfd) {      perror("load_elf_image: fdopen");      return(-1);   }   if (!skip_load) {      for(i=0;i<ehdr->e_shnum;i++) {         scn = elf_getscn(img_elf,i);         shdr = elf32_getshdr(scn);         name = elf_strptr(img_elf, ehdr->e_shstrndx, (size_t)shdr->sh_name);         len  = shdr->sh_size;         if (!(shdr->sh_flags & SHF_ALLOC) || !len)            continue;         fseek(bfd,shdr->sh_offset,SEEK_SET);         vaddr = sign_extend(shdr->sh_addr,32);         if (cpu->vm->debug_level > 0) {            printf("   * Adding section at virtual address 0x%8.8llx "                   "(len=0x%8.8lx)\n",vaddr & 0xFFFFFFFF,(u_long)len);         }                  while(len > 0)         {            haddr = cpu->mem_op_lookup(cpu,vaddr);               if (!haddr) {               fprintf(stderr,"load_elf_image: invalid load address 0x%llx\n",                       vaddr);               return(-1);            }            if (len > MIPS_MIN_PAGE_SIZE)               clen = MIPS_MIN_PAGE_SIZE;            else               clen = len;            remain = PPC32_MIN_PAGE_SIZE;            remain -= (vaddr - (vaddr & PPC32_MIN_PAGE_MASK));            clen = m_min(clen,remain);            if (fread((u_char *)haddr,clen,1,bfd) < 1)               break;            vaddr += clen;            len -= clen;         }      }   } else {      printf("ELF loading skipped, using a ghost RAM file.\n");   }   printf("ELF entry point: 0x%x\n",ehdr->e_entry);   if (entry_point)      *entry_point = ehdr->e_entry;   elf_end(img_elf);   fclose(bfd);   return(0);}/* Symbol lookup */struct symbol *mips64_sym_lookup(cpu_mips_t *cpu,m_uint64_t addr){   return(rbtree_lookup(cpu->sym_tree,&addr));}/* Insert a new symbol */struct symbol *mips64_sym_insert(cpu_mips_t *cpu,char *name,m_uint64_t addr){   struct symbol *sym;   size_t len;   if (!cpu->sym_tree)      return NULL;   len = strlen(name);   if (!(sym = malloc(len+1+sizeof(*sym))))      return NULL;      memcpy(sym->name,name,len+1);   sym->addr = addr;   if (rbtree_insert(cpu->sym_tree,sym,sym) == -1) {      free(sym);      return NULL;   }   return sym;}/* Symbol comparison function */static int mips64_sym_compare(m_uint64_t *a1,struct symbol *sym){   if (*a1 > sym->addr)      return(1);   if (*a1 < sym->addr)      return(-1);   return(0);}/* Create the symbol tree */int mips64_sym_create_tree(cpu_mips_t *cpu){   cpu->sym_tree = rbtree_create((tree_fcompare)mips64_sym_compare,NULL);   return(cpu->sym_tree ? 0 : -1);}/* Load a symbol file */int mips64_sym_load_file(cpu_mips_t *cpu,char *filename){   char buffer[4096],func_name[128];   m_uint64_t addr;   char sym_type;   FILE *fd;   if (!cpu->sym_tree && (mips64_sym_create_tree(cpu) == -1)) {      fprintf(stderr,"CPU%u: Unable to create symbol tree.\n",cpu->gen->id);      return(-1);   }   if (!(fd = fopen(filename,"r"))) {      perror("load_sym_file: fopen");      return(-1);   }   while(!feof(fd)) {      fgets(buffer,sizeof(buffer),fd);      if (sscanf(buffer,"%llx %c %s",&addr,&sym_type,func_name) == 3) {         mips64_sym_insert(cpu,func_name,addr);      }   }   fclose(fd);   return(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -