133965Sjdp/* coffgrok.c 2218822Sdim Copyright 1994, 1995, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2007 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 19218822SdimFoundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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 29218822Sdim#include "sysdep.h" 30104834Sobrien#include "bfd.h" 31104834Sobrien#include "libiberty.h" 3233965Sjdp 3333965Sjdp#include "coff/internal.h" 3433965Sjdp#include "../bfd/libcoff.h" 35218822Sdim#include "bucomm.h" 3633965Sjdp#include "coffgrok.h" 37218822Sdim 38218822Sdimstatic int lofile = 1; 3933965Sjdpstatic struct coff_scope *top_scope; 4033965Sjdpstatic struct coff_scope *file_scope; 4133965Sjdpstatic struct coff_ofile *ofile; 4233965Sjdp 43218822Sdimstatic struct coff_symbol *last_function_symbol; 44218822Sdimstatic struct coff_type *last_function_type; 45218822Sdimstatic struct coff_type *last_struct; 46218822Sdimstatic struct coff_type *last_enum; 47218822Sdimstatic struct coff_sfile *cur_sfile; 4833965Sjdp 4933965Sjdpstatic struct coff_symbol **tindex; 5033965Sjdp 5133965Sjdp 5233965Sjdpstatic asymbol **syms; 5333965Sjdpstatic long symcount; 5433965Sjdp 5533965Sjdp#define N(x) ((x)->_n._n_nptr[1]) 5633965Sjdp 5733965Sjdpstatic struct coff_ptr_struct *rawsyms; 5833965Sjdpstatic int rawcount; 5933965Sjdpstatic bfd *abfd; 6089857Sobrien 61130561Sobrien#define PTR_SIZE 4 62130561Sobrien#define SHORT_SIZE 2 63130561Sobrien#define INT_SIZE 4 64130561Sobrien#define LONG_SIZE 4 65130561Sobrien#define FLOAT_SIZE 4 66130561Sobrien#define DOUBLE_SIZE 8 6733965Sjdp 6833965Sjdp#define INDEXOF(p) ((struct coff_ptr_struct *)(p)-(rawsyms)) 6933965Sjdp 70130561Sobrienstatic struct coff_scope *empty_scope (void); 71130561Sobrienstatic struct coff_symbol *empty_symbol (void); 72130561Sobrienstatic void push_scope (int); 73130561Sobrienstatic void pop_scope (void); 74130561Sobrienstatic void do_sections_p1 (struct coff_ofile *); 75130561Sobrienstatic void do_sections_p2 (struct coff_ofile *); 76130561Sobrienstatic struct coff_where *do_where (int); 77130561Sobrienstatic struct coff_line *do_lines (int, char *); 78130561Sobrienstatic struct coff_type *do_type (int); 79130561Sobrienstatic struct coff_visible *do_visible (int); 80130561Sobrienstatic int do_define (int, struct coff_scope *); 81130561Sobrienstatic struct coff_ofile *doit (void); 8289857Sobrien 8333965Sjdpstatic struct coff_scope * 84130561Sobrienempty_scope (void) 8533965Sjdp{ 8633965Sjdp struct coff_scope *l; 8733965Sjdp l = (struct coff_scope *) (xcalloc (sizeof (struct coff_scope), 1)); 8833965Sjdp return l; 8933965Sjdp} 9033965Sjdp 9133965Sjdpstatic struct coff_symbol * 92130561Sobrienempty_symbol (void) 9333965Sjdp{ 9433965Sjdp return (struct coff_symbol *) (xcalloc (sizeof (struct coff_symbol), 1)); 9533965Sjdp} 9633965Sjdp 9733965Sjdp/*int l;*/ 9833965Sjdpstatic void 99130561Sobrienpush_scope (int link) 10033965Sjdp{ 10133965Sjdp struct coff_scope *n = empty_scope (); 10233965Sjdp if (link) 10333965Sjdp { 10433965Sjdp if (top_scope) 10533965Sjdp { 10633965Sjdp if (top_scope->list_tail) 10733965Sjdp { 10833965Sjdp top_scope->list_tail->next = n; 10933965Sjdp } 11033965Sjdp else 11133965Sjdp { 11233965Sjdp top_scope->list_head = n; 11333965Sjdp } 11433965Sjdp top_scope->list_tail = n; 11533965Sjdp } 11633965Sjdp } 11733965Sjdp n->parent = top_scope; 11833965Sjdp 11933965Sjdp top_scope = n; 12033965Sjdp} 12133965Sjdp 12233965Sjdpstatic void 123130561Sobrienpop_scope (void) 12433965Sjdp{ 12533965Sjdp top_scope = top_scope->parent; 12633965Sjdp} 12733965Sjdp 12833965Sjdpstatic void 129130561Sobriendo_sections_p1 (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; 161218822Sdim head->sections[i].size = bfd_get_section_size (section); 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 178130561Sobriendo_sections_p2 (struct coff_ofile *head) 17933965Sjdp{ 18033965Sjdp asection *section; 18133965Sjdp for (section = abfd->sections; section; section = section->next) 18233965Sjdp { 18338889Sjdp unsigned int j; 18438889Sjdp 18533965Sjdp for (j = 0; j < section->reloc_count; j++) 18633965Sjdp { 18733965Sjdp int idx; 18833965Sjdp int i = section->target_index; 18933965Sjdp struct coff_reloc *r = head->sections[i].relocs + j; 19033965Sjdp arelent *sr = section->relocation + j; 19133965Sjdp r->offset = sr->address; 19233965Sjdp r->addend = sr->addend; 19333965Sjdp idx = ((coff_symbol_type *) (sr->sym_ptr_ptr[0]))->native - rawsyms; 19433965Sjdp r->symbol = tindex[idx]; 19533965Sjdp } 19633965Sjdp } 19733965Sjdp} 19833965Sjdp 19933965Sjdpstatic struct coff_where * 200130561Sobriendo_where (int i) 20133965Sjdp{ 20233965Sjdp struct internal_syment *sym = &rawsyms[i].u.syment; 20333965Sjdp struct coff_where *where = 20433965Sjdp (struct coff_where *) (xmalloc (sizeof (struct coff_where))); 20533965Sjdp where->offset = sym->n_value; 20633965Sjdp 20733965Sjdp if (sym->n_scnum == -1) 20833965Sjdp sym->n_scnum = 0; 20933965Sjdp 21033965Sjdp switch (sym->n_sclass) 21133965Sjdp { 21233965Sjdp case C_FIELD: 21333965Sjdp where->where = coff_where_member_of_struct; 21433965Sjdp where->offset = sym->n_value / 8; 21533965Sjdp where->bitoffset = sym->n_value % 8; 21633965Sjdp where->bitsize = rawsyms[i + 1].u.auxent.x_sym.x_misc.x_lnsz.x_size; 21733965Sjdp break; 21833965Sjdp case C_MOE: 21933965Sjdp where->where = coff_where_member_of_enum; 22033965Sjdp break; 22133965Sjdp case C_MOS: 22233965Sjdp case C_MOU: 22333965Sjdp where->where = coff_where_member_of_struct; 22433965Sjdp break; 22533965Sjdp case C_AUTO: 22633965Sjdp case C_ARG: 22733965Sjdp where->where = coff_where_stack; 22833965Sjdp break; 22933965Sjdp case C_EXT: 23033965Sjdp case C_STAT: 23133965Sjdp case C_EXTDEF: 23233965Sjdp case C_LABEL: 23333965Sjdp where->where = coff_where_memory; 23433965Sjdp where->section = &ofile->sections[sym->n_scnum]; 23533965Sjdp break; 23633965Sjdp case C_REG: 23733965Sjdp case C_REGPARM: 23833965Sjdp where->where = coff_where_register; 23933965Sjdp break; 24033965Sjdp case C_ENTAG: 24133965Sjdp where->where = coff_where_entag; 24233965Sjdp break; 24333965Sjdp case C_STRTAG: 24433965Sjdp case C_UNTAG: 24533965Sjdp where->where = coff_where_strtag; 24633965Sjdp break; 24733965Sjdp case C_TPDEF: 24833965Sjdp where->where = coff_where_typedef; 24933965Sjdp break; 25033965Sjdp default: 25133965Sjdp abort (); 25233965Sjdp break; 25333965Sjdp } 25433965Sjdp return where; 25533965Sjdp} 25633965Sjdp 25733965Sjdpstatic 25833965Sjdpstruct coff_line * 259130561Sobriendo_lines (int i, char *name ATTRIBUTE_UNUSED) 26033965Sjdp{ 26133965Sjdp struct coff_line *res = (struct coff_line *) xcalloc (sizeof (struct coff_line), 1); 26233965Sjdp asection *s; 26338889Sjdp unsigned int l; 26438889Sjdp 26533965Sjdp /* Find out if this function has any line numbers in the table */ 26633965Sjdp for (s = abfd->sections; s; s = s->next) 26733965Sjdp { 26833965Sjdp for (l = 0; l < s->lineno_count; l++) 26933965Sjdp { 27033965Sjdp if (s->lineno[l].line_number == 0) 27133965Sjdp { 27233965Sjdp if (rawsyms + i == ((coff_symbol_type *) (&(s->lineno[l].u.sym[0])))->native) 27333965Sjdp { 27433965Sjdp /* These lines are for this function - so count them and stick them on */ 27533965Sjdp int c = 0; 27633965Sjdp /* Find the linenumber of the top of the function, since coff linenumbers 277104834Sobrien are relative to the start of the function. */ 27833965Sjdp int start_line = rawsyms[i + 3].u.auxent.x_sym.x_misc.x_lnsz.x_lnno; 27933965Sjdp 28033965Sjdp l++; 28133965Sjdp for (c = 0; s->lineno[l + c + 1].line_number; c++) 28233965Sjdp ; 28333965Sjdp 28433965Sjdp /* Add two extra records, one for the prologue and one for the epilogue */ 28533965Sjdp c += 1; 28633965Sjdp res->nlines = c; 28733965Sjdp res->lines = (int *) (xcalloc (sizeof (int), c)); 28833965Sjdp res->addresses = (int *) (xcalloc (sizeof (int), c)); 28933965Sjdp res->lines[0] = start_line; 29033965Sjdp res->addresses[0] = rawsyms[i].u.syment.n_value - s->vma; 29133965Sjdp for (c = 0; s->lineno[l + c + 1].line_number; c++) 29233965Sjdp { 29333965Sjdp res->lines[c + 1] = s->lineno[l + c].line_number + start_line - 1; 29433965Sjdp res->addresses[c + 1] = s->lineno[l + c].u.offset; 29533965Sjdp } 29633965Sjdp return res; 29733965Sjdp } 29833965Sjdp } 29933965Sjdp } 30033965Sjdp } 30133965Sjdp return res; 30233965Sjdp} 30333965Sjdp 30433965Sjdpstatic 30533965Sjdpstruct coff_type * 306130561Sobriendo_type (int i) 30733965Sjdp{ 30833965Sjdp struct internal_syment *sym = &rawsyms[i].u.syment; 30933965Sjdp union internal_auxent *aux = &rawsyms[i + 1].u.auxent; 31033965Sjdp struct coff_type *res = 31133965Sjdp (struct coff_type *) xmalloc (sizeof (struct coff_type)); 31233965Sjdp int type = sym->n_type; 31333965Sjdp int which_dt = 0; 31433965Sjdp int dimind = 0; 31533965Sjdp 31633965Sjdp res->type = coff_basic_type; 31733965Sjdp res->u.basic = type & 0xf; 31833965Sjdp 31933965Sjdp switch (type & 0xf) 32033965Sjdp { 32133965Sjdp case T_NULL: 32233965Sjdp case T_VOID: 32333965Sjdp if (sym->n_numaux && sym->n_sclass == C_STAT) 32433965Sjdp { 32533965Sjdp /* This is probably a section definition */ 32633965Sjdp res->type = coff_secdef_type; 32733965Sjdp res->size = aux->x_scn.x_scnlen; 32833965Sjdp } 32933965Sjdp else 33033965Sjdp { 33133965Sjdp if (type == 0) 33233965Sjdp { 33333965Sjdp /* Don't know what this is, let's make it a simple int */ 33433965Sjdp res->size = INT_SIZE; 33533965Sjdp res->u.basic = T_UINT; 33633965Sjdp } 33733965Sjdp else 33833965Sjdp { 33933965Sjdp /* Else it could be a function or pointer to void */ 34033965Sjdp res->size = 0; 34133965Sjdp } 34233965Sjdp } 34333965Sjdp break; 34433965Sjdp 34533965Sjdp 34633965Sjdp break; 34733965Sjdp case T_UCHAR: 34833965Sjdp case T_CHAR: 34933965Sjdp res->size = 1; 35033965Sjdp break; 35133965Sjdp case T_USHORT: 35233965Sjdp case T_SHORT: 35333965Sjdp res->size = SHORT_SIZE; 35433965Sjdp break; 35533965Sjdp case T_UINT: 35633965Sjdp case T_INT: 35733965Sjdp res->size = INT_SIZE; 35833965Sjdp break; 35933965Sjdp case T_ULONG: 36033965Sjdp case T_LONG: 36133965Sjdp res->size = LONG_SIZE; 36233965Sjdp break; 36333965Sjdp case T_FLOAT: 36433965Sjdp res->size = FLOAT_SIZE; 36533965Sjdp break; 36633965Sjdp case T_DOUBLE: 36733965Sjdp res->size = DOUBLE_SIZE; 36833965Sjdp break; 36933965Sjdp case T_STRUCT: 37033965Sjdp case T_UNION: 37133965Sjdp if (sym->n_numaux) 37233965Sjdp { 37333965Sjdp if (aux->x_sym.x_tagndx.p) 37433965Sjdp { 375130561Sobrien /* Referring to a struct defined elsewhere */ 37633965Sjdp res->type = coff_structref_type; 37733965Sjdp res->u.astructref.ref = tindex[INDEXOF (aux->x_sym.x_tagndx.p)]; 37833965Sjdp res->size = res->u.astructref.ref ? 37933965Sjdp res->u.astructref.ref->type->size : 0; 38033965Sjdp } 38133965Sjdp else 38233965Sjdp { 38333965Sjdp /* A definition of a struct */ 38433965Sjdp last_struct = res; 38533965Sjdp res->type = coff_structdef_type; 38633965Sjdp res->u.astructdef.elements = empty_scope (); 38733965Sjdp res->u.astructdef.idx = 0; 38833965Sjdp res->u.astructdef.isstruct = (type & 0xf) == T_STRUCT; 38933965Sjdp res->size = aux->x_sym.x_misc.x_lnsz.x_size; 39033965Sjdp } 39133965Sjdp } 39233965Sjdp else 39333965Sjdp { 394130561Sobrien /* No auxents - it's anonymous */ 39533965Sjdp res->type = coff_structref_type; 39633965Sjdp res->u.astructref.ref = 0; 39733965Sjdp res->size = 0; 39833965Sjdp } 39933965Sjdp break; 40033965Sjdp case T_ENUM: 40133965Sjdp if (aux->x_sym.x_tagndx.p) 40233965Sjdp { 403130561Sobrien /* Referring to a enum defined elsewhere */ 40433965Sjdp res->type = coff_enumref_type; 40533965Sjdp res->u.aenumref.ref = tindex[INDEXOF (aux->x_sym.x_tagndx.p)]; 40633965Sjdp res->size = res->u.aenumref.ref->type->size; 40733965Sjdp } 40833965Sjdp else 40933965Sjdp { 41033965Sjdp /* A definition of an enum */ 41133965Sjdp last_enum = res; 41233965Sjdp res->type = coff_enumdef_type; 41333965Sjdp res->u.aenumdef.elements = empty_scope (); 41433965Sjdp res->size = aux->x_sym.x_misc.x_lnsz.x_size; 41533965Sjdp } 41633965Sjdp break; 41733965Sjdp case T_MOE: 41833965Sjdp break; 41933965Sjdp } 42033965Sjdp 42133965Sjdp for (which_dt = 5; which_dt >= 0; which_dt--) 42233965Sjdp { 42333965Sjdp switch ((type >> ((which_dt * 2) + 4)) & 0x3) 42433965Sjdp { 42533965Sjdp case 0: 42633965Sjdp break; 42733965Sjdp case DT_ARY: 42833965Sjdp { 42933965Sjdp struct coff_type *ptr = ((struct coff_type *) 43033965Sjdp xmalloc (sizeof (struct coff_type))); 43133965Sjdp int els = (dimind < DIMNUM 43233965Sjdp ? aux->x_sym.x_fcnary.x_ary.x_dimen[dimind] 43333965Sjdp : 0); 43433965Sjdp ++dimind; 43533965Sjdp ptr->type = coff_array_type; 43633965Sjdp ptr->size = els * res->size; 43733965Sjdp ptr->u.array.dim = els; 43833965Sjdp ptr->u.array.array_of = res; 43933965Sjdp res = ptr; 44033965Sjdp break; 44133965Sjdp } 44233965Sjdp case DT_PTR: 44333965Sjdp { 44433965Sjdp struct coff_type *ptr = 44533965Sjdp (struct coff_type *) xmalloc (sizeof (struct coff_type)); 44633965Sjdp ptr->size = PTR_SIZE; 44733965Sjdp ptr->type = coff_pointer_type; 44833965Sjdp ptr->u.pointer.points_to = res; 44933965Sjdp res = ptr; 45033965Sjdp break; 45133965Sjdp } 45233965Sjdp case DT_FCN: 45333965Sjdp { 45433965Sjdp struct coff_type *ptr 45533965Sjdp = (struct coff_type *) xmalloc (sizeof (struct coff_type)); 45633965Sjdp ptr->size = 0; 45733965Sjdp ptr->type = coff_function_type; 45833965Sjdp ptr->u.function.function_returns = res; 45933965Sjdp ptr->u.function.parameters = empty_scope (); 46033965Sjdp ptr->u.function.lines = do_lines (i, sym->_n._n_nptr[1]); 46133965Sjdp ptr->u.function.code = 0; 46233965Sjdp last_function_type = ptr; 46333965Sjdp res = ptr; 46433965Sjdp break; 46533965Sjdp } 46633965Sjdp } 46733965Sjdp } 46833965Sjdp return res; 46933965Sjdp} 47033965Sjdp 47133965Sjdpstatic struct coff_visible * 472130561Sobriendo_visible (int i) 47333965Sjdp{ 47433965Sjdp struct internal_syment *sym = &rawsyms[i].u.syment; 47533965Sjdp struct coff_visible *visible = 47633965Sjdp (struct coff_visible *) (xmalloc (sizeof (struct coff_visible))); 47733965Sjdp enum coff_vis_type t; 47833965Sjdp switch (sym->n_sclass) 47933965Sjdp { 48033965Sjdp case C_MOS: 48133965Sjdp case C_MOU: 48233965Sjdp case C_FIELD: 48333965Sjdp t = coff_vis_member_of_struct; 48433965Sjdp break; 48533965Sjdp case C_MOE: 48633965Sjdp t = coff_vis_member_of_enum; 48733965Sjdp break; 48833965Sjdp 48933965Sjdp case C_REGPARM: 49033965Sjdp t = coff_vis_regparam; 49133965Sjdp break; 49233965Sjdp 49333965Sjdp case C_REG: 49433965Sjdp t = coff_vis_register; 49533965Sjdp break; 49633965Sjdp case C_STRTAG: 49733965Sjdp case C_UNTAG: 49833965Sjdp case C_ENTAG: 49933965Sjdp case C_TPDEF: 50033965Sjdp t = coff_vis_tag; 50133965Sjdp break; 50233965Sjdp case C_AUTOARG: 50333965Sjdp case C_ARG: 50433965Sjdp t = coff_vis_autoparam; 50533965Sjdp break; 50633965Sjdp case C_AUTO: 50733965Sjdp 50833965Sjdp 50933965Sjdp t = coff_vis_auto; 51033965Sjdp break; 51133965Sjdp case C_LABEL: 51233965Sjdp case C_STAT: 51333965Sjdp t = coff_vis_int_def; 51433965Sjdp break; 51533965Sjdp case C_EXT: 51633965Sjdp if (sym->n_scnum == N_UNDEF) 51733965Sjdp { 51833965Sjdp if (sym->n_value) 51933965Sjdp t = coff_vis_common; 52033965Sjdp else 52133965Sjdp t = coff_vis_ext_ref; 52233965Sjdp } 52333965Sjdp else 52433965Sjdp t = coff_vis_ext_def; 52533965Sjdp break; 52633965Sjdp default: 52733965Sjdp abort (); 52833965Sjdp break; 52933965Sjdp 53033965Sjdp } 53133965Sjdp visible->type = t; 53233965Sjdp return visible; 53333965Sjdp} 53433965Sjdp 53533965Sjdpstatic int 536130561Sobriendo_define (int i, struct coff_scope *b) 53733965Sjdp{ 53833965Sjdp static int symbol_index; 53933965Sjdp struct internal_syment *sym = &rawsyms[i].u.syment; 54033965Sjdp 54133965Sjdp /* Define a symbol and attach to block b */ 54233965Sjdp struct coff_symbol *s = empty_symbol (); 54333965Sjdp 54433965Sjdp s->number = ++symbol_index; 54533965Sjdp s->name = sym->_n._n_nptr[1]; 54633965Sjdp s->sfile = cur_sfile; 54733965Sjdp /* Glue onto the ofile list */ 54833965Sjdp if (lofile >= 0) 54933965Sjdp { 55033965Sjdp if (ofile->symbol_list_tail) 55133965Sjdp ofile->symbol_list_tail->next_in_ofile_list = s; 55233965Sjdp else 55333965Sjdp ofile->symbol_list_head = s; 55433965Sjdp ofile->symbol_list_tail = s; 55533965Sjdp /* And the block list */ 55633965Sjdp } 55733965Sjdp if (b->vars_tail) 55833965Sjdp b->vars_tail->next = s; 55933965Sjdp else 56033965Sjdp b->vars_head = s; 56133965Sjdp 56233965Sjdp b->vars_tail = s; 56333965Sjdp b->nvars++; 56433965Sjdp s->type = do_type (i); 56533965Sjdp s->where = do_where (i); 56633965Sjdp s->visible = do_visible (i); 56733965Sjdp 56833965Sjdp tindex[i] = s; 56933965Sjdp 57033965Sjdp /* We remember the lowest address in each section for each source file */ 57133965Sjdp 57233965Sjdp if (s->where->where == coff_where_memory 57333965Sjdp && s->type->type == coff_secdef_type) 57433965Sjdp { 57533965Sjdp struct coff_isection *is = cur_sfile->section + s->where->section->number; 57633965Sjdp 57733965Sjdp if (!is->init) 57833965Sjdp { 57933965Sjdp is->low = s->where->offset; 58033965Sjdp is->high = s->where->offset + s->type->size; 58133965Sjdp is->init = 1; 58233965Sjdp is->parent = s->where->section; 58333965Sjdp } 58433965Sjdp 58533965Sjdp } 58633965Sjdp 58733965Sjdp if (s->type->type == coff_function_type) 58833965Sjdp last_function_symbol = s; 58933965Sjdp 59033965Sjdp return i + sym->n_numaux + 1; 59133965Sjdp} 59233965Sjdp 59333965Sjdp 59433965Sjdpstatic 59533965Sjdpstruct coff_ofile * 596130561Sobriendoit (void) 59733965Sjdp{ 59833965Sjdp int i; 59933965Sjdp int infile = 0; 60033965Sjdp struct coff_ofile *head = 601104834Sobrien (struct coff_ofile *) xmalloc (sizeof (struct coff_ofile)); 60233965Sjdp ofile = head; 60333965Sjdp head->source_head = 0; 60433965Sjdp head->source_tail = 0; 60533965Sjdp head->nsources = 0; 60633965Sjdp head->symbol_list_tail = 0; 60733965Sjdp head->symbol_list_head = 0; 60833965Sjdp do_sections_p1 (head); 60933965Sjdp push_scope (1); 61033965Sjdp 61133965Sjdp for (i = 0; i < rawcount;) 61233965Sjdp { 61333965Sjdp struct internal_syment *sym = &rawsyms[i].u.syment; 61433965Sjdp switch (sym->n_sclass) 61533965Sjdp { 61633965Sjdp case C_FILE: 61733965Sjdp { 61833965Sjdp /* new source file announced */ 61933965Sjdp struct coff_sfile *n = 62033965Sjdp (struct coff_sfile *) xmalloc (sizeof (struct coff_sfile)); 62133965Sjdp n->section = (struct coff_isection *) xcalloc (sizeof (struct coff_isection), abfd->section_count + 1); 62233965Sjdp cur_sfile = n; 62333965Sjdp n->name = sym->_n._n_nptr[1]; 62433965Sjdp n->next = 0; 62533965Sjdp 62633965Sjdp if (infile) 62733965Sjdp { 62833965Sjdp pop_scope (); 62933965Sjdp } 63033965Sjdp infile = 1; 63133965Sjdp push_scope (1); 63233965Sjdp file_scope = n->scope = top_scope; 63333965Sjdp 63433965Sjdp if (head->source_tail) 63533965Sjdp head->source_tail->next = n; 63633965Sjdp else 63733965Sjdp head->source_head = n; 63833965Sjdp head->source_tail = n; 63933965Sjdp head->nsources++; 64033965Sjdp i += sym->n_numaux + 1; 64133965Sjdp } 64233965Sjdp break; 64333965Sjdp case C_FCN: 64433965Sjdp { 64533965Sjdp char *name = sym->_n._n_nptr[1]; 64633965Sjdp if (name[1] == 'b') 64733965Sjdp { 64833965Sjdp /* Function start */ 64933965Sjdp push_scope (0); 65033965Sjdp last_function_type->u.function.code = top_scope; 65133965Sjdp top_scope->sec = ofile->sections + sym->n_scnum; 65233965Sjdp top_scope->offset = sym->n_value; 65333965Sjdp } 65433965Sjdp else 65533965Sjdp { 65633965Sjdp top_scope->size = sym->n_value - top_scope->offset + 1; 65733965Sjdp pop_scope (); 65833965Sjdp 65933965Sjdp } 66033965Sjdp i += sym->n_numaux + 1; 66133965Sjdp } 66233965Sjdp break; 66333965Sjdp 66433965Sjdp case C_BLOCK: 66533965Sjdp { 66633965Sjdp char *name = sym->_n._n_nptr[1]; 66733965Sjdp if (name[1] == 'b') 66833965Sjdp { 66933965Sjdp /* Block start */ 67033965Sjdp push_scope (1); 67133965Sjdp top_scope->sec = ofile->sections + sym->n_scnum; 67233965Sjdp top_scope->offset = sym->n_value; 67333965Sjdp 67433965Sjdp } 67533965Sjdp else 67633965Sjdp { 67733965Sjdp top_scope->size = sym->n_value - top_scope->offset + 1; 67833965Sjdp pop_scope (); 67933965Sjdp } 68033965Sjdp i += sym->n_numaux + 1; 68133965Sjdp } 68233965Sjdp break; 68333965Sjdp case C_REGPARM: 68433965Sjdp case C_ARG: 68533965Sjdp i = do_define (i, last_function_symbol->type->u.function.parameters); 68633965Sjdp break; 68733965Sjdp case C_MOS: 68833965Sjdp case C_MOU: 68933965Sjdp case C_FIELD: 69033965Sjdp i = do_define (i, last_struct->u.astructdef.elements); 69133965Sjdp break; 69233965Sjdp case C_MOE: 69333965Sjdp i = do_define (i, last_enum->u.aenumdef.elements); 69433965Sjdp break; 69533965Sjdp case C_STRTAG: 69633965Sjdp case C_ENTAG: 69733965Sjdp case C_UNTAG: 69833965Sjdp /* Various definition */ 69933965Sjdp i = do_define (i, top_scope); 70033965Sjdp break; 70133965Sjdp case C_EXT: 70233965Sjdp case C_LABEL: 70333965Sjdp i = do_define (i, file_scope); 70433965Sjdp break; 70533965Sjdp case C_STAT: 70633965Sjdp case C_TPDEF: 70733965Sjdp case C_AUTO: 70833965Sjdp case C_REG: 70933965Sjdp i = do_define (i, top_scope); 71033965Sjdp break; 71133965Sjdp default: 71233965Sjdp abort (); 71333965Sjdp case C_EOS: 71433965Sjdp i += sym->n_numaux + 1; 71533965Sjdp break; 71633965Sjdp } 71733965Sjdp } 71833965Sjdp do_sections_p2 (head); 71933965Sjdp return head; 72033965Sjdp} 72133965Sjdp 72233965Sjdpstruct coff_ofile * 723130561Sobriencoff_grok (bfd *inabfd) 72433965Sjdp{ 72533965Sjdp long storage; 72633965Sjdp struct coff_ofile *p; 72733965Sjdp abfd = inabfd; 72833965Sjdp storage = bfd_get_symtab_upper_bound (abfd); 72933965Sjdp 73033965Sjdp if (storage < 0) 73133965Sjdp bfd_fatal (abfd->filename); 73233965Sjdp 73333965Sjdp syms = (asymbol **) xmalloc (storage); 73433965Sjdp symcount = bfd_canonicalize_symtab (abfd, syms); 73533965Sjdp if (symcount < 0) 73633965Sjdp bfd_fatal (abfd->filename); 73733965Sjdp rawsyms = obj_raw_syments (abfd); 73833965Sjdp rawcount = obj_raw_syment_count (abfd);; 73933965Sjdp tindex = (struct coff_symbol **) (xcalloc (sizeof (struct coff_symbol *), rawcount)); 74033965Sjdp 74133965Sjdp p = doit (); 74233965Sjdp return p; 74333965Sjdp} 744