xref: /openbsd-src/gnu/usr.bin/binutils-2.17/binutils/coffgrok.c (revision 3d8817e467ea46cf4772788d6804dd293abfb01a)
1*3d8817e4Smiod /* coffgrok.c
2*3d8817e4Smiod    Copyright 1994, 1995, 1997, 1998, 2000, 2001, 2002, 2003, 2004
3*3d8817e4Smiod    Free Software Foundation, Inc.
4*3d8817e4Smiod 
5*3d8817e4Smiod This file is part of GNU Binutils.
6*3d8817e4Smiod 
7*3d8817e4Smiod This program is free software; you can redistribute it and/or modify
8*3d8817e4Smiod it under the terms of the GNU General Public License as published by
9*3d8817e4Smiod the Free Software Foundation; either version 2 of the License, or
10*3d8817e4Smiod (at your option) any later version.
11*3d8817e4Smiod 
12*3d8817e4Smiod This program is distributed in the hope that it will be useful,
13*3d8817e4Smiod but WITHOUT ANY WARRANTY; without even the implied warranty of
14*3d8817e4Smiod MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*3d8817e4Smiod GNU General Public License for more details.
16*3d8817e4Smiod 
17*3d8817e4Smiod You should have received a copy of the GNU General Public License
18*3d8817e4Smiod along with this program; if not, write to the Free Software
19*3d8817e4Smiod Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
20*3d8817e4Smiod 
21*3d8817e4Smiod /* Written by Steve Chamberlain (sac@cygnus.com)
22*3d8817e4Smiod 
23*3d8817e4Smiod    This module reads a coff file and builds a really simple type tree
24*3d8817e4Smiod    which can be read by other programs.  The first application is a
25*3d8817e4Smiod    coff->sysroff converter.  It can be tested with coffdump.c.
26*3d8817e4Smiod 
27*3d8817e4Smiod */
28*3d8817e4Smiod 
29*3d8817e4Smiod #include "bfd.h"
30*3d8817e4Smiod #include "libiberty.h"
31*3d8817e4Smiod #include "bucomm.h"
32*3d8817e4Smiod 
33*3d8817e4Smiod #include "coff/internal.h"
34*3d8817e4Smiod #include "../bfd/libcoff.h"
35*3d8817e4Smiod #include "coffgrok.h"
36*3d8817e4Smiod static int lofile = 1;
37*3d8817e4Smiod static struct coff_scope *top_scope;
38*3d8817e4Smiod static struct coff_scope *file_scope;
39*3d8817e4Smiod static struct coff_ofile *ofile;
40*3d8817e4Smiod 
41*3d8817e4Smiod static struct coff_symbol *last_function_symbol;
42*3d8817e4Smiod static struct coff_type *last_function_type;
43*3d8817e4Smiod static struct coff_type *last_struct;
44*3d8817e4Smiod static struct coff_type *last_enum;
45*3d8817e4Smiod static struct coff_sfile *cur_sfile;
46*3d8817e4Smiod 
47*3d8817e4Smiod static struct coff_symbol **tindex;
48*3d8817e4Smiod 
49*3d8817e4Smiod 
50*3d8817e4Smiod static asymbol **syms;
51*3d8817e4Smiod static long symcount;
52*3d8817e4Smiod 
53*3d8817e4Smiod #define N(x) ((x)->_n._n_nptr[1])
54*3d8817e4Smiod 
55*3d8817e4Smiod static struct coff_ptr_struct *rawsyms;
56*3d8817e4Smiod static int rawcount;
57*3d8817e4Smiod static bfd *abfd;
58*3d8817e4Smiod 
59*3d8817e4Smiod #define PTR_SIZE	4
60*3d8817e4Smiod #define SHORT_SIZE	2
61*3d8817e4Smiod #define INT_SIZE	4
62*3d8817e4Smiod #define LONG_SIZE	4
63*3d8817e4Smiod #define FLOAT_SIZE	4
64*3d8817e4Smiod #define DOUBLE_SIZE	8
65*3d8817e4Smiod 
66*3d8817e4Smiod #define INDEXOF(p)  ((struct coff_ptr_struct *)(p)-(rawsyms))
67*3d8817e4Smiod 
68*3d8817e4Smiod static struct coff_scope *empty_scope (void);
69*3d8817e4Smiod static struct coff_symbol *empty_symbol (void);
70*3d8817e4Smiod static void push_scope (int);
71*3d8817e4Smiod static void pop_scope (void);
72*3d8817e4Smiod static void do_sections_p1 (struct coff_ofile *);
73*3d8817e4Smiod static void do_sections_p2 (struct coff_ofile *);
74*3d8817e4Smiod static struct coff_where *do_where (int);
75*3d8817e4Smiod static struct coff_line *do_lines (int, char *);
76*3d8817e4Smiod static struct coff_type *do_type (int);
77*3d8817e4Smiod static struct coff_visible *do_visible (int);
78*3d8817e4Smiod static int do_define (int, struct coff_scope *);
79*3d8817e4Smiod static struct coff_ofile *doit (void);
80*3d8817e4Smiod 
81*3d8817e4Smiod static struct coff_scope *
empty_scope(void)82*3d8817e4Smiod empty_scope (void)
83*3d8817e4Smiod {
84*3d8817e4Smiod   struct coff_scope *l;
85*3d8817e4Smiod   l = (struct coff_scope *) (xcalloc (sizeof (struct coff_scope), 1));
86*3d8817e4Smiod   return l;
87*3d8817e4Smiod }
88*3d8817e4Smiod 
89*3d8817e4Smiod static struct coff_symbol *
empty_symbol(void)90*3d8817e4Smiod empty_symbol (void)
91*3d8817e4Smiod {
92*3d8817e4Smiod   return (struct coff_symbol *) (xcalloc (sizeof (struct coff_symbol), 1));
93*3d8817e4Smiod }
94*3d8817e4Smiod 
95*3d8817e4Smiod /*int l;*/
96*3d8817e4Smiod static void
push_scope(int link)97*3d8817e4Smiod push_scope (int link)
98*3d8817e4Smiod {
99*3d8817e4Smiod   struct coff_scope *n = empty_scope ();
100*3d8817e4Smiod   if (link)
101*3d8817e4Smiod     {
102*3d8817e4Smiod       if (top_scope)
103*3d8817e4Smiod 	{
104*3d8817e4Smiod 	  if (top_scope->list_tail)
105*3d8817e4Smiod 	    {
106*3d8817e4Smiod 	      top_scope->list_tail->next = n;
107*3d8817e4Smiod 	    }
108*3d8817e4Smiod 	  else
109*3d8817e4Smiod 	    {
110*3d8817e4Smiod 	      top_scope->list_head = n;
111*3d8817e4Smiod 	    }
112*3d8817e4Smiod 	  top_scope->list_tail = n;
113*3d8817e4Smiod 	}
114*3d8817e4Smiod     }
115*3d8817e4Smiod   n->parent = top_scope;
116*3d8817e4Smiod 
117*3d8817e4Smiod   top_scope = n;
118*3d8817e4Smiod }
119*3d8817e4Smiod 
120*3d8817e4Smiod static void
pop_scope(void)121*3d8817e4Smiod pop_scope (void)
122*3d8817e4Smiod {
123*3d8817e4Smiod   top_scope = top_scope->parent;
124*3d8817e4Smiod }
125*3d8817e4Smiod 
126*3d8817e4Smiod static void
do_sections_p1(struct coff_ofile * head)127*3d8817e4Smiod do_sections_p1 (struct coff_ofile *head)
128*3d8817e4Smiod {
129*3d8817e4Smiod   asection *section;
130*3d8817e4Smiod   int idx;
131*3d8817e4Smiod   struct coff_section *all = (struct coff_section *) (xcalloc (abfd->section_count + 1,
132*3d8817e4Smiod 					     sizeof (struct coff_section)));
133*3d8817e4Smiod   head->nsections = abfd->section_count + 1;
134*3d8817e4Smiod   head->sections = all;
135*3d8817e4Smiod 
136*3d8817e4Smiod   for (idx = 0, section = abfd->sections; section; section = section->next, idx++)
137*3d8817e4Smiod     {
138*3d8817e4Smiod       long relsize;
139*3d8817e4Smiod       int i = section->target_index;
140*3d8817e4Smiod       arelent **relpp;
141*3d8817e4Smiod       long relcount;
142*3d8817e4Smiod 
143*3d8817e4Smiod       relsize = bfd_get_reloc_upper_bound (abfd, section);
144*3d8817e4Smiod       if (relsize < 0)
145*3d8817e4Smiod 	bfd_fatal (bfd_get_filename (abfd));
146*3d8817e4Smiod       if (relsize == 0)
147*3d8817e4Smiod 	continue;
148*3d8817e4Smiod       relpp = (arelent **) xmalloc (relsize);
149*3d8817e4Smiod       relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms);
150*3d8817e4Smiod       if (relcount < 0)
151*3d8817e4Smiod 	bfd_fatal (bfd_get_filename (abfd));
152*3d8817e4Smiod 
153*3d8817e4Smiod       head->sections[i].name = (char *) (section->name);
154*3d8817e4Smiod       head->sections[i].code = section->flags & SEC_CODE;
155*3d8817e4Smiod       head->sections[i].data = section->flags & SEC_DATA;
156*3d8817e4Smiod       if (strcmp (section->name, ".bss") == 0)
157*3d8817e4Smiod 	head->sections[i].data = 1;
158*3d8817e4Smiod       head->sections[i].address = section->lma;
159*3d8817e4Smiod       head->sections[i].size = bfd_get_section_size (section);
160*3d8817e4Smiod       head->sections[i].number = idx;
161*3d8817e4Smiod       head->sections[i].nrelocs = section->reloc_count;
162*3d8817e4Smiod       head->sections[i].relocs =
163*3d8817e4Smiod 	(struct coff_reloc *) (xcalloc (section->reloc_count,
164*3d8817e4Smiod 					sizeof (struct coff_reloc)));
165*3d8817e4Smiod       head->sections[i].bfd_section = section;
166*3d8817e4Smiod     }
167*3d8817e4Smiod   head->sections[0].name = "ABSOLUTE";
168*3d8817e4Smiod   head->sections[0].code = 0;
169*3d8817e4Smiod   head->sections[0].data = 0;
170*3d8817e4Smiod   head->sections[0].address = 0;
171*3d8817e4Smiod   head->sections[0].size = 0;
172*3d8817e4Smiod   head->sections[0].number = 0;
173*3d8817e4Smiod }
174*3d8817e4Smiod 
175*3d8817e4Smiod static void
do_sections_p2(struct coff_ofile * head)176*3d8817e4Smiod do_sections_p2 (struct coff_ofile *head)
177*3d8817e4Smiod {
178*3d8817e4Smiod   asection *section;
179*3d8817e4Smiod   for (section = abfd->sections; section; section = section->next)
180*3d8817e4Smiod     {
181*3d8817e4Smiod       unsigned int j;
182*3d8817e4Smiod 
183*3d8817e4Smiod       for (j = 0; j < section->reloc_count; j++)
184*3d8817e4Smiod 	{
185*3d8817e4Smiod 	  int idx;
186*3d8817e4Smiod 	  int i = section->target_index;
187*3d8817e4Smiod 	  struct coff_reloc *r = head->sections[i].relocs + j;
188*3d8817e4Smiod 	  arelent *sr = section->relocation + j;
189*3d8817e4Smiod 	  r->offset = sr->address;
190*3d8817e4Smiod 	  r->addend = sr->addend;
191*3d8817e4Smiod 	  idx = ((coff_symbol_type *) (sr->sym_ptr_ptr[0]))->native - rawsyms;
192*3d8817e4Smiod 	  r->symbol = tindex[idx];
193*3d8817e4Smiod 	}
194*3d8817e4Smiod     }
195*3d8817e4Smiod }
196*3d8817e4Smiod 
197*3d8817e4Smiod static struct coff_where *
do_where(int i)198*3d8817e4Smiod do_where (int i)
199*3d8817e4Smiod {
200*3d8817e4Smiod   struct internal_syment *sym = &rawsyms[i].u.syment;
201*3d8817e4Smiod   struct coff_where *where =
202*3d8817e4Smiod     (struct coff_where *) (xmalloc (sizeof (struct coff_where)));
203*3d8817e4Smiod   where->offset = sym->n_value;
204*3d8817e4Smiod 
205*3d8817e4Smiod   if (sym->n_scnum == -1)
206*3d8817e4Smiod     sym->n_scnum = 0;
207*3d8817e4Smiod 
208*3d8817e4Smiod   switch (sym->n_sclass)
209*3d8817e4Smiod     {
210*3d8817e4Smiod     case C_FIELD:
211*3d8817e4Smiod       where->where = coff_where_member_of_struct;
212*3d8817e4Smiod       where->offset = sym->n_value / 8;
213*3d8817e4Smiod       where->bitoffset = sym->n_value % 8;
214*3d8817e4Smiod       where->bitsize = rawsyms[i + 1].u.auxent.x_sym.x_misc.x_lnsz.x_size;
215*3d8817e4Smiod       break;
216*3d8817e4Smiod     case C_MOE:
217*3d8817e4Smiod       where->where = coff_where_member_of_enum;
218*3d8817e4Smiod       break;
219*3d8817e4Smiod     case C_MOS:
220*3d8817e4Smiod     case C_MOU:
221*3d8817e4Smiod       where->where = coff_where_member_of_struct;
222*3d8817e4Smiod       break;
223*3d8817e4Smiod     case C_AUTO:
224*3d8817e4Smiod     case C_ARG:
225*3d8817e4Smiod       where->where = coff_where_stack;
226*3d8817e4Smiod       break;
227*3d8817e4Smiod     case C_EXT:
228*3d8817e4Smiod     case C_STAT:
229*3d8817e4Smiod     case C_EXTDEF:
230*3d8817e4Smiod     case C_LABEL:
231*3d8817e4Smiod       where->where = coff_where_memory;
232*3d8817e4Smiod       where->section = &ofile->sections[sym->n_scnum];
233*3d8817e4Smiod       break;
234*3d8817e4Smiod     case C_REG:
235*3d8817e4Smiod     case C_REGPARM:
236*3d8817e4Smiod       where->where = coff_where_register;
237*3d8817e4Smiod       break;
238*3d8817e4Smiod     case C_ENTAG:
239*3d8817e4Smiod       where->where = coff_where_entag;
240*3d8817e4Smiod       break;
241*3d8817e4Smiod     case C_STRTAG:
242*3d8817e4Smiod     case C_UNTAG:
243*3d8817e4Smiod       where->where = coff_where_strtag;
244*3d8817e4Smiod       break;
245*3d8817e4Smiod     case C_TPDEF:
246*3d8817e4Smiod       where->where = coff_where_typedef;
247*3d8817e4Smiod       break;
248*3d8817e4Smiod     default:
249*3d8817e4Smiod       abort ();
250*3d8817e4Smiod       break;
251*3d8817e4Smiod     }
252*3d8817e4Smiod   return where;
253*3d8817e4Smiod }
254*3d8817e4Smiod 
255*3d8817e4Smiod static
256*3d8817e4Smiod struct coff_line *
do_lines(int i,char * name ATTRIBUTE_UNUSED)257*3d8817e4Smiod do_lines (int i, char *name ATTRIBUTE_UNUSED)
258*3d8817e4Smiod {
259*3d8817e4Smiod   struct coff_line *res = (struct coff_line *) xcalloc (sizeof (struct coff_line), 1);
260*3d8817e4Smiod   asection *s;
261*3d8817e4Smiod   unsigned int l;
262*3d8817e4Smiod 
263*3d8817e4Smiod   /* Find out if this function has any line numbers in the table */
264*3d8817e4Smiod   for (s = abfd->sections; s; s = s->next)
265*3d8817e4Smiod     {
266*3d8817e4Smiod       for (l = 0; l < s->lineno_count; l++)
267*3d8817e4Smiod 	{
268*3d8817e4Smiod 	  if (s->lineno[l].line_number == 0)
269*3d8817e4Smiod 	    {
270*3d8817e4Smiod 	      if (rawsyms + i == ((coff_symbol_type *) (&(s->lineno[l].u.sym[0])))->native)
271*3d8817e4Smiod 		{
272*3d8817e4Smiod 		  /* These lines are for this function - so count them and stick them on */
273*3d8817e4Smiod 		  int c = 0;
274*3d8817e4Smiod 		  /* Find the linenumber of the top of the function, since coff linenumbers
275*3d8817e4Smiod 		     are relative to the start of the function.  */
276*3d8817e4Smiod 		  int start_line = rawsyms[i + 3].u.auxent.x_sym.x_misc.x_lnsz.x_lnno;
277*3d8817e4Smiod 
278*3d8817e4Smiod 		  l++;
279*3d8817e4Smiod 		  for (c = 0; s->lineno[l + c + 1].line_number; c++)
280*3d8817e4Smiod 		    ;
281*3d8817e4Smiod 
282*3d8817e4Smiod 		  /* Add two extra records, one for the prologue and one for the epilogue */
283*3d8817e4Smiod 		  c += 1;
284*3d8817e4Smiod 		  res->nlines = c;
285*3d8817e4Smiod 		  res->lines = (int *) (xcalloc (sizeof (int), c));
286*3d8817e4Smiod 		  res->addresses = (int *) (xcalloc (sizeof (int), c));
287*3d8817e4Smiod 		  res->lines[0] = start_line;
288*3d8817e4Smiod 		  res->addresses[0] = rawsyms[i].u.syment.n_value - s->vma;
289*3d8817e4Smiod 		  for (c = 0; s->lineno[l + c + 1].line_number; c++)
290*3d8817e4Smiod 		    {
291*3d8817e4Smiod 		      res->lines[c + 1] = s->lineno[l + c].line_number + start_line - 1;
292*3d8817e4Smiod 		      res->addresses[c + 1] = s->lineno[l + c].u.offset;
293*3d8817e4Smiod 		    }
294*3d8817e4Smiod 		  return res;
295*3d8817e4Smiod 		}
296*3d8817e4Smiod 	    }
297*3d8817e4Smiod 	}
298*3d8817e4Smiod     }
299*3d8817e4Smiod   return res;
300*3d8817e4Smiod }
301*3d8817e4Smiod 
302*3d8817e4Smiod static
303*3d8817e4Smiod struct coff_type *
do_type(int i)304*3d8817e4Smiod do_type (int i)
305*3d8817e4Smiod {
306*3d8817e4Smiod   struct internal_syment *sym = &rawsyms[i].u.syment;
307*3d8817e4Smiod   union internal_auxent *aux = &rawsyms[i + 1].u.auxent;
308*3d8817e4Smiod   struct coff_type *res =
309*3d8817e4Smiod     (struct coff_type *) xmalloc (sizeof (struct coff_type));
310*3d8817e4Smiod   int type = sym->n_type;
311*3d8817e4Smiod   int which_dt = 0;
312*3d8817e4Smiod   int dimind = 0;
313*3d8817e4Smiod 
314*3d8817e4Smiod   res->type = coff_basic_type;
315*3d8817e4Smiod   res->u.basic = type & 0xf;
316*3d8817e4Smiod 
317*3d8817e4Smiod   switch (type & 0xf)
318*3d8817e4Smiod     {
319*3d8817e4Smiod     case T_NULL:
320*3d8817e4Smiod     case T_VOID:
321*3d8817e4Smiod       if (sym->n_numaux && sym->n_sclass == C_STAT)
322*3d8817e4Smiod 	{
323*3d8817e4Smiod 	  /* This is probably a section definition */
324*3d8817e4Smiod 	  res->type = coff_secdef_type;
325*3d8817e4Smiod 	  res->size = aux->x_scn.x_scnlen;
326*3d8817e4Smiod 	}
327*3d8817e4Smiod       else
328*3d8817e4Smiod 	{
329*3d8817e4Smiod 	  if (type == 0)
330*3d8817e4Smiod 	    {
331*3d8817e4Smiod 	      /* Don't know what this is, let's make it a simple int */
332*3d8817e4Smiod 	      res->size = INT_SIZE;
333*3d8817e4Smiod 	      res->u.basic = T_UINT;
334*3d8817e4Smiod 	    }
335*3d8817e4Smiod 	  else
336*3d8817e4Smiod 	    {
337*3d8817e4Smiod 	      /* Else it could be a function or pointer to void */
338*3d8817e4Smiod 	      res->size = 0;
339*3d8817e4Smiod 	    }
340*3d8817e4Smiod 	}
341*3d8817e4Smiod       break;
342*3d8817e4Smiod 
343*3d8817e4Smiod 
344*3d8817e4Smiod       break;
345*3d8817e4Smiod     case T_UCHAR:
346*3d8817e4Smiod     case T_CHAR:
347*3d8817e4Smiod       res->size = 1;
348*3d8817e4Smiod       break;
349*3d8817e4Smiod     case T_USHORT:
350*3d8817e4Smiod     case T_SHORT:
351*3d8817e4Smiod       res->size = SHORT_SIZE;
352*3d8817e4Smiod       break;
353*3d8817e4Smiod     case T_UINT:
354*3d8817e4Smiod     case T_INT:
355*3d8817e4Smiod       res->size = INT_SIZE;
356*3d8817e4Smiod       break;
357*3d8817e4Smiod     case T_ULONG:
358*3d8817e4Smiod     case T_LONG:
359*3d8817e4Smiod       res->size = LONG_SIZE;
360*3d8817e4Smiod       break;
361*3d8817e4Smiod     case T_FLOAT:
362*3d8817e4Smiod       res->size = FLOAT_SIZE;
363*3d8817e4Smiod       break;
364*3d8817e4Smiod     case T_DOUBLE:
365*3d8817e4Smiod       res->size = DOUBLE_SIZE;
366*3d8817e4Smiod       break;
367*3d8817e4Smiod     case T_STRUCT:
368*3d8817e4Smiod     case T_UNION:
369*3d8817e4Smiod       if (sym->n_numaux)
370*3d8817e4Smiod 	{
371*3d8817e4Smiod 	  if (aux->x_sym.x_tagndx.p)
372*3d8817e4Smiod 	    {
373*3d8817e4Smiod 	      /* Referring to a struct defined elsewhere */
374*3d8817e4Smiod 	      res->type = coff_structref_type;
375*3d8817e4Smiod 	      res->u.astructref.ref = tindex[INDEXOF (aux->x_sym.x_tagndx.p)];
376*3d8817e4Smiod 	      res->size = res->u.astructref.ref ?
377*3d8817e4Smiod 		res->u.astructref.ref->type->size : 0;
378*3d8817e4Smiod 	    }
379*3d8817e4Smiod 	  else
380*3d8817e4Smiod 	    {
381*3d8817e4Smiod 	      /* A definition of a struct */
382*3d8817e4Smiod 	      last_struct = res;
383*3d8817e4Smiod 	      res->type = coff_structdef_type;
384*3d8817e4Smiod 	      res->u.astructdef.elements = empty_scope ();
385*3d8817e4Smiod 	      res->u.astructdef.idx = 0;
386*3d8817e4Smiod 	      res->u.astructdef.isstruct = (type & 0xf) == T_STRUCT;
387*3d8817e4Smiod 	      res->size = aux->x_sym.x_misc.x_lnsz.x_size;
388*3d8817e4Smiod 	    }
389*3d8817e4Smiod 	}
390*3d8817e4Smiod       else
391*3d8817e4Smiod 	{
392*3d8817e4Smiod 	  /* No auxents - it's anonymous */
393*3d8817e4Smiod 	  res->type = coff_structref_type;
394*3d8817e4Smiod 	  res->u.astructref.ref = 0;
395*3d8817e4Smiod 	  res->size = 0;
396*3d8817e4Smiod 	}
397*3d8817e4Smiod       break;
398*3d8817e4Smiod     case T_ENUM:
399*3d8817e4Smiod       if (aux->x_sym.x_tagndx.p)
400*3d8817e4Smiod 	{
401*3d8817e4Smiod 	  /* Referring to a enum defined elsewhere */
402*3d8817e4Smiod 	  res->type = coff_enumref_type;
403*3d8817e4Smiod 	  res->u.aenumref.ref = tindex[INDEXOF (aux->x_sym.x_tagndx.p)];
404*3d8817e4Smiod 	  res->size = res->u.aenumref.ref->type->size;
405*3d8817e4Smiod 	}
406*3d8817e4Smiod       else
407*3d8817e4Smiod 	{
408*3d8817e4Smiod 	  /* A definition of an enum */
409*3d8817e4Smiod 	  last_enum = res;
410*3d8817e4Smiod 	  res->type = coff_enumdef_type;
411*3d8817e4Smiod 	  res->u.aenumdef.elements = empty_scope ();
412*3d8817e4Smiod 	  res->size = aux->x_sym.x_misc.x_lnsz.x_size;
413*3d8817e4Smiod 	}
414*3d8817e4Smiod       break;
415*3d8817e4Smiod     case T_MOE:
416*3d8817e4Smiod       break;
417*3d8817e4Smiod     }
418*3d8817e4Smiod 
419*3d8817e4Smiod   for (which_dt = 5; which_dt >= 0; which_dt--)
420*3d8817e4Smiod     {
421*3d8817e4Smiod       switch ((type >> ((which_dt * 2) + 4)) & 0x3)
422*3d8817e4Smiod 	{
423*3d8817e4Smiod 	case 0:
424*3d8817e4Smiod 	  break;
425*3d8817e4Smiod 	case DT_ARY:
426*3d8817e4Smiod 	  {
427*3d8817e4Smiod 	    struct coff_type *ptr = ((struct coff_type *)
428*3d8817e4Smiod 				     xmalloc (sizeof (struct coff_type)));
429*3d8817e4Smiod 	    int els = (dimind < DIMNUM
430*3d8817e4Smiod 		       ? aux->x_sym.x_fcnary.x_ary.x_dimen[dimind]
431*3d8817e4Smiod 		       : 0);
432*3d8817e4Smiod 	    ++dimind;
433*3d8817e4Smiod 	    ptr->type = coff_array_type;
434*3d8817e4Smiod 	    ptr->size = els * res->size;
435*3d8817e4Smiod 	    ptr->u.array.dim = els;
436*3d8817e4Smiod 	    ptr->u.array.array_of = res;
437*3d8817e4Smiod 	    res = ptr;
438*3d8817e4Smiod 	    break;
439*3d8817e4Smiod 	  }
440*3d8817e4Smiod 	case DT_PTR:
441*3d8817e4Smiod 	  {
442*3d8817e4Smiod 	    struct coff_type *ptr =
443*3d8817e4Smiod 	      (struct coff_type *) xmalloc (sizeof (struct coff_type));
444*3d8817e4Smiod 	    ptr->size = PTR_SIZE;
445*3d8817e4Smiod 	    ptr->type = coff_pointer_type;
446*3d8817e4Smiod 	    ptr->u.pointer.points_to = res;
447*3d8817e4Smiod 	    res = ptr;
448*3d8817e4Smiod 	    break;
449*3d8817e4Smiod 	  }
450*3d8817e4Smiod 	case DT_FCN:
451*3d8817e4Smiod 	  {
452*3d8817e4Smiod 	    struct coff_type *ptr
453*3d8817e4Smiod 	      = (struct coff_type *) xmalloc (sizeof (struct coff_type));
454*3d8817e4Smiod 	    ptr->size = 0;
455*3d8817e4Smiod 	    ptr->type = coff_function_type;
456*3d8817e4Smiod 	    ptr->u.function.function_returns = res;
457*3d8817e4Smiod 	    ptr->u.function.parameters = empty_scope ();
458*3d8817e4Smiod 	    ptr->u.function.lines = do_lines (i, sym->_n._n_nptr[1]);
459*3d8817e4Smiod 	    ptr->u.function.code = 0;
460*3d8817e4Smiod 	    last_function_type = ptr;
461*3d8817e4Smiod 	    res = ptr;
462*3d8817e4Smiod 	    break;
463*3d8817e4Smiod 	  }
464*3d8817e4Smiod 	}
465*3d8817e4Smiod     }
466*3d8817e4Smiod   return res;
467*3d8817e4Smiod }
468*3d8817e4Smiod 
469*3d8817e4Smiod static struct coff_visible *
do_visible(int i)470*3d8817e4Smiod do_visible (int i)
471*3d8817e4Smiod {
472*3d8817e4Smiod   struct internal_syment *sym = &rawsyms[i].u.syment;
473*3d8817e4Smiod   struct coff_visible *visible =
474*3d8817e4Smiod     (struct coff_visible *) (xmalloc (sizeof (struct coff_visible)));
475*3d8817e4Smiod   enum coff_vis_type t;
476*3d8817e4Smiod   switch (sym->n_sclass)
477*3d8817e4Smiod     {
478*3d8817e4Smiod     case C_MOS:
479*3d8817e4Smiod     case C_MOU:
480*3d8817e4Smiod     case C_FIELD:
481*3d8817e4Smiod       t = coff_vis_member_of_struct;
482*3d8817e4Smiod       break;
483*3d8817e4Smiod     case C_MOE:
484*3d8817e4Smiod       t = coff_vis_member_of_enum;
485*3d8817e4Smiod       break;
486*3d8817e4Smiod 
487*3d8817e4Smiod     case C_REGPARM:
488*3d8817e4Smiod       t = coff_vis_regparam;
489*3d8817e4Smiod       break;
490*3d8817e4Smiod 
491*3d8817e4Smiod     case C_REG:
492*3d8817e4Smiod       t = coff_vis_register;
493*3d8817e4Smiod       break;
494*3d8817e4Smiod     case C_STRTAG:
495*3d8817e4Smiod     case C_UNTAG:
496*3d8817e4Smiod     case C_ENTAG:
497*3d8817e4Smiod     case C_TPDEF:
498*3d8817e4Smiod       t = coff_vis_tag;
499*3d8817e4Smiod       break;
500*3d8817e4Smiod     case C_AUTOARG:
501*3d8817e4Smiod     case C_ARG:
502*3d8817e4Smiod       t = coff_vis_autoparam;
503*3d8817e4Smiod       break;
504*3d8817e4Smiod     case C_AUTO:
505*3d8817e4Smiod 
506*3d8817e4Smiod 
507*3d8817e4Smiod       t = coff_vis_auto;
508*3d8817e4Smiod       break;
509*3d8817e4Smiod     case C_LABEL:
510*3d8817e4Smiod     case C_STAT:
511*3d8817e4Smiod       t = coff_vis_int_def;
512*3d8817e4Smiod       break;
513*3d8817e4Smiod     case C_EXT:
514*3d8817e4Smiod       if (sym->n_scnum == N_UNDEF)
515*3d8817e4Smiod 	{
516*3d8817e4Smiod 	  if (sym->n_value)
517*3d8817e4Smiod 	    t = coff_vis_common;
518*3d8817e4Smiod 	  else
519*3d8817e4Smiod 	    t = coff_vis_ext_ref;
520*3d8817e4Smiod 	}
521*3d8817e4Smiod       else
522*3d8817e4Smiod 	t = coff_vis_ext_def;
523*3d8817e4Smiod       break;
524*3d8817e4Smiod     default:
525*3d8817e4Smiod       abort ();
526*3d8817e4Smiod       break;
527*3d8817e4Smiod 
528*3d8817e4Smiod     }
529*3d8817e4Smiod   visible->type = t;
530*3d8817e4Smiod   return visible;
531*3d8817e4Smiod }
532*3d8817e4Smiod 
533*3d8817e4Smiod static int
do_define(int i,struct coff_scope * b)534*3d8817e4Smiod do_define (int i, struct coff_scope *b)
535*3d8817e4Smiod {
536*3d8817e4Smiod   static int symbol_index;
537*3d8817e4Smiod   struct internal_syment *sym = &rawsyms[i].u.syment;
538*3d8817e4Smiod 
539*3d8817e4Smiod   /* Define a symbol and attach to block b */
540*3d8817e4Smiod   struct coff_symbol *s = empty_symbol ();
541*3d8817e4Smiod 
542*3d8817e4Smiod   s->number = ++symbol_index;
543*3d8817e4Smiod   s->name = sym->_n._n_nptr[1];
544*3d8817e4Smiod   s->sfile = cur_sfile;
545*3d8817e4Smiod   /* Glue onto the ofile list */
546*3d8817e4Smiod   if (lofile >= 0)
547*3d8817e4Smiod     {
548*3d8817e4Smiod       if (ofile->symbol_list_tail)
549*3d8817e4Smiod 	ofile->symbol_list_tail->next_in_ofile_list = s;
550*3d8817e4Smiod       else
551*3d8817e4Smiod 	ofile->symbol_list_head = s;
552*3d8817e4Smiod       ofile->symbol_list_tail = s;
553*3d8817e4Smiod       /* And the block list */
554*3d8817e4Smiod     }
555*3d8817e4Smiod   if (b->vars_tail)
556*3d8817e4Smiod     b->vars_tail->next = s;
557*3d8817e4Smiod   else
558*3d8817e4Smiod     b->vars_head = s;
559*3d8817e4Smiod 
560*3d8817e4Smiod   b->vars_tail = s;
561*3d8817e4Smiod   b->nvars++;
562*3d8817e4Smiod   s->type = do_type (i);
563*3d8817e4Smiod   s->where = do_where (i);
564*3d8817e4Smiod   s->visible = do_visible (i);
565*3d8817e4Smiod 
566*3d8817e4Smiod   tindex[i] = s;
567*3d8817e4Smiod 
568*3d8817e4Smiod   /* We remember the lowest address in each section for each source file */
569*3d8817e4Smiod 
570*3d8817e4Smiod   if (s->where->where == coff_where_memory
571*3d8817e4Smiod       && s->type->type == coff_secdef_type)
572*3d8817e4Smiod     {
573*3d8817e4Smiod       struct coff_isection *is = cur_sfile->section + s->where->section->number;
574*3d8817e4Smiod 
575*3d8817e4Smiod       if (!is->init)
576*3d8817e4Smiod 	{
577*3d8817e4Smiod 	  is->low = s->where->offset;
578*3d8817e4Smiod 	  is->high = s->where->offset + s->type->size;
579*3d8817e4Smiod 	  is->init = 1;
580*3d8817e4Smiod 	  is->parent = s->where->section;
581*3d8817e4Smiod 	}
582*3d8817e4Smiod 
583*3d8817e4Smiod     }
584*3d8817e4Smiod 
585*3d8817e4Smiod   if (s->type->type == coff_function_type)
586*3d8817e4Smiod     last_function_symbol = s;
587*3d8817e4Smiod 
588*3d8817e4Smiod   return i + sym->n_numaux + 1;
589*3d8817e4Smiod }
590*3d8817e4Smiod 
591*3d8817e4Smiod 
592*3d8817e4Smiod static
593*3d8817e4Smiod struct coff_ofile *
doit(void)594*3d8817e4Smiod doit (void)
595*3d8817e4Smiod {
596*3d8817e4Smiod   int i;
597*3d8817e4Smiod   int infile = 0;
598*3d8817e4Smiod   struct coff_ofile *head =
599*3d8817e4Smiod     (struct coff_ofile *) xmalloc (sizeof (struct coff_ofile));
600*3d8817e4Smiod   ofile = head;
601*3d8817e4Smiod   head->source_head = 0;
602*3d8817e4Smiod   head->source_tail = 0;
603*3d8817e4Smiod   head->nsources = 0;
604*3d8817e4Smiod   head->symbol_list_tail = 0;
605*3d8817e4Smiod   head->symbol_list_head = 0;
606*3d8817e4Smiod   do_sections_p1 (head);
607*3d8817e4Smiod   push_scope (1);
608*3d8817e4Smiod 
609*3d8817e4Smiod   for (i = 0; i < rawcount;)
610*3d8817e4Smiod     {
611*3d8817e4Smiod       struct internal_syment *sym = &rawsyms[i].u.syment;
612*3d8817e4Smiod       switch (sym->n_sclass)
613*3d8817e4Smiod 	{
614*3d8817e4Smiod 	case C_FILE:
615*3d8817e4Smiod 	  {
616*3d8817e4Smiod 	    /* new source file announced */
617*3d8817e4Smiod 	    struct coff_sfile *n =
618*3d8817e4Smiod 	      (struct coff_sfile *) xmalloc (sizeof (struct coff_sfile));
619*3d8817e4Smiod 	    n->section = (struct coff_isection *) xcalloc (sizeof (struct coff_isection), abfd->section_count + 1);
620*3d8817e4Smiod 	    cur_sfile = n;
621*3d8817e4Smiod 	    n->name = sym->_n._n_nptr[1];
622*3d8817e4Smiod 	    n->next = 0;
623*3d8817e4Smiod 
624*3d8817e4Smiod 	    if (infile)
625*3d8817e4Smiod 	      {
626*3d8817e4Smiod 		pop_scope ();
627*3d8817e4Smiod 	      }
628*3d8817e4Smiod 	    infile = 1;
629*3d8817e4Smiod 	    push_scope (1);
630*3d8817e4Smiod 	    file_scope = n->scope = top_scope;
631*3d8817e4Smiod 
632*3d8817e4Smiod 	    if (head->source_tail)
633*3d8817e4Smiod 	      head->source_tail->next = n;
634*3d8817e4Smiod 	    else
635*3d8817e4Smiod 	      head->source_head = n;
636*3d8817e4Smiod 	    head->source_tail = n;
637*3d8817e4Smiod 	    head->nsources++;
638*3d8817e4Smiod 	    i += sym->n_numaux + 1;
639*3d8817e4Smiod 	  }
640*3d8817e4Smiod 	  break;
641*3d8817e4Smiod 	case C_FCN:
642*3d8817e4Smiod 	  {
643*3d8817e4Smiod 	    char *name = sym->_n._n_nptr[1];
644*3d8817e4Smiod 	    if (name[1] == 'b')
645*3d8817e4Smiod 	      {
646*3d8817e4Smiod 		/* Function start */
647*3d8817e4Smiod 		push_scope (0);
648*3d8817e4Smiod 		last_function_type->u.function.code = top_scope;
649*3d8817e4Smiod 		top_scope->sec = ofile->sections + sym->n_scnum;
650*3d8817e4Smiod 		top_scope->offset = sym->n_value;
651*3d8817e4Smiod 	      }
652*3d8817e4Smiod 	    else
653*3d8817e4Smiod 	      {
654*3d8817e4Smiod 		top_scope->size = sym->n_value - top_scope->offset + 1;
655*3d8817e4Smiod 		pop_scope ();
656*3d8817e4Smiod 
657*3d8817e4Smiod 	      }
658*3d8817e4Smiod 	    i += sym->n_numaux + 1;
659*3d8817e4Smiod 	  }
660*3d8817e4Smiod 	  break;
661*3d8817e4Smiod 
662*3d8817e4Smiod 	case C_BLOCK:
663*3d8817e4Smiod 	  {
664*3d8817e4Smiod 	    char *name = sym->_n._n_nptr[1];
665*3d8817e4Smiod 	    if (name[1] == 'b')
666*3d8817e4Smiod 	      {
667*3d8817e4Smiod 		/* Block start */
668*3d8817e4Smiod 		push_scope (1);
669*3d8817e4Smiod 		top_scope->sec = ofile->sections + sym->n_scnum;
670*3d8817e4Smiod 		top_scope->offset = sym->n_value;
671*3d8817e4Smiod 
672*3d8817e4Smiod 	      }
673*3d8817e4Smiod 	    else
674*3d8817e4Smiod 	      {
675*3d8817e4Smiod 		top_scope->size = sym->n_value - top_scope->offset + 1;
676*3d8817e4Smiod 		pop_scope ();
677*3d8817e4Smiod 	      }
678*3d8817e4Smiod 	    i += sym->n_numaux + 1;
679*3d8817e4Smiod 	  }
680*3d8817e4Smiod 	  break;
681*3d8817e4Smiod 	case C_REGPARM:
682*3d8817e4Smiod 	case C_ARG:
683*3d8817e4Smiod 	  i = do_define (i, last_function_symbol->type->u.function.parameters);
684*3d8817e4Smiod 	  break;
685*3d8817e4Smiod 	case C_MOS:
686*3d8817e4Smiod 	case C_MOU:
687*3d8817e4Smiod 	case C_FIELD:
688*3d8817e4Smiod 	  i = do_define (i, last_struct->u.astructdef.elements);
689*3d8817e4Smiod 	  break;
690*3d8817e4Smiod 	case C_MOE:
691*3d8817e4Smiod 	  i = do_define (i, last_enum->u.aenumdef.elements);
692*3d8817e4Smiod 	  break;
693*3d8817e4Smiod 	case C_STRTAG:
694*3d8817e4Smiod 	case C_ENTAG:
695*3d8817e4Smiod 	case C_UNTAG:
696*3d8817e4Smiod 	  /* Various definition */
697*3d8817e4Smiod 	  i = do_define (i, top_scope);
698*3d8817e4Smiod 	  break;
699*3d8817e4Smiod 	case C_EXT:
700*3d8817e4Smiod 	case C_LABEL:
701*3d8817e4Smiod 	  i = do_define (i, file_scope);
702*3d8817e4Smiod 	  break;
703*3d8817e4Smiod 	case C_STAT:
704*3d8817e4Smiod 	case C_TPDEF:
705*3d8817e4Smiod 	case C_AUTO:
706*3d8817e4Smiod 	case C_REG:
707*3d8817e4Smiod 	  i = do_define (i, top_scope);
708*3d8817e4Smiod 	  break;
709*3d8817e4Smiod 	default:
710*3d8817e4Smiod 	  abort ();
711*3d8817e4Smiod 	case C_EOS:
712*3d8817e4Smiod 	  i += sym->n_numaux + 1;
713*3d8817e4Smiod 	  break;
714*3d8817e4Smiod 	}
715*3d8817e4Smiod     }
716*3d8817e4Smiod   do_sections_p2 (head);
717*3d8817e4Smiod   return head;
718*3d8817e4Smiod }
719*3d8817e4Smiod 
720*3d8817e4Smiod struct coff_ofile *
coff_grok(bfd * inabfd)721*3d8817e4Smiod coff_grok (bfd *inabfd)
722*3d8817e4Smiod {
723*3d8817e4Smiod   long storage;
724*3d8817e4Smiod   struct coff_ofile *p;
725*3d8817e4Smiod   abfd = inabfd;
726*3d8817e4Smiod   storage = bfd_get_symtab_upper_bound (abfd);
727*3d8817e4Smiod 
728*3d8817e4Smiod   if (storage < 0)
729*3d8817e4Smiod     bfd_fatal (abfd->filename);
730*3d8817e4Smiod 
731*3d8817e4Smiod   syms = (asymbol **) xmalloc (storage);
732*3d8817e4Smiod   symcount = bfd_canonicalize_symtab (abfd, syms);
733*3d8817e4Smiod   if (symcount < 0)
734*3d8817e4Smiod     bfd_fatal (abfd->filename);
735*3d8817e4Smiod   rawsyms = obj_raw_syments (abfd);
736*3d8817e4Smiod   rawcount = obj_raw_syment_count (abfd);;
737*3d8817e4Smiod   tindex = (struct coff_symbol **) (xcalloc (sizeof (struct coff_symbol *), rawcount));
738*3d8817e4Smiod 
739*3d8817e4Smiod   p = doit ();
740*3d8817e4Smiod   return p;
741*3d8817e4Smiod }
742