2 Copyright 1994, 1995, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
3 2007, 2009 Free Software Foundation, Inc.
5 This file is part of GNU Binutils.
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.
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.
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. */
23 /* Written by Steve Chamberlain (sac@cygnus.com)
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. */
31 #include "libiberty.h"
33 #include "coff/internal.h"
34 #include "../bfd/libcoff.h"
38 static int lofile
= 1;
39 static struct coff_scope
*top_scope
;
40 static struct coff_scope
*file_scope
;
41 static struct coff_ofile
*ofile
;
43 static struct coff_symbol
*last_function_symbol
;
44 static struct coff_type
*last_function_type
;
45 static struct coff_type
*last_struct
;
46 static struct coff_type
*last_enum
;
47 static struct coff_sfile
*cur_sfile
;
49 static struct coff_symbol
**tindex
;
52 static asymbol
**syms
;
55 #define N(x) ((x)->_n._n_nptr[1])
57 static struct coff_ptr_struct
*rawsyms
;
68 #define INDEXOF(p) ((struct coff_ptr_struct *)(p)-(rawsyms))
70 static struct coff_scope
*empty_scope (void);
71 static struct coff_symbol
*empty_symbol (void);
72 static void push_scope (int);
73 static void pop_scope (void);
74 static void do_sections_p1 (struct coff_ofile
*);
75 static void do_sections_p2 (struct coff_ofile
*);
76 static struct coff_where
*do_where (int);
77 static struct coff_line
*do_lines (int, char *);
78 static struct coff_type
*do_type (int);
79 static struct coff_visible
*do_visible (int);
80 static int do_define (int, struct coff_scope
*);
81 static struct coff_ofile
*doit (void);
83 static struct coff_scope
*
87 l
= (struct coff_scope
*) (xcalloc (sizeof (struct coff_scope
), 1));
91 static struct coff_symbol
*
94 return (struct coff_symbol
*) (xcalloc (sizeof (struct coff_symbol
), 1));
99 push_scope (int slink
)
101 struct coff_scope
*n
= empty_scope ();
107 if (top_scope
->list_tail
)
109 top_scope
->list_tail
->next
= n
;
113 top_scope
->list_head
= n
;
115 top_scope
->list_tail
= n
;
118 n
->parent
= top_scope
;
126 top_scope
= top_scope
->parent
;
130 do_sections_p1 (struct coff_ofile
*head
)
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
;
139 for (idx
= 0, section
= abfd
->sections
; section
; section
= section
->next
, idx
++)
142 int i
= section
->target_index
;
146 relsize
= bfd_get_reloc_upper_bound (abfd
, section
);
148 bfd_fatal (bfd_get_filename (abfd
));
151 relpp
= (arelent
**) xmalloc (relsize
);
152 relcount
= bfd_canonicalize_reloc (abfd
, section
, relpp
, syms
);
154 bfd_fatal (bfd_get_filename (abfd
));
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
;
162 head
->sections
[i
].size
= bfd_get_section_size (section
);
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
;
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;
179 do_sections_p2 (struct coff_ofile
*head
)
182 for (section
= abfd
->sections
; section
; section
= section
->next
)
186 for (j
= 0; j
< section
->reloc_count
; j
++)
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
];
200 static struct coff_where
*
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
;
208 if (sym
->n_scnum
== -1)
211 switch (sym
->n_sclass
)
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
;
220 where
->where
= coff_where_member_of_enum
;
224 where
->where
= coff_where_member_of_struct
;
228 where
->where
= coff_where_stack
;
234 where
->where
= coff_where_memory
;
235 where
->section
= &ofile
->sections
[sym
->n_scnum
];
239 where
->where
= coff_where_register
;
242 where
->where
= coff_where_entag
;
246 where
->where
= coff_where_strtag
;
249 where
->where
= coff_where_typedef
;
260 do_lines (int i
, char *name ATTRIBUTE_UNUSED
)
262 struct coff_line
*res
= (struct coff_line
*) xcalloc (sizeof (struct coff_line
), 1);
266 /* Find out if this function has any line numbers in the table */
267 for (s
= abfd
->sections
; s
; s
= s
->next
)
269 for (l
= 0; l
< s
->lineno_count
; l
++)
271 if (s
->lineno
[l
].line_number
== 0)
273 if (rawsyms
+ i
== ((coff_symbol_type
*) (&(s
->lineno
[l
].u
.sym
[0])))->native
)
275 /* These lines are for this function - so count them and stick them on */
277 /* Find the linenumber of the top of the function, since coff linenumbers
278 are relative to the start of the function. */
279 int start_line
= rawsyms
[i
+ 3].u
.auxent
.x_sym
.x_misc
.x_lnsz
.x_lnno
;
282 for (c
= 0; s
->lineno
[l
+ c
+ 1].line_number
; c
++)
285 /* Add two extra records, one for the prologue and one for the epilogue */
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
++)
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
;
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
;
317 res
->type
= coff_basic_type
;
318 res
->u
.basic
= type
& 0xf;
324 if (sym
->n_numaux
&& sym
->n_sclass
== C_STAT
)
326 /* This is probably a section definition */
327 res
->type
= coff_secdef_type
;
328 res
->size
= aux
->x_scn
.x_scnlen
;
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
;
340 /* Else it could be a function or pointer to void */
354 res
->size
= SHORT_SIZE
;
358 res
->size
= INT_SIZE
;
362 res
->size
= LONG_SIZE
;
365 res
->size
= FLOAT_SIZE
;
368 res
->size
= DOUBLE_SIZE
;
374 if (aux
->x_sym
.x_tagndx
.p
)
376 /* Referring to a struct defined elsewhere */
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;
384 /* A definition of a struct */
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
;
395 /* No auxents - it's anonymous */
396 res
->type
= coff_structref_type
;
397 res
->u
.astructref
.ref
= 0;
402 if (aux
->x_sym
.x_tagndx
.p
)
404 /* Referring to a enum defined elsewhere */
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
;
411 /* A definition of an enum */
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
;
422 for (which_dt
= 5; which_dt
>= 0; which_dt
--)
424 switch ((type
>> ((which_dt
* 2) + 4)) & 0x3)
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
]
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
;
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
;
455 struct coff_type
*ptr
456 = (struct coff_type
*) xmalloc (sizeof (struct coff_type
));
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
;
472 static struct coff_visible
*
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
)
484 t
= coff_vis_member_of_struct
;
487 t
= coff_vis_member_of_enum
;
491 t
= coff_vis_regparam
;
495 t
= coff_vis_register
;
505 t
= coff_vis_autoparam
;
514 t
= coff_vis_int_def
;
517 if (sym
->n_scnum
== N_UNDEF
)
522 t
= coff_vis_ext_ref
;
525 t
= coff_vis_ext_def
;
537 do_define (int i
, struct coff_scope
*b
)
539 static int symbol_index
;
540 struct internal_syment
*sym
= &rawsyms
[i
].u
.syment
;
542 /* Define a symbol and attach to block b */
543 struct coff_symbol
*s
= empty_symbol ();
545 s
->number
= ++symbol_index
;
546 s
->name
= sym
->_n
._n_nptr
[1];
547 s
->sfile
= cur_sfile
;
548 /* Glue onto the ofile list */
551 if (ofile
->symbol_list_tail
)
552 ofile
->symbol_list_tail
->next_in_ofile_list
= s
;
554 ofile
->symbol_list_head
= s
;
555 ofile
->symbol_list_tail
= s
;
556 /* And the block list */
559 b
->vars_tail
->next
= s
;
565 s
->type
= do_type (i
);
566 s
->where
= do_where (i
);
567 s
->visible
= do_visible (i
);
571 /* We remember the lowest address in each section for each source file */
573 if (s
->where
->where
== coff_where_memory
574 && s
->type
->type
== coff_secdef_type
)
576 struct coff_isection
*is
= cur_sfile
->section
+ s
->where
->section
->number
;
580 is
->low
= s
->where
->offset
;
581 is
->high
= s
->where
->offset
+ s
->type
->size
;
583 is
->parent
= s
->where
->section
;
588 if (s
->type
->type
== coff_function_type
)
589 last_function_symbol
= s
;
591 return i
+ sym
->n_numaux
+ 1;
601 struct coff_ofile
*head
=
602 (struct coff_ofile
*) xmalloc (sizeof (struct coff_ofile
));
604 head
->source_head
= 0;
605 head
->source_tail
= 0;
607 head
->symbol_list_tail
= 0;
608 head
->symbol_list_head
= 0;
609 do_sections_p1 (head
);
612 for (i
= 0; i
< rawcount
;)
614 struct internal_syment
*sym
= &rawsyms
[i
].u
.syment
;
615 switch (sym
->n_sclass
)
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);
624 n
->name
= sym
->_n
._n_nptr
[1];
633 file_scope
= n
->scope
= top_scope
;
635 if (head
->source_tail
)
636 head
->source_tail
->next
= n
;
638 head
->source_head
= n
;
639 head
->source_tail
= n
;
641 i
+= sym
->n_numaux
+ 1;
646 char *name
= sym
->_n
._n_nptr
[1];
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
;
657 top_scope
->size
= sym
->n_value
- top_scope
->offset
+ 1;
661 i
+= sym
->n_numaux
+ 1;
667 char *name
= sym
->_n
._n_nptr
[1];
672 top_scope
->sec
= ofile
->sections
+ sym
->n_scnum
;
673 top_scope
->offset
= sym
->n_value
;
678 top_scope
->size
= sym
->n_value
- top_scope
->offset
+ 1;
681 i
+= sym
->n_numaux
+ 1;
686 i
= do_define (i
, last_function_symbol
->type
->u
.function
.parameters
);
691 i
= do_define (i
, last_struct
->u
.astructdef
.elements
);
694 i
= do_define (i
, last_enum
->u
.aenumdef
.elements
);
699 /* Various definition */
700 i
= do_define (i
, top_scope
);
704 i
= do_define (i
, file_scope
);
710 i
= do_define (i
, top_scope
);
715 i
+= sym
->n_numaux
+ 1;
719 do_sections_p2 (head
);
724 coff_grok (bfd
*inabfd
)
727 struct coff_ofile
*p
;
729 storage
= bfd_get_symtab_upper_bound (abfd
);
732 bfd_fatal (abfd
->filename
);
734 syms
= (asymbol
**) xmalloc (storage
);
735 symcount
= bfd_canonicalize_symtab (abfd
, syms
);
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
));