1/* stabs.c -- Parse COFF debugging information
2   Copyright 1996, 1999, 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., 51 Franklin Street - Fifth Floor, Boston, MA
20   02110-1301, 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 (struct coff_types *, int);
86static debug_type parse_coff_type
87  (bfd *, struct coff_symbols *, struct coff_types *, long, int,
88   union internal_auxent *, bfd_boolean, void *);
89static debug_type parse_coff_base_type
90  (bfd *, struct coff_symbols *, struct coff_types *, long, int,
91   union internal_auxent *, void *);
92static debug_type parse_coff_struct_type
93  (bfd *, struct coff_symbols *, struct coff_types *, int,
94   union internal_auxent *, void *);
95static debug_type parse_coff_enum_type
96  (bfd *, struct coff_symbols *, struct coff_types *,
97   union internal_auxent *, void *);
98static bfd_boolean parse_coff_symbol
99  (bfd *, struct coff_types *, asymbol *, long, struct internal_syment *,
100   void *, debug_type, bfd_boolean);
101static bfd_boolean external_coff_symbol_p (int sym_class);
102
103/* Return the slot for a type.  */
104
105static debug_type *
106coff_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
134static debug_type
135parse_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
231static debug_type
232parse_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
371static debug_type
372parse_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
478static debug_type
479parse_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
547static bfd_boolean
548parse_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
635static bfd_boolean
636external_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
652bfd_boolean
653parse_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