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