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

📄 load.c

📁 ARM7的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
static int file_start_context = 0;      /* --file-start-context */#define SHOW_PRECEDING_CONTEXT_LINES (5)/* Show the line number, or the source line, in a dissassembly   listing.  */static voidshow_line (abfd, section, addr_offset)     bfd *abfd;     asection *section;     bfd_vma addr_offset;{  const char *filename;  const char *functionname;  unsigned int line;  if (! with_line_numbers && ! with_source_code)    return;  if (! bfd_find_nearest_line (abfd, section, syms, addr_offset, &filename,			       &functionname, &line))    return;  if (filename != NULL && *filename == '\0')    filename = NULL;  if (functionname != NULL && *functionname == '\0')    functionname = NULL;  if (with_line_numbers)    {      if (functionname != NULL	  && (prev_functionname == NULL	      || strcmp (functionname, prev_functionname) != 0))	printf ("%s():\n", functionname);      if (line > 0 && line != prev_line)	printf ("%s:%u\n", filename == NULL ? "???" : filename, line);    }  if (with_source_code      && filename != NULL      && line > 0)    {      struct print_file_list **pp, *p;      for (pp = &print_files; *pp != NULL; pp = &(*pp)->next)	if (strcmp ((*pp)->filename, filename) == 0)	  break;      p = *pp;      if (p != NULL)	{	  if (p != print_files)	    {	      int l;	      /* We have reencountered a file name which we saw		 earlier.  This implies that either we are dumping out		 code from an included file, or the same file was		 linked in more than once.  There are two common cases		 of an included file: inline functions in a header		 file, and a bison or flex skeleton file.  In the		 former case we want to just start printing (but we		 back up a few lines to give context); in the latter		 case we want to continue from where we left off.  I		 can't think of a good way to distinguish the cases,		 so I used a heuristic based on the file name.  */	      if (strcmp (p->filename + strlen (p->filename) - 2, ".h") != 0)		l = p->line;	      else		{		  l = line - SHOW_PRECEDING_CONTEXT_LINES;		  if (l < 0)		    l = 0;		}	      if (p->f == NULL)		{		  p->f = fopen (p->filename, "r");		  p->line = 0;		}	      if (p->f != NULL)		skip_to_line (p, l, FALSE);	      if (print_files->f != NULL)		{		  fclose (print_files->f);		  print_files->f = NULL;		}	    }	  if (p->f != NULL)	    {	      skip_to_line (p, line, TRUE);	      *pp = p->next;	      p->next = print_files;	      print_files = p;	    }	}      else	{	  FILE *f;	  f = fopen (filename, "r");	  if (f != NULL)	    {	      int l;	      p = ((struct print_file_list *)		   xmalloc (sizeof (struct print_file_list)));	      p->filename = xmalloc (strlen (filename) + 1);	      strcpy (p->filename, filename);	      p->line = 0;	      p->f = f;	      if (print_files != NULL && print_files->f != NULL)		{		  fclose (print_files->f);		  print_files->f = NULL;		}	      p->next = print_files;	      print_files = p;	      if (file_start_context)		l = 0;	      else		l = line - SHOW_PRECEDING_CONTEXT_LINES;	      if (l < 0)		l = 0;	      skip_to_line (p, l, FALSE);	      if (p->f != NULL)		skip_to_line (p, line, TRUE);	    }	}    }  if (functionname != NULL      && (prev_functionname == NULL	  || strcmp (functionname, prev_functionname) != 0))    {      if (prev_functionname != NULL)	free (prev_functionname);      prev_functionname = xmalloc (strlen (functionname) + 1);      strcpy (prev_functionname, functionname);    }  if (line > 0 && line != prev_line)    prev_line = line;}/* Disassemble some data in memory between given values.  */static voiddisassemble_bytes (info, disassemble_fn, insns, data,		   start_offset, stop_offset, relppp,		   relppend)     struct disassemble_info *info;     disassembler_ftype disassemble_fn;     bfd_boolean insns;     bfd_byte *data;     bfd_vma start_offset;     bfd_vma stop_offset;     arelent ***relppp;     arelent **relppend;{  struct objdump_disasm_info *aux;  asection *section;  int octets_per_line;  bfd_boolean done_dot;  int skip_addr_chars;  bfd_vma addr_offset;  int opb = info->octets_per_byte;  aux = (struct objdump_disasm_info *) info->application_data;  section = aux->sec;  if (insns)    octets_per_line = 4;  else    octets_per_line = 16;  /* Figure out how many characters to skip at the start of an     address, to make the disassembly look nicer.  We discard leading     zeroes in chunks of 4, ensuring that there is always a leading     zero remaining.  */  skip_addr_chars = 0;  if (! prefix_addresses)    {      char buf[30];      char *s;      bfd_sprintf_vma	(aux->abfd, buf,	 (section->vma	  + bfd_section_size (section->owner, section) / opb));      s = buf;      while (s[0] == '0' && s[1] == '0' && s[2] == '0' && s[3] == '0'	     && s[4] == '0')	{	  skip_addr_chars += 4;	  s += 4;	}    }  info->insn_info_valid = 0;  done_dot = FALSE;  addr_offset = start_offset;  while (addr_offset < stop_offset)    {      bfd_vma z;      int octets = 0;      bfd_boolean need_nl = FALSE;      /* If we see more than SKIP_ZEROES octets of zeroes, we just         print `...'.  */      for (z = addr_offset * opb; z < stop_offset * opb; z++)	if (data[z] != 0)	  break;      if (! disassemble_zeroes	  && (info->insn_info_valid == 0	      || info->branch_delay_insns == 0)	  && (z - addr_offset * opb >= SKIP_ZEROES	      || (z == stop_offset * opb &&		  z - addr_offset * opb < SKIP_ZEROES_AT_END)))	{	  printf ("\t...\n");	  /* If there are more nonzero octets to follow, we only skip             zeroes in multiples of 4, to try to avoid running over             the start of an instruction which happens to start with             zero.  */	  if (z != stop_offset * opb)	    z = addr_offset * opb + ((z - addr_offset * opb) &~ 3);	  octets = z - addr_offset * opb;	}      else	{	  char buf[50];	  SFILE sfile;	  int bpc = 0;	  int pb = 0;	  done_dot = FALSE;	  if (with_line_numbers || with_source_code)	    /* The line number tables will refer to unadjusted	       section VMAs, so we must undo any VMA modifications	       when calling show_line.  */	    show_line (aux->abfd, section, addr_offset - adjust_section_vma);	  if (! prefix_addresses)	    {	      char *s;	      bfd_sprintf_vma (aux->abfd, buf, section->vma + addr_offset);	      for (s = buf + skip_addr_chars; *s == '0'; s++)		*s = ' ';	      if (*s == '\0')		*--s = '0';	      printf ("%s:\t", buf + skip_addr_chars);	    }	  else	    {	      aux->require_sec = TRUE;	      objdump_print_address (section->vma + addr_offset, info);	      aux->require_sec = FALSE;	      putchar (' ');	    }	  if (insns)	    {	      sfile.size = 120;	      sfile.buffer = xmalloc (sfile.size);	      sfile.current = sfile.buffer;	      info->fprintf_func = (fprintf_ftype) objdump_sprintf;	      info->stream = (FILE *) &sfile;	      info->bytes_per_line = 0;	      info->bytes_per_chunk = 0;#ifdef DISASSEMBLER_NEEDS_RELOCS	      /* FIXME: This is wrong.  It tests the number of octets                 in the last instruction, not the current one.  */	      if (*relppp < relppend		  && (**relppp)->address >= addr_offset		  && (**relppp)->address <= addr_offset + octets / opb)		info->flags = INSN_HAS_RELOC;	      else#endif		info->flags = 0;	      octets = (*disassemble_fn) (section->vma + addr_offset, info);	      info->fprintf_func = (fprintf_ftype) fprintf;	      info->stream = stdout;	      if (info->bytes_per_line != 0)		octets_per_line = info->bytes_per_line;	      if (octets < 0)		{		  if (sfile.current != sfile.buffer)		    printf ("%s\n", sfile.buffer);		  free (sfile.buffer);		  break;		}	    }	  else	    {	      bfd_vma j;	      octets = octets_per_line;	      if (addr_offset + octets / opb > stop_offset)		octets = (stop_offset - addr_offset) * opb;	      for (j = addr_offset * opb; j < addr_offset * opb + octets; ++j)		{		  if (isprint (data[j]))		    buf[j - addr_offset * opb] = data[j];		  else		    buf[j - addr_offset * opb] = '.';		}	      buf[j - addr_offset * opb] = '\0';	    }	  if (prefix_addresses	      ? show_raw_insn > 0	      : show_raw_insn >= 0)	    {	      bfd_vma j;	      /* If ! prefix_addresses and ! wide_output, we print                 octets_per_line octets per line.  */	      pb = octets;	      if (pb > octets_per_line && ! prefix_addresses && ! wide_output)		pb = octets_per_line;	      if (info->bytes_per_chunk)		bpc = info->bytes_per_chunk;	      else		bpc = 1;	      for (j = addr_offset * opb; j < addr_offset * opb + pb; j += bpc)		{		  int k;		  if (bpc > 1 && info->display_endian == BFD_ENDIAN_LITTLE)		    {		      for (k = bpc - 1; k >= 0; k--)			printf ("%02x", (unsigned) data[j + k]);		      putchar (' ');		    }		  else		    {		      for (k = 0; k < bpc; k++)			printf ("%02x", (unsigned) data[j + k]);		      putchar (' ');		    }		}	      for (; pb < octets_per_line; pb += bpc)		{		  int k;		  for (k = 0; k < bpc; k++)		    printf ("  ");		  putchar (' ');		}	      /* Separate raw data from instruction by extra space.  */	      if (insns)		putchar ('\t');	      else		printf ("    ");	    }	  if (! insns)	    printf ("%s", buf);	  else	    {	      printf ("%s", sfile.buffer);	      free (sfile.buffer);	    }	  if (prefix_addresses	      ? show_raw_insn > 0	      : show_raw_insn >= 0)	    {	      while (pb < octets)		{		  bfd_vma j;		  char *s;		  putchar ('\n');		  j = addr_offset * opb + pb;		  bfd_sprintf_vma (aux->abfd, buf, section->vma + j / opb);		  for (s = buf + skip_addr_chars; *s == '0'; s++)		    *s = ' ';		  if (*s == '\0')		    *--s = '0';		  printf ("%s:\t", buf + skip_addr_chars);		  pb += octets_per_line;		  if (pb > octets)		    pb = octets;		  for (; j < addr_offset * opb + pb; j += bpc)		    {		      int k;		      if (bpc > 1 && info->display_endian == BFD_ENDIAN_LITTLE)			{			  for (k = bpc - 1; k >= 0; k--)			    printf ("%02x", (unsigned) data[j + k]);			  putchar (' ');			}		      else			{			  for (k = 0; k < bpc; k++)			    printf ("%02x", (unsigned) data[j + k]);			  putchar (' ');			}		    }		}	    }	  if (!wide_output)	    putchar ('\n');	  else	    need_nl = TRUE;	}      if ((section->flags & SEC_RELOC) != 0#ifndef DISASSEMBLER_NEEDS_RELOCS	  && dump_reloc_info#endif	  )	{	  while ((*relppp) < relppend		 && ((**relppp)->address >= (bfd_vma) addr_offset		     && (**relppp)->address < (bfd_vma) addr_offset + octets / opb))#ifdef DISASSEMBLER_NEEDS_RELOCS	    if (! dump_reloc_info)	      ++(*relppp);	    else#endif	    {	      arelent *q;	      q = **relppp;	      if (wide_output)		putchar ('\t');	      else		printf ("\t\t\t");	      objdump_print_value (section->vma + q->address, info, TRUE);	      printf (": %s\t", q->howto->name);	      if (q->sym_ptr_ptr == NULL || *q->sym_ptr_ptr == NULL)		printf ("*unknown*");	      else		{		  const char *sym_name;		  sym_name = bfd_asymbol_name (*q->sym_ptr_ptr);		  if (sym_name != NULL && *sym_name != '\0')		    objdump_print_symname (aux->abfd, info, *q->sym_ptr_ptr);		  else		    {		      asection *sym_sec;		      sym_sec = bfd_get_section (*q->sym_ptr_ptr);		      sym_name = bfd_get_section_name (aux->abfd, sym_sec);		      if (sym_name == NULL || *sym_name == '\0')			sym_name = "*unknown*";		      printf ("%s", sym_name);		    }		}	      if (q->addend)		{		  printf ("+0x");		  objdump_print_value (q->addend, info, TRUE);		}	      printf ("\n");	      need_nl = FALSE;	      ++(*relppp);	    }	}      if (need_nl)	printf ("\n");      addr_offset += octets / opb;    }}/* Disassemble the contents of an object file.  */static voiddisassemble_data (abfd)     bfd *abfd;{  unsigned long addr_offset;  disassembler_ftype disassemble_fn;  struct disassemble_info disasm_info;  struct objdump_disasm_info aux;  asection *section;  unsigned int opb;  print_files = NULL;  prev_functionname = NULL;  prev_line = -1;  /* We make a copy of syms to sort.  We don't want to sort syms     because that will screw up the relocs.  */  sorted_syms = (asymbol **) xmalloc (symcount * sizeof (asymbol *));  memcpy (sorted_syms, syms, symcount * sizeof (asymbol *));  sorted_symcount = remove_useless_symbols (sorted_syms, symcount);  /* Sort the symbols into section and symbol order.  */  qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);  INIT_DISASSEMBLE_INFO (disasm_info, stdout, fprintf);  disasm_info.application_data = (PTR) &aux;  aux.abfd = abfd;  aux.require_sec = FALSE;  disasm_info.print_address_func = objdump_print_address;  disasm_info.symbol_at_address_func = objdump_symbol_at_address;  if (machine != (char *) NULL)    {      const bfd_arch_info_type *info = bfd_scan_arch (machine);      if (info == NULL)	fatal ("Can't use supplied machine %s", machine);      abfd->arch_info = info;    }  if (endian != BFD_ENDIAN_UNKNOWN)    {      struct bfd_target *xvec;      xvec = (struct bfd_target *) xmalloc (sizeof (struct bfd_target));      memcpy (xvec, abfd->xvec, sizeof (struct bfd_target));      xvec->byteorder = endian;      abfd->xvec = xvec;    }  disassemble_fn = disassembler (abfd);  if (!disassemble_fn)    {      non_fatal ("Can't disassemble for architecture %s\n",		 bfd_printable_arch_mach (bfd_get_arch (abfd), 0));      exit_status = 1;      return;    }  opb = bfd_octets_per_byte (abfd);  disasm_info.flavour = bfd_get_flavour (abfd);  disasm_info.arch = bfd_get_arch (abfd);  disasm_info.mach = bfd_get_mach (abfd);  disasm_info.disassembler_options = disassembler_options;  disasm_info.octets_per_byte = opb;  if (bfd_big_endian (abfd))    disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_BIG;  else if (bfd_little_endian (abfd))    disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_LITTLE;  else    /* ??? Aborting here seems too drastic.  We could default to big or little       instead.  */    disasm_info.endian = BFD_ENDIAN_UNKNOWN;  for (section = abfd->sections;       section != (asection *) NULL;       section = section->next)    {      bfd_byte *data = NULL;      bfd_size_type datasize = 0;      arelent **relbuf = NULL;      arelent **relpp = NULL;      arelent **relppend = NULL;      unsigned long stop_offset;      asymbol *sym = NULL;      long place = 0;      if ((section->flags & SEC_LOAD) == 0	  || (! disassemble_all	      && only == NULL	      && (section->flags & SEC_CODE) == 0))	continue;      if (only != (char *) NULL && strcmp (only, section->name) != 0)	continue;      if ((section->flags & SEC_RELOC) != 0#ifndef DISASSEMBLER_NEEDS_RELOCS	  && dump_reloc_info#endif	  )	{	  long relsize;	  relsize = bfd_get_reloc_upper_bound (abfd, section);	  if (relsize < 0)	    bfd_fatal (bfd_get_filename (abfd));	  if (relsize > 0)	    {	      long relcount;	      relbuf = (arelent **) xmalloc (relsize);	      relcount = bfd_canonicalize_reloc (abfd, section, relbuf, syms);	      if (relcount < 0)		bfd_fatal (bfd_get_filename (abfd));	      /* Sort the relocs by address.  */	      qsort (relbuf, relcount, sizeof (arelent *), compare_relocs);	      relpp = relbuf;	      relppend = relpp + relcount;	      /* Skip over the relocs belonging to addresses below the		 start address.  */	      if (start_address != (bfd_vma) -1)

⌨️ 快捷键说明

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