1 /* stabs.c -- Parse COFF debugging information
2    Copyright (C) 1996-2024 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 3 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 "sysdep.h"
25 #include "bfd.h"
26 #include "coff/internal.h"
27 #include "libiberty.h"
28 #include "bucomm.h"
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 
48 struct 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 
61 /* This structure is used to map symbol indices to types.  */
62 
63 struct coff_types
64 {
65   /* Next set of slots.  */
66   struct coff_types *next;
67   /* Where the TYPES array starts.  */
68   unsigned int base_index;
69   /* Slots.  */
70 #define COFF_SLOTS (16)
71   debug_type types[COFF_SLOTS];
72 };
73 
74 static debug_type parse_coff_base_type
75   (bfd *, struct coff_symbols *, struct coff_types **, long, int,
76    union internal_auxent *, void *);
77 static debug_type parse_coff_struct_type
78   (bfd *, struct coff_symbols *, struct coff_types **, int,
79    union internal_auxent *, void *);
80 static debug_type parse_coff_enum_type
81   (bfd *, struct coff_symbols *, struct coff_types **,
82    union internal_auxent *, void *);
83 
84 /* Return the slot for a type.  */
85 
86 static debug_type *
coff_get_slot(void * dhandle,struct coff_types ** types,long indx)87 coff_get_slot (void *dhandle, struct coff_types **types, long indx)
88 {
89   unsigned int base_index;
90 
91   base_index = indx / COFF_SLOTS * COFF_SLOTS;
92   indx -= base_index;
93 
94   while (*types && (*types)->base_index < base_index)
95     types = &(*types)->next;
96 
97   if (*types == NULL || (*types)->base_index != base_index)
98     {
99       struct coff_types *n = debug_xzalloc (dhandle, sizeof (*n));
100       n->next = *types;
101       n->base_index = base_index;
102       *types = n;
103     }
104 
105   return (*types)->types + indx;
106 }
107 
108 /* Parse a COFF type code in NTYPE.  */
109 
110 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,bool useaux,void * dhandle)111 parse_coff_type (bfd *abfd, struct coff_symbols *symbols,
112                      struct coff_types **types, long coff_symno, int ntype,
113                      union internal_auxent *pauxent, bool useaux,
114                      void *dhandle)
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,
135                                                      false);
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,
161                                           pauxent, false, dhandle);
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),
168                                                   0, n - 1, false);
169           }
170       else
171           {
172             non_fatal (_("parse_coff_type: Bad type code 0x%x"), ntype);
173             return DEBUG_TYPE_NULL;
174           }
175 
176       return type;
177     }
178 
179   if (pauxent != NULL && (int32_t) pauxent->x_sym.x_tagndx.u32 > 0)
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.  */
185       slot = coff_get_slot (dhandle, types, pauxent->x_sym.x_tagndx.u32);
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 
207 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)208 parse_coff_base_type (bfd *abfd, struct coff_symbols *symbols,
209                           struct coff_types **types, long coff_symno, int ntype,
210                           union internal_auxent *pauxent, void *dhandle)
211 {
212   debug_type ret;
213   const char *name = NULL;
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:
228       ret = debug_make_int_type (dhandle, 1, false);
229       name = "char";
230       break;
231 
232     case T_SHORT:
233       ret = debug_make_int_type (dhandle, 2, false);
234       name = "short";
235       break;
236 
237     case T_INT:
238       /* FIXME: Perhaps the size should depend upon the architecture.  */
239       ret = debug_make_int_type (dhandle, 4, false);
240       name = "int";
241       break;
242 
243     case T_LONG:
244       ret = debug_make_int_type (dhandle, 4, false);
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:
264       ret = debug_make_int_type (dhandle, 1, true);
265       name = "unsigned char";
266       break;
267 
268     case T_USHORT:
269       ret = debug_make_int_type (dhandle, 2, true);
270       name = "unsigned short";
271       break;
272 
273     case T_UINT:
274       ret = debug_make_int_type (dhandle, 4, true);
275       name = "unsigned int";
276       break;
277 
278     case T_ULONG:
279       ret = debug_make_int_type (dhandle, 4, true);
280       name = "unsigned long";
281       break;
282 
283     case T_STRUCT:
284       if (pauxent == NULL)
285           ret = debug_make_struct_type (dhandle, true, 0,
286                                               (debug_field *) NULL);
287       else
288           ret = parse_coff_struct_type (abfd, symbols, types, ntype, pauxent,
289                                               dhandle);
290       break;
291 
292     case T_UNION:
293       if (pauxent == NULL)
294           ret = debug_make_struct_type (dhandle, false, 0, (debug_field *) NULL);
295       else
296           ret = parse_coff_struct_type (abfd, symbols, types, ntype, pauxent,
297                                               dhandle);
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);
306       break;
307     }
308 
309   if (name != NULL)
310     ret = debug_name_type (dhandle, name, ret);
311 
312   debug_type *slot = coff_get_slot (dhandle, types, coff_symno);
313   *slot = ret;
314 
315   return ret;
316 }
317 
318 /* Parse a struct type.  */
319 
320 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)321 parse_coff_struct_type (bfd *abfd, struct coff_symbols *symbols,
322                               struct coff_types **types, int ntype,
323                               union internal_auxent *pauxent, void *dhandle)
324 {
325   long symend;
326   int alloc;
327   debug_field *fields, *xfields;
328   int count;
329   bool done;
330 
331   symend = pauxent->x_sym.x_fcnary.x_fcn.x_endndx.u32;
332 
333   alloc = 10;
334   fields = (debug_field *) xmalloc (alloc * sizeof *fields);
335   count = 0;
336 
337   done = false;
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           {
353             non_fatal (_("bfd_coff_get_syment failed: %s"),
354                          bfd_errmsg (bfd_get_error ()));
355             free (fields);
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               {
370                 non_fatal (_("bfd_coff_get_auxent failed: %s"),
371                                bfd_errmsg (bfd_get_error ()));
372                 free (fields);
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);
388             if (psubaux != NULL)
389               bitsize = psubaux->x_sym.x_misc.x_lnsz.x_size;
390             break;
391 
392           case C_EOS:
393             done = true;
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,
403                                            syment.n_type, psubaux, true, dhandle);
404             f = debug_make_field (dhandle, bfd_asymbol_name (sym), ftype,
405                                         bitpos, bitsize, DEBUG_VISIBILITY_PUBLIC);
406             if (f == DEBUG_FIELD_NULL)
407               {
408                 free (fields);
409                 return DEBUG_TYPE_NULL;
410               }
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;
425   xfields = debug_xalloc (dhandle, (count + 1) * sizeof (*fields));
426   memcpy (xfields, fields, (count + 1) * sizeof (*fields));
427   free (fields);
428 
429   return debug_make_struct_type (dhandle, ntype == T_STRUCT,
430                                          pauxent->x_sym.x_misc.x_lnsz.x_size,
431                                          xfields);
432 }
433 
434 /* Parse an enum type.  */
435 
436 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)437 parse_coff_enum_type (bfd *abfd, struct coff_symbols *symbols,
438                           struct coff_types **types ATTRIBUTE_UNUSED,
439                           union internal_auxent *pauxent, void *dhandle)
440 {
441   long symend;
442   int alloc;
443   const char **names, **xnames;
444   bfd_signed_vma *vals, *xvals;
445   int count;
446   bool done;
447 
448   symend = pauxent->x_sym.x_fcnary.x_fcn.x_endndx.u32;
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 
455   done = false;
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           {
467             non_fatal (_("bfd_coff_get_syment failed: %s"),
468                          bfd_errmsg (bfd_get_error ()));
469             free (names);
470             free (vals);
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:
495             done = true;
496             break;
497           }
498     }
499 
500   names[count] = NULL;
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);
510 }
511 
512 /* Handle a single COFF symbol.  */
513 
514 static bool
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,bool within_function)515 parse_coff_symbol (bfd *abfd ATTRIBUTE_UNUSED, struct coff_types **types,
516                        asymbol *sym, long coff_symno,
517                        struct internal_syment *psyment, void *dhandle,
518                        debug_type type, bool within_function)
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)))
528           return false;
529       break;
530 
531     case C_WEAKEXT:
532     case C_EXT:
533       if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
534                                            DEBUG_GLOBAL, bfd_asymbol_value (sym)))
535           return false;
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)))
544           return false;
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)))
551           return false;
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)))
560           return false;
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)))
567           return false;
568       break;
569 
570     case C_TPDEF:
571       type = debug_name_type (dhandle, bfd_asymbol_name (sym), type);
572       if (type == DEBUG_TYPE_NULL)
573           return false;
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)
584             return false;
585 
586           /* Store the named type into the slot, so that references get
587            the name.  */
588           slot = coff_get_slot (dhandle, types, coff_symno);
589           *slot = type;
590       }
591       break;
592 
593     default:
594       break;
595     }
596 
597   return true;
598 }
599 
600 /* Determine if a symbol has external visibility.  */
601 
602 static bool
external_coff_symbol_p(int sym_class)603 external_coff_symbol_p (int sym_class)
604 {
605   switch (sym_class)
606     {
607     case C_EXT:
608     case C_WEAKEXT:
609       return true;
610     default:
611       break;
612     }
613   return false;
614 }
615 
616 /* This is the main routine.  It looks through all the symbols and
617    handles them.  */
618 
619 bool
parse_coff(bfd * abfd,asymbol ** syms,long symcount,void * dhandle)620 parse_coff (bfd *abfd, asymbol **syms, long symcount, void *dhandle)
621 {
622   struct coff_symbols symbols;
623   struct coff_types *types;
624   long next_c_file;
625   const char *fnname;
626   int fnclass;
627   int fntype;
628   bfd_vma fnend;
629   alent *linenos;
630   bool within_function;
631   long this_coff_symno;
632 
633   symbols.syms = syms;
634   symbols.symcount = symcount;
635   symbols.symno = 0;
636   symbols.coff_symno = 0;
637 
638   types= NULL;
639 
640   next_c_file = -1;
641   fnname = NULL;
642   fnclass = 0;
643   fntype = 0;
644   fnend = 0;
645   linenos = NULL;
646   within_function = false;
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           {
661             non_fatal (_("bfd_coff_get_syment failed: %s"),
662                          bfd_errmsg (bfd_get_error ()));
663             return false;
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               {
681                 non_fatal (_("bfd_coff_get_auxent failed: %s"),
682                                bfd_errmsg (bfd_get_error ()));
683                 return false;
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*"))
693               return false;
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))
711               return false;
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.  */
720           case C_WEAKEXT:
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,
735                                           syment.n_type, paux, true, dhandle);
736             if (type == DEBUG_TYPE_NULL)
737               return false;
738             if (! parse_coff_symbol (abfd, &types, sym, this_coff_symno, &syment,
739                                            dhandle, type, within_function))
740               return false;
741             break;
742 
743           case C_FCN:
744             if (strcmp (name, ".bf") == 0)
745               {
746                 if (fnname == NULL)
747                     {
748                       non_fatal (_("%ld: .bf without preceding function"),
749                                    this_coff_symno);
750                       return false;
751                     }
752 
753                 type = parse_coff_type (abfd, &symbols, &types, this_coff_symno,
754                                               DECREF (fntype), paux, false, dhandle);
755                 if (type == DEBUG_TYPE_NULL)
756                     return false;
757 
758                 if (! debug_record_function (dhandle, fnname, type,
759                                                      external_coff_symbol_p (fnclass),
760                                                      bfd_asymbol_value (sym)))
761                     return false;
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 
773                       addr = bfd_section_vma (bfd_asymbol_section (sym));
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))
782                               return false;
783                           ++linenos;
784                         }
785                     }
786 
787                 fnname = NULL;
788                 linenos = NULL;
789                 fnclass = 0;
790                 fntype = 0;
791 
792                 within_function = true;
793               }
794             else if (strcmp (name, ".ef") == 0)
795               {
796                 if (! within_function)
797                     {
798                       non_fatal (_("%ld: unexpected .ef\n"), this_coff_symno);
799                       return false;
800                     }
801 
802                 if (bfd_asymbol_value (sym) > fnend)
803                     fnend = bfd_asymbol_value (sym);
804                 if (! debug_end_function (dhandle, fnend))
805                     return false;
806 
807                 fnend = 0;
808                 within_function = false;
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)))
816                     return false;
817               }
818             else if (strcmp (name, ".eb") == 0)
819               {
820                 if (! debug_end_block (dhandle, bfd_asymbol_value (sym)))
821                     return false;
822               }
823             break;
824 
825           default:
826             type = parse_coff_type (abfd, &symbols, &types, this_coff_symno,
827                                           syment.n_type, paux, true, dhandle);
828             if (type == DEBUG_TYPE_NULL)
829               return false;
830             if (! parse_coff_symbol (abfd, &types, sym, this_coff_symno, &syment,
831                                            dhandle, type, within_function))
832               return false;
833             break;
834           }
835     }
836 
837   return true;
838 }
839