coffgrok.c

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

C
738
字号
/* coffgrok.c   Copyright 1994, 1995, 1997, 1998, 2000 Free Software Foundation, Inc.This file is part of GNU Binutils.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  *//* Written by Steve Chamberlain (sac@cygnus.com)   This module reads a coff file and builds a really simple type tree   which can be read by other programs.  The first application is a   coff->sysroff converter.  It can be tested with coffdump.c.*/#include <bfd.h>#include "bucomm.h"#include "coff/internal.h"#include "../bfd/libcoff.h"#include "coffgrok.h"int lofile = 1;static struct coff_scope *top_scope;static struct coff_scope *file_scope;static struct coff_ofile *ofile;struct coff_symbol *last_function_symbol;struct coff_type *last_function_type;struct coff_type *last_struct;struct coff_type *last_enum;struct coff_sfile *cur_sfile;static struct coff_symbol **tindex;static asymbol **syms;static long symcount;#define N(x) ((x)->_n._n_nptr[1])static struct coff_ptr_struct *rawsyms;static int rawcount;static bfd *abfd;extern char *xcalloc ();#define PTR_SIZE 	4#define SHORT_SIZE 	2#define INT_SIZE 	4#define LONG_SIZE 	4#define FLOAT_SIZE 	4#define DOUBLE_SIZE 	8#define INDEXOF(p)  ((struct coff_ptr_struct *)(p)-(rawsyms))static struct coff_scope *empty_scope (){  struct coff_scope *l;  l = (struct coff_scope *) (xcalloc (sizeof (struct coff_scope), 1));  return l;}static struct coff_symbol *empty_symbol (){  return (struct coff_symbol *) (xcalloc (sizeof (struct coff_symbol), 1));}/*int l;*/static voidpush_scope (link)     int link;{  struct coff_scope *n = empty_scope ();  if (link)    {      if (top_scope)	{	  if (top_scope->list_tail)	    {	      top_scope->list_tail->next = n;	    }	  else	    {	      top_scope->list_head = n;	    }	  top_scope->list_tail = n;	}    }  n->parent = top_scope;  top_scope = n;}static voidpop_scope (){  top_scope = top_scope->parent;}static voiddo_sections_p1 (head)     struct coff_ofile *head;{  asection *section;  int idx;  struct coff_section *all = (struct coff_section *) (xcalloc (abfd->section_count + 1,					     sizeof (struct coff_section)));  head->nsections = abfd->section_count + 1;  head->sections = all;  for (idx = 0, section = abfd->sections; section; section = section->next, idx++)    {      long relsize;      int i = section->target_index;      arelent **relpp;      long relcount;      relsize = bfd_get_reloc_upper_bound (abfd, section);      if (relsize < 0)	bfd_fatal (bfd_get_filename (abfd));      if (relsize == 0)        continue;      relpp = (arelent **) xmalloc (relsize);      relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms);      if (relcount < 0)	bfd_fatal (bfd_get_filename (abfd));      head->sections[i].name = (char *) (section->name);      head->sections[i].code = section->flags & SEC_CODE;      head->sections[i].data = section->flags & SEC_DATA;      if (strcmp (section->name, ".bss") == 0)	head->sections[i].data = 1;      head->sections[i].address = section->lma;      head->sections[i].size = section->_raw_size;      head->sections[i].number = idx;      head->sections[i].nrelocs = section->reloc_count;      head->sections[i].relocs =	(struct coff_reloc *) (xcalloc (section->reloc_count,					sizeof (struct coff_reloc)));      head->sections[i].bfd_section = section;    }  head->sections[0].name = "ABSOLUTE";  head->sections[0].code = 0;  head->sections[0].data = 0;  head->sections[0].address = 0;  head->sections[0].size = 0;  head->sections[0].number = 0;}static voiddo_sections_p2 (head)     struct coff_ofile *head;{  asection *section;  for (section = abfd->sections; section; section = section->next)    {      unsigned int j;      for (j = 0; j < section->reloc_count; j++)	{	  int idx;	  int i = section->target_index;	  struct coff_reloc *r = head->sections[i].relocs + j;	  arelent *sr = section->relocation + j;	  r->offset = sr->address;	  r->addend = sr->addend;	  idx = ((coff_symbol_type *) (sr->sym_ptr_ptr[0]))->native - rawsyms;	  r->symbol = tindex[idx];	}    }}static struct coff_where *do_where (i)     int i;{  struct internal_syment *sym = &rawsyms[i].u.syment;  struct coff_where *where =    (struct coff_where *) (xmalloc (sizeof (struct coff_where)));  where->offset = sym->n_value;  if (sym->n_scnum == -1)    sym->n_scnum = 0;  switch (sym->n_sclass)    {    case C_FIELD:      where->where = coff_where_member_of_struct;      where->offset = sym->n_value / 8;      where->bitoffset = sym->n_value % 8;      where->bitsize = rawsyms[i + 1].u.auxent.x_sym.x_misc.x_lnsz.x_size;      break;    case C_MOE:      where->where = coff_where_member_of_enum;      break;    case C_MOS:    case C_MOU:      where->where = coff_where_member_of_struct;      break;    case C_AUTO:    case C_ARG:      where->where = coff_where_stack;      break;    case C_EXT:    case C_STAT:    case C_EXTDEF:    case C_LABEL:      where->where = coff_where_memory;      where->section = &ofile->sections[sym->n_scnum];      break;    case C_REG:    case C_REGPARM:      where->where = coff_where_register;      break;    case C_ENTAG:      where->where = coff_where_entag;      break;    case C_STRTAG:    case C_UNTAG:      where->where = coff_where_strtag;      break;    case C_TPDEF:      where->where = coff_where_typedef;      break;    default:      abort ();      break;    }  return where;}staticstruct coff_line *do_lines (i, name)     int i;     char *name ATTRIBUTE_UNUSED;{  struct coff_line *res = (struct coff_line *) xcalloc (sizeof (struct coff_line), 1);  asection *s;  unsigned int l;  /* Find out if this function has any line numbers in the table */  for (s = abfd->sections; s; s = s->next)    {      for (l = 0; l < s->lineno_count; l++)	{	  if (s->lineno[l].line_number == 0)	    {	      if (rawsyms + i == ((coff_symbol_type *) (&(s->lineno[l].u.sym[0])))->native)		{		  /* These lines are for this function - so count them and stick them on */		  int c = 0;		  /* Find the linenumber of the top of the function, since coff linenumbers		     are relative to the start of the function. */		  int start_line = rawsyms[i + 3].u.auxent.x_sym.x_misc.x_lnsz.x_lnno;		  l++;		  for (c = 0; s->lineno[l + c + 1].line_number; c++)		    ;		  /* Add two extra records, one for the prologue and one for the epilogue */		  c += 1;		  res->nlines = c;		  res->lines = (int *) (xcalloc (sizeof (int), c));		  res->addresses = (int *) (xcalloc (sizeof (int), c));		  res->lines[0] = start_line;		  res->addresses[0] = rawsyms[i].u.syment.n_value - s->vma;		  for (c = 0; s->lineno[l + c + 1].line_number; c++)		    {		      res->lines[c + 1] = s->lineno[l + c].line_number + start_line - 1;		      res->addresses[c + 1] = s->lineno[l + c].u.offset;		    }		  return res;		}	    }	}    }  return res;}staticstruct coff_type *do_type (i)     int i;{  struct internal_syment *sym = &rawsyms[i].u.syment;  union internal_auxent *aux = &rawsyms[i + 1].u.auxent;  struct coff_type *res =    (struct coff_type *) xmalloc (sizeof (struct coff_type));  int type = sym->n_type;  int which_dt = 0;  int dimind = 0;  res->type = coff_basic_type;  res->u.basic = type & 0xf;  switch (type & 0xf)    {    case T_NULL:    case T_VOID:      if (sym->n_numaux && sym->n_sclass == C_STAT)	{	  /* This is probably a section definition */	  res->type = coff_secdef_type;	  res->size = aux->x_scn.x_scnlen;	}      else	{	  if (type == 0)	    {	      /* Don't know what this is, let's make it a simple int */	      res->size = INT_SIZE;	      res->u.basic = T_UINT;	    }	  else	    {	      /* Else it could be a function or pointer to void */	      res->size = 0;	    }	}      break;      break;    case T_UCHAR:    case T_CHAR:      res->size = 1;      break;    case T_USHORT:    case T_SHORT:      res->size = SHORT_SIZE;      break;    case T_UINT:    case T_INT:      res->size = INT_SIZE;      break;    case T_ULONG:    case T_LONG:      res->size = LONG_SIZE;      break;    case T_FLOAT:      res->size = FLOAT_SIZE;      break;    case T_DOUBLE:      res->size = DOUBLE_SIZE;      break;    case T_STRUCT:    case T_UNION:      if (sym->n_numaux)	{	  if (aux->x_sym.x_tagndx.p)	    {	      /* Refering to a struct defined elsewhere */	      res->type = coff_structref_type;	      res->u.astructref.ref = tindex[INDEXOF (aux->x_sym.x_tagndx.p)];	      res->size = res->u.astructref.ref ?		res->u.astructref.ref->type->size : 0;

⌨️ 快捷键说明

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