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