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