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