rdcoff.c

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

C
908
字号
	  bitpos = bfd_asymbol_value (sym);	  bitsize = auxent.x_sym.x_misc.x_lnsz.x_size;	  break;	case C_EOS:	  done = true;	  break;	}      if (! done)	{	  debug_type ftype;	  debug_field f;	  ftype = parse_coff_type (abfd, symbols, types, this_coff_symno,				   syment.n_type, psubaux, true, dhandle);	  f = debug_make_field (dhandle, bfd_asymbol_name (sym), ftype,				bitpos, bitsize, DEBUG_VISIBILITY_PUBLIC);	  if (f == DEBUG_FIELD_NULL)	    return DEBUG_TYPE_NULL;	  if (count + 1 >= alloc)	    {	      alloc += 10;	      fields = ((debug_field *)			xrealloc (fields, alloc * sizeof *fields));	    }	  fields[count] = f;	  ++count;	}    }  fields[count] = DEBUG_FIELD_NULL;  return debug_make_struct_type (dhandle, ntype == T_STRUCT,				 pauxent->x_sym.x_misc.x_lnsz.x_size,				 fields);}/* Parse an enum type.  */static debug_typeparse_coff_enum_type (abfd, symbols, types, pauxent, dhandle)     bfd *abfd;     struct coff_symbols *symbols;     struct coff_types *types ATTRIBUTE_UNUSED;     union internal_auxent *pauxent;     PTR dhandle;{  long symend;  int alloc;  const char **names;  bfd_signed_vma *vals;  int count;  boolean done;  symend = pauxent->x_sym.x_fcnary.x_fcn.x_endndx.l;  alloc = 10;  names = (const char **) xmalloc (alloc * sizeof *names);  vals = (bfd_signed_vma *) xmalloc (alloc * sizeof *vals);  count = 0;  done = false;  while (! done	 && symbols->coff_symno < symend	 && symbols->symno < symbols->symcount)    {      asymbol *sym;      struct internal_syment syment;      sym = symbols->syms[symbols->symno];      if (! bfd_coff_get_syment (abfd, sym, &syment))	{	  non_fatal (_("bfd_coff_get_syment failed: %s"),		     bfd_errmsg (bfd_get_error ()));	  return DEBUG_TYPE_NULL;	}      ++symbols->symno;      symbols->coff_symno += 1 + syment.n_numaux;      switch (syment.n_sclass)	{	case C_MOE:	  if (count + 1 >= alloc)	    {	      alloc += 10;	      names = ((const char **)		       xrealloc (names, alloc * sizeof *names));	      vals = ((bfd_signed_vma *)		      xrealloc (vals, alloc * sizeof *vals));	    }	  names[count] = bfd_asymbol_name (sym);	  vals[count] = bfd_asymbol_value (sym);	  ++count;	  break;	case C_EOS:	  done = true;	  break;	}    }  names[count] = NULL;  return debug_make_enum_type (dhandle, names, vals);}/* Handle a single COFF symbol.  */static booleanparse_coff_symbol (abfd, types, sym, coff_symno, psyment, dhandle, type,		   within_function)     bfd *abfd ATTRIBUTE_UNUSED;     struct coff_types *types;     asymbol *sym;     long coff_symno;     struct internal_syment *psyment;     PTR dhandle;     debug_type type;     boolean within_function;{  switch (psyment->n_sclass)    {    case C_NULL:      break;    case C_AUTO:      if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,				   DEBUG_LOCAL, bfd_asymbol_value (sym)))	return false;      break;    case C_WEAKEXT:    case C_EXT:      if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,				   DEBUG_GLOBAL, bfd_asymbol_value (sym)))	return false;      break;    case C_STAT:      if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,				   (within_function				    ? DEBUG_LOCAL_STATIC				    : DEBUG_STATIC),				   bfd_asymbol_value (sym)))	return false;      break;    case C_REG:      /* FIXME: We may need to convert the register number.  */      if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,				   DEBUG_REGISTER, bfd_asymbol_value (sym)))	return false;      break;    case C_LABEL:      break;    case C_ARG:      if (! debug_record_parameter (dhandle, bfd_asymbol_name (sym), type,				    DEBUG_PARM_STACK, bfd_asymbol_value (sym)))	return false;      break;    case C_REGPARM:      /* FIXME: We may need to convert the register number.  */      if (! debug_record_parameter (dhandle, bfd_asymbol_name (sym), type,				    DEBUG_PARM_REG, bfd_asymbol_value (sym)))	return false;      break;    case C_TPDEF:      type = debug_name_type (dhandle, bfd_asymbol_name (sym), type);      if (type == DEBUG_TYPE_NULL)	return false;      break;    case C_STRTAG:    case C_UNTAG:    case C_ENTAG:      {	debug_type *slot;	type = debug_tag_type (dhandle, bfd_asymbol_name (sym), type);	if (type == DEBUG_TYPE_NULL)	  return false;	/* Store the named type into the slot, so that references get           the name.  */	slot = coff_get_slot (types, coff_symno);	*slot = type;      }      break;    default:      break;    }  return true;				   }/* Determine if a symbol has external visibility.  */static booleanexternal_coff_symbol_p (sym_class)     int sym_class;{  switch (sym_class)    {      case C_EXT:      case C_WEAKEXT:        return true;    default:      break;    }  return false;         }/* This is the main routine.  It looks through all the symbols and   handles them.  */booleanparse_coff (abfd, syms, symcount, dhandle)     bfd *abfd;     asymbol **syms;     long symcount;     PTR dhandle;{  struct coff_symbols symbols;  struct coff_types types;  int i;  long next_c_file;  const char *fnname;  int fnclass;  int fntype;  bfd_vma fnend;  alent *linenos;  boolean within_function;  long this_coff_symno;  symbols.syms = syms;  symbols.symcount = symcount;  symbols.symno = 0;  symbols.coff_symno = 0;  types.slots = NULL;  for (i = 0; i <= T_MAX; i++)    types.basic[i] = DEBUG_TYPE_NULL;  next_c_file = -1;  fnname = NULL;  fnclass = 0;  fntype = 0;  fnend = 0;  linenos = NULL;  within_function = false;  while (symbols.symno < symcount)    {      asymbol *sym;      const char *name;      struct internal_syment syment;      union internal_auxent auxent;      union internal_auxent *paux;      debug_type type;      sym = syms[symbols.symno];      if (! bfd_coff_get_syment (abfd, sym, &syment))	{	  non_fatal (_("bfd_coff_get_syment failed: %s"),		     bfd_errmsg (bfd_get_error ()));	  return false;	}      name = bfd_asymbol_name (sym);      this_coff_symno = symbols.coff_symno;      ++symbols.symno;      symbols.coff_symno += 1 + syment.n_numaux;      /* We only worry about the first auxent, because that is the	 only one which is relevant for debugging information.  */      if (syment.n_numaux == 0)	paux = NULL;      else	{	  if (! bfd_coff_get_auxent (abfd, sym, 0, &auxent))	    {	      non_fatal (_("bfd_coff_get_auxent failed: %s"),			 bfd_errmsg (bfd_get_error ()));	      return false;	    }	  paux = &auxent;	}      if (this_coff_symno == next_c_file && syment.n_sclass != C_FILE)	{	  /* The last C_FILE symbol points to the first external             symbol.  */	  if (! debug_set_filename (dhandle, "*globals*"))	    return false;	}      switch (syment.n_sclass)	{	case C_EFCN:	case C_EXTDEF:	case C_ULABEL:	case C_USTATIC:	case C_LINE:	case C_ALIAS:	case C_HIDDEN:	  /* Just ignore these classes.  */	  break;	case C_FILE:	  next_c_file = syment.n_value;	  if (! debug_set_filename (dhandle, name))	    return false;	  break;	case C_STAT:	  /* Ignore static symbols with a type of T_NULL.  These             represent section entries.  */	  if (syment.n_type == T_NULL)	    break;	  /* Fall through.  */ 	case C_WEAKEXT:	case C_EXT:	  if (ISFCN (syment.n_type))	    {	      fnname = name;	      fnclass = syment.n_sclass;	      fntype = syment.n_type;	      if (syment.n_numaux > 0)		fnend = bfd_asymbol_value (sym) + auxent.x_sym.x_misc.x_fsize;	      else		fnend = 0;	      linenos = BFD_SEND (abfd, _get_lineno, (abfd, sym));	      break;	    }	  type = parse_coff_type (abfd, &symbols, &types, this_coff_symno,				  syment.n_type, paux, true, dhandle);	  if (type == DEBUG_TYPE_NULL)	    return false;	  if (! parse_coff_symbol (abfd, &types, sym, this_coff_symno, &syment,				   dhandle, type, within_function))	    return false;	  break;	case C_FCN:	  if (strcmp (name, ".bf") == 0)	    {	      if (fnname == NULL)		{		  non_fatal (_("%ld: .bf without preceding function"),			     this_coff_symno);		  return false;		}	      type = parse_coff_type (abfd, &symbols, &types, this_coff_symno,				      DECREF (fntype), paux, false, dhandle);	      if (type == DEBUG_TYPE_NULL)		return false;	      if (! debug_record_function (dhandle, fnname, type,					   external_coff_symbol_p (fnclass),					   bfd_asymbol_value (sym)))		return false;	      if (linenos != NULL)		{		  int base;		  bfd_vma addr;		  if (syment.n_numaux == 0)		    base = 0;		  else		    base = auxent.x_sym.x_misc.x_lnsz.x_lnno - 1;		  addr = bfd_get_section_vma (abfd, bfd_get_section (sym));		  ++linenos;		  while (linenos->line_number != 0)		    {		      if (! debug_record_line (dhandle,					       linenos->line_number + base,					       linenos->u.offset + addr))			return false;		      ++linenos;		    }		}	      fnname = NULL;	      linenos = NULL;	      fnclass = 0;	      fntype = 0;	      within_function = true;	    }	  else if (strcmp (name, ".ef") == 0)	    {	      if (! within_function)		{		  non_fatal (_("%ld: unexpected .ef\n"), this_coff_symno);		  return false;		}	      if (bfd_asymbol_value (sym) > fnend)		fnend = bfd_asymbol_value (sym);	      if (! debug_end_function (dhandle, fnend))		return false;	      fnend = 0;	      within_function = false;	    }	  break;	case C_BLOCK:	  if (strcmp (name, ".bb") == 0)	    {	      if (! debug_start_block (dhandle, bfd_asymbol_value (sym)))		return false;	    }	  else if (strcmp (name, ".eb") == 0)	    {	      if (! debug_end_block (dhandle, bfd_asymbol_value (sym)))		return false;	    }	  break;	default:	  type = parse_coff_type (abfd, &symbols, &types, this_coff_symno,				  syment.n_type, paux, true, dhandle);	  if (type == DEBUG_TYPE_NULL)	    return false;	  if (! parse_coff_symbol (abfd, &types, sym, this_coff_symno, &syment,				   dhandle, type, within_function))	    return false;	  break;	}    }  return true;}

⌨️ 快捷键说明

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