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