source: trunk/src/binutils/binutils/rdcoff.c@ 610

Last change on this file since 610 was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

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