1112399Sjake/* coffgrok.c
2112399Sjake   Copyright 1994, 1995, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2007
3223719Smarius   Free Software Foundation, Inc.
4112399Sjake
5112399SjakeThis file is part of GNU Binutils.
6112399Sjake
7112399SjakeThis program is free software; you can redistribute it and/or modify
8112399Sjakeit under the terms of the GNU General Public License as published by
9112399Sjakethe Free Software Foundation; either version 2 of the License, or
10112399Sjake(at your option) any later version.
11112399Sjake
12112399SjakeThis program is distributed in the hope that it will be useful,
13112399Sjakebut WITHOUT ANY WARRANTY; without even the implied warranty of
14112399SjakeMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15112399SjakeGNU General Public License for more details.
16112399Sjake
17112399SjakeYou should have received a copy of the GNU General Public License
18112399Sjakealong with this program; if not, write to the Free Software
19112399SjakeFoundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
20112399Sjake
21112399Sjake/* Written by Steve Chamberlain (sac@cygnus.com)
22112399Sjake
23112399Sjake   This module reads a coff file and builds a really simple type tree
24112399Sjake   which can be read by other programs.  The first application is a
25112399Sjake   coff->sysroff converter.  It can be tested with coffdump.c.
26112399Sjake
27112399Sjake*/
28176994Smarius
29176994Smarius#include "sysdep.h"
30176994Smarius#include "bfd.h"
31112399Sjake#include "libiberty.h"
32181701Smarius
33112399Sjake#include "coff/internal.h"
34112399Sjake#include "../bfd/libcoff.h"
35112399Sjake#include "bucomm.h"
36112399Sjake#include "coffgrok.h"
37112399Sjake
38112399Sjakestatic int lofile = 1;
39112399Sjakestatic struct coff_scope *top_scope;
40207537Smariusstatic struct coff_scope *file_scope;
41112399Sjakestatic struct coff_ofile *ofile;
42182768Smarius
43112399Sjakestatic struct coff_symbol *last_function_symbol;
44182768Smariusstatic struct coff_type *last_function_type;
45182768Smariusstatic struct coff_type *last_struct;
46112399Sjakestatic struct coff_type *last_enum;
47113453Sjakestatic struct coff_sfile *cur_sfile;
48182768Smarius
49182768Smariusstatic struct coff_symbol **tindex;
50112399Sjake
51182768Smarius
52223719Smariusstatic asymbol **syms;
53223719Smariusstatic long symcount;
54223719Smarius
55223719Smarius#define N(x) ((x)->_n._n_nptr[1])
56182768Smarius
57112399Sjakestatic struct coff_ptr_struct *rawsyms;
58223719Smariusstatic int rawcount;
59182768Smariusstatic bfd *abfd;
60182768Smarius
61204152Smarius#define PTR_SIZE	4
62182768Smarius#define SHORT_SIZE	2
63205269Smarius#define INT_SIZE	4
64182768Smarius#define LONG_SIZE	4
65182768Smarius#define FLOAT_SIZE	4
66182768Smarius#define DOUBLE_SIZE	8
67182768Smarius
68182768Smarius#define INDEXOF(p)  ((struct coff_ptr_struct *)(p)-(rawsyms))
69182768Smarius
70182768Smariusstatic struct coff_scope *empty_scope (void);
71182768Smariusstatic struct coff_symbol *empty_symbol (void);
72182768Smariusstatic void push_scope (int);
73182768Smariusstatic void pop_scope (void);
74182768Smariusstatic void do_sections_p1 (struct coff_ofile *);
75182768Smariusstatic void do_sections_p2 (struct coff_ofile *);
76182768Smariusstatic struct coff_where *do_where (int);
77182768Smariusstatic struct coff_line *do_lines (int, char *);
78182768Smariusstatic struct coff_type *do_type (int);
79182768Smariusstatic struct coff_visible *do_visible (int);
80182768Smariusstatic int do_define (int, struct coff_scope *);
81182878Smariusstatic struct coff_ofile *doit (void);
82205269Smarius
83205269Smariusstatic struct coff_scope *
84205269Smariusempty_scope (void)
85205269Smarius{
86205269Smarius  struct coff_scope *l;
87205269Smarius  l = (struct coff_scope *) (xcalloc (sizeof (struct coff_scope), 1));
88205269Smarius  return l;
89205269Smarius}
90205269Smarius
91205269Smariusstatic struct coff_symbol *
92205269Smariusempty_symbol (void)
93205269Smarius{
94182878Smarius  return (struct coff_symbol *) (xcalloc (sizeof (struct coff_symbol), 1));
95182878Smarius}
96182878Smarius
97205269Smarius/*int l;*/
98205269Smariusstatic void
99205269Smariuspush_scope (int link)
100205269Smarius{
101205269Smarius  struct coff_scope *n = empty_scope ();
102205269Smarius  if (link)
103205269Smarius    {
104205269Smarius      if (top_scope)
105205269Smarius	{
106205269Smarius	  if (top_scope->list_tail)
107205269Smarius	    {
108182878Smarius	      top_scope->list_tail->next = n;
109182878Smarius	    }
110205269Smarius	  else
111205269Smarius	    {
112205269Smarius	      top_scope->list_head = n;
113205269Smarius	    }
114205269Smarius	  top_scope->list_tail = n;
115205269Smarius	}
116205269Smarius    }
117205269Smarius  n->parent = top_scope;
118205269Smarius
119205269Smarius  top_scope = n;
120205269Smarius}
121205269Smarius
122205269Smariusstatic void
123205269Smariuspop_scope (void)
124205269Smarius{
125205269Smarius  top_scope = top_scope->parent;
126205269Smarius}
127205269Smarius
128205269Smariusstatic void
129205269Smariusdo_sections_p1 (struct coff_ofile *head)
130205269Smarius{
131205269Smarius  asection *section;
132205269Smarius  int idx;
133182768Smarius  struct coff_section *all = (struct coff_section *) (xcalloc (abfd->section_count + 1,
134182768Smarius					     sizeof (struct coff_section)));
135182768Smarius  head->nsections = abfd->section_count + 1;
136122464Sjake  head->sections = all;
137122464Sjake
138122464Sjake  for (idx = 0, section = abfd->sections; section; section = section->next, idx++)
139204152Smarius    {
140122464Sjake      long relsize;
141182768Smarius      int i = section->target_index;
142176994Smarius      arelent **relpp;
143182768Smarius      long relcount;
144182768Smarius
145205269Smarius      relsize = bfd_get_reloc_upper_bound (abfd, section);
146182768Smarius      if (relsize < 0)
147182768Smarius	bfd_fatal (bfd_get_filename (abfd));
148182768Smarius      if (relsize == 0)
149205269Smarius	continue;
150122464Sjake      relpp = (arelent **) xmalloc (relsize);
151122464Sjake      relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms);
152122464Sjake      if (relcount < 0)
153122464Sjake	bfd_fatal (bfd_get_filename (abfd));
154122464Sjake
155122464Sjake      head->sections[i].name = (char *) (section->name);
156122464Sjake      head->sections[i].code = section->flags & SEC_CODE;
157122464Sjake      head->sections[i].data = section->flags & SEC_DATA;
158182768Smarius      if (strcmp (section->name, ".bss") == 0)
159205269Smarius	head->sections[i].data = 1;
160176994Smarius      head->sections[i].address = section->lma;
161205269Smarius      head->sections[i].size = bfd_get_section_size (section);
162182768Smarius      head->sections[i].number = idx;
163182768Smarius      head->sections[i].nrelocs = section->reloc_count;
164205269Smarius      head->sections[i].relocs =
165205269Smarius	(struct coff_reloc *) (xcalloc (section->reloc_count,
166205269Smarius					sizeof (struct coff_reloc)));
167205269Smarius      head->sections[i].bfd_section = section;
168205269Smarius    }
169205269Smarius  head->sections[0].name = "ABSOLUTE";
170205269Smarius  head->sections[0].code = 0;
171205269Smarius  head->sections[0].data = 0;
172205269Smarius  head->sections[0].address = 0;
173182768Smarius  head->sections[0].size = 0;
174182768Smarius  head->sections[0].number = 0;
175182768Smarius}
176182768Smarius
177205269Smariusstatic void
178182768Smariusdo_sections_p2 (struct coff_ofile *head)
179182768Smarius{
180182768Smarius  asection *section;
181205269Smarius  for (section = abfd->sections; section; section = section->next)
182205269Smarius    {
183205269Smarius      unsigned int j;
184205269Smarius
185182768Smarius      for (j = 0; j < section->reloc_count; j++)
186205269Smarius	{
187205269Smarius	  int idx;
188122464Sjake	  int i = section->target_index;
189122464Sjake	  struct coff_reloc *r = head->sections[i].relocs + j;
190122464Sjake	  arelent *sr = section->relocation + j;
191112399Sjake	  r->offset = sr->address;
192112399Sjake	  r->addend = sr->addend;
193112399Sjake	  idx = ((coff_symbol_type *) (sr->sym_ptr_ptr[0]))->native - rawsyms;
194113238Sjake	  r->symbol = tindex[idx];
195112399Sjake	}
196113238Sjake    }
197112399Sjake}
198112399Sjake
199205269Smariusstatic struct coff_where *
200205269Smariusdo_where (int i)
201112399Sjake{
202205269Smarius  struct internal_syment *sym = &rawsyms[i].u.syment;
203205269Smarius  struct coff_where *where =
204112399Sjake    (struct coff_where *) (xmalloc (sizeof (struct coff_where)));
205112399Sjake  where->offset = sym->n_value;
206112399Sjake
207112399Sjake  if (sym->n_scnum == -1)
208112399Sjake    sym->n_scnum = 0;
209112399Sjake
210112399Sjake  switch (sym->n_sclass)
211112399Sjake    {
212112399Sjake    case C_FIELD:
213207537Smarius      where->where = coff_where_member_of_struct;
214112399Sjake      where->offset = sym->n_value / 8;
215176994Smarius      where->bitoffset = sym->n_value % 8;
216112399Sjake      where->bitsize = rawsyms[i + 1].u.auxent.x_sym.x_misc.x_lnsz.x_size;
217113453Sjake      break;
218176994Smarius    case C_MOE:
219223719Smarius      where->where = coff_where_member_of_enum;
220176994Smarius      break;
221113453Sjake    case C_MOS:
222176994Smarius    case C_MOU:
223176994Smarius      where->where = coff_where_member_of_struct;
224176994Smarius      break;
225223719Smarius    case C_AUTO:
226223719Smarius    case C_ARG:
227223719Smarius      where->where = coff_where_stack;
228176994Smarius      break;
229176994Smarius    case C_EXT:
230176994Smarius    case C_STAT:
231223719Smarius    case C_EXTDEF:
232176994Smarius    case C_LABEL:
233176994Smarius      where->where = coff_where_memory;
234223719Smarius      where->section = &ofile->sections[sym->n_scnum];
235113453Sjake      break;
236223719Smarius    case C_REG:
237223719Smarius    case C_REGPARM:
238223719Smarius      where->where = coff_where_register;
239176994Smarius      break;
240182768Smarius    case C_ENTAG:
241223719Smarius      where->where = coff_where_entag;
242223719Smarius      break;
243182768Smarius    case C_STRTAG:
244223719Smarius    case C_UNTAG:
245223719Smarius      where->where = coff_where_strtag;
246223719Smarius      break;
247223719Smarius    case C_TPDEF:
248223719Smarius      where->where = coff_where_typedef;
249223719Smarius      break;
250223719Smarius    default:
251223719Smarius      abort ();
252223719Smarius      break;
253223719Smarius    }
254223719Smarius  return where;
255223719Smarius}
256223719Smarius
257223719Smariusstatic
258223719Smariusstruct coff_line *
259223719Smariusdo_lines (int i, char *name ATTRIBUTE_UNUSED)
260223719Smarius{
261223719Smarius  struct coff_line *res = (struct coff_line *) xcalloc (sizeof (struct coff_line), 1);
262223719Smarius  asection *s;
263223719Smarius  unsigned int l;
264223719Smarius
265223719Smarius  /* Find out if this function has any line numbers in the table */
266223719Smarius  for (s = abfd->sections; s; s = s->next)
267223719Smarius    {
268223719Smarius      for (l = 0; l < s->lineno_count; l++)
269223719Smarius	{
270223719Smarius	  if (s->lineno[l].line_number == 0)
271223719Smarius	    {
272223719Smarius	      if (rawsyms + i == ((coff_symbol_type *) (&(s->lineno[l].u.sym[0])))->native)
273223719Smarius		{
274223719Smarius		  /* These lines are for this function - so count them and stick them on */
275223719Smarius		  int c = 0;
276223719Smarius		  /* Find the linenumber of the top of the function, since coff linenumbers
277223719Smarius		     are relative to the start of the function.  */
278223719Smarius		  int start_line = rawsyms[i + 3].u.auxent.x_sym.x_misc.x_lnsz.x_lnno;
279223719Smarius
280223719Smarius		  l++;
281223719Smarius		  for (c = 0; s->lineno[l + c + 1].line_number; c++)
282223719Smarius		    ;
283223719Smarius
284223719Smarius		  /* Add two extra records, one for the prologue and one for the epilogue */
285223719Smarius		  c += 1;
286223719Smarius		  res->nlines = c;
287223719Smarius		  res->lines = (int *) (xcalloc (sizeof (int), c));
288223719Smarius		  res->addresses = (int *) (xcalloc (sizeof (int), c));
289223719Smarius		  res->lines[0] = start_line;
290223719Smarius		  res->addresses[0] = rawsyms[i].u.syment.n_value - s->vma;
291223719Smarius		  for (c = 0; s->lineno[l + c + 1].line_number; c++)
292223719Smarius		    {
293223719Smarius		      res->lines[c + 1] = s->lineno[l + c].line_number + start_line - 1;
294223719Smarius		      res->addresses[c + 1] = s->lineno[l + c].u.offset;
295223719Smarius		    }
296223719Smarius		  return res;
297223719Smarius		}
298223719Smarius	    }
299223719Smarius	}
300223719Smarius    }
301223719Smarius  return res;
302223719Smarius}
303223719Smarius
304223719Smariusstatic
305223719Smariusstruct coff_type *
306113453Sjakedo_type (int i)
307{
308  struct internal_syment *sym = &rawsyms[i].u.syment;
309  union internal_auxent *aux = &rawsyms[i + 1].u.auxent;
310  struct coff_type *res =
311    (struct coff_type *) xmalloc (sizeof (struct coff_type));
312  int type = sym->n_type;
313  int which_dt = 0;
314  int dimind = 0;
315
316  res->type = coff_basic_type;
317  res->u.basic = type & 0xf;
318
319  switch (type & 0xf)
320    {
321    case T_NULL:
322    case T_VOID:
323      if (sym->n_numaux && sym->n_sclass == C_STAT)
324	{
325	  /* This is probably a section definition */
326	  res->type = coff_secdef_type;
327	  res->size = aux->x_scn.x_scnlen;
328	}
329      else
330	{
331	  if (type == 0)
332	    {
333	      /* Don't know what this is, let's make it a simple int */
334	      res->size = INT_SIZE;
335	      res->u.basic = T_UINT;
336	    }
337	  else
338	    {
339	      /* Else it could be a function or pointer to void */
340	      res->size = 0;
341	    }
342	}
343      break;
344
345
346      break;
347    case T_UCHAR:
348    case T_CHAR:
349      res->size = 1;
350      break;
351    case T_USHORT:
352    case T_SHORT:
353      res->size = SHORT_SIZE;
354      break;
355    case T_UINT:
356    case T_INT:
357      res->size = INT_SIZE;
358      break;
359    case T_ULONG:
360    case T_LONG:
361      res->size = LONG_SIZE;
362      break;
363    case T_FLOAT:
364      res->size = FLOAT_SIZE;
365      break;
366    case T_DOUBLE:
367      res->size = DOUBLE_SIZE;
368      break;
369    case T_STRUCT:
370    case T_UNION:
371      if (sym->n_numaux)
372	{
373	  if (aux->x_sym.x_tagndx.p)
374	    {
375	      /* Referring to a struct defined elsewhere */
376	      res->type = coff_structref_type;
377	      res->u.astructref.ref = tindex[INDEXOF (aux->x_sym.x_tagndx.p)];
378	      res->size = res->u.astructref.ref ?
379		res->u.astructref.ref->type->size : 0;
380	    }
381	  else
382	    {
383	      /* A definition of a struct */
384	      last_struct = res;
385	      res->type = coff_structdef_type;
386	      res->u.astructdef.elements = empty_scope ();
387	      res->u.astructdef.idx = 0;
388	      res->u.astructdef.isstruct = (type & 0xf) == T_STRUCT;
389	      res->size = aux->x_sym.x_misc.x_lnsz.x_size;
390	    }
391	}
392      else
393	{
394	  /* No auxents - it's anonymous */
395	  res->type = coff_structref_type;
396	  res->u.astructref.ref = 0;
397	  res->size = 0;
398	}
399      break;
400    case T_ENUM:
401      if (aux->x_sym.x_tagndx.p)
402	{
403	  /* Referring to a enum defined elsewhere */
404	  res->type = coff_enumref_type;
405	  res->u.aenumref.ref = tindex[INDEXOF (aux->x_sym.x_tagndx.p)];
406	  res->size = res->u.aenumref.ref->type->size;
407	}
408      else
409	{
410	  /* A definition of an enum */
411	  last_enum = res;
412	  res->type = coff_enumdef_type;
413	  res->u.aenumdef.elements = empty_scope ();
414	  res->size = aux->x_sym.x_misc.x_lnsz.x_size;
415	}
416      break;
417    case T_MOE:
418      break;
419    }
420
421  for (which_dt = 5; which_dt >= 0; which_dt--)
422    {
423      switch ((type >> ((which_dt * 2) + 4)) & 0x3)
424	{
425	case 0:
426	  break;
427	case DT_ARY:
428	  {
429	    struct coff_type *ptr = ((struct coff_type *)
430				     xmalloc (sizeof (struct coff_type)));
431	    int els = (dimind < DIMNUM
432		       ? aux->x_sym.x_fcnary.x_ary.x_dimen[dimind]
433		       : 0);
434	    ++dimind;
435	    ptr->type = coff_array_type;
436	    ptr->size = els * res->size;
437	    ptr->u.array.dim = els;
438	    ptr->u.array.array_of = res;
439	    res = ptr;
440	    break;
441	  }
442	case DT_PTR:
443	  {
444	    struct coff_type *ptr =
445	      (struct coff_type *) xmalloc (sizeof (struct coff_type));
446	    ptr->size = PTR_SIZE;
447	    ptr->type = coff_pointer_type;
448	    ptr->u.pointer.points_to = res;
449	    res = ptr;
450	    break;
451	  }
452	case DT_FCN:
453	  {
454	    struct coff_type *ptr
455	      = (struct coff_type *) xmalloc (sizeof (struct coff_type));
456	    ptr->size = 0;
457	    ptr->type = coff_function_type;
458	    ptr->u.function.function_returns = res;
459	    ptr->u.function.parameters = empty_scope ();
460	    ptr->u.function.lines = do_lines (i, sym->_n._n_nptr[1]);
461	    ptr->u.function.code = 0;
462	    last_function_type = ptr;
463	    res = ptr;
464	    break;
465	  }
466	}
467    }
468  return res;
469}
470
471static struct coff_visible *
472do_visible (int i)
473{
474  struct internal_syment *sym = &rawsyms[i].u.syment;
475  struct coff_visible *visible =
476    (struct coff_visible *) (xmalloc (sizeof (struct coff_visible)));
477  enum coff_vis_type t;
478  switch (sym->n_sclass)
479    {
480    case C_MOS:
481    case C_MOU:
482    case C_FIELD:
483      t = coff_vis_member_of_struct;
484      break;
485    case C_MOE:
486      t = coff_vis_member_of_enum;
487      break;
488
489    case C_REGPARM:
490      t = coff_vis_regparam;
491      break;
492
493    case C_REG:
494      t = coff_vis_register;
495      break;
496    case C_STRTAG:
497    case C_UNTAG:
498    case C_ENTAG:
499    case C_TPDEF:
500      t = coff_vis_tag;
501      break;
502    case C_AUTOARG:
503    case C_ARG:
504      t = coff_vis_autoparam;
505      break;
506    case C_AUTO:
507
508
509      t = coff_vis_auto;
510      break;
511    case C_LABEL:
512    case C_STAT:
513      t = coff_vis_int_def;
514      break;
515    case C_EXT:
516      if (sym->n_scnum == N_UNDEF)
517	{
518	  if (sym->n_value)
519	    t = coff_vis_common;
520	  else
521	    t = coff_vis_ext_ref;
522	}
523      else
524	t = coff_vis_ext_def;
525      break;
526    default:
527      abort ();
528      break;
529
530    }
531  visible->type = t;
532  return visible;
533}
534
535static int
536do_define (int i, struct coff_scope *b)
537{
538  static int symbol_index;
539  struct internal_syment *sym = &rawsyms[i].u.syment;
540
541  /* Define a symbol and attach to block b */
542  struct coff_symbol *s = empty_symbol ();
543
544  s->number = ++symbol_index;
545  s->name = sym->_n._n_nptr[1];
546  s->sfile = cur_sfile;
547  /* Glue onto the ofile list */
548  if (lofile >= 0)
549    {
550      if (ofile->symbol_list_tail)
551	ofile->symbol_list_tail->next_in_ofile_list = s;
552      else
553	ofile->symbol_list_head = s;
554      ofile->symbol_list_tail = s;
555      /* And the block list */
556    }
557  if (b->vars_tail)
558    b->vars_tail->next = s;
559  else
560    b->vars_head = s;
561
562  b->vars_tail = s;
563  b->nvars++;
564  s->type = do_type (i);
565  s->where = do_where (i);
566  s->visible = do_visible (i);
567
568  tindex[i] = s;
569
570  /* We remember the lowest address in each section for each source file */
571
572  if (s->where->where == coff_where_memory
573      && s->type->type == coff_secdef_type)
574    {
575      struct coff_isection *is = cur_sfile->section + s->where->section->number;
576
577      if (!is->init)
578	{
579	  is->low = s->where->offset;
580	  is->high = s->where->offset + s->type->size;
581	  is->init = 1;
582	  is->parent = s->where->section;
583	}
584
585    }
586
587  if (s->type->type == coff_function_type)
588    last_function_symbol = s;
589
590  return i + sym->n_numaux + 1;
591}
592
593
594static
595struct coff_ofile *
596doit (void)
597{
598  int i;
599  int infile = 0;
600  struct coff_ofile *head =
601    (struct coff_ofile *) xmalloc (sizeof (struct coff_ofile));
602  ofile = head;
603  head->source_head = 0;
604  head->source_tail = 0;
605  head->nsources = 0;
606  head->symbol_list_tail = 0;
607  head->symbol_list_head = 0;
608  do_sections_p1 (head);
609  push_scope (1);
610
611  for (i = 0; i < rawcount;)
612    {
613      struct internal_syment *sym = &rawsyms[i].u.syment;
614      switch (sym->n_sclass)
615	{
616	case C_FILE:
617	  {
618	    /* new source file announced */
619	    struct coff_sfile *n =
620	      (struct coff_sfile *) xmalloc (sizeof (struct coff_sfile));
621	    n->section = (struct coff_isection *) xcalloc (sizeof (struct coff_isection), abfd->section_count + 1);
622	    cur_sfile = n;
623	    n->name = sym->_n._n_nptr[1];
624	    n->next = 0;
625
626	    if (infile)
627	      {
628		pop_scope ();
629	      }
630	    infile = 1;
631	    push_scope (1);
632	    file_scope = n->scope = top_scope;
633
634	    if (head->source_tail)
635	      head->source_tail->next = n;
636	    else
637	      head->source_head = n;
638	    head->source_tail = n;
639	    head->nsources++;
640	    i += sym->n_numaux + 1;
641	  }
642	  break;
643	case C_FCN:
644	  {
645	    char *name = sym->_n._n_nptr[1];
646	    if (name[1] == 'b')
647	      {
648		/* Function start */
649		push_scope (0);
650		last_function_type->u.function.code = top_scope;
651		top_scope->sec = ofile->sections + sym->n_scnum;
652		top_scope->offset = sym->n_value;
653	      }
654	    else
655	      {
656		top_scope->size = sym->n_value - top_scope->offset + 1;
657		pop_scope ();
658
659	      }
660	    i += sym->n_numaux + 1;
661	  }
662	  break;
663
664	case C_BLOCK:
665	  {
666	    char *name = sym->_n._n_nptr[1];
667	    if (name[1] == 'b')
668	      {
669		/* Block start */
670		push_scope (1);
671		top_scope->sec = ofile->sections + sym->n_scnum;
672		top_scope->offset = sym->n_value;
673
674	      }
675	    else
676	      {
677		top_scope->size = sym->n_value - top_scope->offset + 1;
678		pop_scope ();
679	      }
680	    i += sym->n_numaux + 1;
681	  }
682	  break;
683	case C_REGPARM:
684	case C_ARG:
685	  i = do_define (i, last_function_symbol->type->u.function.parameters);
686	  break;
687	case C_MOS:
688	case C_MOU:
689	case C_FIELD:
690	  i = do_define (i, last_struct->u.astructdef.elements);
691	  break;
692	case C_MOE:
693	  i = do_define (i, last_enum->u.aenumdef.elements);
694	  break;
695	case C_STRTAG:
696	case C_ENTAG:
697	case C_UNTAG:
698	  /* Various definition */
699	  i = do_define (i, top_scope);
700	  break;
701	case C_EXT:
702	case C_LABEL:
703	  i = do_define (i, file_scope);
704	  break;
705	case C_STAT:
706	case C_TPDEF:
707	case C_AUTO:
708	case C_REG:
709	  i = do_define (i, top_scope);
710	  break;
711	default:
712	  abort ();
713	case C_EOS:
714	  i += sym->n_numaux + 1;
715	  break;
716	}
717    }
718  do_sections_p2 (head);
719  return head;
720}
721
722struct coff_ofile *
723coff_grok (bfd *inabfd)
724{
725  long storage;
726  struct coff_ofile *p;
727  abfd = inabfd;
728  storage = bfd_get_symtab_upper_bound (abfd);
729
730  if (storage < 0)
731    bfd_fatal (abfd->filename);
732
733  syms = (asymbol **) xmalloc (storage);
734  symcount = bfd_canonicalize_symtab (abfd, syms);
735  if (symcount < 0)
736    bfd_fatal (abfd->filename);
737  rawsyms = obj_raw_syments (abfd);
738  rawcount = obj_raw_syment_count (abfd);;
739  tindex = (struct coff_symbol **) (xcalloc (sizeof (struct coff_symbol *), rawcount));
740
741  p = doit ();
742  return p;
743}
744