X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fmdebugread.c;h=f3f3ec42093bedba1e9655ba92a78761ccdc20ac;hb=ebb2647017777453ac3e758f4a1192651ffa43e3;hp=88b7a0857ed11a77d0983750664601f69b19c13e;hpb=2b57629364528ef2fd913154e58f626123d51f1c;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c index 88b7a0857e..f3f3ec4209 100644 --- a/gdb/mdebugread.c +++ b/gdb/mdebugread.c @@ -1,5 +1,5 @@ /* Read a symbol table in ECOFF format (Third-Eye). - Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995 + Copyright 1986, 87, 89, 90, 91, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc. Original version contributed by Alessandro Forin (af@cs.cmu.edu) at CMU. Major work by Per Bothner, John Gilmore and Ian Lance Taylor @@ -19,7 +19,7 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* This module provides the function mdebug_build_psymtabs. It reads ECOFF debugging information into partial symbol tables. The @@ -49,17 +49,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "buildsym.h" #include "stabsread.h" #include "complaints.h" - -#if !defined (SEEK_SET) -#define SEEK_SET 0 -#define SEEK_CUR 1 -#endif +#include "demangle.h" /* These are needed if the tm.h file does not contain the necessary mips specific definitions. */ #ifndef MIPS_EFI_SYMBOL_NAME #define MIPS_EFI_SYMBOL_NAME "__GDB_EFI_INFO__" +extern void ecoff_relocate_efi PARAMS ((struct symbol *, CORE_ADDR)); #include "coff/sym.h" #include "coff/symconst.h" typedef struct mips_extra_func_info { @@ -75,8 +72,6 @@ typedef struct mips_extra_func_info { #include #endif -#include -#include #include "gdb_stat.h" #include "gdb_string.h" @@ -202,6 +197,9 @@ static struct complaint unexpected_type_code_complaint = static struct complaint unable_to_cross_ref_complaint = {"unable to cross ref btTypedef for %s", 0, 0}; +static struct complaint bad_indirect_xref_complaint = +{"unable to cross ref btIndirect for %s", 0, 0}; + static struct complaint illegal_forward_tq0_complaint = {"illegal tq0 in forward typedef for %s", 0, 0}; @@ -256,8 +254,8 @@ static int cur_sdx; /* Note how much "debuggable" this image is. We would like to see at least one FDR with full symbols */ -static max_gdbinfo; -static max_glevel; +static int max_gdbinfo; +static int max_glevel; /* When examining .o files, report on undefined symbols */ @@ -306,6 +304,24 @@ static int found_ecoff_debugging_info; /* Forward declarations */ +static void +add_pending PARAMS ((FDR *, char *, struct type *)); + +static struct mdebug_pending * +is_pending_symbol PARAMS ((FDR *, char *)); + +static void +pop_parse_stack PARAMS ((void)); + +static void +push_parse_stack PARAMS ((void)); + +static char * +fdr_name PARAMS ((FDR *)); + +static void +mdebug_psymtab_to_symtab PARAMS ((struct partial_symtab *)); + static int upgrade_type PARAMS ((int, struct type **, int, union aux_ext *, int, char *)); @@ -348,7 +364,7 @@ static struct type * parse_type PARAMS ((int, union aux_ext *, unsigned int, int *, int, char *)); static struct symbol * -mylookup_symbol PARAMS ((char *, struct block *, enum namespace, +mylookup_symbol PARAMS ((char *, struct block *, namespace_enum, enum address_class)); static struct block * @@ -382,10 +398,10 @@ static struct linetable * shrink_linetable PARAMS ((struct linetable *)); static void -handle_psymbol_enumerators PARAMS ((struct objfile *, FDR *, int)); +handle_psymbol_enumerators PARAMS ((struct objfile *, FDR *, int, CORE_ADDR)); static char * -mdebug_next_symbol_text PARAMS ((void)); +mdebug_next_symbol_text PARAMS ((struct objfile *)); /* Address bounds for the signal trampoline in inferior, if any */ @@ -705,6 +721,7 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets) switch (sh->sc) { case scText: + case scRConst: /* Do not relocate relative values. The value of a stEnd symbol is the displacement from the corresponding start symbol value. @@ -774,7 +791,8 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets) add_symbol (s, b); /* Type could be missing if file is compiled without debugging info. */ - if (sh->sc == scUndefined || sh->sc == scNil || sh->index == indexNil) + if (sh->sc == scUndefined || sh->sc == scSUndefined + || sh->sc == scNil || sh->index == indexNil) SYMBOL_TYPE (s) = nodebug_var_symbol_type; else SYMBOL_TYPE (s) = parse_type (cur_fd, ax, sh->index, 0, bigend, name); @@ -787,7 +805,7 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets) top_stack->numargs++; /* Special GNU C++ name. */ - if (name[0] == CPLUS_MARKER && name[1] == 't' && name[2] == 0) + if (is_cplus_marker (name[0]) && name[1] == 't' && name[2] == 0) name = "this"; /* FIXME, not alloc'd in obstack */ s = new_symbol (name); @@ -833,10 +851,26 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets) SYMBOL_NAMESPACE (s) = VAR_NAMESPACE; SYMBOL_CLASS (s) = LOC_BLOCK; /* Type of the return value */ - if (sh->sc == scUndefined || sh->sc == scNil) + if (sh->sc == scUndefined || sh->sc == scSUndefined || sh->sc == scNil) t = mdebug_type_int; else - t = parse_type (cur_fd, ax, sh->index + 1, 0, bigend, name); + { + t = parse_type (cur_fd, ax, sh->index + 1, 0, bigend, name); + if (STREQ(name, "malloc") && t->code == TYPE_CODE_VOID) + { + /* I don't know why, but, at least under Linux/Alpha, + when linking against a malloc without debugging + symbols, its read as a function returning void---this + is bad because it means we cannot call functions with + string arguments interactively; i.e., "call + printf("howdy\n")" would fail with the error message + "program has no memory available". To avoid this, we + patch up the type and make it void* + instead. (davidm@azstarnet.com) + */ + t = make_pointer_type (t, NULL); + } + } b = top_stack->cur_block; if (sh->st == stProc) { @@ -866,7 +900,7 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets) add_block (b, top_stack->cur_st); /* Not if we only have partial info */ - if (sh->sc == scUndefined || sh->sc == scNil) + if (sh->sc == scUndefined || sh->sc == scSUndefined || sh->sc == scNil) break; push_parse_stack (); @@ -933,15 +967,21 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets) if (nfields == 0 && type_code == TYPE_CODE_UNDEF) /* If the type of the member is Nil (or Void), without qualifiers, assume the tag is an - enumeration. */ - if (tsym.index == indexNil) + enumeration. + Alpha cc -migrate enums are recognized by a zero + index and a zero symbol value. + DU 4.0 cc enums are recognized by a member type of + btEnum without qualifiers and a zero symbol value. */ + if (tsym.index == indexNil + || (tsym.index == 0 && sh->value == 0)) type_code = TYPE_CODE_ENUM; else { (*debug_swap->swap_tir_in) (bigend, &ax[tsym.index].a_ti, &tir); - if ((tir.bt == btNil || tir.bt == btVoid) + if ((tir.bt == btNil || tir.bt == btVoid + || (tir.bt == btEnum && sh->value == 0)) && tir.tq0 == tqNil) type_code = TYPE_CODE_ENUM; } @@ -1060,6 +1100,8 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets) if (type_code == TYPE_CODE_ENUM) { + int unsigned_enum = 1; + /* This is a non-empty enum. */ /* DEC c89 has the number of enumerators in the sh.value field, @@ -1067,8 +1109,11 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets) incompatibility quirk. This might do the wrong thing for an enum with one or two enumerators and gcc -gcoff -fshort-enums, but these cases - are hopefully rare enough. */ - if (TYPE_LENGTH (t) == TYPE_NFIELDS (t)) + are hopefully rare enough. + Alpha cc -migrate has a sh.value field of zero, we adjust + that too. */ + if (TYPE_LENGTH (t) == TYPE_NFIELDS (t) + || TYPE_LENGTH (t) == 0) TYPE_LENGTH (t) = TARGET_INT_BIT / HOST_CHAR_BIT; for (ext_tsym = ext_sh + external_sym_size; ; @@ -1082,26 +1127,32 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets) if (tsym.st != stMember) break; - f->bitpos = tsym.value; - f->type = t; - f->name = debug_info->ss + cur_fdr->issBase + tsym.iss; - f->bitsize = 0; + FIELD_BITPOS (*f) = tsym.value; + FIELD_TYPE (*f) = t; + FIELD_NAME (*f) = debug_info->ss + cur_fdr->issBase + tsym.iss; + FIELD_BITSIZE (*f) = 0; enum_sym = ((struct symbol *) obstack_alloc (¤t_objfile->symbol_obstack, sizeof (struct symbol))); memset ((PTR) enum_sym, 0, sizeof (struct symbol)); - SYMBOL_NAME (enum_sym) = f->name; + SYMBOL_NAME (enum_sym) = + obsavestring (f->name, strlen (f->name), + ¤t_objfile->symbol_obstack); SYMBOL_CLASS (enum_sym) = LOC_CONST; SYMBOL_TYPE (enum_sym) = t; SYMBOL_NAMESPACE (enum_sym) = VAR_NAMESPACE; SYMBOL_VALUE (enum_sym) = tsym.value; + if (SYMBOL_VALUE (enum_sym) < 0) + unsigned_enum = 0; add_symbol (enum_sym, top_stack->cur_block); /* Skip the stMembers that we've handled. */ count++; f++; } + if (unsigned_enum) + TYPE_FLAGS (t) |= TYPE_FLAG_UNSIGNED; } /* make this the current type */ top_stack->cur_type = t; @@ -1266,11 +1317,11 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets) case stMember: /* member of struct or union */ f = &TYPE_FIELDS (top_stack->cur_type)[top_stack->cur_field++]; - f->name = name; - f->bitpos = sh->value; + FIELD_NAME (*f) = name; + FIELD_BITPOS (*f) = sh->value; bitsize = 0; - f->type = parse_type (cur_fd, ax, sh->index, &bitsize, bigend, name); - f->bitsize = bitsize; + FIELD_TYPE (*f) = parse_type (cur_fd, ax, sh->index, &bitsize, bigend, name); + FIELD_BITSIZE (*f) = bitsize; break; case stIndirect: /* forward declaration on Irix5 */ @@ -1481,6 +1532,11 @@ parse_type (fd, ax, aux_index, bs, bigend, sym_name) case btSet: type_code = TYPE_CODE_SET; break; + case btIndirect: + /* alpha cc -migrate uses this for typedefs. The true type will + be obtained by crossreferencing below. */ + type_code = TYPE_CODE_ERROR; + break; case btTypedef: /* alpha cc uses this for typedefs. The true type will be obtained by crossreferencing below. */ @@ -1497,17 +1553,59 @@ parse_type (fd, ax, aux_index, bs, bigend, sym_name) if (t->fBitfield) { + int width = AUX_GET_WIDTH (bigend, ax); + /* Inhibit core dumps with some cfront generated objects that corrupt the TIR. */ if (bs == (int *)NULL) { - complain (&bad_fbitfield_complaint, sym_name); - return mdebug_type_int; + /* Alpha cc -migrate encodes char and unsigned char types + as short and unsigned short types with a field width of 8. + Enum types also have a field width which we ignore for now. */ + if (t->bt == btShort && width == 8) + tp = mdebug_type_char; + else if (t->bt == btUShort && width == 8) + tp = mdebug_type_unsigned_char; + else if (t->bt == btEnum) + ; + else + complain (&bad_fbitfield_complaint, sym_name); } - *bs = AUX_GET_WIDTH (bigend, ax); + else + *bs = width; ax++; } + /* A btIndirect entry cross references to an aux entry containing + the type. */ + if (t->bt == btIndirect) + { + RNDXR rn[1]; + int rf; + FDR *xref_fh; + int xref_fd; + + (*debug_swap->swap_rndx_in) (bigend, &ax->a_rndx, rn); + ax++; + if (rn->rfd == 0xfff) + { + rf = AUX_GET_ISYM (bigend, ax); + ax++; + } + else + rf = rn->rfd; + + if (rf == -1) + { + complain (&bad_indirect_xref_complaint, sym_name); + return mdebug_type_int; + } + xref_fh = get_rfd (fd, rf); + xref_fd = xref_fh - debug_info->fdr; + tp = parse_type (xref_fd, debug_info->external_aux + xref_fh->iauxBase, + rn->index, (int *) NULL, xref_fh->fBigendian, sym_name); + } + /* All these types really point to some (common) MIPS type definition, and only the type-qualifiers fully identify them. We'll make the same effort at sharing. */ @@ -1575,10 +1673,8 @@ parse_type (fd, ax, aux_index, bs, bigend, sym_name) /* All these types really point to some (common) MIPS type definition, and only the type-qualifiers fully identify them. We'll make the same effort at sharing. - FIXME: btIndirect cannot happen here as it is handled by the - switch t->bt above. And we are not doing any guessing on range types. */ - if (t->bt == btIndirect || - t->bt == btRange) + FIXME: We are not doing any guessing on range types. */ + if (t->bt == btRange) { char *name; @@ -1725,7 +1821,8 @@ upgrade_type (fd, tpp, tq, ax, bigend, sym_name) } fh = get_rfd (fd, rf); - indx = parse_type (fd, debug_info->external_aux + fh->iauxBase, + indx = parse_type (fh - debug_info->fdr, + debug_info->external_aux + fh->iauxBase, id, (int *) NULL, bigend, sym_name); /* The bounds type should be an integer type, but might be anything @@ -1763,6 +1860,13 @@ upgrade_type (fd, tpp, tq, ax, bigend, sym_name) ignore the erroneous bitsize from the auxiliary entry safely. dbx seems to ignore it too. */ + /* TYPE_FLAG_TARGET_STUB now takes care of the zero TYPE_LENGTH + problem. */ + if (TYPE_LENGTH (*tpp) == 0) + { + TYPE_FLAGS (t) |= TYPE_FLAG_TARGET_STUB; + } + *tpp = t; return 4 + off; @@ -1792,14 +1896,13 @@ upgrade_type (fd, tpp, tq, ax, bigend, sym_name) to look for the function which contains the MIPS_EFI_SYMBOL_NAME symbol in question, or NULL to use top_stack->cur_block. */ -static void parse_procedure PARAMS ((PDR *, struct symtab *, unsigned long, +static void parse_procedure PARAMS ((PDR *, struct symtab *, struct partial_symtab *)); static void -parse_procedure (pr, search_symtab, first_off, pst) +parse_procedure (pr, search_symtab, pst) PDR *pr; struct symtab *search_symtab; - unsigned long first_off; struct partial_symtab *pst; { struct symbol *s, *i; @@ -1905,7 +2008,18 @@ parse_procedure (pr, search_symtab, first_off, pst) e = (struct mips_extra_func_info *) SYMBOL_VALUE (i); e->pdr = *pr; e->pdr.isym = (long) s; - e->pdr.adr += pst->textlow - first_off; + + /* GDB expects the absolute function start address for the + procedure descriptor in e->pdr.adr. + As the address in the procedure descriptor is usually relative, + we would have to relocate e->pdr.adr with cur_fdr->adr and + ANOFFSET (pst->section_offsets, SECT_OFF_TEXT). + Unfortunately cur_fdr->adr and e->pdr.adr are both absolute + in shared libraries on some systems, and on other systems + e->pdr.adr is sometimes offset by a bogus value. + To work around these problems, we replace e->pdr.adr with + the start address of the function. */ + e->pdr.adr = BLOCK_START (b); /* Correct incorrect setjmp procedure descriptor from the library to make backtrace through setjmp work. */ @@ -1982,7 +2096,8 @@ parse_external (es, bigend, section_offsets) } /* Reading .o files */ - if (es->asym.sc == scUndefined || es->asym.sc == scNil) + if (es->asym.sc == scUndefined || es->asym.sc == scSUndefined + || es->asym.sc == scNil) { char *what; switch (es->asym.st) @@ -2054,20 +2169,20 @@ parse_external (es, bigend, section_offsets) with that and do not need to reorder our linetables */ static void parse_lines PARAMS ((FDR *, PDR *, struct linetable *, int, - struct partial_symtab *)); + struct partial_symtab *, CORE_ADDR)); static void -parse_lines (fh, pr, lt, maxlines, pst) +parse_lines (fh, pr, lt, maxlines, pst, lowest_pdr_addr) FDR *fh; PDR *pr; struct linetable *lt; int maxlines; struct partial_symtab *pst; + CORE_ADDR lowest_pdr_addr; { unsigned char *base; int j, k; int delta, count, lineno = 0; - unsigned long first_off = pr->adr; if (fh->cbLine == 0) return; @@ -2076,8 +2191,8 @@ parse_lines (fh, pr, lt, maxlines, pst) k = 0; for (j = 0; j < fh->cpd; j++, pr++) { - long l; - unsigned long adr; + CORE_ADDR l; + CORE_ADDR adr; unsigned char *halt; /* No code for this one */ @@ -2094,7 +2209,7 @@ parse_lines (fh, pr, lt, maxlines, pst) halt = base + fh->cbLine; base += pr->cbLineOffset; - adr = pst->textlow + pr->adr - first_off; + adr = pst->textlow + pr->adr - lowest_pdr_addr; l = adr >> 2; /* in words */ for (lineno = pr->lnLow; base < halt; ) @@ -2153,7 +2268,7 @@ parse_partial_symbols (objfile, section_offsets) EXTR *ext_in_end; SYMR sh; struct partial_symtab *pst; - + int textlow_not_set = 1; int past_first_source_file = 0; /* List of current psymtab's include files */ @@ -2288,7 +2403,8 @@ parse_partial_symbols (objfile, section_offsets) extern_tab[fdr_to_pst[ext_in->ifd].globals_offset + fdr_to_pst[ext_in->ifd].n_globals++] = *ext_in; - if (ext_in->asym.sc == scUndefined || ext_in->asym.sc == scNil) + if (ext_in->asym.sc == scUndefined || ext_in->asym.sc == scSUndefined + || ext_in->asym.sc == scNil) continue; name = debug_info->ssext + ext_in->asym.iss; @@ -2349,9 +2465,12 @@ parse_partial_symbols (objfile, section_offsets) } break; case stLocal: + case stNil: /* The alpha has the section start addresses in stLocal symbols whose name starts with a `.'. Skip those but complain for all - other stLocal symbols. */ + other stLocal symbols. + Irix6 puts the section start addresses in stNil symbols, skip + those too. */ if (name[0] == '.') continue; /* Fall through. */ @@ -2371,6 +2490,13 @@ parse_partial_symbols (objfile, section_offsets) cur_fdr = fh = debug_info->fdr + f_idx; + /* If a partial symbol table has already been read for this file, + don't make another one. This works around a problem with some + compilers that emit both DWARF and mdebug sections for a single + module. */ + if (lookup_partial_symtab (fdr_name (fh))) + continue; + if (fh->csym == 0) { fdr_to_pst[f_idx].pst = NULL; @@ -2468,7 +2594,7 @@ parse_partial_symbols (objfile, section_offsets) { if (sh.st == stProc || sh.st == stStaticProc) { - long procaddr; + CORE_ADDR procaddr; long isym; sh.value += ANOFFSET (section_offsets, SECT_OFF_TEXT); @@ -2480,6 +2606,7 @@ parse_partial_symbols (objfile, section_offsets) mst_file_text, NULL, SECT_OFF_TEXT, + NULL, objfile); } procaddr = sh.value; @@ -2495,7 +2622,7 @@ parse_partial_symbols (objfile, section_offsets) &sh); if (sh.st == stEnd) { - long high = procaddr + sh.value; + CORE_ADDR high = procaddr + sh.value; /* Kludge for Irix 5.2 zero fh->adr. */ if (!relocatable @@ -2510,6 +2637,7 @@ parse_partial_symbols (objfile, section_offsets) switch (sh.sc) { case scUndefined: + case scSUndefined: case scNil: case scAbs: break; @@ -2526,6 +2654,7 @@ parse_partial_symbols (objfile, section_offsets) mst_file_data, NULL, SECT_OFF_DATA, + NULL, objfile); break; @@ -2537,6 +2666,7 @@ parse_partial_symbols (objfile, section_offsets) mst_file_bss, NULL, SECT_OFF_BSS, + NULL, objfile); break; } @@ -2549,7 +2679,7 @@ parse_partial_symbols (objfile, section_offsets) #define CUR_SYMBOL_VALUE sh.value #define START_PSYMTAB(ofile,secoff,fname,low,symoff,global_syms,static_syms)\ pst = save_pst -#define END_PSYMTAB(pst,ilist,ninc,c_off,c_text,dep_list,n_deps) (void)0 +#define END_PSYMTAB(pst,ilist,ninc,c_off,c_text,dep_list,n_deps,textlow_not_set) (void)0 #define HANDLE_RBRAC(val) \ if ((val) > save_pst->texthigh) save_pst->texthigh = (val); #include "partial-stab.h" @@ -2575,7 +2705,8 @@ parse_partial_symbols (objfile, section_offsets) } /* Non absolute static symbols go into the minimal table. */ - if (sh.sc == scUndefined || sh.sc == scNil + if (sh.sc == scUndefined || sh.sc == scSUndefined + || sh.sc == scNil || (sh.index == indexNil && (sh.st != stStatic || sh.sc == scAbs))) { @@ -2589,6 +2720,7 @@ parse_partial_symbols (objfile, section_offsets) switch (sh.sc) { case scText: + case scRConst: /* The value of a stEnd symbol is the displacement from the corresponding start symbol value, do not relocate it. */ if (sh.st != stEnd) @@ -2609,14 +2741,15 @@ parse_partial_symbols (objfile, section_offsets) switch (sh.st) { - long high; - long procaddr; + CORE_ADDR high; + CORE_ADDR procaddr; int new_sdx; case stStaticProc: prim_record_minimal_symbol_and_info (name, sh.value, mst_file_text, NULL, - SECT_OFF_TEXT, objfile); + SECT_OFF_TEXT, NULL, + objfile); /* FALLTHROUGH */ @@ -2633,15 +2766,15 @@ parse_partial_symbols (objfile, section_offsets) symbol table, and the MAIN__ symbol via the minimal symbol table. */ if (sh.st == stProc) - ADD_PSYMBOL_TO_LIST (name, strlen (name), + add_psymbol_to_list (name, strlen (name), VAR_NAMESPACE, LOC_BLOCK, - objfile->global_psymbols, - sh.value, psymtab_language, objfile); + &objfile->global_psymbols, + 0, sh.value, psymtab_language, objfile); else - ADD_PSYMBOL_TO_LIST (name, strlen (name), + add_psymbol_to_list (name, strlen (name), VAR_NAMESPACE, LOC_BLOCK, - objfile->static_psymbols, - sh.value, psymtab_language, objfile); + &objfile->static_psymbols, + 0, sh.value, psymtab_language, objfile); /* Skip over procedure to next one. */ if (sh.index >= hdr->iauxMax) @@ -2693,11 +2826,13 @@ parse_partial_symbols (objfile, section_offsets) prim_record_minimal_symbol_and_info (name, sh.value, mst_file_data, NULL, SECT_OFF_DATA, + NULL, objfile); else prim_record_minimal_symbol_and_info (name, sh.value, mst_file_bss, NULL, SECT_OFF_BSS, + NULL, objfile); class = LOC_STATIC; break; @@ -2729,13 +2864,13 @@ parse_partial_symbols (objfile, section_offsets) && sh.iss != 0 && sh.index != cur_sdx + 2) { - ADD_PSYMBOL_TO_LIST (name, strlen (name), + add_psymbol_to_list (name, strlen (name), STRUCT_NAMESPACE, LOC_TYPEDEF, - objfile->static_psymbols, - sh.value, + &objfile->static_psymbols, + 0, (CORE_ADDR) 0, psymtab_language, objfile); } - handle_psymbol_enumerators (objfile, fh, sh.st); + handle_psymbol_enumerators (objfile, fh, sh.st, sh.value); /* Skip over the block */ new_sdx = sh.index; @@ -2768,10 +2903,10 @@ parse_partial_symbols (objfile, section_offsets) continue; } /* Use this gdb symbol */ - ADD_PSYMBOL_TO_LIST (name, strlen (name), + add_psymbol_to_list (name, strlen (name), VAR_NAMESPACE, class, - objfile->static_psymbols, sh.value, - psymtab_language, objfile); + &objfile->static_psymbols, + 0, sh.value, psymtab_language, objfile); skip: cur_sdx++; /* Go to next file symbol */ } @@ -2793,13 +2928,15 @@ parse_partial_symbols (objfile, section_offsets) psh = &ext_ptr->asym; /* Do not add undefined symbols to the partial symbol table. */ - if (psh->sc == scUndefined || psh->sc == scNil) + if (psh->sc == scUndefined || psh->sc == scSUndefined + || psh->sc == scNil) continue; svalue = psh->value; switch (psh->sc) { case scText: + case scRConst: svalue += ANOFFSET (section_offsets, SECT_OFF_TEXT); break; case scData: @@ -2844,11 +2981,11 @@ parse_partial_symbols (objfile, section_offsets) break; } name = debug_info->ssext + psh->iss; - ADD_PSYMBOL_ADDR_TO_LIST (name, strlen (name), - VAR_NAMESPACE, class, - objfile->global_psymbols, - svalue, - psymtab_language, objfile); + add_psymbol_to_list (name, strlen (name), + VAR_NAMESPACE, class, + &objfile->global_psymbols, + 0, svalue, + psymtab_language, objfile); } } @@ -2857,7 +2994,10 @@ parse_partial_symbols (objfile, section_offsets) fdr_to_pst[f_idx].pst = end_psymtab (save_pst, psymtab_include_list, includes_used, -1, save_pst->texthigh, - dependency_list, dependencies_used); + dependency_list, dependencies_used, textlow_not_set); + includes_used = 0; + dependencies_used = 0; + if (objfile->ei.entry_point >= save_pst->textlow && objfile->ei.entry_point < save_pst->texthigh) { @@ -2955,10 +3095,11 @@ parse_partial_symbols (objfile, section_offsets) all the the enum constants to the partial symbol table. */ static void -handle_psymbol_enumerators (objfile, fh, stype) +handle_psymbol_enumerators (objfile, fh, stype, svalue) struct objfile *objfile; FDR *fh; int stype; + CORE_ADDR svalue; { const bfd_size_type external_sym_size = debug_swap->external_sym_size; void (* const swap_sym_in) PARAMS ((bfd *, PTR, SYMR *)) @@ -2976,18 +3117,26 @@ handle_psymbol_enumerators (objfile, fh, stype) case stBlock: /* It is an enumerated type if the next symbol entry is a stMember and its auxiliary index is indexNil or its auxiliary entry - is a plain btNil or btVoid. */ + is a plain btNil or btVoid. + Alpha cc -migrate enums are recognized by a zero index and + a zero symbol value. + DU 4.0 cc enums are recognized by a member type of btEnum without + qualifiers and a zero symbol value. */ (*swap_sym_in) (cur_bfd, ext_sym, &sh); if (sh.st != stMember) return; - if (sh.index == indexNil) + if (sh.index == indexNil + || (sh.index == 0 && svalue == 0)) break; (*debug_swap->swap_tir_in) (fh->fBigendian, &(debug_info->external_aux + fh->iauxBase + sh.index)->a_ti, &tir); - if ((tir.bt != btNil && tir.bt != btVoid) || tir.tq0 != tqNil) + if ((tir.bt != btNil + && tir.bt != btVoid + && (tir.bt != btEnum || svalue != 0)) + || tir.tq0 != tqNil) return; break; @@ -3006,16 +3155,17 @@ handle_psymbol_enumerators (objfile, fh, stype) /* Note that the value doesn't matter for enum constants in psymtabs, just in symtabs. */ - ADD_PSYMBOL_TO_LIST (name, strlen (name), + add_psymbol_to_list (name, strlen (name), VAR_NAMESPACE, LOC_CONST, - objfile->static_psymbols, 0, - psymtab_language, objfile); + &objfile->static_psymbols, 0, + (CORE_ADDR) 0, psymtab_language, objfile); ext_sym += external_sym_size; } } static char * -mdebug_next_symbol_text () +mdebug_next_symbol_text (objfile) + struct objfile *objfile; /* argument objfile is currently unused */ { SYMR sh; @@ -3051,6 +3201,7 @@ psymtab_to_symtab_1 (pst, filename) struct symtab *st; FDR *fh; struct linetable *lines; + CORE_ADDR lowest_pdr_addr = 0; if (pst->readin) return; @@ -3124,10 +3275,6 @@ psymtab_to_symtab_1 (pst, filename) if (processing_gcc_compilation != 0) { - char *pdr_ptr; - char *pdr_end; - int first_pdr; - unsigned long first_off = 0; /* This symbol table contains stabs-in-ecoff entries. */ @@ -3150,7 +3297,8 @@ psymtab_to_symtab_1 (pst, filename) &sh); name = debug_info->ss + fh->issBase + sh.iss; valu = sh.value; - if (ECOFF_IS_STAB (&sh)) + /* XXX This is a hack. It will go away! */ + if (ECOFF_IS_STAB (&sh) || (name[0] == '#')) { int type_code = ECOFF_UNMARK_STAB (sh.index); @@ -3162,6 +3310,12 @@ psymtab_to_symtab_1 (pst, filename) process_one_symbol (type_code, 0, valu, name, pst->section_offsets, pst->objfile); } + /* Similarly a hack. */ + else if (name[0] == '#') + { + process_one_symbol (N_SLINE, 0, valu, name, + pst->section_offsets, pst->objfile); + } if (type_code == N_FUN) { /* Make up special symbol to contain @@ -3203,7 +3357,7 @@ psymtab_to_symtab_1 (pst, filename) else complain (&stab_unknown_complaint, name); } - st = end_symtab (pst->texthigh, 0, 0, pst->objfile, SECT_OFF_TEXT); + st = end_symtab (pst->texthigh, pst->objfile, SECT_OFF_TEXT); end_stabs (); /* Sort the symbol table now, we are done adding symbols to it. @@ -3217,21 +3371,42 @@ psymtab_to_symtab_1 (pst, filename) generated via asm statements. */ /* Fill in procedure info next. */ - first_pdr = 1; - pdr_ptr = ((char *) debug_info->external_pdr - + fh->ipdFirst * external_pdr_size); - pdr_end = pdr_ptr + fh->cpd * external_pdr_size; - for (; pdr_ptr < pdr_end; pdr_ptr += external_pdr_size) + if (fh->cpd > 0) { - PDR pr; - - (*swap_pdr_in) (cur_bfd, pdr_ptr, &pr); - if (first_pdr) + PDR *pr_block; + struct cleanup *old_chain; + char *pdr_ptr; + char *pdr_end; + PDR *pdr_in; + PDR *pdr_in_end; + + pr_block = (PDR *) xmalloc (fh->cpd * sizeof (PDR)); + old_chain = make_cleanup (free, pr_block); + + pdr_ptr = ((char *) debug_info->external_pdr + + fh->ipdFirst * external_pdr_size); + pdr_end = pdr_ptr + fh->cpd * external_pdr_size; + pdr_in = pr_block; + for (; + pdr_ptr < pdr_end; + pdr_ptr += external_pdr_size, pdr_in++) { - first_off = pr.adr; - first_pdr = 0; + (*swap_pdr_in) (cur_bfd, pdr_ptr, pdr_in); + + /* Determine lowest PDR address, the PDRs are not always + sorted. */ + if (pdr_in == pr_block) + lowest_pdr_addr = pdr_in->adr; + else if (pdr_in->adr < lowest_pdr_addr) + lowest_pdr_addr = pdr_in->adr; } - parse_procedure (&pr, st, first_off, pst); + + pdr_in = pr_block; + pdr_in_end = pdr_in + fh->cpd; + for (; pdr_in < pdr_in_end; pdr_in++) + parse_procedure (pdr_in, st, pst); + + do_cleanups (old_chain); } } else @@ -3324,9 +3499,18 @@ psymtab_to_symtab_1 (pst, filename) for (; pdr_ptr < pdr_end; pdr_ptr += external_pdr_size, pdr_in++) - (*swap_pdr_in) (cur_bfd, pdr_ptr, pdr_in); + { + (*swap_pdr_in) (cur_bfd, pdr_ptr, pdr_in); + + /* Determine lowest PDR address, the PDRs are not always + sorted. */ + if (pdr_in == pr_block) + lowest_pdr_addr = pdr_in->adr; + else if (pdr_in->adr < lowest_pdr_addr) + lowest_pdr_addr = pdr_in->adr; + } - parse_lines (fh, pr_block, lines, maxlines, pst); + parse_lines (fh, pr_block, lines, maxlines, pst, lowest_pdr_addr); if (lines->nitems < fh->cline) lines = shrink_linetable (lines); @@ -3334,7 +3518,7 @@ psymtab_to_symtab_1 (pst, filename) pdr_in = pr_block; pdr_in_end = pdr_in + fh->cpd; for (; pdr_in < pdr_in_end; pdr_in++) - parse_procedure (pdr_in, 0, pr_block->adr, pst); + parse_procedure (pdr_in, 0, pst); do_cleanups (old_chain); } @@ -3460,7 +3644,7 @@ cross_ref (fd, ax, tpp, type_code, pname, bigend, sym_name) } /* mips cc uses a rf of -1 for opaque struct definitions. - Set TYPE_FLAG_STUB for these types so that check_stub_type will + Set TYPE_FLAG_STUB for these types so that check_typedef will resolve them if the struct gets defined in another compilation unit. */ if (rf == -1) { @@ -3537,9 +3721,9 @@ cross_ref (fd, ax, tpp, type_code, pname, bigend, sym_name) For these the type will be void. This is a bad design decision as cross referencing across compilation units is impossible due to the missing name. - b) forward declarations of structs/unions/enums which are defined - later in this file or in another file in the same compilation - unit. Irix5 cc uses a stIndirect symbol for this. + b) forward declarations of structs/unions/enums/typedefs which + are defined later in this file or in another file in the same + compilation unit. Irix5 cc uses a stIndirect symbol for this. Simply cross reference those again to get the true type. The forward references are not entered in the pending list and in the symbol table. */ @@ -3568,6 +3752,23 @@ cross_ref (fd, ax, tpp, type_code, pname, bigend, sym_name) fh->fBigendian, sym_name); break; + case btTypedef: + /* Follow a forward typedef. This might recursively + call cross_ref till we get a non typedef'ed type. + FIXME: This is not correct behaviour, but gdb currently + cannot handle typedefs without type copying. Type + copying is impossible as we might have mutual forward + references between two files and the copied type would not + get filled in when we later parse its definition. */ + *tpp = parse_type (xref_fd, + debug_info->external_aux + fh->iauxBase, + sh.index, + (int *)NULL, + fh->fBigendian, + debug_info->ss + fh->issBase + sh.iss); + add_pending (fh, esh, *tpp); + break; + default: complain (&illegal_forward_bt_complaint, tir.bt, sym_name); *tpp = init_type (type_code, 0, 0, (char *) NULL, @@ -3616,7 +3817,7 @@ static struct symbol * mylookup_symbol (name, block, namespace, class) char *name; register struct block *block; - enum namespace namespace; + namespace_enum namespace; enum address_class class; { register int bot, top, inc; @@ -3830,7 +4031,8 @@ new_symtab (name, maxsyms, maxlines, objfile) BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK); s->free_code = free_linetable; - + s->debugformat = obsavestring ("ECOFF", 5, + &objfile -> symbol_obstack); return (s); } @@ -3967,7 +4169,8 @@ new_symbol (name) sizeof (struct symbol))); memset ((PTR) s, 0, sizeof (*s)); - SYMBOL_NAME (s) = name; + SYMBOL_NAME (s) = obsavestring (name, strlen (name), + ¤t_objfile->symbol_obstack); SYMBOL_LANGUAGE (s) = psymtab_language; SYMBOL_INIT_DEMANGLED_NAME (s, ¤t_objfile->symbol_obstack); return s; @@ -4026,7 +4229,10 @@ elfmdebug_build_psymtabs (objfile, swap, sec, section_offsets) /* FIXME: This function is called only by mips-tdep.c. It needs to be here because it calls functions defined in this file, but perhaps - this could be handled in a better way. */ + this could be handled in a better way. Only compile it in when + tm-mips.h is included. */ + +#ifdef TM_MIPS_H void fixup_sigtramp () @@ -4128,6 +4334,8 @@ fixup_sigtramp () BLOCK_SYM (b, BLOCK_NSYMS (b)++) = s; } +#endif /* TM_MIPS_H */ + void _initialize_mdebugread () {