123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881 |
- /* stabs.c -- Parse COFF debugging information
- Copyright (C) 1996-2015 Free Software Foundation, Inc.
- Written by Ian Lance Taylor <ian@cygnus.com>.
- This file is part of GNU Binutils.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
- 02110-1301, USA. */
- /* This file contains code which parses COFF debugging information. */
- #include "sysdep.h"
- #include "bfd.h"
- #include "coff/internal.h"
- #include "libiberty.h"
- #include "bucomm.h"
- #include "debug.h"
- #include "budbg.h"
- /* FIXME: We should not need this BFD internal file. We need it for
- the N_BTMASK, etc., values. */
- #include "libcoff.h"
- /* These macros extract the right mask and shifts for this BFD. They
- assume that there is a local variable named ABFD. This is so that
- macros like ISFCN and DECREF, from coff/internal.h, will work
- without modification. */
- #define N_BTMASK (coff_data (abfd)->local_n_btmask)
- #define N_BTSHFT (coff_data (abfd)->local_n_btshft)
- #define N_TMASK (coff_data (abfd)->local_n_tmask)
- #define N_TSHIFT (coff_data (abfd)->local_n_tshift)
- /* This structure is used to hold the symbols, as well as the current
- location within the symbols. */
- struct coff_symbols
- {
- /* The symbols. */
- asymbol **syms;
- /* The number of symbols. */
- long symcount;
- /* The index of the current symbol. */
- long symno;
- /* The index of the current symbol in the COFF symbol table (where
- each auxent counts as a symbol). */
- long coff_symno;
- };
- /* The largest basic type we are prepared to handle. */
- #define T_MAX (T_LNGDBL)
- /* This structure is used to hold slots. */
- struct coff_slots
- {
- /* Next set of slots. */
- struct coff_slots *next;
- /* Slots. */
- #define COFF_SLOTS (16)
- debug_type slots[COFF_SLOTS];
- };
- /* This structure is used to map symbol indices to types. */
- struct coff_types
- {
- /* Slots. */
- struct coff_slots *slots;
- /* Basic types. */
- debug_type basic[T_MAX + 1];
- };
- static debug_type *coff_get_slot (struct coff_types *, long);
- static debug_type parse_coff_type
- (bfd *, struct coff_symbols *, struct coff_types *, long, int,
- union internal_auxent *, bfd_boolean, void *);
- static debug_type parse_coff_base_type
- (bfd *, struct coff_symbols *, struct coff_types *, long, int,
- union internal_auxent *, void *);
- static debug_type parse_coff_struct_type
- (bfd *, struct coff_symbols *, struct coff_types *, int,
- union internal_auxent *, void *);
- static debug_type parse_coff_enum_type
- (bfd *, struct coff_symbols *, struct coff_types *,
- union internal_auxent *, void *);
- static bfd_boolean parse_coff_symbol
- (bfd *, struct coff_types *, asymbol *, long, struct internal_syment *,
- void *, debug_type, bfd_boolean);
- static bfd_boolean external_coff_symbol_p (int sym_class);
- /* Return the slot for a type. */
- static debug_type *
- coff_get_slot (struct coff_types *types, long indx)
- {
- struct coff_slots **pps;
- pps = &types->slots;
- /* PR 17512: file: 078-18333-0.001:0.1.
- FIXME: The value of 1000 is a guess. Maybe a better heuristic is needed. */
- if (indx / COFF_SLOTS > 1000)
- fatal (_("Excessively large slot index: %lx"), indx);
- while (indx >= COFF_SLOTS)
- {
- if (*pps == NULL)
- {
- *pps = (struct coff_slots *) xmalloc (sizeof **pps);
- memset (*pps, 0, sizeof **pps);
- }
- pps = &(*pps)->next;
- indx -= COFF_SLOTS;
- }
- if (*pps == NULL)
- {
- *pps = (struct coff_slots *) xmalloc (sizeof **pps);
- memset (*pps, 0, sizeof **pps);
- }
- return (*pps)->slots + indx;
- }
- /* Parse a COFF type code in NTYPE. */
- 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)
- {
- debug_type type;
- if ((ntype & ~N_BTMASK) != 0)
- {
- int newtype;
- newtype = DECREF (ntype);
- if (ISPTR (ntype))
- {
- type = parse_coff_type (abfd, symbols, types, coff_symno, newtype,
- pauxent, useaux, dhandle);
- type = debug_make_pointer_type (dhandle, type);
- }
- else if (ISFCN (ntype))
- {
- type = parse_coff_type (abfd, symbols, types, coff_symno, newtype,
- pauxent, useaux, dhandle);
- type = debug_make_function_type (dhandle, type, (debug_type *) NULL,
- FALSE);
- }
- else if (ISARY (ntype))
- {
- int n;
- if (pauxent == NULL)
- n = 0;
- else
- {
- unsigned short *dim;
- int i;
- /* FIXME: If pauxent->x_sym.x_tagndx.l == 0, gdb sets
- the c_naux field of the syment to 0. */
- /* Move the dimensions down, so that the next array
- picks up the next one. */
- dim = pauxent->x_sym.x_fcnary.x_ary.x_dimen;
- n = dim[0];
- for (i = 0; *dim != 0 && i < DIMNUM - 1; i++, dim++)
- *dim = *(dim + 1);
- *dim = 0;
- }
- type = parse_coff_type (abfd, symbols, types, coff_symno, newtype,
- pauxent, FALSE, dhandle);
- type = debug_make_array_type (dhandle, type,
- parse_coff_base_type (abfd, symbols,
- types,
- coff_symno,
- T_INT,
- NULL, dhandle),
- 0, n - 1, FALSE);
- }
- else
- {
- non_fatal (_("parse_coff_type: Bad type code 0x%x"), ntype);
- return DEBUG_TYPE_NULL;
- }
- return type;
- }
- if (pauxent != NULL && pauxent->x_sym.x_tagndx.l > 0)
- {
- debug_type *slot;
- /* This is a reference to an existing type. FIXME: gdb checks
- that the class is not C_STRTAG, nor C_UNTAG, nor C_ENTAG. */
- slot = coff_get_slot (types, pauxent->x_sym.x_tagndx.l);
- if (*slot != DEBUG_TYPE_NULL)
- return *slot;
- else
- return debug_make_indirect_type (dhandle, slot, (const char *) NULL);
- }
- /* If the aux entry has already been used for something, useaux will
- have been set to false, indicating that parse_coff_base_type
- should not use it. We need to do it this way, rather than simply
- passing pauxent as NULL, because we need to be able handle
- multiple array dimensions while still discarding pauxent after
- having handled all of them. */
- if (! useaux)
- pauxent = NULL;
- return parse_coff_base_type (abfd, symbols, types, coff_symno, ntype,
- pauxent, dhandle);
- }
- /* Parse a basic COFF type in NTYPE. */
- 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)
- {
- debug_type ret;
- bfd_boolean set_basic;
- const char *name;
- debug_type *slot;
- if (ntype >= 0
- && ntype <= T_MAX
- && types->basic[ntype] != DEBUG_TYPE_NULL)
- return types->basic[ntype];
- set_basic = TRUE;
- name = NULL;
- switch (ntype)
- {
- default:
- ret = debug_make_void_type (dhandle);
- break;
- case T_NULL:
- case T_VOID:
- ret = debug_make_void_type (dhandle);
- name = "void";
- break;
- case T_CHAR:
- ret = debug_make_int_type (dhandle, 1, FALSE);
- name = "char";
- break;
- case T_SHORT:
- ret = debug_make_int_type (dhandle, 2, FALSE);
- name = "short";
- break;
- case T_INT:
- /* FIXME: Perhaps the size should depend upon the architecture. */
- ret = debug_make_int_type (dhandle, 4, FALSE);
- name = "int";
- break;
- case T_LONG:
- ret = debug_make_int_type (dhandle, 4, FALSE);
- name = "long";
- break;
- case T_FLOAT:
- ret = debug_make_float_type (dhandle, 4);
- name = "float";
- break;
- case T_DOUBLE:
- ret = debug_make_float_type (dhandle, 8);
- name = "double";
- break;
- case T_LNGDBL:
- ret = debug_make_float_type (dhandle, 12);
- name = "long double";
- break;
- case T_UCHAR:
- ret = debug_make_int_type (dhandle, 1, TRUE);
- name = "unsigned char";
- break;
- case T_USHORT:
- ret = debug_make_int_type (dhandle, 2, TRUE);
- name = "unsigned short";
- break;
- case T_UINT:
- ret = debug_make_int_type (dhandle, 4, TRUE);
- name = "unsigned int";
- break;
- case T_ULONG:
- ret = debug_make_int_type (dhandle, 4, TRUE);
- name = "unsigned long";
- break;
- case T_STRUCT:
- if (pauxent == NULL)
- ret = debug_make_struct_type (dhandle, TRUE, 0,
- (debug_field *) NULL);
- else
- ret = parse_coff_struct_type (abfd, symbols, types, ntype, pauxent,
- dhandle);
- slot = coff_get_slot (types, coff_symno);
- *slot = ret;
- set_basic = FALSE;
- break;
- case T_UNION:
- if (pauxent == NULL)
- ret = debug_make_struct_type (dhandle, FALSE, 0, (debug_field *) NULL);
- else
- ret = parse_coff_struct_type (abfd, symbols, types, ntype, pauxent,
- dhandle);
- slot = coff_get_slot (types, coff_symno);
- *slot = ret;
- set_basic = FALSE;
- break;
- case T_ENUM:
- if (pauxent == NULL)
- ret = debug_make_enum_type (dhandle, (const char **) NULL,
- (bfd_signed_vma *) NULL);
- else
- ret = parse_coff_enum_type (abfd, symbols, types, pauxent, dhandle);
- slot = coff_get_slot (types, coff_symno);
- *slot = ret;
- set_basic = FALSE;
- break;
- }
- if (name != NULL)
- ret = debug_name_type (dhandle, name, ret);
- if (set_basic
- && ntype >= 0
- && ntype <= T_MAX)
- types->basic[ntype] = ret;
- return ret;
- }
- /* Parse a struct type. */
- 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)
- {
- long symend;
- int alloc;
- debug_field *fields;
- int count;
- bfd_boolean done;
- symend = pauxent->x_sym.x_fcnary.x_fcn.x_endndx.l;
- alloc = 10;
- fields = (debug_field *) xmalloc (alloc * sizeof *fields);
- count = 0;
- done = FALSE;
- while (! done
- && symbols->coff_symno < symend
- && symbols->symno < symbols->symcount)
- {
- asymbol *sym;
- long this_coff_symno;
- struct internal_syment syment;
- union internal_auxent auxent;
- union internal_auxent *psubaux;
- bfd_vma bitpos = 0, bitsize = 0;
- sym = symbols->syms[symbols->symno];
- if (! bfd_coff_get_syment (abfd, sym, &syment))
- {
- non_fatal (_("bfd_coff_get_syment failed: %s"),
- bfd_errmsg (bfd_get_error ()));
- return DEBUG_TYPE_NULL;
- }
- this_coff_symno = symbols->coff_symno;
- ++symbols->symno;
- symbols->coff_symno += 1 + syment.n_numaux;
- if (syment.n_numaux == 0)
- psubaux = NULL;
- else
- {
- if (! bfd_coff_get_auxent (abfd, sym, 0, &auxent))
- {
- non_fatal (_("bfd_coff_get_auxent failed: %s"),
- bfd_errmsg (bfd_get_error ()));
- return DEBUG_TYPE_NULL;
- }
- psubaux = &auxent;
- }
- switch (syment.n_sclass)
- {
- case C_MOS:
- case C_MOU:
- bitpos = 8 * bfd_asymbol_value (sym);
- bitsize = 0;
- break;
- case C_FIELD:
- bitpos = bfd_asymbol_value (sym);
- bitsize = auxent.x_sym.x_misc.x_lnsz.x_size;
- break;
- case C_EOS:
- done = TRUE;
- break;
- }
- if (! done)
- {
- debug_type ftype;
- debug_field f;
- ftype = parse_coff_type (abfd, symbols, types, this_coff_symno,
- syment.n_type, psubaux, TRUE, dhandle);
- f = debug_make_field (dhandle, bfd_asymbol_name (sym), ftype,
- bitpos, bitsize, DEBUG_VISIBILITY_PUBLIC);
- if (f == DEBUG_FIELD_NULL)
- return DEBUG_TYPE_NULL;
- if (count + 1 >= alloc)
- {
- alloc += 10;
- fields = ((debug_field *)
- xrealloc (fields, alloc * sizeof *fields));
- }
- fields[count] = f;
- ++count;
- }
- }
- fields[count] = DEBUG_FIELD_NULL;
- return debug_make_struct_type (dhandle, ntype == T_STRUCT,
- pauxent->x_sym.x_misc.x_lnsz.x_size,
- fields);
- }
- /* Parse an enum type. */
- 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)
- {
- long symend;
- int alloc;
- const char **names;
- bfd_signed_vma *vals;
- int count;
- bfd_boolean done;
- symend = pauxent->x_sym.x_fcnary.x_fcn.x_endndx.l;
- alloc = 10;
- names = (const char **) xmalloc (alloc * sizeof *names);
- vals = (bfd_signed_vma *) xmalloc (alloc * sizeof *vals);
- count = 0;
- done = FALSE;
- while (! done
- && symbols->coff_symno < symend
- && symbols->symno < symbols->symcount)
- {
- asymbol *sym;
- struct internal_syment syment;
- sym = symbols->syms[symbols->symno];
- if (! bfd_coff_get_syment (abfd, sym, &syment))
- {
- non_fatal (_("bfd_coff_get_syment failed: %s"),
- bfd_errmsg (bfd_get_error ()));
- return DEBUG_TYPE_NULL;
- }
- ++symbols->symno;
- symbols->coff_symno += 1 + syment.n_numaux;
- switch (syment.n_sclass)
- {
- case C_MOE:
- if (count + 1 >= alloc)
- {
- alloc += 10;
- names = ((const char **)
- xrealloc (names, alloc * sizeof *names));
- vals = ((bfd_signed_vma *)
- xrealloc (vals, alloc * sizeof *vals));
- }
- names[count] = bfd_asymbol_name (sym);
- vals[count] = bfd_asymbol_value (sym);
- ++count;
- break;
- case C_EOS:
- done = TRUE;
- break;
- }
- }
- names[count] = NULL;
- return debug_make_enum_type (dhandle, names, vals);
- }
- /* Handle a single COFF symbol. */
- 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)
- {
- switch (psyment->n_sclass)
- {
- case C_NULL:
- break;
- case C_AUTO:
- if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
- DEBUG_LOCAL, bfd_asymbol_value (sym)))
- return FALSE;
- break;
- case C_WEAKEXT:
- case C_EXT:
- if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
- DEBUG_GLOBAL, bfd_asymbol_value (sym)))
- return FALSE;
- break;
- case C_STAT:
- if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
- (within_function
- ? DEBUG_LOCAL_STATIC
- : DEBUG_STATIC),
- bfd_asymbol_value (sym)))
- return FALSE;
- break;
- case C_REG:
- /* FIXME: We may need to convert the register number. */
- if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
- DEBUG_REGISTER, bfd_asymbol_value (sym)))
- return FALSE;
- break;
- case C_LABEL:
- break;
- case C_ARG:
- if (! debug_record_parameter (dhandle, bfd_asymbol_name (sym), type,
- DEBUG_PARM_STACK, bfd_asymbol_value (sym)))
- return FALSE;
- break;
- case C_REGPARM:
- /* FIXME: We may need to convert the register number. */
- if (! debug_record_parameter (dhandle, bfd_asymbol_name (sym), type,
- DEBUG_PARM_REG, bfd_asymbol_value (sym)))
- return FALSE;
- break;
- case C_TPDEF:
- type = debug_name_type (dhandle, bfd_asymbol_name (sym), type);
- if (type == DEBUG_TYPE_NULL)
- return FALSE;
- break;
- case C_STRTAG:
- case C_UNTAG:
- case C_ENTAG:
- {
- debug_type *slot;
- type = debug_tag_type (dhandle, bfd_asymbol_name (sym), type);
- if (type == DEBUG_TYPE_NULL)
- return FALSE;
- /* Store the named type into the slot, so that references get
- the name. */
- slot = coff_get_slot (types, coff_symno);
- *slot = type;
- }
- break;
- default:
- break;
- }
- return TRUE;
- }
- /* Determine if a symbol has external visibility. */
- static bfd_boolean
- external_coff_symbol_p (int sym_class)
- {
- switch (sym_class)
- {
- case C_EXT:
- case C_WEAKEXT:
- return TRUE;
- default:
- break;
- }
- return FALSE;
- }
- /* This is the main routine. It looks through all the symbols and
- handles them. */
- bfd_boolean
- parse_coff (bfd *abfd, asymbol **syms, long symcount, void *dhandle)
- {
- struct coff_symbols symbols;
- struct coff_types types;
- int i;
- long next_c_file;
- const char *fnname;
- int fnclass;
- int fntype;
- bfd_vma fnend;
- alent *linenos;
- bfd_boolean within_function;
- long this_coff_symno;
- symbols.syms = syms;
- symbols.symcount = symcount;
- symbols.symno = 0;
- symbols.coff_symno = 0;
- types.slots = NULL;
- for (i = 0; i <= T_MAX; i++)
- types.basic[i] = DEBUG_TYPE_NULL;
- next_c_file = -1;
- fnname = NULL;
- fnclass = 0;
- fntype = 0;
- fnend = 0;
- linenos = NULL;
- within_function = FALSE;
- while (symbols.symno < symcount)
- {
- asymbol *sym;
- const char *name;
- struct internal_syment syment;
- union internal_auxent auxent;
- union internal_auxent *paux;
- debug_type type;
- sym = syms[symbols.symno];
- if (! bfd_coff_get_syment (abfd, sym, &syment))
- {
- non_fatal (_("bfd_coff_get_syment failed: %s"),
- bfd_errmsg (bfd_get_error ()));
- return FALSE;
- }
- name = bfd_asymbol_name (sym);
- this_coff_symno = symbols.coff_symno;
- ++symbols.symno;
- symbols.coff_symno += 1 + syment.n_numaux;
- /* We only worry about the first auxent, because that is the
- only one which is relevant for debugging information. */
- if (syment.n_numaux == 0)
- paux = NULL;
- else
- {
- if (! bfd_coff_get_auxent (abfd, sym, 0, &auxent))
- {
- non_fatal (_("bfd_coff_get_auxent failed: %s"),
- bfd_errmsg (bfd_get_error ()));
- return FALSE;
- }
- paux = &auxent;
- }
- if (this_coff_symno == next_c_file && syment.n_sclass != C_FILE)
- {
- /* The last C_FILE symbol points to the first external
- symbol. */
- if (! debug_set_filename (dhandle, "*globals*"))
- return FALSE;
- }
- switch (syment.n_sclass)
- {
- case C_EFCN:
- case C_EXTDEF:
- case C_ULABEL:
- case C_USTATIC:
- case C_LINE:
- case C_ALIAS:
- case C_HIDDEN:
- /* Just ignore these classes. */
- break;
- case C_FILE:
- next_c_file = syment.n_value;
- if (! debug_set_filename (dhandle, name))
- return FALSE;
- break;
- case C_STAT:
- /* Ignore static symbols with a type of T_NULL. These
- represent section entries. */
- if (syment.n_type == T_NULL)
- break;
- /* Fall through. */
- case C_WEAKEXT:
- case C_EXT:
- if (ISFCN (syment.n_type))
- {
- fnname = name;
- fnclass = syment.n_sclass;
- fntype = syment.n_type;
- if (syment.n_numaux > 0)
- fnend = bfd_asymbol_value (sym) + auxent.x_sym.x_misc.x_fsize;
- else
- fnend = 0;
- linenos = BFD_SEND (abfd, _get_lineno, (abfd, sym));
- break;
- }
- type = parse_coff_type (abfd, &symbols, &types, this_coff_symno,
- syment.n_type, paux, TRUE, dhandle);
- if (type == DEBUG_TYPE_NULL)
- return FALSE;
- if (! parse_coff_symbol (abfd, &types, sym, this_coff_symno, &syment,
- dhandle, type, within_function))
- return FALSE;
- break;
- case C_FCN:
- if (strcmp (name, ".bf") == 0)
- {
- if (fnname == NULL)
- {
- non_fatal (_("%ld: .bf without preceding function"),
- this_coff_symno);
- return FALSE;
- }
- type = parse_coff_type (abfd, &symbols, &types, this_coff_symno,
- DECREF (fntype), paux, FALSE, dhandle);
- if (type == DEBUG_TYPE_NULL)
- return FALSE;
- if (! debug_record_function (dhandle, fnname, type,
- external_coff_symbol_p (fnclass),
- bfd_asymbol_value (sym)))
- return FALSE;
- if (linenos != NULL)
- {
- int base;
- bfd_vma addr;
- if (syment.n_numaux == 0)
- base = 0;
- else
- base = auxent.x_sym.x_misc.x_lnsz.x_lnno - 1;
- addr = bfd_get_section_vma (abfd, bfd_get_section (sym));
- ++linenos;
- while (linenos->line_number != 0)
- {
- if (! debug_record_line (dhandle,
- linenos->line_number + base,
- linenos->u.offset + addr))
- return FALSE;
- ++linenos;
- }
- }
- fnname = NULL;
- linenos = NULL;
- fnclass = 0;
- fntype = 0;
- within_function = TRUE;
- }
- else if (strcmp (name, ".ef") == 0)
- {
- if (! within_function)
- {
- non_fatal (_("%ld: unexpected .ef\n"), this_coff_symno);
- return FALSE;
- }
- if (bfd_asymbol_value (sym) > fnend)
- fnend = bfd_asymbol_value (sym);
- if (! debug_end_function (dhandle, fnend))
- return FALSE;
- fnend = 0;
- within_function = FALSE;
- }
- break;
- case C_BLOCK:
- if (strcmp (name, ".bb") == 0)
- {
- if (! debug_start_block (dhandle, bfd_asymbol_value (sym)))
- return FALSE;
- }
- else if (strcmp (name, ".eb") == 0)
- {
- if (! debug_end_block (dhandle, bfd_asymbol_value (sym)))
- return FALSE;
- }
- break;
- default:
- type = parse_coff_type (abfd, &symbols, &types, this_coff_symno,
- syment.n_type, paux, TRUE, dhandle);
- if (type == DEBUG_TYPE_NULL)
- return FALSE;
- if (! parse_coff_symbol (abfd, &types, sym, this_coff_symno, &syment,
- dhandle, type, within_function))
- return FALSE;
- break;
- }
- }
- return TRUE;
- }
|