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