2 Copyright (C) 1994-2022 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
22 /* Written by Steve Chamberlain (sac@cygnus.com)
24 This module reads a coff file and builds a really simple type tree
25 which can be read by other programs. The first application is a
26 coff->sysroff converter. It can be tested with coffdump.c. */
30 #include "libiberty.h"
31 #include "coff/internal.h"
32 #include "../bfd/libcoff.h"
36 static int lofile
= 1;
38 static struct coff_scope
* top_scope
;
39 static struct coff_scope
* file_scope
;
40 static struct coff_ofile
* ofile
;
41 static struct coff_symbol
* last_function_symbol
;
42 static struct coff_type
* last_function_type
;
43 static struct coff_type
* last_struct
;
44 static struct coff_type
* last_enum
;
45 static struct coff_sfile
* cur_sfile
;
46 static struct coff_symbol
** tindex
;
47 static asymbol
** syms
;
49 static struct coff_ptr_struct
* rawsyms
;
50 static unsigned int rawcount
;
53 #define N(x) ((x)->_n._n_nptr[1])
62 #define INDEXOF(p) ((struct coff_ptr_struct *)(p)-(rawsyms))
65 static struct coff_scope
*
68 return (struct coff_scope
*) (xcalloc (sizeof (struct coff_scope
), 1));
71 static struct coff_symbol
*
74 return (struct coff_symbol
*) (xcalloc (sizeof (struct coff_symbol
), 1));
78 push_scope (int slink
)
80 struct coff_scope
*n
= empty_scope ();
86 if (top_scope
->list_tail
)
88 top_scope
->list_tail
->next
= n
;
92 top_scope
->list_head
= n
;
94 top_scope
->list_tail
= n
;
97 n
->parent
= top_scope
;
105 /* PR 17512: file: 809933ac. */
106 if (top_scope
== NULL
)
107 fatal (_("Out of context scope change encountered"));
108 top_scope
= top_scope
->parent
;
112 do_sections_p1 (struct coff_ofile
*head
)
116 struct coff_section
*all
= (struct coff_section
*) (xcalloc (abfd
->section_count
+ 1,
117 sizeof (struct coff_section
)));
118 head
->nsections
= abfd
->section_count
+ 1;
119 head
->sections
= all
;
121 for (idx
= 0, section
= abfd
->sections
; section
; section
= section
->next
, idx
++)
124 unsigned int i
= section
->target_index
;
128 /* PR 17512: file: 2d6effca. */
129 if (i
> abfd
->section_count
)
130 fatal (_("Invalid section target index: %u"), i
);
132 relsize
= bfd_get_reloc_upper_bound (abfd
, section
);
134 bfd_fatal (bfd_get_filename (abfd
));
137 relpp
= (arelent
**) xmalloc (relsize
);
138 relcount
= bfd_canonicalize_reloc (abfd
, section
, relpp
, syms
);
140 bfd_fatal (bfd_get_filename (abfd
));
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
->lma
;
148 head
->sections
[i
].size
= bfd_section_size (section
);
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
;
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;
165 do_sections_p2 (struct coff_ofile
*head
)
169 for (section
= abfd
->sections
; section
; section
= section
->next
)
173 /* PR 17512: file: 7c1a36e8.
174 A corrupt COFF binary might have a reloc count but no relocs.
176 if (section
->relocation
== NULL
)
179 for (j
= 0; j
< section
->reloc_count
; j
++)
182 int i
= section
->target_index
;
183 struct coff_reloc
*r
;
184 arelent
*sr
= section
->relocation
+ j
;
186 if (i
> head
->nsections
)
187 fatal (_("Invalid section target index: %d"), i
);
188 /* PR 17512: file: db850ff4. */
189 if (j
>= head
->sections
[i
].nrelocs
)
190 fatal (_("Target section has insufficient relocs"));
191 r
= head
->sections
[i
].relocs
+ j
;
192 r
->offset
= sr
->address
;
193 r
->addend
= sr
->addend
;
194 idx
= ((coff_symbol_type
*) (sr
->sym_ptr_ptr
[0]))->native
- rawsyms
;
198 fatal (_("Symbol index %u encountered when there are no symbols"), idx
);
199 non_fatal (_("Invalid symbol index %u encountered"), idx
);
202 r
->symbol
= tindex
[idx
];
207 static struct coff_where
*
208 do_where (unsigned int i
)
210 struct internal_syment
*sym
;
211 struct coff_where
*where
=
212 (struct coff_where
*) (xmalloc (sizeof (struct coff_where
)));
215 fatal ("Invalid symbol index: %d\n", i
);
217 sym
= &rawsyms
[i
].u
.syment
;
218 where
->offset
= sym
->n_value
;
220 if (sym
->n_scnum
== -1)
223 switch (sym
->n_sclass
)
226 where
->where
= coff_where_member_of_struct
;
227 where
->offset
= sym
->n_value
/ 8;
228 where
->bitoffset
= sym
->n_value
% 8;
229 where
->bitsize
= rawsyms
[i
+ 1].u
.auxent
.x_sym
.x_misc
.x_lnsz
.x_size
;
232 where
->where
= coff_where_member_of_enum
;
236 where
->where
= coff_where_member_of_struct
;
240 where
->where
= coff_where_stack
;
246 where
->where
= coff_where_memory
;
247 /* PR 17512: file: 07a37c40. */
248 /* PR 17512: file: 0c2eb101. */
249 if (sym
->n_scnum
>= ofile
->nsections
|| sym
->n_scnum
< 0)
251 non_fatal (_("Invalid section number (%d) encountered"),
253 where
->section
= ofile
->sections
;
256 where
->section
= &ofile
->sections
[sym
->n_scnum
];
260 where
->where
= coff_where_register
;
263 where
->where
= coff_where_entag
;
267 where
->where
= coff_where_strtag
;
270 where
->where
= coff_where_typedef
;
273 fatal (_("Unrecognized symbol class: %d"), sym
->n_sclass
);
279 static struct coff_line
*
280 do_lines (int i
, char *name ATTRIBUTE_UNUSED
)
282 struct coff_line
*res
= (struct coff_line
*) xcalloc (sizeof (struct coff_line
), 1);
286 /* Find out if this function has any line numbers in the table. */
287 for (s
= abfd
->sections
; s
; s
= s
->next
)
289 /* PR 17512: file: 07a37c40.
290 A corrupt COFF binary can have a linenumber count in the header
291 but no line number table. This should be reported elsewhere, but
292 do not rely upon this. */
293 if (s
->lineno
== NULL
)
296 for (l
= 0; l
< s
->lineno_count
; l
++)
298 if (s
->lineno
[l
].line_number
== 0)
300 if (rawsyms
+ i
== ((coff_symbol_type
*) (&(s
->lineno
[l
].u
.sym
[0])))->native
)
302 /* These lines are for this function - so count them and stick them on. */
304 /* Find the linenumber of the top of the function, since coff linenumbers
305 are relative to the start of the function. */
306 int start_line
= rawsyms
[i
+ 3].u
.auxent
.x_sym
.x_misc
.x_lnsz
.x_lnno
;
310 /* PR 17512: file: c2825452. */
311 l
+ c
+ 1 < s
->lineno_count
312 && s
->lineno
[l
+ c
+ 1].line_number
;
316 /* Add two extra records, one for the prologue and one for the epilogue. */
319 res
->lines
= (int *) (xcalloc (sizeof (int), c
));
320 res
->addresses
= (int *) (xcalloc (sizeof (int), c
));
321 res
->lines
[0] = start_line
;
322 res
->addresses
[0] = rawsyms
[i
].u
.syment
.n_value
- s
->vma
;
324 /* PR 17512: file: c2825452. */
325 l
+ c
+ 1 < s
->lineno_count
326 && s
->lineno
[l
+ c
+ 1].line_number
;
329 res
->lines
[c
+ 1] = s
->lineno
[l
+ c
].line_number
+ start_line
- 1;
330 res
->addresses
[c
+ 1] = s
->lineno
[l
+ c
].u
.offset
;
340 static struct coff_type
*
341 do_type (unsigned int i
)
343 struct internal_syment
*sym
;
344 union internal_auxent
*aux
;
345 struct coff_type
*res
= (struct coff_type
*) xmalloc (sizeof (struct coff_type
));
351 fatal (_("Type entry %u does not have enough symbolic information"), i
);
353 if (!rawsyms
[i
].is_sym
)
354 fatal (_("Type entry %u does not refer to a symbol"), i
);
355 sym
= &rawsyms
[i
].u
.syment
;
357 if (sym
->n_numaux
== 0 || i
>= rawcount
-1 || rawsyms
[i
+ 1].is_sym
)
360 aux
= &rawsyms
[i
+ 1].u
.auxent
;
364 res
->type
= coff_basic_type
;
365 res
->u
.basic
= type
& 0xf;
371 if (sym
->n_numaux
&& sym
->n_sclass
== C_STAT
)
373 /* This is probably a section definition. */
374 res
->type
= coff_secdef_type
;
376 fatal (_("Section definition needs a section length"));
377 res
->size
= aux
->x_scn
.x_scnlen
;
379 /* PR 17512: file: 081c955d.
380 Fill in the asecdef structure as well. */
381 res
->u
.asecdef
.address
= 0;
382 res
->u
.asecdef
.size
= 0;
388 /* Don't know what this is, let's make it a simple int. */
389 res
->size
= INT_SIZE
;
390 res
->u
.basic
= T_UINT
;
394 /* Else it could be a function or pointer to void. */
406 res
->size
= SHORT_SIZE
;
410 res
->size
= INT_SIZE
;
414 res
->size
= LONG_SIZE
;
417 res
->size
= FLOAT_SIZE
;
420 res
->size
= DOUBLE_SIZE
;
427 fatal (_("Aggregate definition needs auxiliary information"));
429 if (aux
->x_sym
.x_tagndx
.p
)
433 /* PR 17512: file: e72f3988. */
434 if (aux
->x_sym
.x_tagndx
.l
< 0 || aux
->x_sym
.x_tagndx
.p
< rawsyms
)
436 non_fatal (_("Invalid tag index %#lx encountered"), aux
->x_sym
.x_tagndx
.l
);
440 idx
= INDEXOF (aux
->x_sym
.x_tagndx
.p
);
445 fatal (_("Symbol index %u encountered when there are no symbols"), idx
);
446 non_fatal (_("Invalid symbol index %u encountered"), idx
);
450 /* Referring to a struct defined elsewhere. */
451 res
->type
= coff_structref_type
;
452 res
->u
.astructref
.ref
= tindex
[idx
];
453 res
->size
= res
->u
.astructref
.ref
?
454 res
->u
.astructref
.ref
->type
->size
: 0;
458 /* A definition of a struct. */
460 res
->type
= coff_structdef_type
;
461 res
->u
.astructdef
.elements
= empty_scope ();
462 res
->u
.astructdef
.idx
= 0;
463 res
->u
.astructdef
.isstruct
= (type
& 0xf) == T_STRUCT
;
464 res
->size
= aux
->x_sym
.x_misc
.x_lnsz
.x_size
;
469 /* No auxents - it's anonymous. */
470 res
->type
= coff_structref_type
;
471 res
->u
.astructref
.ref
= 0;
477 fatal (_("Enum definition needs auxiliary information"));
478 if (aux
->x_sym
.x_tagndx
.p
)
480 unsigned int idx
= INDEXOF (aux
->x_sym
.x_tagndx
.p
);
482 /* PR 17512: file: 1ef037c7. */
484 fatal (_("Invalid enum symbol index %u encountered"), idx
);
485 /* Referring to a enum defined elsewhere. */
486 res
->type
= coff_enumref_type
;
487 res
->u
.aenumref
.ref
= tindex
[idx
];
488 /* PR 17512: file: b85b67e8. */
489 if (res
->u
.aenumref
.ref
)
490 res
->size
= res
->u
.aenumref
.ref
->type
->size
;
496 /* A definition of an enum. */
498 res
->type
= coff_enumdef_type
;
499 res
->u
.aenumdef
.elements
= empty_scope ();
500 res
->size
= aux
->x_sym
.x_misc
.x_lnsz
.x_size
;
507 for (which_dt
= 5; which_dt
>= 0; which_dt
--)
509 switch ((type
>> ((which_dt
* 2) + 4)) & 0x3)
515 struct coff_type
*ptr
= ((struct coff_type
*)
516 xmalloc (sizeof (struct coff_type
)));
520 fatal (_("Array definition needs auxiliary information"));
521 els
= (dimind
< DIMNUM
522 ? aux
->x_sym
.x_fcnary
.x_ary
.x_dimen
[dimind
]
526 ptr
->type
= coff_array_type
;
527 /* PR 17512: file: ae1971e2.
528 Check for integer overflow. */
536 non_fatal (_("Out of range sum for els (%#x) * size (%#x)"), els
, res
->size
);
538 ptr
->u
.array
.dim
= els
;
539 ptr
->u
.array
.array_of
= res
;
545 struct coff_type
*ptr
=
546 (struct coff_type
*) xmalloc (sizeof (struct coff_type
));
548 ptr
->size
= PTR_SIZE
;
549 ptr
->type
= coff_pointer_type
;
550 ptr
->u
.pointer
.points_to
= res
;
556 struct coff_type
*ptr
557 = (struct coff_type
*) xmalloc (sizeof (struct coff_type
));
560 ptr
->type
= coff_function_type
;
561 ptr
->u
.function
.function_returns
= res
;
562 ptr
->u
.function
.parameters
= empty_scope ();
563 ptr
->u
.function
.lines
= do_lines (i
, N(sym
));
564 ptr
->u
.function
.code
= 0;
565 last_function_type
= ptr
;
574 static struct coff_visible
*
577 struct internal_syment
*sym
= &rawsyms
[i
].u
.syment
;
578 struct coff_visible
*visible
=
579 (struct coff_visible
*) (xmalloc (sizeof (struct coff_visible
)));
580 enum coff_vis_type t
;
582 switch (sym
->n_sclass
)
587 t
= coff_vis_member_of_struct
;
590 t
= coff_vis_member_of_enum
;
593 t
= coff_vis_regparam
;
596 t
= coff_vis_register
;
606 t
= coff_vis_autoparam
;
613 t
= coff_vis_int_def
;
616 if (sym
->n_scnum
== N_UNDEF
)
621 t
= coff_vis_ext_ref
;
624 t
= coff_vis_ext_def
;
627 fatal (_("Unrecognised symbol class: %d"), sym
->n_sclass
);
634 /* Define a symbol and attach to block B. */
637 do_define (unsigned int i
, struct coff_scope
*b
)
639 static int symbol_index
;
640 struct internal_syment
*sym
;
641 struct coff_symbol
*s
= empty_symbol ();
644 fatal (_("ICE: do_define called without a block"));
646 fatal (_("Out of range symbol index: %u"), i
);
648 sym
= &rawsyms
[i
].u
.syment
;
649 s
->number
= ++symbol_index
;
651 s
->sfile
= cur_sfile
;
652 /* Glue onto the ofile list. */
655 if (ofile
->symbol_list_tail
)
656 ofile
->symbol_list_tail
->next_in_ofile_list
= s
;
658 ofile
->symbol_list_head
= s
;
659 ofile
->symbol_list_tail
= s
;
660 /* And the block list. */
663 b
->vars_tail
->next
= s
;
669 s
->type
= do_type (i
);
670 s
->where
= do_where (i
);
671 s
->visible
= do_visible (i
);
675 /* We remember the lowest address in each section for each source file. */
676 if (s
->where
->where
== coff_where_memory
677 && s
->type
->type
== coff_secdef_type
)
679 struct coff_isection
*is
;
681 /* PR 17512: file: 4676c97f. */
682 if (cur_sfile
== NULL
)
683 non_fatal (_("Section referenced before any file is defined"));
686 is
= cur_sfile
->section
+ s
->where
->section
->number
;
690 is
->low
= s
->where
->offset
;
691 /* PR 17512: file: 37e7a80d.
692 Check for integer overflow computing low + size. */
696 a
= s
->where
->offset
;
701 non_fatal (_("Out of range sum for offset (%#x) + size (%#x)"),
702 is
->low
, s
->type
->size
);
704 /* PR 17512: file: 37e7a80d. */
705 if (is
->high
< s
->where
->offset
)
706 fatal (_("Out of range type size: %u"), s
->type
->size
);
708 is
->parent
= s
->where
->section
;
713 if (s
->type
->type
== coff_function_type
)
714 last_function_symbol
= s
;
716 return i
+ sym
->n_numaux
+ 1;
719 static struct coff_ofile
*
724 struct coff_ofile
*head
=
725 (struct coff_ofile
*) xmalloc (sizeof (struct coff_ofile
));
728 head
->source_head
= 0;
729 head
->source_tail
= 0;
731 head
->symbol_list_tail
= 0;
732 head
->symbol_list_head
= 0;
733 do_sections_p1 (head
);
736 for (i
= 0; i
< rawcount
;)
738 struct internal_syment
*sym
= &rawsyms
[i
].u
.syment
;
740 switch (sym
->n_sclass
)
744 /* New source file announced. */
745 struct coff_sfile
*n
=
746 (struct coff_sfile
*) xmalloc (sizeof (struct coff_sfile
));
748 n
->section
= (struct coff_isection
*) xcalloc (sizeof (struct coff_isection
), abfd
->section_count
+ 1);
759 file_scope
= n
->scope
= top_scope
;
761 if (head
->source_tail
)
762 head
->source_tail
->next
= n
;
764 head
->source_head
= n
;
765 head
->source_tail
= n
;
767 i
+= sym
->n_numaux
+ 1;
776 /* Function start. */
778 /* PR 17512: file: 0ef7fbaf. */
779 if (last_function_type
)
780 last_function_type
->u
.function
.code
= top_scope
;
781 /* PR 17512: file: 22908266. */
782 if (sym
->n_scnum
< ofile
->nsections
&& sym
->n_scnum
>= 0)
783 top_scope
->sec
= ofile
->sections
+ sym
->n_scnum
;
785 top_scope
->sec
= NULL
;
786 top_scope
->offset
= sym
->n_value
;
790 /* PR 17512: file: e92e42e1. */
791 if (top_scope
== NULL
)
792 fatal (_("Function start encountered without a top level scope."));
793 top_scope
->size
= sym
->n_value
- top_scope
->offset
+ 1;
796 i
+= sym
->n_numaux
+ 1;
808 /* PR 17512: file: af7e8e83. */
809 if (sym
->n_scnum
< ofile
->nsections
&& sym
->n_scnum
>= 0)
810 top_scope
->sec
= ofile
->sections
+ sym
->n_scnum
;
812 top_scope
->sec
= NULL
;
813 top_scope
->offset
= sym
->n_value
;
817 if (top_scope
== NULL
)
818 fatal (_("Block start encountered without a scope for it."));
819 top_scope
->size
= sym
->n_value
- top_scope
->offset
+ 1;
822 i
+= sym
->n_numaux
+ 1;
827 if (last_function_symbol
== NULL
)
828 fatal (_("Function arguments encountered without a function definition"));
829 i
= do_define (i
, last_function_symbol
->type
->u
.function
.parameters
);
834 /* PR 17512: file: 43ab21f4. */
835 if (last_struct
== NULL
)
836 fatal (_("Structure element encountered without a structure definition"));
837 i
= do_define (i
, last_struct
->u
.astructdef
.elements
);
840 if (last_enum
== NULL
)
841 fatal (_("Enum element encountered without an enum definition"));
842 i
= do_define (i
, last_enum
->u
.aenumdef
.elements
);
847 /* Various definition. */
848 if (top_scope
== NULL
)
849 fatal (_("Aggregate definition encountered without a scope"));
850 i
= do_define (i
, top_scope
);
854 if (file_scope
== NULL
)
855 fatal (_("Label definition encountered without a file scope"));
856 i
= do_define (i
, file_scope
);
862 if (top_scope
== NULL
)
863 fatal (_("Variable definition encountered without a scope"));
864 i
= do_define (i
, top_scope
);
867 i
+= sym
->n_numaux
+ 1;
870 fatal (_("Unrecognised symbol class: %d"), sym
->n_sclass
);
873 do_sections_p2 (head
);
878 coff_grok (bfd
*inabfd
)
881 struct coff_ofile
*p
;
884 if (! bfd_family_coff (abfd
))
886 non_fatal (_("%s: is not a COFF format file"), bfd_get_filename (abfd
));
890 storage
= bfd_get_symtab_upper_bound (abfd
);
893 bfd_fatal (bfd_get_filename (abfd
));
895 syms
= (asymbol
**) xmalloc (storage
);
896 symcount
= bfd_canonicalize_symtab (abfd
, syms
);
898 bfd_fatal (bfd_get_filename (abfd
));
899 rawsyms
= obj_raw_syments (abfd
);
900 rawcount
= obj_raw_syment_count (abfd
);
901 tindex
= (struct coff_symbol
**) (xcalloc (sizeof (struct coff_symbol
*), rawcount
));