]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/rdcoff.c
[gdb/symtab] Work around PR gas/29517, dwarf2 case
[thirdparty/binutils-gdb.git] / binutils / rdcoff.c
CommitLineData
252b5132 1/* stabs.c -- Parse COFF debugging information
fd67aa11 2 Copyright (C) 1996-2024 Free Software Foundation, Inc.
252b5132
RH
3 Written by Ian Lance Taylor <ian@cygnus.com>.
4
5 This file is part of GNU Binutils.
6
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
32866df7 9 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
10 (at your option) any later version.
11
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
b43b5d5f
NC
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
252b5132
RH
21
22/* This file contains code which parses COFF debugging information. */
23
3db64b00 24#include "sysdep.h"
252b5132
RH
25#include "bfd.h"
26#include "coff/internal.h"
252b5132 27#include "libiberty.h"
3db64b00 28#include "bucomm.h"
252b5132
RH
29#include "debug.h"
30#include "budbg.h"
31
32/* FIXME: We should not need this BFD internal file. We need it for
33 the N_BTMASK, etc., values. */
34#include "libcoff.h"
35
36/* These macros extract the right mask and shifts for this BFD. They
37 assume that there is a local variable named ABFD. This is so that
38 macros like ISFCN and DECREF, from coff/internal.h, will work
39 without modification. */
40#define N_BTMASK (coff_data (abfd)->local_n_btmask)
41#define N_BTSHFT (coff_data (abfd)->local_n_btshft)
42#define N_TMASK (coff_data (abfd)->local_n_tmask)
43#define N_TSHIFT (coff_data (abfd)->local_n_tshift)
44
45/* This structure is used to hold the symbols, as well as the current
46 location within the symbols. */
47
48struct coff_symbols
49{
50 /* The symbols. */
51 asymbol **syms;
52 /* The number of symbols. */
53 long symcount;
54 /* The index of the current symbol. */
55 long symno;
56 /* The index of the current symbol in the COFF symbol table (where
57 each auxent counts as a symbol). */
58 long coff_symno;
59};
60
945efa5c 61/* This structure is used to map symbol indices to types. */
252b5132 62
945efa5c 63struct coff_types
252b5132
RH
64{
65 /* Next set of slots. */
945efa5c
AM
66 struct coff_types *next;
67 /* Where the TYPES array starts. */
de357ff4 68 unsigned int base_index;
252b5132
RH
69 /* Slots. */
70#define COFF_SLOTS (16)
945efa5c 71 debug_type types[COFF_SLOTS];
252b5132
RH
72};
73
252b5132 74static debug_type parse_coff_base_type
945efa5c 75 (bfd *, struct coff_symbols *, struct coff_types **, long, int,
2da42df6 76 union internal_auxent *, void *);
252b5132 77static debug_type parse_coff_struct_type
945efa5c 78 (bfd *, struct coff_symbols *, struct coff_types **, int,
2da42df6 79 union internal_auxent *, void *);
252b5132 80static debug_type parse_coff_enum_type
945efa5c 81 (bfd *, struct coff_symbols *, struct coff_types **,
2da42df6 82 union internal_auxent *, void *);
252b5132
RH
83\f
84/* Return the slot for a type. */
85
86static debug_type *
19cacf67 87coff_get_slot (void *dhandle, struct coff_types **types, long indx)
252b5132 88{
de357ff4 89 unsigned int base_index;
252b5132 90
de357ff4
AM
91 base_index = indx / COFF_SLOTS * COFF_SLOTS;
92 indx -= base_index;
252b5132 93
945efa5c
AM
94 while (*types && (*types)->base_index < base_index)
95 types = &(*types)->next;
f41e4712 96
945efa5c 97 if (*types == NULL || (*types)->base_index != base_index)
252b5132 98 {
19cacf67 99 struct coff_types *n = debug_xzalloc (dhandle, sizeof (*n));
945efa5c 100 n->next = *types;
de357ff4 101 n->base_index = base_index;
945efa5c 102 *types = n;
252b5132
RH
103 }
104
945efa5c 105 return (*types)->types + indx;
252b5132
RH
106}
107
108/* Parse a COFF type code in NTYPE. */
109
110static debug_type
2da42df6 111parse_coff_type (bfd *abfd, struct coff_symbols *symbols,
945efa5c 112 struct coff_types **types, long coff_symno, int ntype,
015dc7e1 113 union internal_auxent *pauxent, bool useaux,
2da42df6 114 void *dhandle)
252b5132
RH
115{
116 debug_type type;
117
118 if ((ntype & ~N_BTMASK) != 0)
119 {
120 int newtype;
121
122 newtype = DECREF (ntype);
123
124 if (ISPTR (ntype))
125 {
126 type = parse_coff_type (abfd, symbols, types, coff_symno, newtype,
127 pauxent, useaux, dhandle);
128 type = debug_make_pointer_type (dhandle, type);
129 }
130 else if (ISFCN (ntype))
131 {
132 type = parse_coff_type (abfd, symbols, types, coff_symno, newtype,
133 pauxent, useaux, dhandle);
134 type = debug_make_function_type (dhandle, type, (debug_type *) NULL,
015dc7e1 135 false);
252b5132
RH
136 }
137 else if (ISARY (ntype))
138 {
139 int n;
140
141 if (pauxent == NULL)
142 n = 0;
143 else
144 {
145 unsigned short *dim;
146 int i;
147
148 /* FIXME: If pauxent->x_sym.x_tagndx.l == 0, gdb sets
149 the c_naux field of the syment to 0. */
150
151 /* Move the dimensions down, so that the next array
152 picks up the next one. */
153 dim = pauxent->x_sym.x_fcnary.x_ary.x_dimen;
154 n = dim[0];
155 for (i = 0; *dim != 0 && i < DIMNUM - 1; i++, dim++)
156 *dim = *(dim + 1);
157 *dim = 0;
158 }
159
160 type = parse_coff_type (abfd, symbols, types, coff_symno, newtype,
015dc7e1 161 pauxent, false, dhandle);
252b5132
RH
162 type = debug_make_array_type (dhandle, type,
163 parse_coff_base_type (abfd, symbols,
164 types,
165 coff_symno,
166 T_INT,
167 NULL, dhandle),
015dc7e1 168 0, n - 1, false);
252b5132
RH
169 }
170 else
171 {
37cc8ec1 172 non_fatal (_("parse_coff_type: Bad type code 0x%x"), ntype);
252b5132
RH
173 return DEBUG_TYPE_NULL;
174 }
175
176 return type;
177 }
178
a2c7ca15 179 if (pauxent != NULL && (int32_t) pauxent->x_sym.x_tagndx.u32 > 0)
252b5132
RH
180 {
181 debug_type *slot;
182
183 /* This is a reference to an existing type. FIXME: gdb checks
184 that the class is not C_STRTAG, nor C_UNTAG, nor C_ENTAG. */
19cacf67 185 slot = coff_get_slot (dhandle, types, pauxent->x_sym.x_tagndx.u32);
252b5132
RH
186 if (*slot != DEBUG_TYPE_NULL)
187 return *slot;
188 else
189 return debug_make_indirect_type (dhandle, slot, (const char *) NULL);
190 }
191
192 /* If the aux entry has already been used for something, useaux will
193 have been set to false, indicating that parse_coff_base_type
194 should not use it. We need to do it this way, rather than simply
195 passing pauxent as NULL, because we need to be able handle
196 multiple array dimensions while still discarding pauxent after
197 having handled all of them. */
198 if (! useaux)
199 pauxent = NULL;
200
201 return parse_coff_base_type (abfd, symbols, types, coff_symno, ntype,
202 pauxent, dhandle);
203}
204
205/* Parse a basic COFF type in NTYPE. */
206
207static debug_type
2da42df6 208parse_coff_base_type (bfd *abfd, struct coff_symbols *symbols,
945efa5c 209 struct coff_types **types, long coff_symno, int ntype,
2da42df6 210 union internal_auxent *pauxent, void *dhandle)
252b5132
RH
211{
212 debug_type ret;
945efa5c 213 const char *name = NULL;
252b5132
RH
214
215 switch (ntype)
216 {
217 default:
218 ret = debug_make_void_type (dhandle);
219 break;
220
221 case T_NULL:
222 case T_VOID:
223 ret = debug_make_void_type (dhandle);
224 name = "void";
225 break;
226
227 case T_CHAR:
015dc7e1 228 ret = debug_make_int_type (dhandle, 1, false);
252b5132
RH
229 name = "char";
230 break;
231
232 case T_SHORT:
015dc7e1 233 ret = debug_make_int_type (dhandle, 2, false);
252b5132
RH
234 name = "short";
235 break;
236
237 case T_INT:
238 /* FIXME: Perhaps the size should depend upon the architecture. */
015dc7e1 239 ret = debug_make_int_type (dhandle, 4, false);
252b5132
RH
240 name = "int";
241 break;
242
243 case T_LONG:
015dc7e1 244 ret = debug_make_int_type (dhandle, 4, false);
252b5132
RH
245 name = "long";
246 break;
247
248 case T_FLOAT:
249 ret = debug_make_float_type (dhandle, 4);
250 name = "float";
251 break;
252
253 case T_DOUBLE:
254 ret = debug_make_float_type (dhandle, 8);
255 name = "double";
256 break;
257
258 case T_LNGDBL:
259 ret = debug_make_float_type (dhandle, 12);
260 name = "long double";
261 break;
262
263 case T_UCHAR:
015dc7e1 264 ret = debug_make_int_type (dhandle, 1, true);
252b5132
RH
265 name = "unsigned char";
266 break;
267
268 case T_USHORT:
015dc7e1 269 ret = debug_make_int_type (dhandle, 2, true);
252b5132
RH
270 name = "unsigned short";
271 break;
272
273 case T_UINT:
015dc7e1 274 ret = debug_make_int_type (dhandle, 4, true);
252b5132
RH
275 name = "unsigned int";
276 break;
277
278 case T_ULONG:
015dc7e1 279 ret = debug_make_int_type (dhandle, 4, true);
252b5132
RH
280 name = "unsigned long";
281 break;
282
283 case T_STRUCT:
284 if (pauxent == NULL)
015dc7e1 285 ret = debug_make_struct_type (dhandle, true, 0,
252b5132
RH
286 (debug_field *) NULL);
287 else
288 ret = parse_coff_struct_type (abfd, symbols, types, ntype, pauxent,
289 dhandle);
252b5132
RH
290 break;
291
292 case T_UNION:
293 if (pauxent == NULL)
015dc7e1 294 ret = debug_make_struct_type (dhandle, false, 0, (debug_field *) NULL);
252b5132
RH
295 else
296 ret = parse_coff_struct_type (abfd, symbols, types, ntype, pauxent,
297 dhandle);
252b5132
RH
298 break;
299
300 case T_ENUM:
301 if (pauxent == NULL)
302 ret = debug_make_enum_type (dhandle, (const char **) NULL,
303 (bfd_signed_vma *) NULL);
304 else
305 ret = parse_coff_enum_type (abfd, symbols, types, pauxent, dhandle);
252b5132
RH
306 break;
307 }
308
309 if (name != NULL)
310 ret = debug_name_type (dhandle, name, ret);
311
19cacf67 312 debug_type *slot = coff_get_slot (dhandle, types, coff_symno);
945efa5c 313 *slot = ret;
252b5132
RH
314
315 return ret;
316}
317
318/* Parse a struct type. */
319
320static debug_type
2da42df6 321parse_coff_struct_type (bfd *abfd, struct coff_symbols *symbols,
945efa5c 322 struct coff_types **types, int ntype,
2da42df6 323 union internal_auxent *pauxent, void *dhandle)
252b5132
RH
324{
325 long symend;
326 int alloc;
19cacf67 327 debug_field *fields, *xfields;
252b5132 328 int count;
015dc7e1 329 bool done;
252b5132 330
a2c7ca15 331 symend = pauxent->x_sym.x_fcnary.x_fcn.x_endndx.u32;
252b5132
RH
332
333 alloc = 10;
334 fields = (debug_field *) xmalloc (alloc * sizeof *fields);
335 count = 0;
336
015dc7e1 337 done = false;
252b5132
RH
338 while (! done
339 && symbols->coff_symno < symend
340 && symbols->symno < symbols->symcount)
341 {
342 asymbol *sym;
343 long this_coff_symno;
344 struct internal_syment syment;
345 union internal_auxent auxent;
346 union internal_auxent *psubaux;
347 bfd_vma bitpos = 0, bitsize = 0;
348
349 sym = symbols->syms[symbols->symno];
350
351 if (! bfd_coff_get_syment (abfd, sym, &syment))
352 {
37cc8ec1
AM
353 non_fatal (_("bfd_coff_get_syment failed: %s"),
354 bfd_errmsg (bfd_get_error ()));
e3d39609 355 free (fields);
252b5132
RH
356 return DEBUG_TYPE_NULL;
357 }
358
359 this_coff_symno = symbols->coff_symno;
360
361 ++symbols->symno;
362 symbols->coff_symno += 1 + syment.n_numaux;
363
364 if (syment.n_numaux == 0)
365 psubaux = NULL;
366 else
367 {
368 if (! bfd_coff_get_auxent (abfd, sym, 0, &auxent))
369 {
37cc8ec1
AM
370 non_fatal (_("bfd_coff_get_auxent failed: %s"),
371 bfd_errmsg (bfd_get_error ()));
e3d39609 372 free (fields);
252b5132
RH
373 return DEBUG_TYPE_NULL;
374 }
375 psubaux = &auxent;
376 }
377
378 switch (syment.n_sclass)
379 {
380 case C_MOS:
381 case C_MOU:
382 bitpos = 8 * bfd_asymbol_value (sym);
383 bitsize = 0;
384 break;
385
386 case C_FIELD:
387 bitpos = bfd_asymbol_value (sym);
341eba4f
AM
388 if (psubaux != NULL)
389 bitsize = psubaux->x_sym.x_misc.x_lnsz.x_size;
252b5132
RH
390 break;
391
392 case C_EOS:
015dc7e1 393 done = true;
252b5132
RH
394 break;
395 }
396
397 if (! done)
398 {
399 debug_type ftype;
400 debug_field f;
401
402 ftype = parse_coff_type (abfd, symbols, types, this_coff_symno,
015dc7e1 403 syment.n_type, psubaux, true, dhandle);
252b5132
RH
404 f = debug_make_field (dhandle, bfd_asymbol_name (sym), ftype,
405 bitpos, bitsize, DEBUG_VISIBILITY_PUBLIC);
406 if (f == DEBUG_FIELD_NULL)
19cacf67
AM
407 {
408 free (fields);
409 return DEBUG_TYPE_NULL;
410 }
252b5132
RH
411
412 if (count + 1 >= alloc)
413 {
414 alloc += 10;
415 fields = ((debug_field *)
416 xrealloc (fields, alloc * sizeof *fields));
417 }
418
419 fields[count] = f;
420 ++count;
421 }
422 }
423
424 fields[count] = DEBUG_FIELD_NULL;
19cacf67
AM
425 xfields = debug_xalloc (dhandle, (count + 1) * sizeof (*fields));
426 memcpy (xfields, fields, (count + 1) * sizeof (*fields));
427 free (fields);
252b5132
RH
428
429 return debug_make_struct_type (dhandle, ntype == T_STRUCT,
430 pauxent->x_sym.x_misc.x_lnsz.x_size,
19cacf67 431 xfields);
252b5132
RH
432}
433
434/* Parse an enum type. */
435
436static debug_type
2da42df6 437parse_coff_enum_type (bfd *abfd, struct coff_symbols *symbols,
945efa5c 438 struct coff_types **types ATTRIBUTE_UNUSED,
2da42df6 439 union internal_auxent *pauxent, void *dhandle)
252b5132
RH
440{
441 long symend;
442 int alloc;
19cacf67
AM
443 const char **names, **xnames;
444 bfd_signed_vma *vals, *xvals;
252b5132 445 int count;
015dc7e1 446 bool done;
252b5132 447
a2c7ca15 448 symend = pauxent->x_sym.x_fcnary.x_fcn.x_endndx.u32;
252b5132
RH
449
450 alloc = 10;
451 names = (const char **) xmalloc (alloc * sizeof *names);
452 vals = (bfd_signed_vma *) xmalloc (alloc * sizeof *vals);
453 count = 0;
454
015dc7e1 455 done = false;
252b5132
RH
456 while (! done
457 && symbols->coff_symno < symend
458 && symbols->symno < symbols->symcount)
459 {
460 asymbol *sym;
461 struct internal_syment syment;
462
463 sym = symbols->syms[symbols->symno];
464
465 if (! bfd_coff_get_syment (abfd, sym, &syment))
466 {
37cc8ec1
AM
467 non_fatal (_("bfd_coff_get_syment failed: %s"),
468 bfd_errmsg (bfd_get_error ()));
e3d39609
NC
469 free (names);
470 free (vals);
252b5132
RH
471 return DEBUG_TYPE_NULL;
472 }
473
474 ++symbols->symno;
475 symbols->coff_symno += 1 + syment.n_numaux;
476
477 switch (syment.n_sclass)
478 {
479 case C_MOE:
480 if (count + 1 >= alloc)
481 {
482 alloc += 10;
483 names = ((const char **)
484 xrealloc (names, alloc * sizeof *names));
485 vals = ((bfd_signed_vma *)
486 xrealloc (vals, alloc * sizeof *vals));
487 }
488
489 names[count] = bfd_asymbol_name (sym);
490 vals[count] = bfd_asymbol_value (sym);
491 ++count;
492 break;
493
494 case C_EOS:
015dc7e1 495 done = true;
252b5132
RH
496 break;
497 }
498 }
499
500 names[count] = NULL;
19cacf67
AM
501 vals[count] = 0;
502 xnames = debug_xalloc (dhandle, (count + 1) * sizeof (*names));
503 memcpy (xnames, names, (count + 1) * sizeof (*names));
504 free (names);
505 xvals = debug_xalloc (dhandle, (count + 1) * sizeof (*vals));
506 memcpy (xvals, vals, (count + 1) * sizeof (*vals));
507 free (vals);
508
509 return debug_make_enum_type (dhandle, xnames, xvals);
252b5132
RH
510}
511
512/* Handle a single COFF symbol. */
513
015dc7e1 514static bool
945efa5c 515parse_coff_symbol (bfd *abfd ATTRIBUTE_UNUSED, struct coff_types **types,
2da42df6
AJ
516 asymbol *sym, long coff_symno,
517 struct internal_syment *psyment, void *dhandle,
015dc7e1 518 debug_type type, bool within_function)
252b5132
RH
519{
520 switch (psyment->n_sclass)
521 {
522 case C_NULL:
523 break;
524
525 case C_AUTO:
526 if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
527 DEBUG_LOCAL, bfd_asymbol_value (sym)))
015dc7e1 528 return false;
252b5132
RH
529 break;
530
05c58a7c 531 case C_WEAKEXT:
252b5132
RH
532 case C_EXT:
533 if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
534 DEBUG_GLOBAL, bfd_asymbol_value (sym)))
015dc7e1 535 return false;
252b5132
RH
536 break;
537
538 case C_STAT:
539 if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
540 (within_function
541 ? DEBUG_LOCAL_STATIC
542 : DEBUG_STATIC),
543 bfd_asymbol_value (sym)))
015dc7e1 544 return false;
252b5132
RH
545 break;
546
547 case C_REG:
548 /* FIXME: We may need to convert the register number. */
549 if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
550 DEBUG_REGISTER, bfd_asymbol_value (sym)))
015dc7e1 551 return false;
252b5132
RH
552 break;
553
554 case C_LABEL:
555 break;
556
557 case C_ARG:
558 if (! debug_record_parameter (dhandle, bfd_asymbol_name (sym), type,
559 DEBUG_PARM_STACK, bfd_asymbol_value (sym)))
015dc7e1 560 return false;
252b5132
RH
561 break;
562
563 case C_REGPARM:
564 /* FIXME: We may need to convert the register number. */
565 if (! debug_record_parameter (dhandle, bfd_asymbol_name (sym), type,
566 DEBUG_PARM_REG, bfd_asymbol_value (sym)))
015dc7e1 567 return false;
252b5132
RH
568 break;
569
570 case C_TPDEF:
571 type = debug_name_type (dhandle, bfd_asymbol_name (sym), type);
572 if (type == DEBUG_TYPE_NULL)
015dc7e1 573 return false;
252b5132
RH
574 break;
575
576 case C_STRTAG:
577 case C_UNTAG:
578 case C_ENTAG:
579 {
580 debug_type *slot;
581
582 type = debug_tag_type (dhandle, bfd_asymbol_name (sym), type);
583 if (type == DEBUG_TYPE_NULL)
015dc7e1 584 return false;
252b5132
RH
585
586 /* Store the named type into the slot, so that references get
587 the name. */
19cacf67 588 slot = coff_get_slot (dhandle, types, coff_symno);
252b5132
RH
589 *slot = type;
590 }
591 break;
592
593 default:
594 break;
595 }
596
015dc7e1 597 return true;
252b5132
RH
598}
599
05c58a7c
NC
600/* Determine if a symbol has external visibility. */
601
015dc7e1 602static bool
2da42df6 603external_coff_symbol_p (int sym_class)
05c58a7c
NC
604{
605 switch (sym_class)
606 {
53c7db4b
KH
607 case C_EXT:
608 case C_WEAKEXT:
015dc7e1 609 return true;
05c58a7c
NC
610 default:
611 break;
612 }
015dc7e1 613 return false;
05c58a7c
NC
614}
615
252b5132
RH
616/* This is the main routine. It looks through all the symbols and
617 handles them. */
618
015dc7e1 619bool
2da42df6 620parse_coff (bfd *abfd, asymbol **syms, long symcount, void *dhandle)
252b5132
RH
621{
622 struct coff_symbols symbols;
945efa5c 623 struct coff_types *types;
252b5132
RH
624 long next_c_file;
625 const char *fnname;
626 int fnclass;
627 int fntype;
628 bfd_vma fnend;
629 alent *linenos;
015dc7e1 630 bool within_function;
252b5132
RH
631 long this_coff_symno;
632
633 symbols.syms = syms;
634 symbols.symcount = symcount;
635 symbols.symno = 0;
636 symbols.coff_symno = 0;
637
945efa5c 638 types= NULL;
252b5132
RH
639
640 next_c_file = -1;
641 fnname = NULL;
642 fnclass = 0;
643 fntype = 0;
644 fnend = 0;
645 linenos = NULL;
015dc7e1 646 within_function = false;
252b5132
RH
647
648 while (symbols.symno < symcount)
649 {
650 asymbol *sym;
651 const char *name;
652 struct internal_syment syment;
653 union internal_auxent auxent;
654 union internal_auxent *paux;
655 debug_type type;
656
657 sym = syms[symbols.symno];
658
659 if (! bfd_coff_get_syment (abfd, sym, &syment))
660 {
37cc8ec1
AM
661 non_fatal (_("bfd_coff_get_syment failed: %s"),
662 bfd_errmsg (bfd_get_error ()));
015dc7e1 663 return false;
252b5132
RH
664 }
665
666 name = bfd_asymbol_name (sym);
667
668 this_coff_symno = symbols.coff_symno;
669
670 ++symbols.symno;
671 symbols.coff_symno += 1 + syment.n_numaux;
672
673 /* We only worry about the first auxent, because that is the
674 only one which is relevant for debugging information. */
675 if (syment.n_numaux == 0)
676 paux = NULL;
677 else
678 {
679 if (! bfd_coff_get_auxent (abfd, sym, 0, &auxent))
680 {
37cc8ec1
AM
681 non_fatal (_("bfd_coff_get_auxent failed: %s"),
682 bfd_errmsg (bfd_get_error ()));
015dc7e1 683 return false;
252b5132
RH
684 }
685 paux = &auxent;
686 }
687
688 if (this_coff_symno == next_c_file && syment.n_sclass != C_FILE)
689 {
690 /* The last C_FILE symbol points to the first external
691 symbol. */
692 if (! debug_set_filename (dhandle, "*globals*"))
015dc7e1 693 return false;
252b5132
RH
694 }
695
696 switch (syment.n_sclass)
697 {
698 case C_EFCN:
699 case C_EXTDEF:
700 case C_ULABEL:
701 case C_USTATIC:
702 case C_LINE:
703 case C_ALIAS:
704 case C_HIDDEN:
705 /* Just ignore these classes. */
706 break;
707
708 case C_FILE:
709 next_c_file = syment.n_value;
710 if (! debug_set_filename (dhandle, name))
015dc7e1 711 return false;
252b5132
RH
712 break;
713
714 case C_STAT:
715 /* Ignore static symbols with a type of T_NULL. These
716 represent section entries. */
717 if (syment.n_type == T_NULL)
718 break;
719 /* Fall through. */
53c7db4b 720 case C_WEAKEXT:
252b5132
RH
721 case C_EXT:
722 if (ISFCN (syment.n_type))
723 {
724 fnname = name;
725 fnclass = syment.n_sclass;
726 fntype = syment.n_type;
727 if (syment.n_numaux > 0)
728 fnend = bfd_asymbol_value (sym) + auxent.x_sym.x_misc.x_fsize;
729 else
730 fnend = 0;
731 linenos = BFD_SEND (abfd, _get_lineno, (abfd, sym));
732 break;
733 }
734 type = parse_coff_type (abfd, &symbols, &types, this_coff_symno,
015dc7e1 735 syment.n_type, paux, true, dhandle);
252b5132 736 if (type == DEBUG_TYPE_NULL)
015dc7e1 737 return false;
252b5132
RH
738 if (! parse_coff_symbol (abfd, &types, sym, this_coff_symno, &syment,
739 dhandle, type, within_function))
015dc7e1 740 return false;
252b5132
RH
741 break;
742
743 case C_FCN:
744 if (strcmp (name, ".bf") == 0)
745 {
746 if (fnname == NULL)
747 {
37cc8ec1
AM
748 non_fatal (_("%ld: .bf without preceding function"),
749 this_coff_symno);
015dc7e1 750 return false;
252b5132
RH
751 }
752
753 type = parse_coff_type (abfd, &symbols, &types, this_coff_symno,
015dc7e1 754 DECREF (fntype), paux, false, dhandle);
252b5132 755 if (type == DEBUG_TYPE_NULL)
015dc7e1 756 return false;
252b5132
RH
757
758 if (! debug_record_function (dhandle, fnname, type,
05c58a7c 759 external_coff_symbol_p (fnclass),
252b5132 760 bfd_asymbol_value (sym)))
015dc7e1 761 return false;
252b5132
RH
762
763 if (linenos != NULL)
764 {
765 int base;
766 bfd_vma addr;
767
768 if (syment.n_numaux == 0)
769 base = 0;
770 else
771 base = auxent.x_sym.x_misc.x_lnsz.x_lnno - 1;
772
fd361982 773 addr = bfd_section_vma (bfd_asymbol_section (sym));
252b5132
RH
774
775 ++linenos;
776
777 while (linenos->line_number != 0)
778 {
779 if (! debug_record_line (dhandle,
780 linenos->line_number + base,
781 linenos->u.offset + addr))
015dc7e1 782 return false;
252b5132
RH
783 ++linenos;
784 }
785 }
786
787 fnname = NULL;
788 linenos = NULL;
789 fnclass = 0;
790 fntype = 0;
791
015dc7e1 792 within_function = true;
252b5132
RH
793 }
794 else if (strcmp (name, ".ef") == 0)
795 {
796 if (! within_function)
797 {
37cc8ec1 798 non_fatal (_("%ld: unexpected .ef\n"), this_coff_symno);
015dc7e1 799 return false;
252b5132
RH
800 }
801
802 if (bfd_asymbol_value (sym) > fnend)
803 fnend = bfd_asymbol_value (sym);
804 if (! debug_end_function (dhandle, fnend))
015dc7e1 805 return false;
252b5132
RH
806
807 fnend = 0;
015dc7e1 808 within_function = false;
252b5132
RH
809 }
810 break;
811
812 case C_BLOCK:
813 if (strcmp (name, ".bb") == 0)
814 {
815 if (! debug_start_block (dhandle, bfd_asymbol_value (sym)))
015dc7e1 816 return false;
252b5132
RH
817 }
818 else if (strcmp (name, ".eb") == 0)
819 {
820 if (! debug_end_block (dhandle, bfd_asymbol_value (sym)))
015dc7e1 821 return false;
252b5132
RH
822 }
823 break;
824
825 default:
826 type = parse_coff_type (abfd, &symbols, &types, this_coff_symno,
015dc7e1 827 syment.n_type, paux, true, dhandle);
252b5132 828 if (type == DEBUG_TYPE_NULL)
015dc7e1 829 return false;
252b5132
RH
830 if (! parse_coff_symbol (abfd, &types, sym, this_coff_symno, &syment,
831 dhandle, type, within_function))
015dc7e1 832 return false;
252b5132
RH
833 break;
834 }
835 }
836
015dc7e1 837 return true;
252b5132 838}