Back to index

cell-binutils  2.17cvs20070401
rdcoff.c
Go to the documentation of this file.
00001 /* stabs.c -- Parse COFF debugging information
00002    Copyright 1996, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
00003    Written by Ian Lance Taylor <ian@cygnus.com>.
00004 
00005    This file is part of GNU Binutils.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
00020    02110-1301, USA.  */
00021 
00022 /* This file contains code which parses COFF debugging information.  */
00023 
00024 #include "bfd.h"
00025 #include "coff/internal.h"
00026 #include "bucomm.h"
00027 #include "libiberty.h"
00028 #include "debug.h"
00029 #include "budbg.h"
00030 
00031 /* FIXME: We should not need this BFD internal file.  We need it for
00032    the N_BTMASK, etc., values.  */
00033 #include "libcoff.h"
00034 
00035 /* These macros extract the right mask and shifts for this BFD.  They
00036    assume that there is a local variable named ABFD.  This is so that
00037    macros like ISFCN and DECREF, from coff/internal.h, will work
00038    without modification.  */
00039 #define N_BTMASK (coff_data (abfd)->local_n_btmask)
00040 #define       N_BTSHFT (coff_data (abfd)->local_n_btshft)
00041 #define       N_TMASK  (coff_data (abfd)->local_n_tmask)
00042 #define       N_TSHIFT (coff_data (abfd)->local_n_tshift)
00043 
00044 /* This structure is used to hold the symbols, as well as the current
00045    location within the symbols.  */
00046 
00047 struct coff_symbols
00048 {
00049   /* The symbols.  */
00050   asymbol **syms;
00051   /* The number of symbols.  */
00052   long symcount;
00053   /* The index of the current symbol.  */
00054   long symno;
00055   /* The index of the current symbol in the COFF symbol table (where
00056      each auxent counts as a symbol).  */
00057   long coff_symno;
00058 };
00059 
00060 /* The largest basic type we are prepared to handle.  */
00061 
00062 #define T_MAX (T_LNGDBL)
00063 
00064 /* This structure is used to hold slots.  */
00065 
00066 struct coff_slots
00067 {
00068   /* Next set of slots.  */
00069   struct coff_slots *next;
00070   /* Slots.  */
00071 #define COFF_SLOTS (16)
00072   debug_type slots[COFF_SLOTS];
00073 };
00074 
00075 /* This structure is used to map symbol indices to types.  */
00076 
00077 struct coff_types
00078 {
00079   /* Slots.  */
00080   struct coff_slots *slots;
00081   /* Basic types.  */
00082   debug_type basic[T_MAX + 1];
00083 };
00084 
00085 static debug_type *coff_get_slot (struct coff_types *, int);
00086 static debug_type parse_coff_type
00087   (bfd *, struct coff_symbols *, struct coff_types *, long, int,
00088    union internal_auxent *, bfd_boolean, void *);
00089 static debug_type parse_coff_base_type
00090   (bfd *, struct coff_symbols *, struct coff_types *, long, int,
00091    union internal_auxent *, void *);
00092 static debug_type parse_coff_struct_type
00093   (bfd *, struct coff_symbols *, struct coff_types *, int,
00094    union internal_auxent *, void *);
00095 static debug_type parse_coff_enum_type
00096   (bfd *, struct coff_symbols *, struct coff_types *,
00097    union internal_auxent *, void *);
00098 static bfd_boolean parse_coff_symbol
00099   (bfd *, struct coff_types *, asymbol *, long, struct internal_syment *,
00100    void *, debug_type, bfd_boolean);
00101 static bfd_boolean external_coff_symbol_p (int sym_class);
00102 
00103 /* Return the slot for a type.  */
00104 
00105 static debug_type *
00106 coff_get_slot (struct coff_types *types, int indx)
00107 {
00108   struct coff_slots **pps;
00109 
00110   pps = &types->slots;
00111 
00112   while (indx >= COFF_SLOTS)
00113     {
00114       if (*pps == NULL)
00115        {
00116          *pps = (struct coff_slots *) xmalloc (sizeof **pps);
00117          memset (*pps, 0, sizeof **pps);
00118        }
00119       pps = &(*pps)->next;
00120       indx -= COFF_SLOTS;
00121     }
00122 
00123   if (*pps == NULL)
00124     {
00125       *pps = (struct coff_slots *) xmalloc (sizeof **pps);
00126       memset (*pps, 0, sizeof **pps);
00127     }
00128 
00129   return (*pps)->slots + indx;
00130 }
00131 
00132 /* Parse a COFF type code in NTYPE.  */
00133 
00134 static debug_type
00135 parse_coff_type (bfd *abfd, struct coff_symbols *symbols,
00136                struct coff_types *types, long coff_symno, int ntype,
00137                union internal_auxent *pauxent, bfd_boolean useaux,
00138                void *dhandle)
00139 {
00140   debug_type type;
00141 
00142   if ((ntype & ~N_BTMASK) != 0)
00143     {
00144       int newtype;
00145 
00146       newtype = DECREF (ntype);
00147 
00148       if (ISPTR (ntype))
00149        {
00150          type = parse_coff_type (abfd, symbols, types, coff_symno, newtype,
00151                               pauxent, useaux, dhandle);
00152          type = debug_make_pointer_type (dhandle, type);
00153        }
00154       else if (ISFCN (ntype))
00155        {
00156          type = parse_coff_type (abfd, symbols, types, coff_symno, newtype,
00157                               pauxent, useaux, dhandle);
00158          type = debug_make_function_type (dhandle, type, (debug_type *) NULL,
00159                                       FALSE);
00160        }
00161       else if (ISARY (ntype))
00162        {
00163          int n;
00164 
00165          if (pauxent == NULL)
00166            n = 0;
00167          else
00168            {
00169              unsigned short *dim;
00170              int i;
00171 
00172              /* FIXME: If pauxent->x_sym.x_tagndx.l == 0, gdb sets
00173                  the c_naux field of the syment to 0.  */
00174 
00175              /* Move the dimensions down, so that the next array
00176                  picks up the next one.  */
00177              dim = pauxent->x_sym.x_fcnary.x_ary.x_dimen;
00178              n = dim[0];
00179              for (i = 0; *dim != 0 && i < DIMNUM - 1; i++, dim++)
00180               *dim = *(dim + 1);
00181              *dim = 0;
00182            }
00183 
00184          type = parse_coff_type (abfd, symbols, types, coff_symno, newtype,
00185                               pauxent, FALSE, dhandle);
00186          type = debug_make_array_type (dhandle, type,
00187                                    parse_coff_base_type (abfd, symbols,
00188                                                        types,
00189                                                        coff_symno,
00190                                                        T_INT,
00191                                                        NULL, dhandle),
00192                                    0, n - 1, FALSE);
00193        }
00194       else
00195        {
00196          non_fatal (_("parse_coff_type: Bad type code 0x%x"), ntype);
00197          return DEBUG_TYPE_NULL;
00198        }
00199 
00200       return type;
00201     }
00202 
00203   if (pauxent != NULL && pauxent->x_sym.x_tagndx.l > 0)
00204     {
00205       debug_type *slot;
00206 
00207       /* This is a reference to an existing type.  FIXME: gdb checks
00208         that the class is not C_STRTAG, nor C_UNTAG, nor C_ENTAG.  */
00209       slot = coff_get_slot (types, pauxent->x_sym.x_tagndx.l);
00210       if (*slot != DEBUG_TYPE_NULL)
00211        return *slot;
00212       else
00213        return debug_make_indirect_type (dhandle, slot, (const char *) NULL);
00214     }
00215 
00216   /* If the aux entry has already been used for something, useaux will
00217      have been set to false, indicating that parse_coff_base_type
00218      should not use it.  We need to do it this way, rather than simply
00219      passing pauxent as NULL, because we need to be able handle
00220      multiple array dimensions while still discarding pauxent after
00221      having handled all of them.  */
00222   if (! useaux)
00223     pauxent = NULL;
00224 
00225   return parse_coff_base_type (abfd, symbols, types, coff_symno, ntype,
00226                             pauxent, dhandle);
00227 }
00228 
00229 /* Parse a basic COFF type in NTYPE.  */
00230 
00231 static debug_type
00232 parse_coff_base_type (bfd *abfd, struct coff_symbols *symbols,
00233                     struct coff_types *types, long coff_symno, int ntype,
00234                     union internal_auxent *pauxent, void *dhandle)
00235 {
00236   debug_type ret;
00237   bfd_boolean set_basic;
00238   const char *name;
00239   debug_type *slot;
00240 
00241   if (ntype >= 0
00242       && ntype <= T_MAX
00243       && types->basic[ntype] != DEBUG_TYPE_NULL)
00244     return types->basic[ntype];
00245 
00246   set_basic = TRUE;
00247   name = NULL;
00248 
00249   switch (ntype)
00250     {
00251     default:
00252       ret = debug_make_void_type (dhandle);
00253       break;
00254 
00255     case T_NULL:
00256     case T_VOID:
00257       ret = debug_make_void_type (dhandle);
00258       name = "void";
00259       break;
00260 
00261     case T_CHAR:
00262       ret = debug_make_int_type (dhandle, 1, FALSE);
00263       name = "char";
00264       break;
00265 
00266     case T_SHORT:
00267       ret = debug_make_int_type (dhandle, 2, FALSE);
00268       name = "short";
00269       break;
00270 
00271     case T_INT:
00272       /* FIXME: Perhaps the size should depend upon the architecture.  */
00273       ret = debug_make_int_type (dhandle, 4, FALSE);
00274       name = "int";
00275       break;
00276 
00277     case T_LONG:
00278       ret = debug_make_int_type (dhandle, 4, FALSE);
00279       name = "long";
00280       break;
00281 
00282     case T_FLOAT:
00283       ret = debug_make_float_type (dhandle, 4);
00284       name = "float";
00285       break;
00286 
00287     case T_DOUBLE:
00288       ret = debug_make_float_type (dhandle, 8);
00289       name = "double";
00290       break;
00291 
00292     case T_LNGDBL:
00293       ret = debug_make_float_type (dhandle, 12);
00294       name = "long double";
00295       break;
00296 
00297     case T_UCHAR:
00298       ret = debug_make_int_type (dhandle, 1, TRUE);
00299       name = "unsigned char";
00300       break;
00301 
00302     case T_USHORT:
00303       ret = debug_make_int_type (dhandle, 2, TRUE);
00304       name = "unsigned short";
00305       break;
00306 
00307     case T_UINT:
00308       ret = debug_make_int_type (dhandle, 4, TRUE);
00309       name = "unsigned int";
00310       break;
00311 
00312     case T_ULONG:
00313       ret = debug_make_int_type (dhandle, 4, TRUE);
00314       name = "unsigned long";
00315       break;
00316 
00317     case T_STRUCT:
00318       if (pauxent == NULL)
00319        ret = debug_make_struct_type (dhandle, TRUE, 0,
00320                                   (debug_field *) NULL);
00321       else
00322        ret = parse_coff_struct_type (abfd, symbols, types, ntype, pauxent,
00323                                   dhandle);
00324 
00325       slot = coff_get_slot (types, coff_symno);
00326       *slot = ret;
00327 
00328       set_basic = FALSE;
00329       break;
00330 
00331     case T_UNION:
00332       if (pauxent == NULL)
00333        ret = debug_make_struct_type (dhandle, FALSE, 0, (debug_field *) NULL);
00334       else
00335        ret = parse_coff_struct_type (abfd, symbols, types, ntype, pauxent,
00336                                   dhandle);
00337 
00338       slot = coff_get_slot (types, coff_symno);
00339       *slot = ret;
00340 
00341       set_basic = FALSE;
00342       break;
00343 
00344     case T_ENUM:
00345       if (pauxent == NULL)
00346        ret = debug_make_enum_type (dhandle, (const char **) NULL,
00347                                 (bfd_signed_vma *) NULL);
00348       else
00349        ret = parse_coff_enum_type (abfd, symbols, types, pauxent, dhandle);
00350 
00351       slot = coff_get_slot (types, coff_symno);
00352       *slot = ret;
00353 
00354       set_basic = FALSE;
00355       break;
00356     }
00357 
00358   if (name != NULL)
00359     ret = debug_name_type (dhandle, name, ret);
00360 
00361   if (set_basic
00362       && ntype >= 0
00363       && ntype <= T_MAX)
00364     types->basic[ntype] = ret;
00365 
00366   return ret;
00367 }
00368 
00369 /* Parse a struct type.  */
00370 
00371 static debug_type
00372 parse_coff_struct_type (bfd *abfd, struct coff_symbols *symbols,
00373                      struct coff_types *types, int ntype,
00374                      union internal_auxent *pauxent, void *dhandle)
00375 {
00376   long symend;
00377   int alloc;
00378   debug_field *fields;
00379   int count;
00380   bfd_boolean done;
00381 
00382   symend = pauxent->x_sym.x_fcnary.x_fcn.x_endndx.l;
00383 
00384   alloc = 10;
00385   fields = (debug_field *) xmalloc (alloc * sizeof *fields);
00386   count = 0;
00387 
00388   done = FALSE;
00389   while (! done
00390         && symbols->coff_symno < symend
00391         && symbols->symno < symbols->symcount)
00392     {
00393       asymbol *sym;
00394       long this_coff_symno;
00395       struct internal_syment syment;
00396       union internal_auxent auxent;
00397       union internal_auxent *psubaux;
00398       bfd_vma bitpos = 0, bitsize = 0;
00399 
00400       sym = symbols->syms[symbols->symno];
00401 
00402       if (! bfd_coff_get_syment (abfd, sym, &syment))
00403        {
00404          non_fatal (_("bfd_coff_get_syment failed: %s"),
00405                    bfd_errmsg (bfd_get_error ()));
00406          return DEBUG_TYPE_NULL;
00407        }
00408 
00409       this_coff_symno = symbols->coff_symno;
00410 
00411       ++symbols->symno;
00412       symbols->coff_symno += 1 + syment.n_numaux;
00413 
00414       if (syment.n_numaux == 0)
00415        psubaux = NULL;
00416       else
00417        {
00418          if (! bfd_coff_get_auxent (abfd, sym, 0, &auxent))
00419            {
00420              non_fatal (_("bfd_coff_get_auxent failed: %s"),
00421                       bfd_errmsg (bfd_get_error ()));
00422              return DEBUG_TYPE_NULL;
00423            }
00424          psubaux = &auxent;
00425        }
00426 
00427       switch (syment.n_sclass)
00428        {
00429        case C_MOS:
00430        case C_MOU:
00431          bitpos = 8 * bfd_asymbol_value (sym);
00432          bitsize = 0;
00433          break;
00434 
00435        case C_FIELD:
00436          bitpos = bfd_asymbol_value (sym);
00437          bitsize = auxent.x_sym.x_misc.x_lnsz.x_size;
00438          break;
00439 
00440        case C_EOS:
00441          done = TRUE;
00442          break;
00443        }
00444 
00445       if (! done)
00446        {
00447          debug_type ftype;
00448          debug_field f;
00449 
00450          ftype = parse_coff_type (abfd, symbols, types, this_coff_symno,
00451                                syment.n_type, psubaux, TRUE, dhandle);
00452          f = debug_make_field (dhandle, bfd_asymbol_name (sym), ftype,
00453                             bitpos, bitsize, DEBUG_VISIBILITY_PUBLIC);
00454          if (f == DEBUG_FIELD_NULL)
00455            return DEBUG_TYPE_NULL;
00456 
00457          if (count + 1 >= alloc)
00458            {
00459              alloc += 10;
00460              fields = ((debug_field *)
00461                      xrealloc (fields, alloc * sizeof *fields));
00462            }
00463 
00464          fields[count] = f;
00465          ++count;
00466        }
00467     }
00468 
00469   fields[count] = DEBUG_FIELD_NULL;
00470 
00471   return debug_make_struct_type (dhandle, ntype == T_STRUCT,
00472                              pauxent->x_sym.x_misc.x_lnsz.x_size,
00473                              fields);
00474 }
00475 
00476 /* Parse an enum type.  */
00477 
00478 static debug_type
00479 parse_coff_enum_type (bfd *abfd, struct coff_symbols *symbols,
00480                     struct coff_types *types ATTRIBUTE_UNUSED,
00481                     union internal_auxent *pauxent, void *dhandle)
00482 {
00483   long symend;
00484   int alloc;
00485   const char **names;
00486   bfd_signed_vma *vals;
00487   int count;
00488   bfd_boolean done;
00489 
00490   symend = pauxent->x_sym.x_fcnary.x_fcn.x_endndx.l;
00491 
00492   alloc = 10;
00493   names = (const char **) xmalloc (alloc * sizeof *names);
00494   vals = (bfd_signed_vma *) xmalloc (alloc * sizeof *vals);
00495   count = 0;
00496 
00497   done = FALSE;
00498   while (! done
00499         && symbols->coff_symno < symend
00500         && symbols->symno < symbols->symcount)
00501     {
00502       asymbol *sym;
00503       struct internal_syment syment;
00504 
00505       sym = symbols->syms[symbols->symno];
00506 
00507       if (! bfd_coff_get_syment (abfd, sym, &syment))
00508        {
00509          non_fatal (_("bfd_coff_get_syment failed: %s"),
00510                    bfd_errmsg (bfd_get_error ()));
00511          return DEBUG_TYPE_NULL;
00512        }
00513 
00514       ++symbols->symno;
00515       symbols->coff_symno += 1 + syment.n_numaux;
00516 
00517       switch (syment.n_sclass)
00518        {
00519        case C_MOE:
00520          if (count + 1 >= alloc)
00521            {
00522              alloc += 10;
00523              names = ((const char **)
00524                      xrealloc (names, alloc * sizeof *names));
00525              vals = ((bfd_signed_vma *)
00526                     xrealloc (vals, alloc * sizeof *vals));
00527            }
00528 
00529          names[count] = bfd_asymbol_name (sym);
00530          vals[count] = bfd_asymbol_value (sym);
00531          ++count;
00532          break;
00533 
00534        case C_EOS:
00535          done = TRUE;
00536          break;
00537        }
00538     }
00539 
00540   names[count] = NULL;
00541 
00542   return debug_make_enum_type (dhandle, names, vals);
00543 }
00544 
00545 /* Handle a single COFF symbol.  */
00546 
00547 static bfd_boolean
00548 parse_coff_symbol (bfd *abfd ATTRIBUTE_UNUSED, struct coff_types *types,
00549                  asymbol *sym, long coff_symno,
00550                  struct internal_syment *psyment, void *dhandle,
00551                  debug_type type, bfd_boolean within_function)
00552 {
00553   switch (psyment->n_sclass)
00554     {
00555     case C_NULL:
00556       break;
00557 
00558     case C_AUTO:
00559       if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
00560                                DEBUG_LOCAL, bfd_asymbol_value (sym)))
00561        return FALSE;
00562       break;
00563 
00564     case C_WEAKEXT:
00565     case C_EXT:
00566       if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
00567                                DEBUG_GLOBAL, bfd_asymbol_value (sym)))
00568        return FALSE;
00569       break;
00570 
00571     case C_STAT:
00572       if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
00573                                (within_function
00574                                 ? DEBUG_LOCAL_STATIC
00575                                 : DEBUG_STATIC),
00576                                bfd_asymbol_value (sym)))
00577        return FALSE;
00578       break;
00579 
00580     case C_REG:
00581       /* FIXME: We may need to convert the register number.  */
00582       if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
00583                                DEBUG_REGISTER, bfd_asymbol_value (sym)))
00584        return FALSE;
00585       break;
00586 
00587     case C_LABEL:
00588       break;
00589 
00590     case C_ARG:
00591       if (! debug_record_parameter (dhandle, bfd_asymbol_name (sym), type,
00592                                 DEBUG_PARM_STACK, bfd_asymbol_value (sym)))
00593        return FALSE;
00594       break;
00595 
00596     case C_REGPARM:
00597       /* FIXME: We may need to convert the register number.  */
00598       if (! debug_record_parameter (dhandle, bfd_asymbol_name (sym), type,
00599                                 DEBUG_PARM_REG, bfd_asymbol_value (sym)))
00600        return FALSE;
00601       break;
00602 
00603     case C_TPDEF:
00604       type = debug_name_type (dhandle, bfd_asymbol_name (sym), type);
00605       if (type == DEBUG_TYPE_NULL)
00606        return FALSE;
00607       break;
00608 
00609     case C_STRTAG:
00610     case C_UNTAG:
00611     case C_ENTAG:
00612       {
00613        debug_type *slot;
00614 
00615        type = debug_tag_type (dhandle, bfd_asymbol_name (sym), type);
00616        if (type == DEBUG_TYPE_NULL)
00617          return FALSE;
00618 
00619        /* Store the named type into the slot, so that references get
00620            the name.  */
00621        slot = coff_get_slot (types, coff_symno);
00622        *slot = type;
00623       }
00624       break;
00625 
00626     default:
00627       break;
00628     }
00629 
00630   return TRUE;
00631 }
00632 
00633 /* Determine if a symbol has external visibility.  */
00634 
00635 static bfd_boolean
00636 external_coff_symbol_p (int sym_class)
00637 {
00638   switch (sym_class)
00639     {
00640     case C_EXT:
00641     case C_WEAKEXT:
00642       return TRUE;
00643     default:
00644       break;
00645     }
00646   return FALSE;
00647 }
00648 
00649 /* This is the main routine.  It looks through all the symbols and
00650    handles them.  */
00651 
00652 bfd_boolean
00653 parse_coff (bfd *abfd, asymbol **syms, long symcount, void *dhandle)
00654 {
00655   struct coff_symbols symbols;
00656   struct coff_types types;
00657   int i;
00658   long next_c_file;
00659   const char *fnname;
00660   int fnclass;
00661   int fntype;
00662   bfd_vma fnend;
00663   alent *linenos;
00664   bfd_boolean within_function;
00665   long this_coff_symno;
00666 
00667   symbols.syms = syms;
00668   symbols.symcount = symcount;
00669   symbols.symno = 0;
00670   symbols.coff_symno = 0;
00671 
00672   types.slots = NULL;
00673   for (i = 0; i <= T_MAX; i++)
00674     types.basic[i] = DEBUG_TYPE_NULL;
00675 
00676   next_c_file = -1;
00677   fnname = NULL;
00678   fnclass = 0;
00679   fntype = 0;
00680   fnend = 0;
00681   linenos = NULL;
00682   within_function = FALSE;
00683 
00684   while (symbols.symno < symcount)
00685     {
00686       asymbol *sym;
00687       const char *name;
00688       struct internal_syment syment;
00689       union internal_auxent auxent;
00690       union internal_auxent *paux;
00691       debug_type type;
00692 
00693       sym = syms[symbols.symno];
00694 
00695       if (! bfd_coff_get_syment (abfd, sym, &syment))
00696        {
00697          non_fatal (_("bfd_coff_get_syment failed: %s"),
00698                    bfd_errmsg (bfd_get_error ()));
00699          return FALSE;
00700        }
00701 
00702       name = bfd_asymbol_name (sym);
00703 
00704       this_coff_symno = symbols.coff_symno;
00705 
00706       ++symbols.symno;
00707       symbols.coff_symno += 1 + syment.n_numaux;
00708 
00709       /* We only worry about the first auxent, because that is the
00710         only one which is relevant for debugging information.  */
00711       if (syment.n_numaux == 0)
00712        paux = NULL;
00713       else
00714        {
00715          if (! bfd_coff_get_auxent (abfd, sym, 0, &auxent))
00716            {
00717              non_fatal (_("bfd_coff_get_auxent failed: %s"),
00718                       bfd_errmsg (bfd_get_error ()));
00719              return FALSE;
00720            }
00721          paux = &auxent;
00722        }
00723 
00724       if (this_coff_symno == next_c_file && syment.n_sclass != C_FILE)
00725        {
00726          /* The last C_FILE symbol points to the first external
00727              symbol.  */
00728          if (! debug_set_filename (dhandle, "*globals*"))
00729            return FALSE;
00730        }
00731 
00732       switch (syment.n_sclass)
00733        {
00734        case C_EFCN:
00735        case C_EXTDEF:
00736        case C_ULABEL:
00737        case C_USTATIC:
00738        case C_LINE:
00739        case C_ALIAS:
00740        case C_HIDDEN:
00741          /* Just ignore these classes.  */
00742          break;
00743 
00744        case C_FILE:
00745          next_c_file = syment.n_value;
00746          if (! debug_set_filename (dhandle, name))
00747            return FALSE;
00748          break;
00749 
00750        case C_STAT:
00751          /* Ignore static symbols with a type of T_NULL.  These
00752              represent section entries.  */
00753          if (syment.n_type == T_NULL)
00754            break;
00755          /* Fall through.  */
00756        case C_WEAKEXT:
00757        case C_EXT:
00758          if (ISFCN (syment.n_type))
00759            {
00760              fnname = name;
00761              fnclass = syment.n_sclass;
00762              fntype = syment.n_type;
00763              if (syment.n_numaux > 0)
00764               fnend = bfd_asymbol_value (sym) + auxent.x_sym.x_misc.x_fsize;
00765              else
00766               fnend = 0;
00767              linenos = BFD_SEND (abfd, _get_lineno, (abfd, sym));
00768              break;
00769            }
00770          type = parse_coff_type (abfd, &symbols, &types, this_coff_symno,
00771                               syment.n_type, paux, TRUE, dhandle);
00772          if (type == DEBUG_TYPE_NULL)
00773            return FALSE;
00774          if (! parse_coff_symbol (abfd, &types, sym, this_coff_symno, &syment,
00775                                dhandle, type, within_function))
00776            return FALSE;
00777          break;
00778 
00779        case C_FCN:
00780          if (strcmp (name, ".bf") == 0)
00781            {
00782              if (fnname == NULL)
00783               {
00784                 non_fatal (_("%ld: .bf without preceding function"),
00785                           this_coff_symno);
00786                 return FALSE;
00787               }
00788 
00789              type = parse_coff_type (abfd, &symbols, &types, this_coff_symno,
00790                                   DECREF (fntype), paux, FALSE, dhandle);
00791              if (type == DEBUG_TYPE_NULL)
00792               return FALSE;
00793 
00794              if (! debug_record_function (dhandle, fnname, type,
00795                                       external_coff_symbol_p (fnclass),
00796                                       bfd_asymbol_value (sym)))
00797               return FALSE;
00798 
00799              if (linenos != NULL)
00800               {
00801                 int base;
00802                 bfd_vma addr;
00803 
00804                 if (syment.n_numaux == 0)
00805                   base = 0;
00806                 else
00807                   base = auxent.x_sym.x_misc.x_lnsz.x_lnno - 1;
00808 
00809                 addr = bfd_get_section_vma (abfd, bfd_get_section (sym));
00810 
00811                 ++linenos;
00812 
00813                 while (linenos->line_number != 0)
00814                   {
00815                     if (! debug_record_line (dhandle,
00816                                           linenos->line_number + base,
00817                                           linenos->u.offset + addr))
00818                      return FALSE;
00819                     ++linenos;
00820                   }
00821               }
00822 
00823              fnname = NULL;
00824              linenos = NULL;
00825              fnclass = 0;
00826              fntype = 0;
00827 
00828              within_function = TRUE;
00829            }
00830          else if (strcmp (name, ".ef") == 0)
00831            {
00832              if (! within_function)
00833               {
00834                 non_fatal (_("%ld: unexpected .ef\n"), this_coff_symno);
00835                 return FALSE;
00836               }
00837 
00838              if (bfd_asymbol_value (sym) > fnend)
00839               fnend = bfd_asymbol_value (sym);
00840              if (! debug_end_function (dhandle, fnend))
00841               return FALSE;
00842 
00843              fnend = 0;
00844              within_function = FALSE;
00845            }
00846          break;
00847 
00848        case C_BLOCK:
00849          if (strcmp (name, ".bb") == 0)
00850            {
00851              if (! debug_start_block (dhandle, bfd_asymbol_value (sym)))
00852               return FALSE;
00853            }
00854          else if (strcmp (name, ".eb") == 0)
00855            {
00856              if (! debug_end_block (dhandle, bfd_asymbol_value (sym)))
00857               return FALSE;
00858            }
00859          break;
00860 
00861        default:
00862          type = parse_coff_type (abfd, &symbols, &types, this_coff_symno,
00863                               syment.n_type, paux, TRUE, dhandle);
00864          if (type == DEBUG_TYPE_NULL)
00865            return FALSE;
00866          if (! parse_coff_symbol (abfd, &types, sym, this_coff_symno, &syment,
00867                                dhandle, type, within_function))
00868            return FALSE;
00869          break;
00870        }
00871     }
00872 
00873   return TRUE;
00874 }