diff options
author | Stu Grossman <grossman@cygnus> | 1991-09-17 05:17:00 +0000 |
---|---|---|
committer | Stu Grossman <grossman@cygnus> | 1991-09-17 05:17:00 +0000 |
commit | 3eaebb754c0088104868c14e5bc9072225a9c512 (patch) | |
tree | 6e1254c052849fde2ca1d357a2da369475a0997e /gdb/mipsread.c | |
parent | 5e4953bc10261ebf8da309203673e9ed66899a5c (diff) | |
download | gdb-3eaebb754c0088104868c14e5bc9072225a9c512.zip gdb-3eaebb754c0088104868c14e5bc9072225a9c512.tar.gz gdb-3eaebb754c0088104868c14e5bc9072225a9c512.tar.bz2 |
Fix signed vs. unsigned char bug in parse_lines().
Diffstat (limited to 'gdb/mipsread.c')
-rw-r--r-- | gdb/mipsread.c | 444 |
1 files changed, 229 insertions, 215 deletions
diff --git a/gdb/mipsread.c b/gdb/mipsread.c index 2530eb7..c966d19 100644 --- a/gdb/mipsread.c +++ b/gdb/mipsread.c @@ -18,6 +18,21 @@ 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. */ +/* This module provides three functions: mipscoff_symfile_init, + which initializes to read a symbol file; mipscoff_new_init, which + discards existing cached information when all symbols are being + discarded; and mipscoff_symfile_read, which reads a symbol table + from a file. + + mipscoff_symfile_read only does the minimum work necessary for letting the + user "name" things symbolically; it does not read the entire symtab. + Instead, it reads the external and static symbols and puts them in partial + symbol tables. When more extensive information is requested of a + file, the corresponding partial symbol table is mutated into a full + fledged symbol table by going back and reading the symbols + for real. mipscoff_psymtab_to_symtab() is called indirectly through + a pointer in the psymtab to do this. */ + #include <stdio.h> #include "param.h" #include "obstack.h" @@ -35,33 +50,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <sym.h> #endif /* not CMUCS */ -/* Since these things are defined differently on various systems I'll - (re)define here what I really need in this module. I only assume the - three standard COFF structure definitions: filehdr, aouthdr, scnhdr */ -#define MIPS /* Kludge to get MIPS version of coff */ -#undef _ETEXT /* Avoid duplicated define from <syms.h> */ #include "ecoff.h" struct coff_exec { struct external_filehdr f; struct external_aouthdr a; }; -#undef a_magic -#undef a_text -#undef a_data -#undef a_bss -#undef a_syms -#undef a_entry -#define a_magic a.magic /* magic number */ -#define a_text a.tsize /* size of text segment */ -#define a_data a.dsize /* size of initialized data */ -#define a_bss a.bsize /* size of uninitialized data */ -#define a_syms f.f_nsyms /* size of symbol table */ -#define a_entry a.entry /* entry point */ - -#undef N_BADMAG -#define N_BADMAG(x) \ - (((x).a_magic)!=OMAGIC && ((x).a_magic)!=NMAGIC && ((x).a_magic)!=ZMAGIC) /* Things we import explicitly from other modules */ @@ -69,12 +63,8 @@ extern int info_verbose; extern struct block *block_for_pc(); extern void sort_symtab_syms(); -/* Forward declarations */ - -static void psymtab_to_symtab_1(); - -/* Macros and extra defs */ - +/* Various complaints about symbol reading that don't abort the process */ + struct complaint unknown_ext_complaint = {"unknown external symbol %s", 0, 0}; @@ -84,7 +74,24 @@ struct complaint unknown_sym_complaint = struct complaint unknown_st_complaint = {"with type %d", 0, 0}; -/* Already parsed symbols are marked specially */ +struct complaint block_overflow_complaint = + {"block containing %s overfilled", 0, 0}; + +struct complaint basic_type_complaint = + {"cannot map MIPS basic type 0x%x", 0, 0}; + +struct complaint unknown_type_qual_complaint = + {"unknown type qualifier 0x%x", 0, 0}; + +struct complaint array_bitsize_complaint = + {"size of array target type not known, assuming %d bits", 0, 0}; + +struct complaint array_parse_complaint = + {"array type with strange relative symbol", 0, 0}; + +/* Macros and extra defs */ + +/* Already-parsed symbols are marked specially */ #define stParsed stType @@ -95,7 +102,7 @@ struct complaint unknown_st_complaint = (((a) == GLEVEL_3) ? ((b) < GLEVEL_3) : \ ((b) == GLEVEL_3) ? -1 : (int)((b) - (a))) -/* When looking at .o files avoid tripping over bad addresses */ +/* When looking at .o files, avoid tripping over bad addresses */ #define SAFE_TEXT_ADDR 0x400000 #define SAFE_DATA_ADDR 0x10000000 @@ -108,6 +115,10 @@ struct complaint unknown_st_complaint = static struct symtab *cur_stab; +/* MIPS symtab header for the current file */ + +static HDRR *cur_hdr; + /* Pointer to current file decriptor record, and its index */ static FDR *cur_fdr; @@ -144,8 +155,7 @@ static struct type *builtin_type_enum; static struct type *builtin_type_range; static struct type *builtin_type_set; - -/* Forward decls */ +/* Forward declarations */ static struct symbol *new_symbol(); static struct type *new_type(); @@ -168,8 +178,13 @@ static struct partial_symtab *new_psymtab(); static struct partial_symtab *parse_fdr(); static int compare_psymbols(); +static void psymtab_to_symtab_1(); +static void add_block(); +static void add_symbol(); +static int add_line(); static void reorder_symtabs(); static void reorder_psymtabs(); +static void shrink_linetable(); /* Things we export to other modules */ @@ -178,22 +193,6 @@ static void reorder_psymtabs(); CORE_ADDR sigtramp_address, sigtramp_end; - -/* Functions that we really export */ - -/* THIS DESCRIPTION IS OBSOLETE POST-BFD; FIXME! */ -/* Basically, this module must provide two functions: symbol_file_command() - which loads the symbol table from a file, and add_file_command() which - adds more symbols to the symbol table (incrementally). - - These two functions only do the minimum work necessary for letting the - user "name" things symbolically, they do not read the entire symtab. - Instead, they read in the external and static symbols and put them in partial - symbol tables. When more extensive information is requested of a - file the corresponding partial symbol table is mutated into a full - fledged symbol table by going back and reading the relative symbols - for real. mipscoff_psymtab_to_symtab() is the function that does this */ - /* The entry point (starting address) of the file, if it is an executable. */ static CORE_ADDR entry_point; @@ -204,6 +203,10 @@ extern CORE_ADDR startup_file_end; /* From blockframe.c */ void mipscoff_new_init() { + /* If we have a file symbol header lying around, blow it away. */ + if (cur_hdr) + free ((char *)cur_hdr); + cur_hdr = 0; } void @@ -212,6 +215,7 @@ mipscoff_symfile_init (sf) { bfd *abfd = sf->sym_bfd; sf->sym_private = NULL; + /* Save startup file's range of PC addresses to help blockframe.c decide where the bottom of the stack is. */ if (bfd_get_file_flags (abfd) & EXEC_P) @@ -242,51 +246,14 @@ mipscoff_symfile_read(sf, addr, mainline) char *name = bfd_get_filename (abfd); int desc; register int val; - int num_symbols; int symtab_offset; int stringtab_offset; /* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */ desc = fileno ((FILE *)(abfd->iostream)); /* Raw file descriptor */ - num_symbols = bfd_get_symcount (abfd); /* How many syms */ -/* symtab_offset = obj_sym_filepos (abfd); * Symbol table file offset */ -/* stringtab_offset = symtab_offset + num_symbols * SYMESZ; * String tab */ /* End of warning */ -#ifdef TDESC - debug_info = text_hdr.s_relptr; - if (tdesc_handle) - { - dc_terminate (tdesc_handle); - tdesc_handle = 0; - } -#endif - -#if 0 - /* Read the line number table, all at once. */ - info->min_lineno_offset = 0; - info->max_lineno_offset = 0; - bfd_map_over_sections (abfd, find_linenos, info); - - val = init_lineno (desc, info->min_lineno_offset, - info->max_lineno_offset - info->min_lineno_offset); - if (val < 0) - error ("\"%s\": error reading line numbers\n", name); - - /* Now read the string table, all at once. */ - - val = init_stringtab (desc, stringtab_offset); - if (val < 0) - { - free_all_symtabs (); /* FIXME blows whole symtab */ - printf ("\"%s\": can't get string table", name); - fflush (stdout); - return; - } - make_cleanup (free_stringtab, 0); -#endif - - /* Position to read the symbol table. Do not read it all at once. */ + /* Position to read the symbol table. */ val = lseek (desc, (long)symtab_offset, 0); if (val < 0) perror_with_name (name); @@ -299,20 +266,9 @@ mipscoff_symfile_read(sf, addr, mainline) read_mips_symtab(abfd, desc); -/* patch_opaque_types ();*/ - - /* Sort symbols alphabetically within each block. */ - - sort_all_symtab_syms (); - /* Go over the misc symbol bunches and install them in vector. */ - condense_misc_bunches (0); -} - -void -mipscoff_symfile_discard() -{ + condense_misc_bunches (!mainline); } /* Exported procedure: Allocate zeroed memory */ @@ -330,10 +286,7 @@ char *xzalloc(size) most of the work to an ancillary procedure, and sorts and reorders the symtab list at the end */ -/* Forward decls */ -static HDRR *cur_hdr; /* MIPS symtab header for the current file */ - -void +static void mipscoff_psymtab_to_symtab(pst) struct partial_symtab *pst; { @@ -351,11 +304,10 @@ mipscoff_psymtab_to_symtab(pst) /* FIXME, we should use private data that is a proper pointer. */ cur_hdr = (HDRR *) pst->ldsymlen; - psymtab_to_symtab_1(pst); + psymtab_to_symtab_1(pst, pst->filename); reorder_symtabs(); - /* Finish up the debug error message. */ if (info_verbose) printf_filtered("done.\n"); } @@ -561,8 +513,9 @@ fixup_symtab( hdr, data, f_ptr) /* Find a file descriptor given its index RF relative to a file CF */ -static -FDR *get_rfd( cf, rf) +static FDR * +get_rfd (cf, rf) + int cf, rf; { register FDR *f; @@ -576,8 +529,8 @@ FDR *get_rfd( cf, rf) /* Return a safer print NAME for a file descriptor */ -static -char *fdr_name(name) +static char * +fdr_name(name) char *name; { if (name == (char *) -1) @@ -601,8 +554,7 @@ read_mips_symtab (abfd, desc) read_the_mips_symtab(abfd, desc, &end_of_text_seg); - parse_partial_symbols(cur_hdr, end_of_text_seg); - cur_hdr = 0; + parse_partial_symbols(end_of_text_seg); /* * Check to make sure file was compiled with -g. @@ -614,18 +566,10 @@ read_mips_symtab (abfd, desc) printf("\nYou should compile with -g2 or -g3 for best debugging support.\n"); fflush(stdout); } - - /* - * Dont allow char * to have a typename (else would get - * caddr_t.) - */ - TYPE_NAME(lookup_pointer_type(builtin_type_char)) = 0; } - /* Local utilities */ - /* Map of FDR indexes to partial symtabs */ static struct pst_map { @@ -804,7 +748,7 @@ lookup_numargs(adr) /* Release storage when done with this file */ -static +static void free_numargs() { struct numarg *n = numargs_list, *m; @@ -824,7 +768,7 @@ free_numargs() For blocks, procedures and types we open a new lexical context. This is basically just a big switch on the symbol's type */ -static +static void parse_symbol(sh, ax) SYMR *sh; AUXU *ax; @@ -843,7 +787,7 @@ parse_symbol(sh, ax) case stNil: break; - case stGlobal: /* external symbol, goes into the primary block */ + case stGlobal: /* external symbol, goes into global block */ class = LOC_STATIC; b = BLOCKVECTOR_BLOCK(BLOCKVECTOR(top_stack->cur_st), GLOBAL_BLOCK); @@ -851,14 +795,14 @@ parse_symbol(sh, ax) SYMBOL_VALUE_ADDRESS(s) = (CORE_ADDR)sh->value; goto data; - case stStatic: /* static data, goes into the current block. */ + case stStatic: /* static data, goes into current block. */ class = LOC_STATIC; b = top_stack->cur_block; s = new_symbol(sh->iss); SYMBOL_VALUE_ADDRESS(s) = (CORE_ADDR)sh->value; goto data; - case stLocal: /* local variable, goes into the current block */ + case stLocal: /* local variable, goes into current block */ if (sh->sc == scRegister) { class = LOC_REGISTER; if (sh->value > 31) @@ -883,7 +827,7 @@ data: /* Common code for symbols describing data */ /* Value of a data symbol is its memory address */ break; - case stParam: /* argument to procedure, goes into current block */ + case stParam: /* arg to procedure, goes into current block */ max_gdbinfo++; top_stack->numargs++; s = new_symbol(sh->iss); @@ -899,7 +843,7 @@ data: /* Common code for symbols describing data */ add_symbol(s, top_stack->cur_block); break; - case stLabel: /* label, we do make a symbol for it */ + case stLabel: /* label, goes into current block */ s = new_symbol(sh->iss); SYMBOL_NAMESPACE(s) = VAR_NAMESPACE; /* so that it can be used */ SYMBOL_CLASS(s) = LOC_LABEL; /* but not misused */ @@ -908,8 +852,8 @@ data: /* Common code for symbols describing data */ add_symbol(s, top_stack->cur_block); break; - case stProc: /* Procedure */ - case stStaticProc: /* Static procedure */ + case stProc: /* Procedure, goes into current block? FIXME */ + case stStaticProc: /* Static procedure, goes into current block */ s = new_symbol(sh->iss); SYMBOL_NAMESPACE(s) = VAR_NAMESPACE; SYMBOL_CLASS(s) = LOC_BLOCK; @@ -1113,7 +1057,7 @@ static struct type *parse_type(ax, sh, bs) /* Use aux as a type information record, map its basic type */ t = &ax->ti; if (t->bt > 26 || t->bt == btPicture) { - printf_filtered("Internal: cannot map MIPS basic type x%x\n", t->bt); + complain (&basic_type_complaint, t->bt); return builtin_type_int; } if (map_bt[t->bt]) @@ -1249,72 +1193,97 @@ again: PARSE_TQ(tq0); the symbol SX we are currently analyzing. Returns the number of aux symbols we parsed. */ -static +static int upgrade_type(tpp, tq, ax, sh) struct type **tpp; AUXU *ax; SYMR *sh; { - int off = 0; - int ret = 0; + int off; struct type *t; - if (tq == tqPtr) { + /* Used in array processing */ + int rf, id; + FDR *fh; + struct field *f; + SYMR ss; + int lower, upper; + + switch (tq) { + case tqPtr: t = lookup_pointer_type (*tpp); - } else if (tq == tqProc) { + *tpp = t; + return 0; + + case tqProc: t = lookup_function_type (*tpp); - } else if (tq == tqArray) { - int rf, id; - FDR *fh; - struct field *f; - SYMR ss; + *tpp = t; + return 0; + case tqArray: + off = 0; t = make_type(TYPE_CODE_ARRAY, 0, 0, 0); TYPE_TARGET_TYPE(t) = *tpp; - /* Pointer to domain type (type of index) */ + /* Determine and record the domain type (type of index) */ id = ax->rndx.index; - if ((rf = ax->rndx.rfd) == 0xfff) - rf = (++ax)->isym, off++; - + rf = ax->rndx.rfd; + if (rf == 0xfff) { + rf = (++ax)->isym; + off++; + } fh = get_rfd(cur_fd, rf); - f = new_field(t, 0); + f = new_field(t, (char *)0); bzero(&ss, sizeof ss); /* XXX */ f->type = parse_type(fh->iauxBase + id * sizeof(AUXU), &ss, &f->bitsize); + if (off == 0) { /* * This seems to be a pointer to the end of the Block defining * the type. Why it is here is magic for me, and I have no * good use for it anyways. */ - if (off == 0) { + /* This used to occur because cross_ref returned + the wrong result (ax pointed wrong). FIXME, + delete this code in a while. -- gnu@cygnus jul91 */ + complain (&array_parse_complaint, 0); off++; id = (++ax)->rndx.index; if ((rf = ax->rndx.rfd) == 0xfff) rf = (++ax)->isym, off++; } - f->bitpos = (++ax)->dnLow; /* ?? */ - f->bitsize = (++ax)->dnHigh; /* ?? */ - rf = (++ax)->width - 1; /* bit alignment */ + lower = (++ax)->dnLow; + upper = (++ax)->dnHigh; + rf = (++ax)->width; /* bit size of array element */ + + /* Check whether supplied array element bit size matches + the known size of the element type. If this complaint + ends up not happening, we can remove this code. It's + here because we aren't sure we understand this *&%&$ + symbol format. */ id = TYPE_LENGTH(TYPE_TARGET_TYPE(t)) << 3; /* bitsize */ - if (id == 0) { /* Most likely an undefined type */ - id = rf + 1; + id = rf; TYPE_LENGTH(TYPE_TARGET_TYPE(t)) = id >> 3; } - TYPE_LENGTH(t) = (f->bitsize < 0) ? 0 : - (f->bitsize - f->bitpos + 1) * (id >> 3); - ret = 4 + off; - } else { - if (tq != tqVol) - printf_filtered("Internal: unknown type qualifier %x\n", tq); - return ret; - } + if (id != rf) + complain (&array_bitsize_complaint, rf); + + TYPE_LENGTH(t) = (upper < 0) ? 0 : + (upper - lower + 1) * (rf >> 3); + *tpp = t; + return 4 + off; - *tpp = t; - return ret; + case tqVol: + /* Volatile -- currently ignored */ + return 0; + + default: + complain (&unknown_type_qual_complaint, tq); + return 0; + } } @@ -1412,14 +1381,14 @@ parse_external(es, skip_procedures) char *what; switch (es->asym.st) { case stStaticProc: - case stProc: what = "Procedure"; n_undef_procs++; break; - case stGlobal: what = "Variable"; n_undef_vars++; break; - case stLabel: what = "Label"; n_undef_labels++; break; - default : what = "Symbol"; break; + case stProc: what = "procedure"; n_undef_procs++; break; + case stGlobal: what = "variable"; n_undef_vars++; break; + case stLabel: what = "label"; n_undef_labels++; break; + default : what = "symbol"; break; } n_undef_symbols++; if (info_verbose) - printf_filtered("Warning: %s %s is undefined (in %s)\n", what, + printf_filtered("Warning: %s `%s' is undefined (in %s)\n", what, es->asym.iss, fdr_name(cur_fdr->rss)); return; } @@ -1457,7 +1426,7 @@ parse_lines(fh, lt) FDR *fh; struct linetable *lt; { - char *base = (char*)fh->cbLineOffset; + unsigned char *base = (unsigned char*)fh->cbLineOffset; int i, j, k; int delta, count, lineno = 0; PDR *pr; @@ -1491,14 +1460,16 @@ parse_lines(fh, lt) */ if (pr->iline >= halt) continue; - base = (char*)pr->cbLineOffset; + base = (unsigned char*)pr->cbLineOffset; l = pr->adr >> 2; /* in words */ halt += (pr->adr >> 2) - pr->iline; for (lineno = pr->lnLow; l < halt;) { count = *base & 0x0f; delta = *base++ >> 4; + if (delta >= 8) + delta -= 16; if (delta == -8) { - delta = (base[0] << 8) | (base[1] & 0xff); + delta = (base[0] << 8) | base[1]; base += 2; } lineno += delta;/* first delta is 0 */ @@ -1549,16 +1520,17 @@ parse_one_file(fh, f_idx, bound) /* Master parsing procedure for first-pass reading of file symbols into a partial_symtab. - Parses the symtab described by the symbolic header HDR. + Parses the symtab described by the global symbolic header CUR_HDR. END_OF_TEXT_SEG gives the address just after the text segment for the symtab we are reading. */ static -parse_partial_symbols(hdr, end_of_text_seg) - HDRR *hdr; +parse_partial_symbols(end_of_text_seg) + int end_of_text_seg; { int f_idx, s_idx, h_max, stat_idx; CORE_ADDR dummy, *prevhigh; + HDRR *hdr; /* Running pointers */ FDR *fh; RFDT *rh; @@ -1575,7 +1547,7 @@ parse_partial_symbols(hdr, end_of_text_seg) * look at. (XXX) */ - cur_hdr = hdr; + hdr = cur_hdr; max_gdbinfo = 0; max_glevel = MIN_GLEVEL; @@ -1776,6 +1748,12 @@ parse_partial_symbols(hdr, end_of_text_seg) dependent file it will cause loading of foo.c as well, so everything will be fine at the end. */ + /* First, sort the psymtabs by their textlow addresses. */ + reorder_psymtabs(); + + /* Now, rip through and fill in "texthigh" from the textlow + of the following psymtab. Slimy but it might work. + Sort the global psymbols while we're at it. */ prevhigh = &dummy; for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++) { struct partial_symtab *pst = fdr_to_pst[f_idx].pst; @@ -1793,7 +1771,6 @@ parse_partial_symbols(hdr, end_of_text_seg) *prevhigh = end_of_text_seg; hdr->cbDnOffset = end_of_text_seg; - reorder_psymtabs(); free(&fdr_to_pst[-1]); fdr_to_pst = 0; } @@ -1855,12 +1832,12 @@ parse_fdr(f_idx, lev) pst->number_of_dependencies = fh->crfd - s_id0; pst->dependencies = (struct partial_symtab **) obstack_alloc (psymbol_obstack, - pst->number_of_dependencies * sizeof(char*)); + pst->number_of_dependencies * + sizeof (struct partial_symtab *)); for (s_idx = s_id0; s_idx < fh->crfd; s_idx++) { RFDT *rh = (RFDT *) (fh->rfdBase) + s_idx; pst->dependencies[s_idx-s_id0] = parse_fdr(*rh, lev+1); - } return pst; @@ -1869,11 +1846,14 @@ parse_fdr(f_idx, lev) /* Ancillary function to psymtab_to_symtab(). Does all the work for turning the partial symtab PST into a symtab, recurring - first on all dependent psymtabs */ + first on all dependent psymtabs. The argument FILENAME is + only passed so we can see in debug stack traces what file + is being read. */ static void -psymtab_to_symtab_1(pst) +psymtab_to_symtab_1(pst, filename) struct partial_symtab *pst; + char *filename; { int i, f_max; struct symtab *st; @@ -1891,6 +1871,7 @@ psymtab_to_symtab_1(pst) } /* How many symbols will we need */ + /* FIXME, this does not count enum values. */ f_max = pst->n_global_syms + pst->n_static_syms; if (pst->ldsymoff == -1) { fh = 0; @@ -1901,17 +1882,27 @@ psymtab_to_symtab_1(pst) st = new_symtab(pst->filename, 2 * f_max, 2 * fh->cline); } - /* - * Read in all partial symbtabs on which this one is dependent. - * NOTE that we do have circular dependencies, sigh. - */ + /* Read in all partial symbtabs on which this one is dependent. + NOTE that we do have circular dependencies, sigh. We solved + that by setting pst->readin before this point. */ + for (i = 0; i < pst->number_of_dependencies; i++) if (!pst->dependencies[i]->readin) { - /* - * DO NOT inform about additional files that need to - * be read in, it would only annoy the user. - */ - psymtab_to_symtab_1(pst->dependencies[i]); + /* Inform about additional files to be read in. */ + if (info_verbose) + { + fputs_filtered (" ", stdout); + wrap_here (""); + fputs_filtered ("and ", stdout); + wrap_here (""); + printf_filtered ("%s...", + pst->dependencies[i]->filename); + wrap_here (""); /* Flush output */ + fflush (stdout); + } + /* We only pass the filename for debug purposes */ + psymtab_to_symtab_1(pst->dependencies[i], + pst->dependencies[i]->filename); } /* Now read the symbols for this symtab */ @@ -1929,7 +1920,7 @@ psymtab_to_symtab_1(pst) BLOCK_START(top_stack->cur_block) = fh ? fh->adr : 0; BLOCK_END(top_stack->cur_block) = 0; top_stack->blocktype = stFile; - top_stack->maxsyms = f_max; + top_stack->maxsyms = 2*f_max; top_stack->cur_type = 0; top_stack->procadr = 0; top_stack->numargs = 0; @@ -2032,7 +2023,9 @@ cross_ref(rn, tpp, pname) add_pending(fh, sh, *tpp); } } - return (rn->rfd == 0xfff); + + /* We used one auxent normally, two if we got a "next one" rf. */ + return (rn->rfd == 0xfff? 2: 1); } @@ -2067,23 +2060,44 @@ mylookup_symbol (name, block, namespace, class) } -/* Add a new symbol S to a block B */ +/* Add a new symbol S to a block B. + Infrequently, we will need to reallocate the block to make it bigger. + We only detect this case when adding to top_stack->cur_block, since + that's the only time we know how big the block is. FIXME. */ -static +static void add_symbol(s,b) struct symbol *s; struct block *b; { - BLOCK_SYM(b,BLOCK_NSYMS(b)++) = s; + int nsyms = BLOCK_NSYMS(b)++; + struct block *origb; + struct parse_stack *stackp; + if (b == top_stack->cur_block && - BLOCK_NSYMS(b) > top_stack->maxsyms) - printf_filtered("Internal: block at @%x overfilled (by %d)\n", - b, BLOCK_NSYMS(b) - top_stack->maxsyms); + nsyms >= top_stack->maxsyms) { + complain (&block_overflow_complaint, s->name); + /* In this case shrink_block is actually grow_block, since + BLOCK_NSYMS(b) is larger than its current size. */ + origb = b; + b = shrink_block (top_stack->cur_block, top_stack->cur_st); + + /* Now run through the stack replacing pointers to the + original block. shrink_block has already done this + for the blockvector and BLOCK_FUNCTION. */ + for (stackp = top_stack; stackp; stackp = stackp->next) { + if (stackp->cur_block == origb) { + stackp->cur_block = b; + stackp->maxsyms = BLOCK_NSYMS (b); + } + } + } + BLOCK_SYM(b,nsyms) = s; } /* Add a new block B to a symtab S */ -static +static void add_block(b,s) struct block *b; struct symtab *s; @@ -2102,10 +2116,12 @@ add_block(b,s) MIPS' linenumber encoding might need more than one byte to describe it, LAST is used to detect these continuation lines */ -static +static int add_line(lt, lineno, adr, last) struct linetable *lt; + int lineno; CORE_ADDR adr; + int last; { if (last == 0) last = -2; /* make sure we record first line */ @@ -2391,7 +2407,8 @@ struct linetable *new_linetable(size) /* Oops, too big. Shrink it. This was important with the 2.4 linetables, I am not so sure about the 3.4 ones */ -static shrink_linetable(s) +static void +shrink_linetable(s) struct symtab *s; { struct linetable *l = new_linetable(LINETABLE(s)->nitems); @@ -2405,7 +2422,8 @@ static shrink_linetable(s) /* Allocate and zero a new blockvector of NBLOCKS blocks. */ static -struct blockvector *new_bvect(nblocks) +struct blockvector * +new_bvect(nblocks) { struct blockvector *bv; int size; @@ -2421,7 +2439,8 @@ struct blockvector *new_bvect(nblocks) /* Allocate and zero a new block of MAXSYMS symbols */ static -struct block *new_block(maxsyms) +struct block * +new_block(maxsyms) { int size = sizeof(struct block) + (maxsyms-1) * sizeof(struct symbol *); struct block *b = (struct block *)xzalloc(size); @@ -2429,7 +2448,8 @@ struct block *new_block(maxsyms) return b; } -/* Ooops, too big. Shrink block B in symtab S to its minimal size */ +/* Ooops, too big. Shrink block B in symtab S to its minimal size. + Shrink_block can also be used by add_symbol to grow a block. */ static struct block * shrink_block(b, s) @@ -2440,23 +2460,20 @@ shrink_block(b, s) struct blockvector *bv = BLOCKVECTOR(s); int i; - /* Just get a new one, copy, and fix references to the old one */ + /* Just reallocate it and fix references to the old one */ - new = (struct block *)xmalloc(sizeof(struct block) + + new = (struct block *) xrealloc ((char *)b, sizeof(struct block) + (BLOCK_NSYMS(b)-1) * sizeof(struct symbol *)); - bcopy(b, new, sizeof(*new) + (BLOCK_NSYMS(b) - 1) * sizeof(struct symbol*)); - /* Should chase pointers to old one. Fortunately, that`s just the block`s function and inferior blocks */ - if (BLOCK_FUNCTION(b) && SYMBOL_BLOCK_VALUE(BLOCK_FUNCTION(b)) == b) - SYMBOL_BLOCK_VALUE(BLOCK_FUNCTION(b)) = new; + if (BLOCK_FUNCTION(new) && SYMBOL_BLOCK_VALUE(BLOCK_FUNCTION(new)) == b) + SYMBOL_BLOCK_VALUE(BLOCK_FUNCTION(new)) = new; for (i = 0; i < BLOCKVECTOR_NBLOCKS(bv); i++) if (BLOCKVECTOR_BLOCK(bv,i) == b) BLOCKVECTOR_BLOCK(bv,i) = new; else if (BLOCK_SUPERBLOCK(BLOCKVECTOR_BLOCK(bv,i)) == b) BLOCK_SUPERBLOCK(BLOCKVECTOR_BLOCK(bv,i)) = new; - free(b); return new; } @@ -2515,7 +2532,8 @@ make_type(code, length, uns, name) /* Allocate a new field named NAME to the type TYPE */ static -struct field *new_field(type,name) +struct field * +new_field(type,name) struct type *type; char *name; { @@ -2526,11 +2544,11 @@ struct field *new_field(type,name) TYPE_FIELDS(type) = (struct field*)xrealloc(TYPE_FIELDS(type), (TYPE_NFIELDS(type)+1) * sizeof(struct field)); else - TYPE_FIELDS(type) = (struct field*)xzalloc(2*sizeof(struct field)); - f = &(TYPE_FIELD(type,TYPE_NFIELDS(type)++)); + TYPE_FIELDS(type) = (struct field*)xzalloc(sizeof(struct field)); + f = &(TYPE_FIELD(type,TYPE_NFIELDS(type))); + TYPE_NFIELDS(type)++; bzero(f, sizeof(struct field)); - if (name) - f->name = name; + f->name = name; /* Whether or not NAME is zero, this works. */ return f; } @@ -2726,21 +2744,17 @@ fixup_sigtramp() BLOCK_SYM(b,BLOCK_NSYMS(b)++) = s; } - /* Initialization */ static struct sym_fns ecoff_sym_fns = {"ecoff", 5, mipscoff_new_init, mipscoff_symfile_init, - mipscoff_symfile_read, mipscoff_symfile_discard}; + mipscoff_symfile_read}; _initialize_mipsread () { add_symtab_fns (&ecoff_sym_fns); - bzero (&global_psymbols, sizeof (global_psymbols)); - bzero (&static_psymbols, sizeof (static_psymbols)); - /* Missing basic types */ builtin_type_string = make_type(TYPE_CODE_PASCAL_ARRAY, 1, 0, "string"); |