coffgrok.c

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

C
738
字号
	    }	  else	    {	      /* A definition of a struct */	      last_struct = res;	      res->type = coff_structdef_type;	      res->u.astructdef.elements = empty_scope ();	      res->u.astructdef.idx = 0;	      res->u.astructdef.isstruct = (type & 0xf) == T_STRUCT;	      res->size = aux->x_sym.x_misc.x_lnsz.x_size;	    }	}      else	{	  /* No auxents - it's anonynmous */	  res->type = coff_structref_type;	  res->u.astructref.ref = 0;	  res->size = 0;	}      break;    case T_ENUM:      if (aux->x_sym.x_tagndx.p)	{	  /* Refering to a enum defined elsewhere */	  res->type = coff_enumref_type;	  res->u.aenumref.ref = tindex[INDEXOF (aux->x_sym.x_tagndx.p)];	  res->size = res->u.aenumref.ref->type->size;	}      else	{	  /* A definition of an enum */	  last_enum = res;	  res->type = coff_enumdef_type;	  res->u.aenumdef.elements = empty_scope ();	  res->size = aux->x_sym.x_misc.x_lnsz.x_size;	}      break;    case T_MOE:      break;    }  for (which_dt = 5; which_dt >= 0; which_dt--)    {      switch ((type >> ((which_dt * 2) + 4)) & 0x3)	{	case 0:	  break;	case DT_ARY:	  {	    struct coff_type *ptr = ((struct coff_type *)				     xmalloc (sizeof (struct coff_type)));	    int els = (dimind < DIMNUM		       ? aux->x_sym.x_fcnary.x_ary.x_dimen[dimind]		       : 0);	    ++dimind;	    ptr->type = coff_array_type;	    ptr->size = els * res->size;	    ptr->u.array.dim = els;	    ptr->u.array.array_of = res;	    res = ptr;	    break;	  }	case DT_PTR:	  {	    struct coff_type *ptr =	      (struct coff_type *) xmalloc (sizeof (struct coff_type));	    ptr->size = PTR_SIZE;	    ptr->type = coff_pointer_type;	    ptr->u.pointer.points_to = res;	    res = ptr;	    break;	  }	case DT_FCN:	  {	    struct coff_type *ptr	      = (struct coff_type *) xmalloc (sizeof (struct coff_type));	    ptr->size = 0;	    ptr->type = coff_function_type;	    ptr->u.function.function_returns = res;	    ptr->u.function.parameters = empty_scope ();	    ptr->u.function.lines = do_lines (i, sym->_n._n_nptr[1]);	    ptr->u.function.code = 0;	    last_function_type = ptr;	    res = ptr;	    break;	  }	}    }  return res;}static struct coff_visible *do_visible (i)     int i;{  struct internal_syment *sym = &rawsyms[i].u.syment;  struct coff_visible *visible =    (struct coff_visible *) (xmalloc (sizeof (struct coff_visible)));  enum coff_vis_type t;  switch (sym->n_sclass)    {    case C_MOS:    case C_MOU:    case C_FIELD:      t = coff_vis_member_of_struct;      break;    case C_MOE:      t = coff_vis_member_of_enum;      break;    case C_REGPARM:      t = coff_vis_regparam;      break;    case C_REG:      t = coff_vis_register;      break;    case C_STRTAG:    case C_UNTAG:    case C_ENTAG:    case C_TPDEF:      t = coff_vis_tag;      break;    case C_AUTOARG:    case C_ARG:      t = coff_vis_autoparam;      break;    case C_AUTO:      t = coff_vis_auto;      break;    case C_LABEL:    case C_STAT:      t = coff_vis_int_def;      break;    case C_EXT:      if (sym->n_scnum == N_UNDEF)	{	  if (sym->n_value)	    t = coff_vis_common;	  else	    t = coff_vis_ext_ref;	}      else	t = coff_vis_ext_def;      break;    default:      abort ();      break;    }  visible->type = t;  return visible;}static intdo_define (i, b)     int i;     struct coff_scope *b;{  static int symbol_index;  struct internal_syment *sym = &rawsyms[i].u.syment;  /* Define a symbol and attach to block b */  struct coff_symbol *s = empty_symbol ();  s->number = ++symbol_index;  s->name = sym->_n._n_nptr[1];  s->sfile = cur_sfile;  /* Glue onto the ofile list */  if (lofile >= 0)    {      if (ofile->symbol_list_tail)	ofile->symbol_list_tail->next_in_ofile_list = s;      else	ofile->symbol_list_head = s;      ofile->symbol_list_tail = s;      /* And the block list */    }  if (b->vars_tail)    b->vars_tail->next = s;  else    b->vars_head = s;  b->vars_tail = s;  b->nvars++;  s->type = do_type (i);  s->where = do_where (i);  s->visible = do_visible (i);  tindex[i] = s;  /* We remember the lowest address in each section for each source file */  if (s->where->where == coff_where_memory      && s->type->type == coff_secdef_type)    {      struct coff_isection *is = cur_sfile->section + s->where->section->number;      if (!is->init)	{	  is->low = s->where->offset;	  is->high = s->where->offset + s->type->size;	  is->init = 1;	  is->parent = s->where->section;	}    }  if (s->type->type == coff_function_type)    last_function_symbol = s;  return i + sym->n_numaux + 1;}staticstruct coff_ofile *doit (){  int i;  int infile = 0;  struct coff_ofile *head =  (struct coff_ofile *) xmalloc (sizeof (struct coff_ofile));  ofile = head;  head->source_head = 0;  head->source_tail = 0;  head->nsources = 0;  head->symbol_list_tail = 0;  head->symbol_list_head = 0;  do_sections_p1 (head);  push_scope (1);  for (i = 0; i < rawcount;)    {      struct internal_syment *sym = &rawsyms[i].u.syment;      switch (sym->n_sclass)	{	case C_FILE:	  {	    /* new source file announced */	    struct coff_sfile *n =	      (struct coff_sfile *) xmalloc (sizeof (struct coff_sfile));	    n->section = (struct coff_isection *) xcalloc (sizeof (struct coff_isection), abfd->section_count + 1);	    cur_sfile = n;	    n->name = sym->_n._n_nptr[1];	    n->next = 0;	    if (infile)	      {		pop_scope ();	      }	    infile = 1;	    push_scope (1);	    file_scope = n->scope = top_scope;	    if (head->source_tail)	      head->source_tail->next = n;	    else	      head->source_head = n;	    head->source_tail = n;	    head->nsources++;	    i += sym->n_numaux + 1;	  }	  break;	case C_FCN:	  {	    char *name = sym->_n._n_nptr[1];	    if (name[1] == 'b')	      {		/* Function start */		push_scope (0);		last_function_type->u.function.code = top_scope;		top_scope->sec = ofile->sections + sym->n_scnum;		top_scope->offset = sym->n_value;	      }	    else	      {		top_scope->size = sym->n_value - top_scope->offset + 1;		pop_scope ();	      }	    i += sym->n_numaux + 1;	  }	  break;	case C_BLOCK:	  {	    char *name = sym->_n._n_nptr[1];	    if (name[1] == 'b')	      {		/* Block start */		push_scope (1);		top_scope->sec = ofile->sections + sym->n_scnum;		top_scope->offset = sym->n_value;	      }	    else	      {		top_scope->size = sym->n_value - top_scope->offset + 1;		pop_scope ();	      }	    i += sym->n_numaux + 1;	  }	  break;	case C_REGPARM:	case C_ARG:	  i = do_define (i, last_function_symbol->type->u.function.parameters);	  break;	case C_MOS:	case C_MOU:	case C_FIELD:	  i = do_define (i, last_struct->u.astructdef.elements);	  break;	case C_MOE:	  i = do_define (i, last_enum->u.aenumdef.elements);	  break;	case C_STRTAG:	case C_ENTAG:	case C_UNTAG:	  /* Various definition */	  i = do_define (i, top_scope);	  break;	case C_EXT:	case C_LABEL:	  i = do_define (i, file_scope);	  break;	case C_STAT:	case C_TPDEF:	case C_AUTO:	case C_REG:	  i = do_define (i, top_scope);	  break;	default:	  abort ();	case C_EOS:	  i += sym->n_numaux + 1;	  break;	}    }  do_sections_p2 (head);  return head;}struct coff_ofile *coff_grok (inabfd)     bfd *inabfd;{  long storage;  struct coff_ofile *p;  abfd = inabfd;  storage = bfd_get_symtab_upper_bound (abfd);  if (storage < 0)    bfd_fatal (abfd->filename);  syms = (asymbol **) xmalloc (storage);  symcount = bfd_canonicalize_symtab (abfd, syms);  if (symcount < 0)    bfd_fatal (abfd->filename);  rawsyms = obj_raw_syments (abfd);  rawcount = obj_raw_syment_count (abfd);;  tindex = (struct coff_symbol **) (xcalloc (sizeof (struct coff_symbol *), rawcount));  p = doit ();  return p;}

⌨️ 快捷键说明

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