coffgrok.c revision 38889
133965Sjdp/* coffgrok.c 238889Sjdp Copyright (C) 1994, 95, 97, 1998 Free Software Foundation, Inc. 333965Sjdp 433965SjdpThis file is part of GNU Binutils. 533965Sjdp 633965SjdpThis program is free software; you can redistribute it and/or modify 733965Sjdpit under the terms of the GNU General Public License as published by 833965Sjdpthe Free Software Foundation; either version 2 of the License, or 933965Sjdp(at your option) any later version. 1033965Sjdp 1133965SjdpThis program is distributed in the hope that it will be useful, 1233965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of 1333965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1433965SjdpGNU General Public License for more details. 1533965Sjdp 1633965SjdpYou should have received a copy of the GNU General Public License 1733965Sjdpalong with this program; if not, write to the Free Software 1833965SjdpFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 1933965Sjdp 2033965Sjdp/* Written by Steve Chamberlain (sac@cygnus.com) 2133965Sjdp 2233965Sjdp This module reads a coff file and builds a really simple type tree 2333965Sjdp which can be read by other programs. The first application is a 2433965Sjdp coff->sysroff converter. It can be tested with coffdump.c. 2533965Sjdp 2633965Sjdp*/ 2733965Sjdp 2833965Sjdp#include <bfd.h> 2933965Sjdp#include "bucomm.h" 3033965Sjdp 3133965Sjdp#include "coff/internal.h" 3233965Sjdp#include "../bfd/libcoff.h" 3333965Sjdp#include "coffgrok.h" 3433965Sjdpint lofile = 1; 3533965Sjdpstatic struct coff_scope *top_scope; 3633965Sjdpstatic struct coff_scope *file_scope; 3733965Sjdpstatic struct coff_ofile *ofile; 3833965Sjdp 3933965Sjdpstruct coff_symbol *last_function_symbol; 4033965Sjdpstruct coff_type *last_function_type; 4133965Sjdpstruct coff_type *last_struct; 4233965Sjdpstruct coff_type *last_enum; 4333965Sjdpstruct coff_sfile *cur_sfile; 4433965Sjdp 4533965Sjdpstatic struct coff_symbol **tindex; 4633965Sjdp 4733965Sjdp 4833965Sjdpstatic asymbol **syms; 4933965Sjdpstatic long symcount; 5033965Sjdp 5133965Sjdp#define N(x) ((x)->_n._n_nptr[1]) 5233965Sjdp 5333965Sjdpstatic struct coff_ptr_struct *rawsyms; 5433965Sjdpstatic int rawcount; 5533965Sjdpstatic bfd *abfd; 5633965Sjdpextern char *xcalloc (); 5733965Sjdp#define PTR_SIZE 4 5833965Sjdp#define SHORT_SIZE 2 5933965Sjdp#define INT_SIZE 4 6033965Sjdp#define LONG_SIZE 4 6133965Sjdp#define FLOAT_SIZE 4 6233965Sjdp#define DOUBLE_SIZE 8 6333965Sjdp 6433965Sjdp#define INDEXOF(p) ((struct coff_ptr_struct *)(p)-(rawsyms)) 6533965Sjdp 6633965Sjdpstatic struct coff_scope * 6733965Sjdpempty_scope () 6833965Sjdp{ 6933965Sjdp struct coff_scope *l; 7033965Sjdp l = (struct coff_scope *) (xcalloc (sizeof (struct coff_scope), 1)); 7133965Sjdp return l; 7233965Sjdp} 7333965Sjdp 7433965Sjdpstatic struct coff_symbol * 7533965Sjdpempty_symbol () 7633965Sjdp{ 7733965Sjdp return (struct coff_symbol *) (xcalloc (sizeof (struct coff_symbol), 1)); 7833965Sjdp} 7933965Sjdp 8033965Sjdp/*int l;*/ 8133965Sjdpstatic void 8233965Sjdppush_scope (link) 8333965Sjdp int link; 8433965Sjdp{ 8533965Sjdp struct coff_scope *n = empty_scope (); 8633965Sjdp if (link) 8733965Sjdp { 8833965Sjdp if (top_scope) 8933965Sjdp { 9033965Sjdp if (top_scope->list_tail) 9133965Sjdp { 9233965Sjdp top_scope->list_tail->next = n; 9333965Sjdp } 9433965Sjdp else 9533965Sjdp { 9633965Sjdp top_scope->list_head = n; 9733965Sjdp } 9833965Sjdp top_scope->list_tail = n; 9933965Sjdp } 10033965Sjdp } 10133965Sjdp n->parent = top_scope; 10233965Sjdp 10333965Sjdp top_scope = n; 10433965Sjdp} 10533965Sjdp 10633965Sjdpstatic void 10733965Sjdppop_scope () 10833965Sjdp{ 10933965Sjdp top_scope = top_scope->parent; 11033965Sjdp} 11133965Sjdp 11233965Sjdpstatic void 11333965Sjdpdo_sections_p1 (head) 11433965Sjdp struct coff_ofile *head; 11533965Sjdp{ 11633965Sjdp asection *section; 11733965Sjdp int idx; 11833965Sjdp struct coff_section *all = (struct coff_section *) (xcalloc (abfd->section_count + 1, 11933965Sjdp sizeof (struct coff_section))); 12033965Sjdp head->nsections = abfd->section_count + 1; 12133965Sjdp head->sections = all; 12233965Sjdp 12333965Sjdp for (idx = 0, section = abfd->sections; section; section = section->next, idx++) 12433965Sjdp { 12533965Sjdp long relsize; 12633965Sjdp int i = section->target_index; 12733965Sjdp arelent **relpp; 12833965Sjdp long relcount; 12933965Sjdp 13033965Sjdp relsize = bfd_get_reloc_upper_bound (abfd, section); 13133965Sjdp if (relsize < 0) 13233965Sjdp bfd_fatal (bfd_get_filename (abfd)); 13333965Sjdp if (relsize == 0) 13433965Sjdp continue; 13533965Sjdp relpp = (arelent **) xmalloc (relsize); 13633965Sjdp relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms); 13733965Sjdp if (relcount < 0) 13833965Sjdp bfd_fatal (bfd_get_filename (abfd)); 13933965Sjdp 14033965Sjdp head->sections[i].name = (char *) (section->name); 14133965Sjdp head->sections[i].code = section->flags & SEC_CODE; 14233965Sjdp head->sections[i].data = section->flags & SEC_DATA; 14333965Sjdp if (strcmp (section->name, ".bss") == 0) 14433965Sjdp head->sections[i].data = 1; 14538889Sjdp head->sections[i].address = section->lma; 14633965Sjdp head->sections[i].size = section->_raw_size; 14733965Sjdp head->sections[i].number = idx; 14833965Sjdp head->sections[i].nrelocs = section->reloc_count; 14933965Sjdp head->sections[i].relocs = 15033965Sjdp (struct coff_reloc *) (xcalloc (section->reloc_count, 15133965Sjdp sizeof (struct coff_reloc))); 15233965Sjdp head->sections[i].bfd_section = section; 15333965Sjdp } 15433965Sjdp head->sections[0].name = "ABSOLUTE"; 15533965Sjdp head->sections[0].code = 0; 15633965Sjdp head->sections[0].data = 0; 15733965Sjdp head->sections[0].address = 0; 15833965Sjdp head->sections[0].size = 0; 15933965Sjdp head->sections[0].number = 0; 16033965Sjdp} 16133965Sjdp 16233965Sjdpstatic void 16333965Sjdpdo_sections_p2 (head) 16433965Sjdp struct coff_ofile *head; 16533965Sjdp{ 16633965Sjdp asection *section; 16733965Sjdp for (section = abfd->sections; section; section = section->next) 16833965Sjdp { 16938889Sjdp unsigned int j; 17038889Sjdp 17133965Sjdp for (j = 0; j < section->reloc_count; j++) 17233965Sjdp { 17333965Sjdp int idx; 17433965Sjdp int i = section->target_index; 17533965Sjdp struct coff_reloc *r = head->sections[i].relocs + j; 17633965Sjdp arelent *sr = section->relocation + j; 17733965Sjdp r->offset = sr->address; 17833965Sjdp r->addend = sr->addend; 17933965Sjdp idx = ((coff_symbol_type *) (sr->sym_ptr_ptr[0]))->native - rawsyms; 18033965Sjdp r->symbol = tindex[idx]; 18133965Sjdp } 18233965Sjdp } 18333965Sjdp} 18433965Sjdp 18533965Sjdpstatic struct coff_where * 18633965Sjdpdo_where (i) 18733965Sjdp int i; 18833965Sjdp{ 18933965Sjdp struct internal_syment *sym = &rawsyms[i].u.syment; 19033965Sjdp struct coff_where *where = 19133965Sjdp (struct coff_where *) (xmalloc (sizeof (struct coff_where))); 19233965Sjdp where->offset = sym->n_value; 19333965Sjdp 19433965Sjdp if (sym->n_scnum == -1) 19533965Sjdp sym->n_scnum = 0; 19633965Sjdp 19733965Sjdp switch (sym->n_sclass) 19833965Sjdp { 19933965Sjdp case C_FIELD: 20033965Sjdp where->where = coff_where_member_of_struct; 20133965Sjdp where->offset = sym->n_value / 8; 20233965Sjdp where->bitoffset = sym->n_value % 8; 20333965Sjdp where->bitsize = rawsyms[i + 1].u.auxent.x_sym.x_misc.x_lnsz.x_size; 20433965Sjdp break; 20533965Sjdp case C_MOE: 20633965Sjdp where->where = coff_where_member_of_enum; 20733965Sjdp break; 20833965Sjdp case C_MOS: 20933965Sjdp case C_MOU: 21033965Sjdp where->where = coff_where_member_of_struct; 21133965Sjdp break; 21233965Sjdp case C_AUTO: 21333965Sjdp case C_ARG: 21433965Sjdp where->where = coff_where_stack; 21533965Sjdp break; 21633965Sjdp case C_EXT: 21733965Sjdp case C_STAT: 21833965Sjdp case C_EXTDEF: 21933965Sjdp case C_LABEL: 22033965Sjdp where->where = coff_where_memory; 22133965Sjdp where->section = &ofile->sections[sym->n_scnum]; 22233965Sjdp break; 22333965Sjdp case C_REG: 22433965Sjdp case C_REGPARM: 22533965Sjdp where->where = coff_where_register; 22633965Sjdp break; 22733965Sjdp case C_ENTAG: 22833965Sjdp where->where = coff_where_entag; 22933965Sjdp break; 23033965Sjdp case C_STRTAG: 23133965Sjdp case C_UNTAG: 23233965Sjdp where->where = coff_where_strtag; 23333965Sjdp break; 23433965Sjdp case C_TPDEF: 23533965Sjdp where->where = coff_where_typedef; 23633965Sjdp break; 23733965Sjdp default: 23833965Sjdp abort (); 23933965Sjdp break; 24033965Sjdp } 24133965Sjdp return where; 24233965Sjdp} 24333965Sjdp 24433965Sjdpstatic 24533965Sjdpstruct coff_line * 24633965Sjdpdo_lines (i, name) 24733965Sjdp int i; 24833965Sjdp char *name; 24933965Sjdp{ 25033965Sjdp struct coff_line *res = (struct coff_line *) xcalloc (sizeof (struct coff_line), 1); 25133965Sjdp asection *s; 25238889Sjdp unsigned int l; 25338889Sjdp 25433965Sjdp /* Find out if this function has any line numbers in the table */ 25533965Sjdp for (s = abfd->sections; s; s = s->next) 25633965Sjdp { 25733965Sjdp for (l = 0; l < s->lineno_count; l++) 25833965Sjdp { 25933965Sjdp if (s->lineno[l].line_number == 0) 26033965Sjdp { 26133965Sjdp if (rawsyms + i == ((coff_symbol_type *) (&(s->lineno[l].u.sym[0])))->native) 26233965Sjdp { 26333965Sjdp /* These lines are for this function - so count them and stick them on */ 26433965Sjdp int c = 0; 26533965Sjdp /* Find the linenumber of the top of the function, since coff linenumbers 26633965Sjdp are relative to the start of the function. */ 26733965Sjdp int start_line = rawsyms[i + 3].u.auxent.x_sym.x_misc.x_lnsz.x_lnno; 26833965Sjdp 26933965Sjdp l++; 27033965Sjdp for (c = 0; s->lineno[l + c + 1].line_number; c++) 27133965Sjdp ; 27233965Sjdp 27333965Sjdp /* Add two extra records, one for the prologue and one for the epilogue */ 27433965Sjdp c += 1; 27533965Sjdp res->nlines = c; 27633965Sjdp res->lines = (int *) (xcalloc (sizeof (int), c)); 27733965Sjdp res->addresses = (int *) (xcalloc (sizeof (int), c)); 27833965Sjdp res->lines[0] = start_line; 27933965Sjdp res->addresses[0] = rawsyms[i].u.syment.n_value - s->vma; 28033965Sjdp for (c = 0; s->lineno[l + c + 1].line_number; c++) 28133965Sjdp { 28233965Sjdp res->lines[c + 1] = s->lineno[l + c].line_number + start_line - 1; 28333965Sjdp res->addresses[c + 1] = s->lineno[l + c].u.offset; 28433965Sjdp } 28533965Sjdp return res; 28633965Sjdp } 28733965Sjdp } 28833965Sjdp } 28933965Sjdp } 29033965Sjdp return res; 29133965Sjdp} 29233965Sjdp 29333965Sjdpstatic 29433965Sjdpstruct coff_type * 29533965Sjdpdo_type (i) 29633965Sjdp int i; 29733965Sjdp{ 29833965Sjdp struct internal_syment *sym = &rawsyms[i].u.syment; 29933965Sjdp union internal_auxent *aux = &rawsyms[i + 1].u.auxent; 30033965Sjdp struct coff_type *res = 30133965Sjdp (struct coff_type *) xmalloc (sizeof (struct coff_type)); 30233965Sjdp int type = sym->n_type; 30333965Sjdp int which_dt = 0; 30433965Sjdp int dimind = 0; 30533965Sjdp 30633965Sjdp res->type = coff_basic_type; 30733965Sjdp res->u.basic = type & 0xf; 30833965Sjdp 30933965Sjdp switch (type & 0xf) 31033965Sjdp { 31133965Sjdp case T_NULL: 31233965Sjdp case T_VOID: 31333965Sjdp if (sym->n_numaux && sym->n_sclass == C_STAT) 31433965Sjdp { 31533965Sjdp /* This is probably a section definition */ 31633965Sjdp res->type = coff_secdef_type; 31733965Sjdp res->size = aux->x_scn.x_scnlen; 31833965Sjdp } 31933965Sjdp else 32033965Sjdp { 32133965Sjdp if (type == 0) 32233965Sjdp { 32333965Sjdp /* Don't know what this is, let's make it a simple int */ 32433965Sjdp res->size = INT_SIZE; 32533965Sjdp res->u.basic = T_UINT; 32633965Sjdp } 32733965Sjdp else 32833965Sjdp { 32933965Sjdp /* Else it could be a function or pointer to void */ 33033965Sjdp res->size = 0; 33133965Sjdp } 33233965Sjdp } 33333965Sjdp break; 33433965Sjdp 33533965Sjdp 33633965Sjdp break; 33733965Sjdp case T_UCHAR: 33833965Sjdp case T_CHAR: 33933965Sjdp res->size = 1; 34033965Sjdp break; 34133965Sjdp case T_USHORT: 34233965Sjdp case T_SHORT: 34333965Sjdp res->size = SHORT_SIZE; 34433965Sjdp break; 34533965Sjdp case T_UINT: 34633965Sjdp case T_INT: 34733965Sjdp res->size = INT_SIZE; 34833965Sjdp break; 34933965Sjdp case T_ULONG: 35033965Sjdp case T_LONG: 35133965Sjdp res->size = LONG_SIZE; 35233965Sjdp break; 35333965Sjdp case T_FLOAT: 35433965Sjdp res->size = FLOAT_SIZE; 35533965Sjdp break; 35633965Sjdp case T_DOUBLE: 35733965Sjdp res->size = DOUBLE_SIZE; 35833965Sjdp break; 35933965Sjdp case T_STRUCT: 36033965Sjdp case T_UNION: 36133965Sjdp if (sym->n_numaux) 36233965Sjdp { 36333965Sjdp if (aux->x_sym.x_tagndx.p) 36433965Sjdp { 36533965Sjdp /* Refering to a struct defined elsewhere */ 36633965Sjdp res->type = coff_structref_type; 36733965Sjdp res->u.astructref.ref = tindex[INDEXOF (aux->x_sym.x_tagndx.p)]; 36833965Sjdp res->size = res->u.astructref.ref ? 36933965Sjdp res->u.astructref.ref->type->size : 0; 37033965Sjdp } 37133965Sjdp else 37233965Sjdp { 37333965Sjdp /* A definition of a struct */ 37433965Sjdp last_struct = res; 37533965Sjdp res->type = coff_structdef_type; 37633965Sjdp res->u.astructdef.elements = empty_scope (); 37733965Sjdp res->u.astructdef.idx = 0; 37833965Sjdp res->u.astructdef.isstruct = (type & 0xf) == T_STRUCT; 37933965Sjdp res->size = aux->x_sym.x_misc.x_lnsz.x_size; 38033965Sjdp } 38133965Sjdp } 38233965Sjdp else 38333965Sjdp { 38433965Sjdp /* No auxents - it's anonynmous */ 38533965Sjdp res->type = coff_structref_type; 38633965Sjdp res->u.astructref.ref = 0; 38733965Sjdp res->size = 0; 38833965Sjdp } 38933965Sjdp break; 39033965Sjdp case T_ENUM: 39133965Sjdp if (aux->x_sym.x_tagndx.p) 39233965Sjdp { 39333965Sjdp /* Refering to a enum defined elsewhere */ 39433965Sjdp res->type = coff_enumref_type; 39533965Sjdp res->u.aenumref.ref = tindex[INDEXOF (aux->x_sym.x_tagndx.p)]; 39633965Sjdp res->size = res->u.aenumref.ref->type->size; 39733965Sjdp } 39833965Sjdp else 39933965Sjdp { 40033965Sjdp /* A definition of an enum */ 40133965Sjdp last_enum = res; 40233965Sjdp res->type = coff_enumdef_type; 40333965Sjdp res->u.aenumdef.elements = empty_scope (); 40433965Sjdp res->size = aux->x_sym.x_misc.x_lnsz.x_size; 40533965Sjdp } 40633965Sjdp break; 40733965Sjdp case T_MOE: 40833965Sjdp break; 40933965Sjdp } 41033965Sjdp 41133965Sjdp for (which_dt = 5; which_dt >= 0; which_dt--) 41233965Sjdp { 41333965Sjdp switch ((type >> ((which_dt * 2) + 4)) & 0x3) 41433965Sjdp { 41533965Sjdp case 0: 41633965Sjdp break; 41733965Sjdp case DT_ARY: 41833965Sjdp { 41933965Sjdp struct coff_type *ptr = ((struct coff_type *) 42033965Sjdp xmalloc (sizeof (struct coff_type))); 42133965Sjdp int els = (dimind < DIMNUM 42233965Sjdp ? aux->x_sym.x_fcnary.x_ary.x_dimen[dimind] 42333965Sjdp : 0); 42433965Sjdp ++dimind; 42533965Sjdp ptr->type = coff_array_type; 42633965Sjdp ptr->size = els * res->size; 42733965Sjdp ptr->u.array.dim = els; 42833965Sjdp ptr->u.array.array_of = res; 42933965Sjdp res = ptr; 43033965Sjdp break; 43133965Sjdp } 43233965Sjdp case DT_PTR: 43333965Sjdp { 43433965Sjdp struct coff_type *ptr = 43533965Sjdp (struct coff_type *) xmalloc (sizeof (struct coff_type)); 43633965Sjdp ptr->size = PTR_SIZE; 43733965Sjdp ptr->type = coff_pointer_type; 43833965Sjdp ptr->u.pointer.points_to = res; 43933965Sjdp res = ptr; 44033965Sjdp break; 44133965Sjdp } 44233965Sjdp case DT_FCN: 44333965Sjdp { 44433965Sjdp struct coff_type *ptr 44533965Sjdp = (struct coff_type *) xmalloc (sizeof (struct coff_type)); 44633965Sjdp ptr->size = 0; 44733965Sjdp ptr->type = coff_function_type; 44833965Sjdp ptr->u.function.function_returns = res; 44933965Sjdp ptr->u.function.parameters = empty_scope (); 45033965Sjdp ptr->u.function.lines = do_lines (i, sym->_n._n_nptr[1]); 45133965Sjdp ptr->u.function.code = 0; 45233965Sjdp last_function_type = ptr; 45333965Sjdp res = ptr; 45433965Sjdp break; 45533965Sjdp } 45633965Sjdp } 45733965Sjdp } 45833965Sjdp return res; 45933965Sjdp} 46033965Sjdp 46133965Sjdpstatic struct coff_visible * 46233965Sjdpdo_visible (i) 46333965Sjdp int i; 46433965Sjdp{ 46533965Sjdp struct internal_syment *sym = &rawsyms[i].u.syment; 46633965Sjdp struct coff_visible *visible = 46733965Sjdp (struct coff_visible *) (xmalloc (sizeof (struct coff_visible))); 46833965Sjdp enum coff_vis_type t; 46933965Sjdp switch (sym->n_sclass) 47033965Sjdp { 47133965Sjdp case C_MOS: 47233965Sjdp case C_MOU: 47333965Sjdp case C_FIELD: 47433965Sjdp t = coff_vis_member_of_struct; 47533965Sjdp break; 47633965Sjdp case C_MOE: 47733965Sjdp t = coff_vis_member_of_enum; 47833965Sjdp break; 47933965Sjdp 48033965Sjdp case C_REGPARM: 48133965Sjdp t = coff_vis_regparam; 48233965Sjdp break; 48333965Sjdp 48433965Sjdp case C_REG: 48533965Sjdp t = coff_vis_register; 48633965Sjdp break; 48733965Sjdp case C_STRTAG: 48833965Sjdp case C_UNTAG: 48933965Sjdp case C_ENTAG: 49033965Sjdp case C_TPDEF: 49133965Sjdp t = coff_vis_tag; 49233965Sjdp break; 49333965Sjdp case C_AUTOARG: 49433965Sjdp case C_ARG: 49533965Sjdp t = coff_vis_autoparam; 49633965Sjdp break; 49733965Sjdp case C_AUTO: 49833965Sjdp 49933965Sjdp 50033965Sjdp t = coff_vis_auto; 50133965Sjdp break; 50233965Sjdp case C_LABEL: 50333965Sjdp case C_STAT: 50433965Sjdp t = coff_vis_int_def; 50533965Sjdp break; 50633965Sjdp case C_EXT: 50733965Sjdp if (sym->n_scnum == N_UNDEF) 50833965Sjdp { 50933965Sjdp if (sym->n_value) 51033965Sjdp t = coff_vis_common; 51133965Sjdp else 51233965Sjdp t = coff_vis_ext_ref; 51333965Sjdp } 51433965Sjdp else 51533965Sjdp t = coff_vis_ext_def; 51633965Sjdp break; 51733965Sjdp default: 51833965Sjdp abort (); 51933965Sjdp break; 52033965Sjdp 52133965Sjdp } 52233965Sjdp visible->type = t; 52333965Sjdp return visible; 52433965Sjdp} 52533965Sjdp 52633965Sjdpstatic int 52733965Sjdpdo_define (i, b) 52833965Sjdp int i; 52933965Sjdp struct coff_scope *b; 53033965Sjdp{ 53133965Sjdp static int symbol_index; 53233965Sjdp struct internal_syment *sym = &rawsyms[i].u.syment; 53333965Sjdp 53433965Sjdp /* Define a symbol and attach to block b */ 53533965Sjdp struct coff_symbol *s = empty_symbol (); 53633965Sjdp 53733965Sjdp s->number = ++symbol_index; 53833965Sjdp s->name = sym->_n._n_nptr[1]; 53933965Sjdp s->sfile = cur_sfile; 54033965Sjdp /* Glue onto the ofile list */ 54133965Sjdp if (lofile >= 0) 54233965Sjdp { 54333965Sjdp if (ofile->symbol_list_tail) 54433965Sjdp ofile->symbol_list_tail->next_in_ofile_list = s; 54533965Sjdp else 54633965Sjdp ofile->symbol_list_head = s; 54733965Sjdp ofile->symbol_list_tail = s; 54833965Sjdp /* And the block list */ 54933965Sjdp } 55033965Sjdp if (b->vars_tail) 55133965Sjdp b->vars_tail->next = s; 55233965Sjdp else 55333965Sjdp b->vars_head = s; 55433965Sjdp 55533965Sjdp b->vars_tail = s; 55633965Sjdp b->nvars++; 55733965Sjdp s->type = do_type (i); 55833965Sjdp s->where = do_where (i); 55933965Sjdp s->visible = do_visible (i); 56033965Sjdp 56133965Sjdp tindex[i] = s; 56233965Sjdp 56333965Sjdp /* We remember the lowest address in each section for each source file */ 56433965Sjdp 56533965Sjdp if (s->where->where == coff_where_memory 56633965Sjdp && s->type->type == coff_secdef_type) 56733965Sjdp { 56833965Sjdp struct coff_isection *is = cur_sfile->section + s->where->section->number; 56933965Sjdp 57033965Sjdp if (!is->init) 57133965Sjdp { 57233965Sjdp is->low = s->where->offset; 57333965Sjdp is->high = s->where->offset + s->type->size; 57433965Sjdp is->init = 1; 57533965Sjdp is->parent = s->where->section; 57633965Sjdp } 57733965Sjdp 57833965Sjdp } 57933965Sjdp 58033965Sjdp if (s->type->type == coff_function_type) 58133965Sjdp last_function_symbol = s; 58233965Sjdp 58333965Sjdp return i + sym->n_numaux + 1; 58433965Sjdp} 58533965Sjdp 58633965Sjdp 58733965Sjdpstatic 58833965Sjdpstruct coff_ofile * 58933965Sjdpdoit () 59033965Sjdp{ 59133965Sjdp int i; 59233965Sjdp int infile = 0; 59333965Sjdp struct coff_ofile *head = 59433965Sjdp (struct coff_ofile *) xmalloc (sizeof (struct coff_ofile)); 59533965Sjdp ofile = head; 59633965Sjdp head->source_head = 0; 59733965Sjdp head->source_tail = 0; 59833965Sjdp head->nsources = 0; 59933965Sjdp head->symbol_list_tail = 0; 60033965Sjdp head->symbol_list_head = 0; 60133965Sjdp do_sections_p1 (head); 60233965Sjdp push_scope (1); 60333965Sjdp 60433965Sjdp for (i = 0; i < rawcount;) 60533965Sjdp { 60633965Sjdp struct internal_syment *sym = &rawsyms[i].u.syment; 60733965Sjdp switch (sym->n_sclass) 60833965Sjdp { 60933965Sjdp case C_FILE: 61033965Sjdp { 61133965Sjdp /* new source file announced */ 61233965Sjdp struct coff_sfile *n = 61333965Sjdp (struct coff_sfile *) xmalloc (sizeof (struct coff_sfile)); 61433965Sjdp n->section = (struct coff_isection *) xcalloc (sizeof (struct coff_isection), abfd->section_count + 1); 61533965Sjdp cur_sfile = n; 61633965Sjdp n->name = sym->_n._n_nptr[1]; 61733965Sjdp n->next = 0; 61833965Sjdp 61933965Sjdp if (infile) 62033965Sjdp { 62133965Sjdp pop_scope (); 62233965Sjdp } 62333965Sjdp infile = 1; 62433965Sjdp push_scope (1); 62533965Sjdp file_scope = n->scope = top_scope; 62633965Sjdp 62733965Sjdp if (head->source_tail) 62833965Sjdp head->source_tail->next = n; 62933965Sjdp else 63033965Sjdp head->source_head = n; 63133965Sjdp head->source_tail = n; 63233965Sjdp head->nsources++; 63333965Sjdp i += sym->n_numaux + 1; 63433965Sjdp } 63533965Sjdp break; 63633965Sjdp case C_FCN: 63733965Sjdp { 63833965Sjdp char *name = sym->_n._n_nptr[1]; 63933965Sjdp if (name[1] == 'b') 64033965Sjdp { 64133965Sjdp /* Function start */ 64233965Sjdp push_scope (0); 64333965Sjdp last_function_type->u.function.code = top_scope; 64433965Sjdp top_scope->sec = ofile->sections + sym->n_scnum; 64533965Sjdp top_scope->offset = sym->n_value; 64633965Sjdp } 64733965Sjdp else 64833965Sjdp { 64933965Sjdp top_scope->size = sym->n_value - top_scope->offset + 1; 65033965Sjdp pop_scope (); 65133965Sjdp 65233965Sjdp } 65333965Sjdp i += sym->n_numaux + 1; 65433965Sjdp } 65533965Sjdp break; 65633965Sjdp 65733965Sjdp case C_BLOCK: 65833965Sjdp { 65933965Sjdp char *name = sym->_n._n_nptr[1]; 66033965Sjdp if (name[1] == 'b') 66133965Sjdp { 66233965Sjdp /* Block start */ 66333965Sjdp push_scope (1); 66433965Sjdp top_scope->sec = ofile->sections + sym->n_scnum; 66533965Sjdp top_scope->offset = sym->n_value; 66633965Sjdp 66733965Sjdp } 66833965Sjdp else 66933965Sjdp { 67033965Sjdp top_scope->size = sym->n_value - top_scope->offset + 1; 67133965Sjdp pop_scope (); 67233965Sjdp } 67333965Sjdp i += sym->n_numaux + 1; 67433965Sjdp } 67533965Sjdp break; 67633965Sjdp case C_REGPARM: 67733965Sjdp case C_ARG: 67833965Sjdp i = do_define (i, last_function_symbol->type->u.function.parameters); 67933965Sjdp break; 68033965Sjdp case C_MOS: 68133965Sjdp case C_MOU: 68233965Sjdp case C_FIELD: 68333965Sjdp i = do_define (i, last_struct->u.astructdef.elements); 68433965Sjdp break; 68533965Sjdp case C_MOE: 68633965Sjdp i = do_define (i, last_enum->u.aenumdef.elements); 68733965Sjdp break; 68833965Sjdp case C_STRTAG: 68933965Sjdp case C_ENTAG: 69033965Sjdp case C_UNTAG: 69133965Sjdp /* Various definition */ 69233965Sjdp i = do_define (i, top_scope); 69333965Sjdp break; 69433965Sjdp case C_EXT: 69533965Sjdp case C_LABEL: 69633965Sjdp i = do_define (i, file_scope); 69733965Sjdp break; 69833965Sjdp case C_STAT: 69933965Sjdp case C_TPDEF: 70033965Sjdp case C_AUTO: 70133965Sjdp case C_REG: 70233965Sjdp i = do_define (i, top_scope); 70333965Sjdp break; 70433965Sjdp default: 70533965Sjdp abort (); 70633965Sjdp case C_EOS: 70733965Sjdp i += sym->n_numaux + 1; 70833965Sjdp break; 70933965Sjdp } 71033965Sjdp } 71133965Sjdp do_sections_p2 (head); 71233965Sjdp return head; 71333965Sjdp} 71433965Sjdp 71533965Sjdpstruct coff_ofile * 71633965Sjdpcoff_grok (inabfd) 71733965Sjdp bfd *inabfd; 71833965Sjdp{ 71933965Sjdp long storage; 72033965Sjdp struct coff_ofile *p; 72133965Sjdp abfd = inabfd; 72233965Sjdp storage = bfd_get_symtab_upper_bound (abfd); 72333965Sjdp 72433965Sjdp if (storage < 0) 72533965Sjdp bfd_fatal (abfd->filename); 72633965Sjdp 72733965Sjdp syms = (asymbol **) xmalloc (storage); 72833965Sjdp symcount = bfd_canonicalize_symtab (abfd, syms); 72933965Sjdp if (symcount < 0) 73033965Sjdp bfd_fatal (abfd->filename); 73133965Sjdp rawsyms = obj_raw_syments (abfd); 73233965Sjdp rawcount = obj_raw_syment_count (abfd);; 73333965Sjdp tindex = (struct coff_symbol **) (xcalloc (sizeof (struct coff_symbol *), rawcount)); 73433965Sjdp 73533965Sjdp p = doit (); 73633965Sjdp return p; 73733965Sjdp} 738