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

📄 arm-dis.c

📁 qemu性能直逼VMware的仿真器QEMU 的模擬速度約為實機的 25%;約為 Bochs 的 60 倍。Plex86、User-Mode-Linux、VMware 和 Virtual PC 則比
💻 C
📖 第 1 页 / 共 4 页
字号:
		  func (stream, "blx\t");		  offset &= 0xfffffffc;		}	      else		func (stream, "bl\t");	      info->print_address_func (offset, info);              return 4;            }          else            {	      info->bytes_per_chunk = 2;	      info->bytes_per_line  = 4;	  	                    given &= 0xffff;	                    for (; *c; c++)                {                  if (*c == '%')                    {                      int domaskpc = 0;                      int domasklr = 0;		                            switch (*++c)                        {                        case '%':                          func (stream, "%%");                          break;                        case 'S':                          {                            long reg;			                                reg = (given >> 3) & 0x7;                            if (given & (1 << 6))                              reg += 8;			                                func (stream, "%s", arm_regnames[reg]);                          }                          break;                        case 'D':                          {                            long reg;			                                reg = given & 0x7;                            if (given & (1 << 7))                             reg += 8;			                                func (stream, "%s", arm_regnames[reg]);                          }                          break;                        case 'T':                          func (stream, "%s",                                arm_conditional [(given >> 8) & 0xf]);                          break;                        case 'N':                          if (given & (1 << 8))                            domasklr = 1;                          /* Fall through.  */                        case 'O':                          if (*c == 'O' && (given & (1 << 8)))                            domaskpc = 1;                          /* Fall through.  */                        case 'M':                          {                            int started = 0;                            int reg;			                                func (stream, "{");			                                /* It would be nice if we could spot                               ranges, and generate the rS-rE format: */                            for (reg = 0; (reg < 8); reg++)                              if ((given & (1 << reg)) != 0)                                {                                  if (started)                                    func (stream, ", ");                                  started = 1;                                  func (stream, "%s", arm_regnames[reg]);                                }                            if (domasklr)                              {                                if (started)                                  func (stream, ", ");                                started = 1;                                func (stream, arm_regnames[14] /* "lr" */);                              }                            if (domaskpc)                              {                                if (started)                                  func (stream, ", ");                                func (stream, arm_regnames[15] /* "pc" */);                              }                            func (stream, "}");                          }                          break;                        case '0': case '1': case '2': case '3': case '4':                         case '5': case '6': case '7': case '8': case '9':                          {                            int bitstart = *c++ - '0';                            int bitend = 0;			                                while (*c >= '0' && *c <= '9')                              bitstart = (bitstart * 10) + *c++ - '0';                            switch (*c)                              {                              case '-':                                {                                  long reg;				                                    c++;                                  while (*c >= '0' && *c <= '9')                                    bitend = (bitend * 10) + *c++ - '0';                                  if (!bitend)                                    abort ();                                  reg = given >> bitstart;                                  reg &= (2 << (bitend - bitstart)) - 1;                                  switch (*c)                                    {                                    case 'r':                                      func (stream, "%s", arm_regnames[reg]);                                      break;                                    case 'd':                                      func (stream, "%d", reg);                                      break;                                    case 'H':                                      func (stream, "%d", reg << 1);                                      break;                                    case 'W':                                      func (stream, "%d", reg << 2);                                      break;                                    case 'a':				      /* PC-relative address -- the bottom two					 bits of the address are dropped					 before the calculation.  */                                      info->print_address_func					(((pc + 4) & ~3) + (reg << 2), info);                                      break;                                    case 'x':                                      func (stream, "0x%04x", reg);                                      break;                                    case 'I':                                      reg = ((reg ^ (1 << bitend)) - (1 << bitend));                                      func (stream, "%d", reg);                                      break;                                    case 'B':                                      reg = ((reg ^ (1 << bitend)) - (1 << bitend));                                      (*info->print_address_func)                                        (reg * 2 + pc + 4, info);                                      break;                                    default:                                      abort ();                                    }                                }                                break;                              case '\'':                                c++;                                if ((given & (1 << bitstart)) != 0)                                  func (stream, "%c", *c);                                break;                              case '?':                                ++c;                                if ((given & (1 << bitstart)) != 0)                                  func (stream, "%c", *c++);                                else                                  func (stream, "%c", *++c);                                break;                              default:                                 abort ();                              }                          }                          break;                        default:                          abort ();                        }                    }                  else                    func (stream, "%c", *c);                }             }          return 2;       }    }  /* No match.  */  abort ();}/* Parse an individual disassembler option.  */voidparse_arm_disassembler_option (option)     char * option;{  if (option == NULL)    return;        if (strneq (option, "reg-names-", 10))    {      int i;	      option += 10;      for (i = NUM_ARM_REGNAMES; i--;)	if (streq (option, regnames[i].name))	  {	    regname_selected = i;	    break;	  }            if (i < 0)	fprintf (stderr, _("Unrecognised register name set: %s\n"), option);    }  else if (streq (option, "force-thumb"))    force_thumb = 1;  else if (streq (option, "no-force-thumb"))    force_thumb = 0;  else    fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);    return;}/* Parse the string of disassembler options, spliting it at whitespaces.  */static voidparse_disassembler_options (options)     char * options;{  char * space;    if (options == NULL)    return;  do    {      space = strchr (options, ' ');      if (space)	{	  * space = '\0';	  parse_arm_disassembler_option (options);	  * space = ' ';	  options = space + 1;	}      else	parse_arm_disassembler_option (options);    }  while (space);}/* NOTE: There are no checks in these routines that   the relevant number of data bytes exist.  */intprint_insn_arm (pc, info)     bfd_vma pc;     struct disassemble_info * info;{  unsigned char      b[4];  long               given;  int                status;  int                is_thumb;  int little;  if (info->disassembler_options)    {      parse_disassembler_options (info->disassembler_options);            /* To avoid repeated parsing of these options, we remove them here.  */      info->disassembler_options = NULL;    }    is_thumb = force_thumb;  if (pc & 1)    {      is_thumb = 1;      pc &= ~(bfd_vma) 1;    }  #if 0  if (!is_thumb && info->symbols != NULL)    {      if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)	{	  coff_symbol_type * cs;	  	  cs = coffsymbol (*info->symbols);	  is_thumb = (   cs->native->u.syment.n_sclass == C_THUMBEXT		      || cs->native->u.syment.n_sclass == C_THUMBSTAT		      || cs->native->u.syment.n_sclass == C_THUMBLABEL		      || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC		      || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);	}      else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)	{	  elf_symbol_type *  es;	  unsigned int       type;	  	  es = *(elf_symbol_type **)(info->symbols);	  type = ELF_ST_TYPE (es->internal_elf_sym.st_info);	  	  is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);	}    }#endif    little = (info->endian == BFD_ENDIAN_LITTLE);  info->bytes_per_chunk = 4;  info->display_endian  = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;  if (little)    {      status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);      if (status != 0 && is_thumb)	{	  info->bytes_per_chunk = 2;	  	  status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);	  b[3] = b[2] = 0;	}            if (status != 0)	{	  info->memory_error_func (status, pc, info);	  return -1;	}            given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);    }  else    {      status = info->read_memory_func	(pc & ~ 0x3, (bfd_byte *) &b[0], 4, info);      if (status != 0)	{	  info->memory_error_func (status, pc, info);	  return -1;	}            if (is_thumb)	{	  if (pc & 0x2)	    {	      given = (b[2] << 8) | b[3];	      	      status = info->read_memory_func		((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info);	      if (status != 0)		{		  info->memory_error_func (status, pc + 4, info);		  return -1;		}	      	      given |= (b[0] << 24) | (b[1] << 16);	    }	  else	    given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);	}      else	given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);    }    if (info->flags & INSN_HAS_RELOC)    /* If the instruction has a reloc associated with it, then       the offset field in the instruction will actually be the       addend for the reloc.  (We are using REL type relocs).       In such cases, we can ignore the pc when computing       addresses, since the addend is not currently pc-relative.  */    pc = 0;  if (is_thumb)    status = print_insn_thumb (pc, info, given);  else    status = print_insn_arm1 (pc, info, given);  return status;}voidprint_arm_disassembler_options (FILE * stream){  int i;  fprintf (stream, _("\n\The following ARM specific disassembler options are supported for use with\n\the -M switch:\n"));    for (i = NUM_ARM_REGNAMES; i--;)    fprintf (stream, "  reg-names-%s %*c%s\n",	     regnames[i].name,	     (int)(14 - strlen (regnames[i].name)), ' ',	     regnames[i].description);  fprintf (stream, "  force-thumb              Assume all insns are Thumb insns\n");  fprintf (stream, "  no-force-thumb           Examine preceeding label to determine an insn's type\n\n");}

⌨️ 快捷键说明

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