X-Git-Url: https://repo.jachan.dev/binutils.git/blobdiff_plain/7c622b41052032c7d28eb261319e85f9af9d12d0..86165efce578a0e5a8c8265a8e668498fab318ea:/gdb/buildsym.c diff --git a/gdb/buildsym.c b/gdb/buildsym.c index 21020befa9..e4dcbddc56 100644 --- a/gdb/buildsym.c +++ b/gdb/buildsym.c @@ -39,6 +39,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "buildsym.h" /* Our own declarations */ #undef EXTERN +/* For cleanup_undefined_types and finish_global_stabs (somewhat + questionable--see comment where we call them). */ +#include "stabsread.h" + static int compare_line_numbers PARAMS ((const void *, const void *)); @@ -62,7 +66,7 @@ struct complaint innerblock_anon_complaint = {"inner block not inside outer block", 0, 0}; struct complaint blockvector_complaint = - {"block at 0x%x out of order", 0, 0}; + {"block at 0x%lx out of order", 0, 0}; /* maintain the lists of symbols and blocks */ @@ -98,7 +102,8 @@ add_symbol_to_list (symbol, listhead) (*listhead)->symbol[(*listhead)->nsyms++] = symbol; } -/* Find a symbol on a pending list. */ +/* Find a symbol named NAME on a LIST. NAME need not be '\0'-terminated; + LENGTH is the length of the name. */ struct symbol * find_symbol_in_list (list, name, length) @@ -297,7 +302,7 @@ finish_block (symbol, listhead, old_blocks, start, end, objfile) static struct blockvector * make_blockvector (objfile) - struct objfile *objfile; + struct objfile *objfile; { register struct pending_block *next; register struct blockvector *blockvector; @@ -346,8 +351,17 @@ make_blockvector (objfile) if (BLOCK_START(BLOCKVECTOR_BLOCK (blockvector, i-1)) > BLOCK_START(BLOCKVECTOR_BLOCK (blockvector, i))) { + + /* FIXME-32x64: loses if CORE_ADDR doesn't fit in a + long. Possible solutions include a version of + complain which takes a callback, a + sprintf_address_numeric to match + print_address_numeric, or a way to set up a GDB_FILE + * which causes sprintf rather than fprintf to be + called. */ + complain (&blockvector_complaint, - BLOCK_START(BLOCKVECTOR_BLOCK (blockvector, i))); + (unsigned long) BLOCK_START(BLOCKVECTOR_BLOCK (blockvector, i))); } } } @@ -358,7 +372,9 @@ make_blockvector (objfile) /* Start recording information about source code that came from an included - (or otherwise merged-in) source file with a different name. */ + (or otherwise merged-in) source file with a different name. NAME is + the name of the file (cannot be NULL), DIRNAME is the directory in which + it resides (or NULL if not known). */ void start_subfile (name, dirname) @@ -389,8 +405,9 @@ start_subfile (name, dirname) current_subfile = subfile; /* Save its name and compilation directory name */ - subfile->name = (name == NULL)? NULL : strdup (name); - subfile->dirname = (dirname == NULL) ? NULL : strdup (dirname); + subfile->name = (name == NULL) ? NULL : savestring (name, strlen (name)); + subfile->dirname = + (dirname == NULL) ? NULL : savestring (dirname, strlen (dirname)); /* Initialize line-number recording for this subfile. */ subfile->line_vector = NULL; @@ -412,6 +429,34 @@ start_subfile (name, dirname) { subfile->language = subfile->next->language; } + + /* cfront output is a C program, so in most ways it looks like a C + program. But to demangle we need to set the language to C++. We + can distinguish cfront code by the fact that it has #line + directives which specify a file name ending in .C. + + So if the filename of this subfile ends in .C, then change the language + of any pending subfiles from C to C++. We also accept any other C++ + suffixes accepted by deduce_language_from_filename (in particular, + some people use .cxx with cfront). */ + + if (subfile->name) + { + struct subfile *s; + + if (deduce_language_from_filename (subfile->name) == language_cplus) + for (s = subfiles; s != NULL; s = s->next) + if (s->language == language_c) + s->language = language_cplus; + } + + /* And patch up this file if necessary. */ + if (subfile->language == language_c + && subfile->next != NULL + && subfile->next->language == language_cplus) + { + subfile->language = language_cplus; + } } /* For stabs readers, the first N_SO symbol is assumed to be the source @@ -435,7 +480,7 @@ patch_subfile_names (subfile, name) && subfile->name[strlen(subfile->name)-1] == '/') { subfile->dirname = subfile->name; - subfile->name = strdup (name); + subfile->name = savestring (name, strlen (name)); /* Default the source language to whatever can be deduced from the filename. If nothing can be deduced (such as for a C/C++ @@ -495,7 +540,8 @@ pop_subfile () } -/* Manage the vector of line numbers for each subfile. */ +/* Add a linetable entry for line number LINE and address PC to the line + vector for SUBFILE. */ void record_line (subfile, line, pc) @@ -541,8 +587,20 @@ compare_line_numbers (ln1p, ln2p) const PTR ln1p; const PTR ln2p; { - return (((struct linetable_entry *) ln1p) -> line - - ((struct linetable_entry *) ln2p) -> line); + struct linetable_entry *ln1 = (struct linetable_entry *) ln1p; + struct linetable_entry *ln2 = (struct linetable_entry *) ln2p; + + /* Note: this code does not assume that CORE_ADDRs can fit in ints. + Please keep it that way. */ + if (ln1->pc < ln2->pc) + return -1; + + if (ln1->pc > ln2->pc) + return 1; + + /* If pc equal, sort by line. I'm not sure whether this is optimum + behavior (see comment at struct linetable in symtab.h). */ + return ln1->line - ln2->line; } @@ -588,6 +646,8 @@ start_symtab (name, dirname, start_addr) for that file and put it in the list of all such. END_ADDR is the address of the end of the file's text. + SECTION is the section number (in objfile->section_offsets) of + the blockvector and linetable. Note that it is possible for end_symtab() to return NULL. In particular, for the DWARF case at least, it will return NULL when it finds a @@ -597,13 +657,14 @@ start_symtab (name, dirname, start_addr) because then gdb will never know about this empty file (FIXME). */ struct symtab * -end_symtab (end_addr, sort_pending, sort_linevec, objfile) +end_symtab (end_addr, sort_pending, sort_linevec, objfile, section) CORE_ADDR end_addr; int sort_pending; int sort_linevec; struct objfile *objfile; + int section; { - register struct symtab *symtab; + register struct symtab *symtab = NULL; register struct blockvector *blockvector; register struct subfile *subfile; register struct context_stack *cstk; @@ -620,11 +681,16 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile) finish_block (cstk->name, &local_symbols, cstk->old_blocks, cstk->start_addr, end_addr, objfile); - /* Debug: if context stack still has something in it, - we are in trouble. */ if (context_stack_depth > 0) { - abort (); + /* This is said to happen with SCO. The old coffread.c code + simply emptied the context stack, so we do the same. FIXME: + Find out why it is happening. This is not believed to happen + in most cases (even for coffread.c); it used to be an abort(). */ + static struct complaint msg = + {"Context stack not empty in end_symtab", 0, 0}; + complain (&msg); + context_stack_depth = 0; } } @@ -665,7 +731,13 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile) /* Cleanup any undefined types that have been left hanging around (this needs to be done before the finish_blocks so that file_symbols is still good). - FIXME: Stabs specific. */ + + Both cleanup_undefined_types and finish_global_stabs are stabs + specific, but harmless for other symbol readers, since on gdb + startup or when finished reading stabs, the state is set so these + are no-ops. FIXME: Is this handled right in case of QUIT? Can + we make this cleaner? */ + cleanup_undefined_types (); finish_global_stabs (objfile); @@ -695,7 +767,7 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile) for (subfile = subfiles; subfile; subfile = nextsub) { - int linetablesize; + int linetablesize = 0; /* If we have blocks of symbols, make a symtab. Otherwise, just ignore this file and any line number info in it. */ symtab = NULL; @@ -703,11 +775,20 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile) { if (subfile->line_vector) { - /* First, shrink the linetable to make more memory. */ linetablesize = sizeof (struct linetable) + subfile->line_vector->nitems * sizeof (struct linetable_entry); +#if 0 + /* I think this is artifact from before it went on the obstack. + I doubt we'll need the memory between now and when we + free it later in this function. */ + /* First, shrink the linetable to make more memory. */ subfile->line_vector = (struct linetable *) xrealloc ((char *) subfile->line_vector, linetablesize); +#endif + /* If sort_linevec is false, we might want just check to make + sure they are sorted and complain() if not, as a way of + tracking down compilers/symbol readers which don't get + them sorted right. */ if (sort_linevec) qsort (subfile->line_vector->item, @@ -731,6 +812,7 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile) { symtab->linetable = NULL; } + symtab->block_line_section = section; if (subfile->dirname) { /* Reallocate the dirname on the symbol obstack */ @@ -753,14 +835,11 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile) language it is from things we found in the symbols. */ symtab->language = subfile->language; -#ifdef IBM6000_TARGET - /* In case we need to duplicate symbol tables (to represent include - files), and in case our system needs relocation, we want to - relocate the main symbol table node only (for the main file, - not for the include files). */ + /* All symtabs for the main file and the subfiles share a + blockvector, so we need to clear primary for everything but + the main file. */ - symtab->nonreloc = TRUE; -#endif + symtab->primary = 0; } if (subfile->name != NULL) { @@ -779,14 +858,11 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile) free ((PTR)subfile); } -#ifdef IBM6000_TARGET - /* all include symbol tables are non-relocatable, except the main source - file's. */ + /* Set this for the main source file. */ if (symtab) { - symtab->nonreloc = FALSE; + symtab->primary = 1; } -#endif last_source_file = NULL; current_subfile = NULL; @@ -825,6 +901,37 @@ push_context (desc, valu) return (new); } + +/* Compute a small integer hash code for the given name. */ + +int +hashname (name) + char *name; +{ + register char *p = name; + register int total = p[0]; + register int c; + + c = p[1]; + total += c << 2; + if (c) + { + c = p[2]; + total += c << 4; + if (c) + { + total += p[3] << 6; + } + } + + /* Ensure result is positive. */ + if (total < 0) + { + total += (1000 << 6); + } + return (total % HASHSIZE); +} + /* Initialize anything that needs initializing when starting to read a fresh piece of a symbol file, e.g. reading in the stuff corresponding