srconv.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,032 行 · 第 1/3 页

C
2,032
字号
    }#else  dus.drb[0] = 0;  dus.fname[0] = sfile->name;#endif  sysroff_swap_dus_out (file, &dus);}/* Find the offset of the .text section for this sfile in the   .text section for the output file */static intfind_base (sfile, section)     struct coff_sfile *sfile;     struct coff_section *section;{  return sfile->section[section->number].low;}static voidwr_dln (p, sfile, n)     struct coff_ofile *p ATTRIBUTE_UNUSED;     struct coff_sfile *sfile;     int n ATTRIBUTE_UNUSED;{#if 0  if (n == 0)    {      /* Count up all the linenumbers */      struct coff_symbol *sy;      int lc = 0;      struct IT_dln dln;      int idx;      for (sy = p->symbol_list_head;	   sy;	   sy = sy->next_in_ofile_list)	{	  struct coff_type *t = sy->type;	  if (t->type == coff_function_type)	    {	      struct coff_line *l = t->u.function.lines;	      lc += l->nlines;	    }	}      dln.sfn = nints (lc);      dln.sln = nints (lc);      dln.lln = nints (lc);      dln.section = nints (lc);      dln.from_address = nints (lc);      dln.to_address = nints (lc);      dln.neg = 0x1001;      dln.nln = lc;      /* Run through once more and fill up the structure */      idx = 0;      for (sy = p->symbol_list_head;	   sy;	   sy = sy->next_in_ofile_list)	{	  if (sy->type->type == coff_function_type)	    {	      int i;	      struct coff_line *l = sy->type->u.function.lines;	      for (i = 0; i < l->nlines; i++)		{		  dln.section[idx] = sy->where->section->number;		  dln.sfn[idx] = n;		  dln.sln[idx] = l->lines[i];		  dln.from_address[idx] = l->addresses[i];		  if (idx)		    dln.to_address[idx - 1] = dln.from_address[idx];		  idx++;		}	    }	  n++;	}      sysroff_swap_dln_out (file, &dln);    }#endif#if 1  /* Count up all the linenumbers */  struct coff_symbol *sy;  int lc = 0;  struct IT_dln dln;  int idx;  for (sy = sfile->scope->vars_head;       sy;       sy = sy->next)    {      struct coff_type *t = sy->type;      if (t->type == coff_function_type)	{	  struct coff_line *l = t->u.function.lines;	  if (l)	    lc += l->nlines;	}    }  dln.sfn = nints (lc);  dln.sln = nints (lc);  dln.cc = nints (lc);  dln.section = nints (lc);  dln.from_address = nints (lc);  dln.to_address = nints (lc);  dln.neg = 0x1001;  dln.nln = lc;  /* Run through once more and fill up the structure */  idx = 0;  for (sy = sfile->scope->vars_head;       sy;       sy = sy->next)    {      if (sy->type->type == coff_function_type)	{	  int i;	  struct coff_line *l = sy->type->u.function.lines;	  if (l)	    {	      int base = find_base (sfile, sy->where->section);	      for (i = 0; i < l->nlines; i++)		{		  dln.section[idx] = sy->where->section->number;		  dln.sfn[idx] = 0;		  dln.sln[idx] = l->lines[i];		  dln.from_address[idx] =		    l->addresses[i] + sy->where->section->address - base;		  dln.cc[idx] = 0;		  if (idx)		    dln.to_address[idx - 1] = dln.from_address[idx];		  idx++;		}	      dln.to_address[idx - 1] = dln.from_address[idx - 1] + 2;	    }	}    }  if (lc)    sysroff_swap_dln_out (file, &dln);#endif}/* Write the global symbols out to the debug info */static voidwr_globals (p, sfile, n)     struct coff_ofile *p;     struct coff_sfile *sfile;     int n ATTRIBUTE_UNUSED;{  struct coff_symbol *sy;  for (sy = p->symbol_list_head;       sy;       sy = sy->next_in_ofile_list)    {      if (sy->visible->type == coff_vis_ext_def	  || sy->visible->type == coff_vis_ext_ref)	{	  /* Only write out symbols if they belong to	     the current source file */	  if (sy->sfile == sfile)	    walk_tree_symbol (sfile, 0, sy, 0);	}    }}static voidwr_debug (p)     struct coff_ofile *p;{  struct coff_sfile *sfile;  int n = 0;  for (sfile = p->source_head;       sfile;       sfile = sfile->next)    {      if (debug)	{	  printf ("%s\n", sfile->name);	}      wr_du (p, sfile, n);      wr_dus (p, sfile);      wr_program_structure (p, sfile);      wr_dln (p, sfile, n);      n++;    }}static voidwr_cs (){  /* It seems that the CS struct is not normal - the size is wrong     heres one I prepared earlier.. */  static char b[] = {    0x80,			/* IT */    0x21,			/* RL */    0x00,			/* number of chars in variable length part */    0x80,			/* hd */     0x00,			/* hs */     0x80,			/* un */     0x00,			/* us */     0x80,			/* sc */     0x00,			/* ss */     0x80,			/* er */     0x80,			/* ed */     0x80,			/* sh */     0x80,			/* ob */     0x80,			/* rl */     0x80,			/* du */    0x80,			/* dps */    0x80,			/* dsy */    0x80,			/* dty */    0x80,			/* dln */    0x80,			/* dso */    0x80,			/* dus */    0x00,			/* dss */    0x80,			/* dbt */    0x00,			/* dpp */    0x80,			/* dfp */    0x80,			/* den */    0x80,			/* dds */    0x80,			/* dar */    0x80,			/* dpt */    0x00,			/* dul */    0x00,			/* dse */    0x00,			/* dot */    0xDE			/* CS */  };  fwrite (b, 1, sizeof (b), file);}/* Write out the SC records for a unit.  Create an SC   for all the sections which appear in the output file, even   if there isn't an equivalent one on the input */static intwr_sc (ptr, sfile)     struct coff_ofile *ptr;     struct coff_sfile *sfile;{  int i;int scount = 0;  /* First work out the total number of sections */  int total_sec = ptr->nsections;  struct myinfo    {      struct coff_section *sec;      struct coff_symbol *symbol;    };  struct coff_symbol *symbol;  struct myinfo *info    = (struct myinfo *) calloc (total_sec, sizeof (struct myinfo));  for (i = 0; i < total_sec; i++)    {      info[i].sec = ptr->sections + i;      info[i].symbol = 0;    }  for (symbol = sfile->scope->vars_head;       symbol;       symbol = symbol->next)    {      if (symbol->type->type == coff_secdef_type)	{	  for (i = 0; i < total_sec; i++)	    {	      if (symbol->where->section == info[i].sec)		{		  info[i].symbol = symbol;		  break;		}	    }	}    }  /* Now output all the section info, and fake up some stuff for sections     we don't have */  for (i = 1; i < total_sec; i++)    {      struct IT_sc sc;      char *name;      symbol = info[i].symbol;      sc.spare = 0;      sc.spare1 = 0;      if (!symbol)	{	  /* Don't have a symbol set aside for this section, which means that nothing	     in this file does anything for the section. */	  sc.format = !(bfd_get_file_flags (abfd) & EXEC_P);	  sc.addr = 0;	  sc.length = 0;	  name = info[i].sec->name;	}      else	{	  if (bfd_get_file_flags (abfd) & EXEC_P)	    {	      sc.format = 0;	      sc.addr = symbol->where->offset;	    }	  else	    {	      sc.format = 1;	      sc.addr = 0;	    }	  sc.length = symbol->type->size;	  name = symbol->name;	}      sc.align = 4;      sc.concat = CONCAT_SIMPLE;      sc.read = 3;      sc.write = 3;      sc.exec = 3;      sc.init = 3;      sc.mode = 3;      sc.spare = 0;      sc.segadd = 0;      sc.spare1 = 0;		/* If not zero, then it doesn't work */      sc.name = section_translate (name);      if (strlen (sc.name) == 1)	{	  switch (sc.name[0])	    {	    case 'D':	    case 'B':	      sc.contents = CONTENTS_DATA;	      break;	    default:	      sc.contents = CONTENTS_CODE;	    }	}      else	{	  sc.contents = CONTENTS_CODE;	}#if 0      /* NEW */      if (sc.length) {#endif	sysroff_swap_sc_out (file, &sc);	scount++;#if 0      }#endif    }return scount;}/* Write out the ER records for a unit. */static voidwr_er (ptr, sfile, first)     struct coff_ofile *ptr;     struct coff_sfile *sfile ATTRIBUTE_UNUSED;     int first;{  int idx = 0;  struct coff_symbol *sym;  if (first)    {      for (sym = ptr->symbol_list_head; sym; sym = sym->next_in_ofile_list)	{	  if (sym->visible->type == coff_vis_ext_ref)	    {	      struct IT_er er;	      er.spare = 0;	      er.type = ER_NOTSPEC;	      er.name = sym->name;	      sysroff_swap_er_out (file, &er);	      sym->er_number = idx++;	    }	}    }}/* Write out the ED records for a unit. */static voidwr_ed (ptr, sfile, first)     struct coff_ofile *ptr;     struct coff_sfile *sfile ATTRIBUTE_UNUSED;     int first;{  struct coff_symbol *s;  if (first)    {      for (s = ptr->symbol_list_head; s; s = s->next_in_ofile_list)	{	  if (s->visible->type == coff_vis_ext_def	      || s->visible->type == coff_vis_common)	    {	      struct IT_ed ed;	      ed.section = s->where->section->number;	      ed.spare = 0;	      if (s->where->section->data)		{		  ed.type = ED_TYPE_DATA;		}	      else if (s->where->section->code & SEC_CODE)		{		  ed.type = ED_TYPE_ENTRY;		}	      else		{		  ed.type = ED_TYPE_NOTSPEC;		  ed.type = ED_TYPE_DATA;		}	      ed.address = s->where->offset - s->where->section->address;	      ed.name = s->name;	      sysroff_swap_ed_out (file, &ed);	    }	}    }}static voidwr_unit_info (ptr)     struct coff_ofile *ptr;{  struct coff_sfile *sfile;  int first = 1;  for (sfile = ptr->source_head;       sfile;       sfile = sfile->next)    {      long p1;      long p2;      int nsecs;      p1 = ftell (file);      wr_un (ptr, sfile, first, 0);      nsecs = wr_sc (ptr, sfile);      p2 = ftell (file);      fseek (file, p1, SEEK_SET);      wr_un (ptr, sfile, first, nsecs);      fseek (file, p2, SEEK_SET);       wr_er (ptr, sfile, first);      wr_ed (ptr, sfile, first);      first = 0;    }}static voidwr_module (p)     struct coff_ofile *p;{  wr_cs ();  wr_hd (p);  wr_unit_info (p);  wr_object_body (p);  wr_debug (p);  wr_tr ();}static intalign (x)     int x;{  return (x + 3) & ~3;}/* Find all the common variables and turn them into   ordinary defs - dunno why, but thats what hitachi does with 'em */static voidprescan (tree)     struct coff_ofile *tree;{  struct coff_symbol *s;  struct coff_section *common_section;  /* Find the common section - always section 3 */  common_section = tree->sections + 3;  for (s = tree->symbol_list_head;       s;       s = s->next_in_ofile_list)    {      if (s->visible->type == coff_vis_common)	{	  struct coff_where *w = s->where;	  /*      s->visible->type = coff_vis_ext_def; leave it as common */	  common_section->size = align (common_section->size);	  w->offset = common_section->size + common_section->address;	  w->section = common_section;	  common_section->size += s->type->size;	  common_section->size = align (common_section->size);	}    }}char *program_name;static voidshow_usage (file, status)     FILE *file;     int status;{  fprintf (file, _("Usage: %s [-dhVq] in-file [out-file]\n"), program_name);  exit (status);}static voidshow_help (){  printf (_("%s: Convert a COFF object file into a SYSROFF object file\n"),	  program_name);  show_usage (stdout, 0);}intmain (ac, av)     int ac;     char *av[];{  int opt;  static struct option long_options[] =  {    {"debug", no_argument, 0, 'd'},    {"quick", no_argument, 0, 'q'},    {"noprescan", no_argument, 0, 'n'},    {"help", no_argument, 0, 'h'},    {"version", no_argument, 0, 'V'},    {NULL, no_argument, 0, 0}  };  char **matching;  char *input_file;  char *output_file;#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)  setlocale (LC_MESSAGES, "");#endif  bindtextdomain (PACKAGE, LOCALEDIR);  textdomain (PACKAGE);  program_name = av[0];  xmalloc_set_program_name (program_name);  while ((opt = getopt_long (ac, av, "dhVqn", long_options,			     (int *) NULL))	 != EOF)    {      switch (opt)	{	case 'q':	  quick = 1;	  break;	case 'n':	  noprescan = 1;	  break;	case 'd':	  debug = 1;	  break;	case 'h':	  show_help ();	  /*NOTREACHED */	case 'V':	  printf (_("GNU %s version %s\n"), program_name, PROGRAM_VERSION);	  exit (0);	  /*NOTREACHED */	case 0:	  break;	default:	  show_usage (stderr, 1);	  /*NOTREACHED */	}    }  /* The input and output files may be named on the command line.  */  output_file = NULL;  if (optind < ac)    {      input_file = av[optind];      ++optind;      if (optind < ac)	{	  output_file = av[optind];	  ++optind;	  if (optind < ac)	    show_usage (stderr, 1);	  if (strcmp (input_file, output_file) == 0)	    {	      fatal (_("input and output files must be different"));	    }	}    }  else    input_file = 0;  if (!input_file)    {      fatal (_("no input file specified"));    }  if (!output_file)    {      /* Take a .o off the input file and stick on a .obj.  If         it doesn't end in .o, then stick a .obj on anyway */      int len = strlen (input_file);      output_file = xmalloc (len + 5);      strcpy (output_file, input_file);      if (len > 3	  && output_file[len - 2] == '.'	  && output_file[len - 1] == 'o')	{	  output_file[len] = 'b';	  output_file[len + 1] = 'j';	  output_file[len + 2] = 0;	}      else	{	  strcat (output_file, ".obj");	}    }  abfd = bfd_openr (input_file, 0);  if (!abfd)    bfd_fatal (input_file);  if (!bfd_check_format_matches (abfd, bfd_object, &matching))    {      bfd_nonfatal (input_file);      if (bfd_get_error () == bfd_error_file_ambiguously_recognized)	{	  list_matching_formats (matching);	  free (matching);	}      exit (1);    }  file = fopen (output_file, FOPEN_WB);  if (!file)    {      fatal (_("unable to open output file %s"), output_file);    }  if (debug)    printf ("ids %d %d\n", base1, base2);  tree = coff_grok (abfd);  if (!noprescan)    prescan (tree);  wr_module (tree);  return 0;}

⌨️ 快捷键说明

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