OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [binutils/] [coffgrok.c] - Diff between revs 156 and 816

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 156 Rev 816
/* coffgrok.c
/* coffgrok.c
   Copyright 1994, 1995, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2007
   Copyright 1994, 1995, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2007
   Free Software Foundation, Inc.
   Free Software Foundation, Inc.
 
 
   This file is part of GNU Binutils.
   This file is part of GNU Binutils.
 
 
   This program is free software; you can redistribute it and/or modify
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.
   (at your option) any later version.
 
 
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */
   MA 02110-1301, USA.  */
 
 
 
 
/* Written by Steve Chamberlain (sac@cygnus.com)
/* Written by Steve Chamberlain (sac@cygnus.com)
 
 
   This module reads a coff file and builds a really simple type tree
   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
   which can be read by other programs.  The first application is a
   coff->sysroff converter.  It can be tested with coffdump.c.  */
   coff->sysroff converter.  It can be tested with coffdump.c.  */
 
 
#include "sysdep.h"
#include "sysdep.h"
#include "bfd.h"
#include "bfd.h"
#include "libiberty.h"
#include "libiberty.h"
 
 
#include "coff/internal.h"
#include "coff/internal.h"
#include "../bfd/libcoff.h"
#include "../bfd/libcoff.h"
#include "bucomm.h"
#include "bucomm.h"
#include "coffgrok.h"
#include "coffgrok.h"
 
 
static int lofile = 1;
static int lofile = 1;
static struct coff_scope *top_scope;
static struct coff_scope *top_scope;
static struct coff_scope *file_scope;
static struct coff_scope *file_scope;
static struct coff_ofile *ofile;
static struct coff_ofile *ofile;
 
 
static struct coff_symbol *last_function_symbol;
static struct coff_symbol *last_function_symbol;
static struct coff_type *last_function_type;
static struct coff_type *last_function_type;
static struct coff_type *last_struct;
static struct coff_type *last_struct;
static struct coff_type *last_enum;
static struct coff_type *last_enum;
static struct coff_sfile *cur_sfile;
static struct coff_sfile *cur_sfile;
 
 
static struct coff_symbol **tindex;
static struct coff_symbol **tindex;
 
 
 
 
static asymbol **syms;
static asymbol **syms;
static long symcount;
static long symcount;
 
 
#define N(x) ((x)->_n._n_nptr[1])
#define N(x) ((x)->_n._n_nptr[1])
 
 
static struct coff_ptr_struct *rawsyms;
static struct coff_ptr_struct *rawsyms;
static int rawcount;
static int rawcount;
static bfd *abfd;
static bfd *abfd;
 
 
#define PTR_SIZE        4
#define PTR_SIZE        4
#define SHORT_SIZE      2
#define SHORT_SIZE      2
#define INT_SIZE        4
#define INT_SIZE        4
#define LONG_SIZE       4
#define LONG_SIZE       4
#define FLOAT_SIZE      4
#define FLOAT_SIZE      4
#define DOUBLE_SIZE     8
#define DOUBLE_SIZE     8
 
 
#define INDEXOF(p)  ((struct coff_ptr_struct *)(p)-(rawsyms))
#define INDEXOF(p)  ((struct coff_ptr_struct *)(p)-(rawsyms))
 
 
static struct coff_scope *empty_scope (void);
static struct coff_scope *empty_scope (void);
static struct coff_symbol *empty_symbol (void);
static struct coff_symbol *empty_symbol (void);
static void push_scope (int);
static void push_scope (int);
static void pop_scope (void);
static void pop_scope (void);
static void do_sections_p1 (struct coff_ofile *);
static void do_sections_p1 (struct coff_ofile *);
static void do_sections_p2 (struct coff_ofile *);
static void do_sections_p2 (struct coff_ofile *);
static struct coff_where *do_where (int);
static struct coff_where *do_where (int);
static struct coff_line *do_lines (int, char *);
static struct coff_line *do_lines (int, char *);
static struct coff_type *do_type (int);
static struct coff_type *do_type (int);
static struct coff_visible *do_visible (int);
static struct coff_visible *do_visible (int);
static int do_define (int, struct coff_scope *);
static int do_define (int, struct coff_scope *);
static struct coff_ofile *doit (void);
static struct coff_ofile *doit (void);
 
 
static struct coff_scope *
static struct coff_scope *
empty_scope (void)
empty_scope (void)
{
{
  struct coff_scope *l;
  struct coff_scope *l;
  l = (struct coff_scope *) (xcalloc (sizeof (struct coff_scope), 1));
  l = (struct coff_scope *) (xcalloc (sizeof (struct coff_scope), 1));
  return l;
  return l;
}
}
 
 
static struct coff_symbol *
static struct coff_symbol *
empty_symbol (void)
empty_symbol (void)
{
{
  return (struct coff_symbol *) (xcalloc (sizeof (struct coff_symbol), 1));
  return (struct coff_symbol *) (xcalloc (sizeof (struct coff_symbol), 1));
}
}
 
 
/*int l;*/
/*int l;*/
static void
static void
push_scope (int link)
push_scope (int link)
{
{
  struct coff_scope *n = empty_scope ();
  struct coff_scope *n = empty_scope ();
  if (link)
  if (link)
    {
    {
      if (top_scope)
      if (top_scope)
        {
        {
          if (top_scope->list_tail)
          if (top_scope->list_tail)
            {
            {
              top_scope->list_tail->next = n;
              top_scope->list_tail->next = n;
            }
            }
          else
          else
            {
            {
              top_scope->list_head = n;
              top_scope->list_head = n;
            }
            }
          top_scope->list_tail = n;
          top_scope->list_tail = n;
        }
        }
    }
    }
  n->parent = top_scope;
  n->parent = top_scope;
 
 
  top_scope = n;
  top_scope = n;
}
}
 
 
static void
static void
pop_scope (void)
pop_scope (void)
{
{
  top_scope = top_scope->parent;
  top_scope = top_scope->parent;
}
}
 
 
static void
static void
do_sections_p1 (struct coff_ofile *head)
do_sections_p1 (struct coff_ofile *head)
{
{
  asection *section;
  asection *section;
  int idx;
  int idx;
  struct coff_section *all = (struct coff_section *) (xcalloc (abfd->section_count + 1,
  struct coff_section *all = (struct coff_section *) (xcalloc (abfd->section_count + 1,
                                             sizeof (struct coff_section)));
                                             sizeof (struct coff_section)));
  head->nsections = abfd->section_count + 1;
  head->nsections = abfd->section_count + 1;
  head->sections = all;
  head->sections = all;
 
 
  for (idx = 0, section = abfd->sections; section; section = section->next, idx++)
  for (idx = 0, section = abfd->sections; section; section = section->next, idx++)
    {
    {
      long relsize;
      long relsize;
      int i = section->target_index;
      int i = section->target_index;
      arelent **relpp;
      arelent **relpp;
      long relcount;
      long relcount;
 
 
      relsize = bfd_get_reloc_upper_bound (abfd, section);
      relsize = bfd_get_reloc_upper_bound (abfd, section);
      if (relsize < 0)
      if (relsize < 0)
        bfd_fatal (bfd_get_filename (abfd));
        bfd_fatal (bfd_get_filename (abfd));
      if (relsize == 0)
      if (relsize == 0)
        continue;
        continue;
      relpp = (arelent **) xmalloc (relsize);
      relpp = (arelent **) xmalloc (relsize);
      relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms);
      relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms);
      if (relcount < 0)
      if (relcount < 0)
        bfd_fatal (bfd_get_filename (abfd));
        bfd_fatal (bfd_get_filename (abfd));
 
 
      head->sections[i].name = (char *) (section->name);
      head->sections[i].name = (char *) (section->name);
      head->sections[i].code = section->flags & SEC_CODE;
      head->sections[i].code = section->flags & SEC_CODE;
      head->sections[i].data = section->flags & SEC_DATA;
      head->sections[i].data = section->flags & SEC_DATA;
      if (strcmp (section->name, ".bss") == 0)
      if (strcmp (section->name, ".bss") == 0)
        head->sections[i].data = 1;
        head->sections[i].data = 1;
      head->sections[i].address = section->lma;
      head->sections[i].address = section->lma;
      head->sections[i].size = bfd_get_section_size (section);
      head->sections[i].size = bfd_get_section_size (section);
      head->sections[i].number = idx;
      head->sections[i].number = idx;
      head->sections[i].nrelocs = section->reloc_count;
      head->sections[i].nrelocs = section->reloc_count;
      head->sections[i].relocs =
      head->sections[i].relocs =
        (struct coff_reloc *) (xcalloc (section->reloc_count,
        (struct coff_reloc *) (xcalloc (section->reloc_count,
                                        sizeof (struct coff_reloc)));
                                        sizeof (struct coff_reloc)));
      head->sections[i].bfd_section = section;
      head->sections[i].bfd_section = section;
    }
    }
  head->sections[0].name = "ABSOLUTE";
  head->sections[0].name = "ABSOLUTE";
  head->sections[0].code = 0;
  head->sections[0].code = 0;
  head->sections[0].data = 0;
  head->sections[0].data = 0;
  head->sections[0].address = 0;
  head->sections[0].address = 0;
  head->sections[0].size = 0;
  head->sections[0].size = 0;
  head->sections[0].number = 0;
  head->sections[0].number = 0;
}
}
 
 
static void
static void
do_sections_p2 (struct coff_ofile *head)
do_sections_p2 (struct coff_ofile *head)
{
{
  asection *section;
  asection *section;
  for (section = abfd->sections; section; section = section->next)
  for (section = abfd->sections; section; section = section->next)
    {
    {
      unsigned int j;
      unsigned int j;
 
 
      for (j = 0; j < section->reloc_count; j++)
      for (j = 0; j < section->reloc_count; j++)
        {
        {
          int idx;
          int idx;
          int i = section->target_index;
          int i = section->target_index;
          struct coff_reloc *r = head->sections[i].relocs + j;
          struct coff_reloc *r = head->sections[i].relocs + j;
          arelent *sr = section->relocation + j;
          arelent *sr = section->relocation + j;
          r->offset = sr->address;
          r->offset = sr->address;
          r->addend = sr->addend;
          r->addend = sr->addend;
          idx = ((coff_symbol_type *) (sr->sym_ptr_ptr[0]))->native - rawsyms;
          idx = ((coff_symbol_type *) (sr->sym_ptr_ptr[0]))->native - rawsyms;
          r->symbol = tindex[idx];
          r->symbol = tindex[idx];
        }
        }
    }
    }
}
}
 
 
static struct coff_where *
static struct coff_where *
do_where (int i)
do_where (int i)
{
{
  struct internal_syment *sym = &rawsyms[i].u.syment;
  struct internal_syment *sym = &rawsyms[i].u.syment;
  struct coff_where *where =
  struct coff_where *where =
    (struct coff_where *) (xmalloc (sizeof (struct coff_where)));
    (struct coff_where *) (xmalloc (sizeof (struct coff_where)));
  where->offset = sym->n_value;
  where->offset = sym->n_value;
 
 
  if (sym->n_scnum == -1)
  if (sym->n_scnum == -1)
    sym->n_scnum = 0;
    sym->n_scnum = 0;
 
 
  switch (sym->n_sclass)
  switch (sym->n_sclass)
    {
    {
    case C_FIELD:
    case C_FIELD:
      where->where = coff_where_member_of_struct;
      where->where = coff_where_member_of_struct;
      where->offset = sym->n_value / 8;
      where->offset = sym->n_value / 8;
      where->bitoffset = 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;
      where->bitsize = rawsyms[i + 1].u.auxent.x_sym.x_misc.x_lnsz.x_size;
      break;
      break;
    case C_MOE:
    case C_MOE:
      where->where = coff_where_member_of_enum;
      where->where = coff_where_member_of_enum;
      break;
      break;
    case C_MOS:
    case C_MOS:
    case C_MOU:
    case C_MOU:
      where->where = coff_where_member_of_struct;
      where->where = coff_where_member_of_struct;
      break;
      break;
    case C_AUTO:
    case C_AUTO:
    case C_ARG:
    case C_ARG:
      where->where = coff_where_stack;
      where->where = coff_where_stack;
      break;
      break;
    case C_EXT:
    case C_EXT:
    case C_STAT:
    case C_STAT:
    case C_EXTDEF:
    case C_EXTDEF:
    case C_LABEL:
    case C_LABEL:
      where->where = coff_where_memory;
      where->where = coff_where_memory;
      where->section = &ofile->sections[sym->n_scnum];
      where->section = &ofile->sections[sym->n_scnum];
      break;
      break;
    case C_REG:
    case C_REG:
    case C_REGPARM:
    case C_REGPARM:
      where->where = coff_where_register;
      where->where = coff_where_register;
      break;
      break;
    case C_ENTAG:
    case C_ENTAG:
      where->where = coff_where_entag;
      where->where = coff_where_entag;
      break;
      break;
    case C_STRTAG:
    case C_STRTAG:
    case C_UNTAG:
    case C_UNTAG:
      where->where = coff_where_strtag;
      where->where = coff_where_strtag;
      break;
      break;
    case C_TPDEF:
    case C_TPDEF:
      where->where = coff_where_typedef;
      where->where = coff_where_typedef;
      break;
      break;
    default:
    default:
      abort ();
      abort ();
      break;
      break;
    }
    }
  return where;
  return where;
}
}
 
 
static
static
struct coff_line *
struct coff_line *
do_lines (int i, char *name ATTRIBUTE_UNUSED)
do_lines (int i, char *name ATTRIBUTE_UNUSED)
{
{
  struct coff_line *res = (struct coff_line *) xcalloc (sizeof (struct coff_line), 1);
  struct coff_line *res = (struct coff_line *) xcalloc (sizeof (struct coff_line), 1);
  asection *s;
  asection *s;
  unsigned int l;
  unsigned int l;
 
 
  /* Find out if this function has any line numbers in the table */
  /* Find out if this function has any line numbers in the table */
  for (s = abfd->sections; s; s = s->next)
  for (s = abfd->sections; s; s = s->next)
    {
    {
      for (l = 0; l < s->lineno_count; l++)
      for (l = 0; l < s->lineno_count; l++)
        {
        {
          if (s->lineno[l].line_number == 0)
          if (s->lineno[l].line_number == 0)
            {
            {
              if (rawsyms + i == ((coff_symbol_type *) (&(s->lineno[l].u.sym[0])))->native)
              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 */
                  /* These lines are for this function - so count them and stick them on */
                  int c = 0;
                  int c = 0;
                  /* Find the linenumber of the top of the function, since coff linenumbers
                  /* Find the linenumber of the top of the function, since coff linenumbers
                     are relative to the start of the function.  */
                     are relative to the start of the function.  */
                  int start_line = rawsyms[i + 3].u.auxent.x_sym.x_misc.x_lnsz.x_lnno;
                  int start_line = rawsyms[i + 3].u.auxent.x_sym.x_misc.x_lnsz.x_lnno;
 
 
                  l++;
                  l++;
                  for (c = 0; s->lineno[l + c + 1].line_number; c++)
                  for (c = 0; s->lineno[l + c + 1].line_number; c++)
                    ;
                    ;
 
 
                  /* Add two extra records, one for the prologue and one for the epilogue */
                  /* Add two extra records, one for the prologue and one for the epilogue */
                  c += 1;
                  c += 1;
                  res->nlines = c;
                  res->nlines = c;
                  res->lines = (int *) (xcalloc (sizeof (int), c));
                  res->lines = (int *) (xcalloc (sizeof (int), c));
                  res->addresses = (int *) (xcalloc (sizeof (int), c));
                  res->addresses = (int *) (xcalloc (sizeof (int), c));
                  res->lines[0] = start_line;
                  res->lines[0] = start_line;
                  res->addresses[0] = rawsyms[i].u.syment.n_value - s->vma;
                  res->addresses[0] = rawsyms[i].u.syment.n_value - s->vma;
                  for (c = 0; s->lineno[l + c + 1].line_number; c++)
                  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->lines[c + 1] = s->lineno[l + c].line_number + start_line - 1;
                      res->addresses[c + 1] = s->lineno[l + c].u.offset;
                      res->addresses[c + 1] = s->lineno[l + c].u.offset;
                    }
                    }
                  return res;
                  return res;
                }
                }
            }
            }
        }
        }
    }
    }
  return res;
  return res;
}
}
 
 
static
static
struct coff_type *
struct coff_type *
do_type (int i)
do_type (int i)
{
{
  struct internal_syment *sym = &rawsyms[i].u.syment;
  struct internal_syment *sym = &rawsyms[i].u.syment;
  union internal_auxent *aux = &rawsyms[i + 1].u.auxent;
  union internal_auxent *aux = &rawsyms[i + 1].u.auxent;
  struct coff_type *res =
  struct coff_type *res =
    (struct coff_type *) xmalloc (sizeof (struct coff_type));
    (struct coff_type *) xmalloc (sizeof (struct coff_type));
  int type = sym->n_type;
  int type = sym->n_type;
  int which_dt = 0;
  int which_dt = 0;
  int dimind = 0;
  int dimind = 0;
 
 
  res->type = coff_basic_type;
  res->type = coff_basic_type;
  res->u.basic = type & 0xf;
  res->u.basic = type & 0xf;
 
 
  switch (type & 0xf)
  switch (type & 0xf)
    {
    {
    case T_NULL:
    case T_NULL:
    case T_VOID:
    case T_VOID:
      if (sym->n_numaux && sym->n_sclass == C_STAT)
      if (sym->n_numaux && sym->n_sclass == C_STAT)
        {
        {
          /* This is probably a section definition */
          /* This is probably a section definition */
          res->type = coff_secdef_type;
          res->type = coff_secdef_type;
          res->size = aux->x_scn.x_scnlen;
          res->size = aux->x_scn.x_scnlen;
        }
        }
      else
      else
        {
        {
          if (type == 0)
          if (type == 0)
            {
            {
              /* Don't know what this is, let's make it a simple int */
              /* Don't know what this is, let's make it a simple int */
              res->size = INT_SIZE;
              res->size = INT_SIZE;
              res->u.basic = T_UINT;
              res->u.basic = T_UINT;
            }
            }
          else
          else
            {
            {
              /* Else it could be a function or pointer to void */
              /* Else it could be a function or pointer to void */
              res->size = 0;
              res->size = 0;
            }
            }
        }
        }
      break;
      break;
 
 
 
 
      break;
      break;
    case T_UCHAR:
    case T_UCHAR:
    case T_CHAR:
    case T_CHAR:
      res->size = 1;
      res->size = 1;
      break;
      break;
    case T_USHORT:
    case T_USHORT:
    case T_SHORT:
    case T_SHORT:
      res->size = SHORT_SIZE;
      res->size = SHORT_SIZE;
      break;
      break;
    case T_UINT:
    case T_UINT:
    case T_INT:
    case T_INT:
      res->size = INT_SIZE;
      res->size = INT_SIZE;
      break;
      break;
    case T_ULONG:
    case T_ULONG:
    case T_LONG:
    case T_LONG:
      res->size = LONG_SIZE;
      res->size = LONG_SIZE;
      break;
      break;
    case T_FLOAT:
    case T_FLOAT:
      res->size = FLOAT_SIZE;
      res->size = FLOAT_SIZE;
      break;
      break;
    case T_DOUBLE:
    case T_DOUBLE:
      res->size = DOUBLE_SIZE;
      res->size = DOUBLE_SIZE;
      break;
      break;
    case T_STRUCT:
    case T_STRUCT:
    case T_UNION:
    case T_UNION:
      if (sym->n_numaux)
      if (sym->n_numaux)
        {
        {
          if (aux->x_sym.x_tagndx.p)
          if (aux->x_sym.x_tagndx.p)
            {
            {
              /* Referring to a struct defined elsewhere */
              /* Referring to a struct defined elsewhere */
              res->type = coff_structref_type;
              res->type = coff_structref_type;
              res->u.astructref.ref = tindex[INDEXOF (aux->x_sym.x_tagndx.p)];
              res->u.astructref.ref = tindex[INDEXOF (aux->x_sym.x_tagndx.p)];
              res->size = res->u.astructref.ref ?
              res->size = res->u.astructref.ref ?
                res->u.astructref.ref->type->size : 0;
                res->u.astructref.ref->type->size : 0;
            }
            }
          else
          else
            {
            {
              /* A definition of a struct */
              /* A definition of a struct */
              last_struct = res;
              last_struct = res;
              res->type = coff_structdef_type;
              res->type = coff_structdef_type;
              res->u.astructdef.elements = empty_scope ();
              res->u.astructdef.elements = empty_scope ();
              res->u.astructdef.idx = 0;
              res->u.astructdef.idx = 0;
              res->u.astructdef.isstruct = (type & 0xf) == T_STRUCT;
              res->u.astructdef.isstruct = (type & 0xf) == T_STRUCT;
              res->size = aux->x_sym.x_misc.x_lnsz.x_size;
              res->size = aux->x_sym.x_misc.x_lnsz.x_size;
            }
            }
        }
        }
      else
      else
        {
        {
          /* No auxents - it's anonymous */
          /* No auxents - it's anonymous */
          res->type = coff_structref_type;
          res->type = coff_structref_type;
          res->u.astructref.ref = 0;
          res->u.astructref.ref = 0;
          res->size = 0;
          res->size = 0;
        }
        }
      break;
      break;
    case T_ENUM:
    case T_ENUM:
      if (aux->x_sym.x_tagndx.p)
      if (aux->x_sym.x_tagndx.p)
        {
        {
          /* Referring to a enum defined elsewhere */
          /* Referring to a enum defined elsewhere */
          res->type = coff_enumref_type;
          res->type = coff_enumref_type;
          res->u.aenumref.ref = tindex[INDEXOF (aux->x_sym.x_tagndx.p)];
          res->u.aenumref.ref = tindex[INDEXOF (aux->x_sym.x_tagndx.p)];
          res->size = res->u.aenumref.ref->type->size;
          res->size = res->u.aenumref.ref->type->size;
        }
        }
      else
      else
        {
        {
          /* A definition of an enum */
          /* A definition of an enum */
          last_enum = res;
          last_enum = res;
          res->type = coff_enumdef_type;
          res->type = coff_enumdef_type;
          res->u.aenumdef.elements = empty_scope ();
          res->u.aenumdef.elements = empty_scope ();
          res->size = aux->x_sym.x_misc.x_lnsz.x_size;
          res->size = aux->x_sym.x_misc.x_lnsz.x_size;
        }
        }
      break;
      break;
    case T_MOE:
    case T_MOE:
      break;
      break;
    }
    }
 
 
  for (which_dt = 5; which_dt >= 0; which_dt--)
  for (which_dt = 5; which_dt >= 0; which_dt--)
    {
    {
      switch ((type >> ((which_dt * 2) + 4)) & 0x3)
      switch ((type >> ((which_dt * 2) + 4)) & 0x3)
        {
        {
        case 0:
        case 0:
          break;
          break;
        case DT_ARY:
        case DT_ARY:
          {
          {
            struct coff_type *ptr = ((struct coff_type *)
            struct coff_type *ptr = ((struct coff_type *)
                                     xmalloc (sizeof (struct coff_type)));
                                     xmalloc (sizeof (struct coff_type)));
            int els = (dimind < DIMNUM
            int els = (dimind < DIMNUM
                       ? aux->x_sym.x_fcnary.x_ary.x_dimen[dimind]
                       ? aux->x_sym.x_fcnary.x_ary.x_dimen[dimind]
                       : 0);
                       : 0);
            ++dimind;
            ++dimind;
            ptr->type = coff_array_type;
            ptr->type = coff_array_type;
            ptr->size = els * res->size;
            ptr->size = els * res->size;
            ptr->u.array.dim = els;
            ptr->u.array.dim = els;
            ptr->u.array.array_of = res;
            ptr->u.array.array_of = res;
            res = ptr;
            res = ptr;
            break;
            break;
          }
          }
        case DT_PTR:
        case DT_PTR:
          {
          {
            struct coff_type *ptr =
            struct coff_type *ptr =
              (struct coff_type *) xmalloc (sizeof (struct coff_type));
              (struct coff_type *) xmalloc (sizeof (struct coff_type));
            ptr->size = PTR_SIZE;
            ptr->size = PTR_SIZE;
            ptr->type = coff_pointer_type;
            ptr->type = coff_pointer_type;
            ptr->u.pointer.points_to = res;
            ptr->u.pointer.points_to = res;
            res = ptr;
            res = ptr;
            break;
            break;
          }
          }
        case DT_FCN:
        case DT_FCN:
          {
          {
            struct coff_type *ptr
            struct coff_type *ptr
              = (struct coff_type *) xmalloc (sizeof (struct coff_type));
              = (struct coff_type *) xmalloc (sizeof (struct coff_type));
            ptr->size = 0;
            ptr->size = 0;
            ptr->type = coff_function_type;
            ptr->type = coff_function_type;
            ptr->u.function.function_returns = res;
            ptr->u.function.function_returns = res;
            ptr->u.function.parameters = empty_scope ();
            ptr->u.function.parameters = empty_scope ();
            ptr->u.function.lines = do_lines (i, sym->_n._n_nptr[1]);
            ptr->u.function.lines = do_lines (i, sym->_n._n_nptr[1]);
            ptr->u.function.code = 0;
            ptr->u.function.code = 0;
            last_function_type = ptr;
            last_function_type = ptr;
            res = ptr;
            res = ptr;
            break;
            break;
          }
          }
        }
        }
    }
    }
  return res;
  return res;
}
}
 
 
static struct coff_visible *
static struct coff_visible *
do_visible (int i)
do_visible (int i)
{
{
  struct internal_syment *sym = &rawsyms[i].u.syment;
  struct internal_syment *sym = &rawsyms[i].u.syment;
  struct coff_visible *visible =
  struct coff_visible *visible =
    (struct coff_visible *) (xmalloc (sizeof (struct coff_visible)));
    (struct coff_visible *) (xmalloc (sizeof (struct coff_visible)));
  enum coff_vis_type t;
  enum coff_vis_type t;
  switch (sym->n_sclass)
  switch (sym->n_sclass)
    {
    {
    case C_MOS:
    case C_MOS:
    case C_MOU:
    case C_MOU:
    case C_FIELD:
    case C_FIELD:
      t = coff_vis_member_of_struct;
      t = coff_vis_member_of_struct;
      break;
      break;
    case C_MOE:
    case C_MOE:
      t = coff_vis_member_of_enum;
      t = coff_vis_member_of_enum;
      break;
      break;
 
 
    case C_REGPARM:
    case C_REGPARM:
      t = coff_vis_regparam;
      t = coff_vis_regparam;
      break;
      break;
 
 
    case C_REG:
    case C_REG:
      t = coff_vis_register;
      t = coff_vis_register;
      break;
      break;
    case C_STRTAG:
    case C_STRTAG:
    case C_UNTAG:
    case C_UNTAG:
    case C_ENTAG:
    case C_ENTAG:
    case C_TPDEF:
    case C_TPDEF:
      t = coff_vis_tag;
      t = coff_vis_tag;
      break;
      break;
    case C_AUTOARG:
    case C_AUTOARG:
    case C_ARG:
    case C_ARG:
      t = coff_vis_autoparam;
      t = coff_vis_autoparam;
      break;
      break;
    case C_AUTO:
    case C_AUTO:
 
 
 
 
      t = coff_vis_auto;
      t = coff_vis_auto;
      break;
      break;
    case C_LABEL:
    case C_LABEL:
    case C_STAT:
    case C_STAT:
      t = coff_vis_int_def;
      t = coff_vis_int_def;
      break;
      break;
    case C_EXT:
    case C_EXT:
      if (sym->n_scnum == N_UNDEF)
      if (sym->n_scnum == N_UNDEF)
        {
        {
          if (sym->n_value)
          if (sym->n_value)
            t = coff_vis_common;
            t = coff_vis_common;
          else
          else
            t = coff_vis_ext_ref;
            t = coff_vis_ext_ref;
        }
        }
      else
      else
        t = coff_vis_ext_def;
        t = coff_vis_ext_def;
      break;
      break;
    default:
    default:
      abort ();
      abort ();
      break;
      break;
 
 
    }
    }
  visible->type = t;
  visible->type = t;
  return visible;
  return visible;
}
}
 
 
static int
static int
do_define (int i, struct coff_scope *b)
do_define (int i, struct coff_scope *b)
{
{
  static int symbol_index;
  static int symbol_index;
  struct internal_syment *sym = &rawsyms[i].u.syment;
  struct internal_syment *sym = &rawsyms[i].u.syment;
 
 
  /* Define a symbol and attach to block b */
  /* Define a symbol and attach to block b */
  struct coff_symbol *s = empty_symbol ();
  struct coff_symbol *s = empty_symbol ();
 
 
  s->number = ++symbol_index;
  s->number = ++symbol_index;
  s->name = sym->_n._n_nptr[1];
  s->name = sym->_n._n_nptr[1];
  s->sfile = cur_sfile;
  s->sfile = cur_sfile;
  /* Glue onto the ofile list */
  /* Glue onto the ofile list */
  if (lofile >= 0)
  if (lofile >= 0)
    {
    {
      if (ofile->symbol_list_tail)
      if (ofile->symbol_list_tail)
        ofile->symbol_list_tail->next_in_ofile_list = s;
        ofile->symbol_list_tail->next_in_ofile_list = s;
      else
      else
        ofile->symbol_list_head = s;
        ofile->symbol_list_head = s;
      ofile->symbol_list_tail = s;
      ofile->symbol_list_tail = s;
      /* And the block list */
      /* And the block list */
    }
    }
  if (b->vars_tail)
  if (b->vars_tail)
    b->vars_tail->next = s;
    b->vars_tail->next = s;
  else
  else
    b->vars_head = s;
    b->vars_head = s;
 
 
  b->vars_tail = s;
  b->vars_tail = s;
  b->nvars++;
  b->nvars++;
  s->type = do_type (i);
  s->type = do_type (i);
  s->where = do_where (i);
  s->where = do_where (i);
  s->visible = do_visible (i);
  s->visible = do_visible (i);
 
 
  tindex[i] = s;
  tindex[i] = s;
 
 
  /* We remember the lowest address in each section for each source file */
  /* We remember the lowest address in each section for each source file */
 
 
  if (s->where->where == coff_where_memory
  if (s->where->where == coff_where_memory
      && s->type->type == coff_secdef_type)
      && s->type->type == coff_secdef_type)
    {
    {
      struct coff_isection *is = cur_sfile->section + s->where->section->number;
      struct coff_isection *is = cur_sfile->section + s->where->section->number;
 
 
      if (!is->init)
      if (!is->init)
        {
        {
          is->low = s->where->offset;
          is->low = s->where->offset;
          is->high = s->where->offset + s->type->size;
          is->high = s->where->offset + s->type->size;
          is->init = 1;
          is->init = 1;
          is->parent = s->where->section;
          is->parent = s->where->section;
        }
        }
 
 
    }
    }
 
 
  if (s->type->type == coff_function_type)
  if (s->type->type == coff_function_type)
    last_function_symbol = s;
    last_function_symbol = s;
 
 
  return i + sym->n_numaux + 1;
  return i + sym->n_numaux + 1;
}
}
 
 
 
 
static
static
struct coff_ofile *
struct coff_ofile *
doit (void)
doit (void)
{
{
  int i;
  int i;
  int infile = 0;
  int infile = 0;
  struct coff_ofile *head =
  struct coff_ofile *head =
    (struct coff_ofile *) xmalloc (sizeof (struct coff_ofile));
    (struct coff_ofile *) xmalloc (sizeof (struct coff_ofile));
  ofile = head;
  ofile = head;
  head->source_head = 0;
  head->source_head = 0;
  head->source_tail = 0;
  head->source_tail = 0;
  head->nsources = 0;
  head->nsources = 0;
  head->symbol_list_tail = 0;
  head->symbol_list_tail = 0;
  head->symbol_list_head = 0;
  head->symbol_list_head = 0;
  do_sections_p1 (head);
  do_sections_p1 (head);
  push_scope (1);
  push_scope (1);
 
 
  for (i = 0; i < rawcount;)
  for (i = 0; i < rawcount;)
    {
    {
      struct internal_syment *sym = &rawsyms[i].u.syment;
      struct internal_syment *sym = &rawsyms[i].u.syment;
      switch (sym->n_sclass)
      switch (sym->n_sclass)
        {
        {
        case C_FILE:
        case C_FILE:
          {
          {
            /* new source file announced */
            /* new source file announced */
            struct coff_sfile *n =
            struct coff_sfile *n =
              (struct coff_sfile *) xmalloc (sizeof (struct coff_sfile));
              (struct coff_sfile *) xmalloc (sizeof (struct coff_sfile));
            n->section = (struct coff_isection *) xcalloc (sizeof (struct coff_isection), abfd->section_count + 1);
            n->section = (struct coff_isection *) xcalloc (sizeof (struct coff_isection), abfd->section_count + 1);
            cur_sfile = n;
            cur_sfile = n;
            n->name = sym->_n._n_nptr[1];
            n->name = sym->_n._n_nptr[1];
            n->next = 0;
            n->next = 0;
 
 
            if (infile)
            if (infile)
              {
              {
                pop_scope ();
                pop_scope ();
              }
              }
            infile = 1;
            infile = 1;
            push_scope (1);
            push_scope (1);
            file_scope = n->scope = top_scope;
            file_scope = n->scope = top_scope;
 
 
            if (head->source_tail)
            if (head->source_tail)
              head->source_tail->next = n;
              head->source_tail->next = n;
            else
            else
              head->source_head = n;
              head->source_head = n;
            head->source_tail = n;
            head->source_tail = n;
            head->nsources++;
            head->nsources++;
            i += sym->n_numaux + 1;
            i += sym->n_numaux + 1;
          }
          }
          break;
          break;
        case C_FCN:
        case C_FCN:
          {
          {
            char *name = sym->_n._n_nptr[1];
            char *name = sym->_n._n_nptr[1];
            if (name[1] == 'b')
            if (name[1] == 'b')
              {
              {
                /* Function start */
                /* Function start */
                push_scope (0);
                push_scope (0);
                last_function_type->u.function.code = top_scope;
                last_function_type->u.function.code = top_scope;
                top_scope->sec = ofile->sections + sym->n_scnum;
                top_scope->sec = ofile->sections + sym->n_scnum;
                top_scope->offset = sym->n_value;
                top_scope->offset = sym->n_value;
              }
              }
            else
            else
              {
              {
                top_scope->size = sym->n_value - top_scope->offset + 1;
                top_scope->size = sym->n_value - top_scope->offset + 1;
                pop_scope ();
                pop_scope ();
 
 
              }
              }
            i += sym->n_numaux + 1;
            i += sym->n_numaux + 1;
          }
          }
          break;
          break;
 
 
        case C_BLOCK:
        case C_BLOCK:
          {
          {
            char *name = sym->_n._n_nptr[1];
            char *name = sym->_n._n_nptr[1];
            if (name[1] == 'b')
            if (name[1] == 'b')
              {
              {
                /* Block start */
                /* Block start */
                push_scope (1);
                push_scope (1);
                top_scope->sec = ofile->sections + sym->n_scnum;
                top_scope->sec = ofile->sections + sym->n_scnum;
                top_scope->offset = sym->n_value;
                top_scope->offset = sym->n_value;
 
 
              }
              }
            else
            else
              {
              {
                top_scope->size = sym->n_value - top_scope->offset + 1;
                top_scope->size = sym->n_value - top_scope->offset + 1;
                pop_scope ();
                pop_scope ();
              }
              }
            i += sym->n_numaux + 1;
            i += sym->n_numaux + 1;
          }
          }
          break;
          break;
        case C_REGPARM:
        case C_REGPARM:
        case C_ARG:
        case C_ARG:
          i = do_define (i, last_function_symbol->type->u.function.parameters);
          i = do_define (i, last_function_symbol->type->u.function.parameters);
          break;
          break;
        case C_MOS:
        case C_MOS:
        case C_MOU:
        case C_MOU:
        case C_FIELD:
        case C_FIELD:
          i = do_define (i, last_struct->u.astructdef.elements);
          i = do_define (i, last_struct->u.astructdef.elements);
          break;
          break;
        case C_MOE:
        case C_MOE:
          i = do_define (i, last_enum->u.aenumdef.elements);
          i = do_define (i, last_enum->u.aenumdef.elements);
          break;
          break;
        case C_STRTAG:
        case C_STRTAG:
        case C_ENTAG:
        case C_ENTAG:
        case C_UNTAG:
        case C_UNTAG:
          /* Various definition */
          /* Various definition */
          i = do_define (i, top_scope);
          i = do_define (i, top_scope);
          break;
          break;
        case C_EXT:
        case C_EXT:
        case C_LABEL:
        case C_LABEL:
          i = do_define (i, file_scope);
          i = do_define (i, file_scope);
          break;
          break;
        case C_STAT:
        case C_STAT:
        case C_TPDEF:
        case C_TPDEF:
        case C_AUTO:
        case C_AUTO:
        case C_REG:
        case C_REG:
          i = do_define (i, top_scope);
          i = do_define (i, top_scope);
          break;
          break;
        default:
        default:
          abort ();
          abort ();
        case C_EOS:
        case C_EOS:
          i += sym->n_numaux + 1;
          i += sym->n_numaux + 1;
          break;
          break;
        }
        }
    }
    }
  do_sections_p2 (head);
  do_sections_p2 (head);
  return head;
  return head;
}
}
 
 
struct coff_ofile *
struct coff_ofile *
coff_grok (bfd *inabfd)
coff_grok (bfd *inabfd)
{
{
  long storage;
  long storage;
  struct coff_ofile *p;
  struct coff_ofile *p;
  abfd = inabfd;
  abfd = inabfd;
  storage = bfd_get_symtab_upper_bound (abfd);
  storage = bfd_get_symtab_upper_bound (abfd);
 
 
  if (storage < 0)
  if (storage < 0)
    bfd_fatal (abfd->filename);
    bfd_fatal (abfd->filename);
 
 
  syms = (asymbol **) xmalloc (storage);
  syms = (asymbol **) xmalloc (storage);
  symcount = bfd_canonicalize_symtab (abfd, syms);
  symcount = bfd_canonicalize_symtab (abfd, syms);
  if (symcount < 0)
  if (symcount < 0)
    bfd_fatal (abfd->filename);
    bfd_fatal (abfd->filename);
  rawsyms = obj_raw_syments (abfd);
  rawsyms = obj_raw_syments (abfd);
  rawcount = obj_raw_syment_count (abfd);;
  rawcount = obj_raw_syment_count (abfd);;
  tindex = (struct coff_symbol **) (xcalloc (sizeof (struct coff_symbol *), rawcount));
  tindex = (struct coff_symbol **) (xcalloc (sizeof (struct coff_symbol *), rawcount));
 
 
  p = doit ();
  p = doit ();
  return p;
  return p;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.