From: John Gilmore Date: Sun, 27 Oct 1991 22:26:02 +0000 (+0000) Subject: * buildsym.c: Break out initial malloc sizes. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4137c5fc0d1b24d00ceec0981ea5d9da77477f0e;p=binutils-gdb.git * buildsym.c: Break out initial malloc sizes. (record_line): Record directly in a subfile. Alloc on demand. (compare_line_numbers): Add from xcoffread.c. (end_symtab): New params say whether to sort pendings and linetable. Patch block stabs if defined. Shrink linetable before allocating the symtab. * buildsym.h: Delete line_vector* and prev_line_number. Add global_stabs and file_stabs for xcoffread. * dbxread.c (start_subfile): Move to buildsym. Change above calls. * symtab.h: LINETABLE(symtab) can now be null. Zap LINELIST. * symmisc.c, symtab.c: Cope with null LINETABLEs. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 3ff9fd1f01b..cf279c0ade1 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,25 @@ +Sun Oct 27 14:09:25 1991 John Gilmore (gnu at cygnus.com) + + * buildsym.c: Break out initial malloc sizes. + (record_line): Record directly in a subfile. Alloc on demand. + (compare_line_numbers): Add from xcoffread.c. + (end_symtab): New params say whether to sort pendings and + linetable. Patch block stabs if defined. Shrink linetable before + allocating the symtab. + * buildsym.h: Delete line_vector* and prev_line_number. Add + global_stabs and file_stabs for xcoffread. + * dbxread.c (start_subfile): Move to buildsym. Change above calls. + * symtab.h: LINETABLE(symtab) can now be null. Zap LINELIST. + * symmisc.c, symtab.c: Cope with null LINETABLEs. + + * blockframe.c: Pass fromleaf to INIT_EXTRA_FRAME_INFO. + * tm-29k.h, tm-88k.h, tm-i960.h, tm-irix3.h, tm-mips.h, tm-pyr.h, + tm-sparc.h: Accept fromleaf parameter. + * c-exp.y (yyerror): Pass error message if given. + * configure.in: Add rs6000 host and target. + * inflow.c (new_tty): O_NOCTTY kludge for RS/6000. + * symfile.h (entry_point): Add. + Sat Oct 26 00:16:32 1991 John Gilmore (gnu at cygus.com) * buildsym.c: New file. Breaks out symbol-table-building routines diff --git a/gdb/buildsym.c b/gdb/buildsym.c index 2920b86c1ec..09d6c01df49 100644 --- a/gdb/buildsym.c +++ b/gdb/buildsym.c @@ -46,9 +46,10 @@ extern double atof (); /* Things we export from outside, and probably shouldn't. FIXME. */ extern void new_object_header_files (); -extern void start_subfile (); extern char *next_symbol_text (); extern int hashname (); +extern void patch_block_stabs (); /* AIX xcoffread.c */ +#define patch_block_stabs abort /* FIXME scaffolding */ static struct symbol *define_symbol (); static void cleanup_undefined_types (); @@ -70,6 +71,12 @@ static const char vb_name[] = { '_','v','b',CPLUS_MARKER,'\0' }; static struct type **undef_types; static int undef_types_allocated, undef_types_length; +/* Initial sizes of data structures. These are realloc'd larger if needed, + and realloc'd down to the size actually used, when completed. */ + +#define INITIAL_CONTEXT_STACK_SIZE 10 +#define INITIAL_TYPE_VECTOR_LENGTH 160 +#define INITIAL_LINE_VECTOR_LENGTH 1000 /* Complaints about the symbols we have encountered. */ @@ -174,6 +181,7 @@ dbx_create_type () /* Make sure there is a type allocated for type numbers TYPENUMS and return the type object. This can create an empty (zeroed) type object. +OBSOLETE -- call dbx_create_type instead -- FIXME: TYPENUMS may be (-1, -1) to return a new type object that is not put into the type vector, and so may not be referred to by number. */ @@ -191,6 +199,7 @@ dbx_alloc_type (typenums) } else { + abort(); /* FIXME -- Must give a real type number now */ type_addr = 0; type = 0; } @@ -445,10 +454,53 @@ make_blockvector () return blockvector; } -/* Manage the vector of line numbers. */ +/* Start recording information about source code that came from an included + (or otherwise merged-in) source file with a different name. */ + +void +start_subfile (name, dirname) + char *name; + char *dirname; +{ + register struct subfile *subfile; + + /* See if this subfile is already known as a subfile of the + current main source file. */ + + for (subfile = subfiles; subfile; subfile = subfile->next) + { + if (!strcmp (subfile->name, name)) + { + current_subfile = subfile; + return; + } + } + + /* This subfile is not known. Add an entry for it. + Make an entry for this subfile in the list of all subfiles + of the current main source file. */ + + subfile = (struct subfile *) xmalloc (sizeof (struct subfile)); + subfile->next = subfiles; + subfiles = subfile; + current_subfile = subfile; + + /* Save its name and compilation directory name */ + subfile->name = obsavestring (name, strlen (name)); + if (dirname == NULL) + subfile->dirname = NULL; + else + subfile->dirname = obsavestring (dirname, strlen (dirname)); + + /* Initialize line-number recording for this subfile. */ + subfile->line_vector = 0; +} + +/* Manage the vector of line numbers for each subfile. */ void -record_line (line, pc) +record_line (subfile, line, pc) + register struct subfile *subfile; int line; CORE_ADDR pc; { @@ -458,21 +510,37 @@ record_line (line, pc) if (line == 0xffff) return; - /* Make sure line vector is big enough. */ + /* Make sure line vector exists and is big enough. */ + if (!subfile->line_vector) { + subfile->line_vector_length = INITIAL_LINE_VECTOR_LENGTH; + subfile->line_vector = (struct linetable *) + xmalloc (sizeof (struct linetable) + + subfile->line_vector_length * sizeof (struct linetable_entry)); + subfile->line_vector->nitems = 0; + } - if (line_vector_index + 1 >= line_vector_length) + if (subfile->line_vector->nitems + 1 >= subfile->line_vector_length) { - line_vector_length *= 2; - line_vector = (struct linetable *) - xrealloc (line_vector, - (sizeof (struct linetable) - + line_vector_length * sizeof (struct linetable_entry))); - current_subfile->line_vector = line_vector; + subfile->line_vector_length *= 2; + subfile->line_vector = (struct linetable *) + xrealloc (subfile->line_vector, (sizeof (struct linetable) + + subfile->line_vector_length * sizeof (struct linetable_entry))); } - e = line_vector->item + line_vector_index++; + e = subfile->line_vector->item + subfile->line_vector->nitems++; e->line = line; e->pc = pc; } + + +/* Needed in order to sort line tables from IBM xcoff files. Sigh! */ + +/* static */ +int +compare_line_numbers (ln1, ln2) + struct linetable_entry *ln1, *ln2; +{ + return ln1->line - ln2->line; +} /* Start a new symtab for a new source file. This is called when a dbx symbol of type N_SO is seen; @@ -489,17 +557,19 @@ start_symtab (name, dirname, start_addr) last_source_start_addr = start_addr; file_symbols = 0; global_symbols = 0; + global_stabs = 0; /* AIX COFF */ + file_stabs = 0; /* AIX COFF */ within_function = 0; /* Context stack is initially empty, with room for 10 levels. */ - context_stack - = (struct context_stack *) xmalloc (10 * sizeof (struct context_stack)); - context_stack_size = 10; + context_stack_size = INITIAL_CONTEXT_STACK_SIZE; + context_stack = (struct context_stack *) + xmalloc (context_stack_size * sizeof (struct context_stack)); context_stack_depth = 0; new_object_header_files (); - type_vector_length = 160; + type_vector_length = INITIAL_TYPE_VECTOR_LENGTH; type_vector = (struct type **) xmalloc (type_vector_length * sizeof (struct type *)); bzero (type_vector, type_vector_length * sizeof (struct type *)); @@ -520,8 +590,10 @@ start_symtab (name, dirname, start_addr) END_ADDR is the address of the end of the file's text. */ struct symtab * -end_symtab (end_addr) +end_symtab (end_addr, sort_pending, sort_linevec) CORE_ADDR end_addr; + int sort_pending; + int sort_linevec; { register struct symtab *symtab; register struct blockvector *blockvector; @@ -542,43 +614,83 @@ end_symtab (end_addr) cstk->start_addr, end_addr); } + /* It is unfortunate that in aixcoff, pending blocks might not be ordered + in this stage. Especially, blocks for static functions will show up at + the end. We need to sort them, so tools like `find_pc_function' and + `find_pc_block' can work reliably. */ + if (sort_pending) { + /* FIXME! Remove this horrid bubble sort and use qsort!!! */ + int swapped; + do { + struct pending_block *pb, *pbnext; + + pb = pending_blocks, pbnext = pb->next; + swapped = 0; + + while ( pbnext ) { + + /* swap blocks if unordered! */ + + if (BLOCK_START(pb->block) < BLOCK_START(pbnext->block)) { + struct block *tmp = pb->block; + pb->block = pbnext->block; + pbnext->block = tmp; + swapped = 1; + } + pb = pbnext; + pbnext = pbnext->next; + } + } while (swapped); + } + /* 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). */ cleanup_undefined_types (); + if (file_stabs) { + patch_block_stabs (file_symbols, file_stabs); + free (file_stabs); + file_stabs = 0; + } + + if (global_stabs) { + patch_block_stabs (global_symbols, global_stabs); + free (global_stabs); + global_stabs = 0; + } + /* Define the STATIC_BLOCK and GLOBAL_BLOCK, and build the blockvector. */ finish_block (0, &file_symbols, 0, last_source_start_addr, end_addr); finish_block (0, &global_symbols, 0, last_source_start_addr, end_addr); blockvector = make_blockvector (); - current_subfile->line_vector_index = line_vector_index; - /* Now create the symtab objects proper, one for each subfile. */ /* (The main file is the last one on the chain.) */ for (subfile = subfiles; subfile; subfile = nextsub) { + if (subfile->line_vector) { + /* First, shrink the linetable to make more memory. */ + subfile->line_vector = (struct linetable *) + xrealloc (subfile->line_vector, (sizeof (struct linetable) + + subfile->line_vector->nitems * sizeof (struct linetable_entry))); + + if (sort_linevec) + qsort (subfile->line_vector->item, subfile->line_vector->nitems, + sizeof (struct linetable_entry), compare_line_numbers); + } + + /* Now, allocate a symbol table. */ symtab = allocate_symtab (subfile->name); /* Fill in its components. */ symtab->blockvector = blockvector; - lv = subfile->line_vector; - lv->nitems = subfile->line_vector_index; - symtab->linetable = (struct linetable *) - xrealloc (lv, (sizeof (struct linetable) - + lv->nitems * sizeof (struct linetable_entry))); - + symtab->linetable = subfile->line_vector; symtab->dirname = subfile->dirname; - symtab->free_code = free_linetable; symtab->free_ptr = 0; - /* There should never already be a symtab for this name, since - any prev dups have been removed when the psymtab was read in. - FIXME, there ought to be a way to check this here. */ - /* FIXME blewit |= free_named_symtabs (symtab->filename); */ - /* Link the new symtab into the list of such. */ symtab->next = symtab_list; symtab_list = symtab; @@ -590,9 +702,9 @@ end_symtab (end_addr) free ((char *) type_vector); type_vector = 0; type_vector_length = -1; - line_vector = 0; - line_vector_length = -1; + last_source_file = 0; + current_subfile = 0; return symtab; } diff --git a/gdb/buildsym.h b/gdb/buildsym.h index 7cef879c0f3..0cea60bcfe0 100644 --- a/gdb/buildsym.h +++ b/gdb/buildsym.h @@ -47,6 +47,7 @@ extern void finish_block (); extern struct blockvector *make_blockvector (); extern void add_undefined_type (); extern void really_free_pendings (); +extern void start_subfile (); extern struct symtab *end_symtab (); extern void scan_file_globals (); extern void buildsym_new_init (); @@ -79,8 +80,6 @@ struct subfile char *dirname; struct linetable *line_vector; int line_vector_length; - int line_vector_index; - int prev_line_number; }; EXTERN struct subfile *subfiles; @@ -108,22 +107,6 @@ EXTERN struct type **type_vector; EXTERN int type_vector_length; -/* Vector of line number information. */ - -EXTERN struct linetable *line_vector; - -/* Index of next entry to go in line_vector_index. */ - -EXTERN int line_vector_index; - -/* Last line number recorded in the line vector. */ - -EXTERN int prev_line_number; - -/* Number of elements allocated for line_vector currently. */ - -EXTERN int line_vector_length; - /* Hash table of global symbols whose values are not known yet. They are chained thru the SYMBOL_VALUE_CHAIN, since we don't have the correct data for that slot yet. */ @@ -155,7 +138,16 @@ EXTERN struct pending *file_symbols; /* static at top level, and types */ EXTERN struct pending *global_symbols; /* global functions and variables */ -EXTERN struct pending *local_symbols; /* everything local to lexical context */ +EXTERN struct pending *local_symbols; /* everything local to lexic context */ + +/* Kludge for xcoffread.c */ +struct pending_stabs { + int count, length; + char *stab[1]; +}; + +EXTERN struct pending_stabs *global_stabs; +EXTERN struct pending_stabs *file_stabs; /* List of symbols declared since the last BCOMM. This list is a tail of local_symbols. When ECOMM is seen, the symbols on the list diff --git a/gdb/dbxread.c b/gdb/dbxread.c index 822a2f47aaf..c7741abe98c 100644 --- a/gdb/dbxread.c +++ b/gdb/dbxread.c @@ -327,67 +327,6 @@ explicit_lookup_type (real_filenum, index) } #endif -/* Handle an N_SOL symbol, which indicates the start of - code that came from an included (or otherwise merged-in) - source file with a different name. */ - -void -start_subfile (name, dirname) - char *name; - char *dirname; -{ - register struct subfile *subfile; - - /* Save the current subfile's line vector data. */ - - if (current_subfile) - { - current_subfile->line_vector_index = line_vector_index; - current_subfile->line_vector_length = line_vector_length; - current_subfile->prev_line_number = prev_line_number; - } - - /* See if this subfile is already known as a subfile of the - current main source file. */ - - for (subfile = subfiles; subfile; subfile = subfile->next) - { - if (!strcmp (subfile->name, name)) - { - line_vector = subfile->line_vector; - line_vector_index = subfile->line_vector_index; - line_vector_length = subfile->line_vector_length; - prev_line_number = subfile->prev_line_number; - current_subfile = subfile; - return; - } - } - - /* This subfile is not known. Add an entry for it. */ - - line_vector_index = 0; - line_vector_length = 1000; - prev_line_number = -2; /* Force first line number to be explicit */ - line_vector = (struct linetable *) - xmalloc (sizeof (struct linetable) - + line_vector_length * sizeof (struct linetable_entry)); - - /* Make an entry for this subfile in the list of all subfiles - of the current main source file. */ - - subfile = (struct subfile *) xmalloc (sizeof (struct subfile)); - subfile->next = subfiles; - subfile->name = obsavestring (name, strlen (name)); - if (dirname == NULL) - subfile->dirname = NULL; - else - subfile->dirname = obsavestring (dirname, strlen (dirname)); - - subfile->line_vector = line_vector; - subfiles = subfile; - current_subfile = subfile; -} - /* Handle the N_BINCL and N_EINCL symbol types that act like N_SOL for switching source files (different subfiles, as we call them) within one object file, @@ -1920,7 +1859,7 @@ process_symbol_pair (type1, desc1, value1, name1, /* No need to check PCC_SOL_BROKEN, on the assumption that such broken PCC's don't put out N_SO pairs. */ if (last_source_file) - (void)end_symtab (value2); + (void)end_symtab (value2, 0, 0); start_symtab (name2, name1, value2); } @@ -2083,7 +2022,7 @@ read_ofile_symtab (desc, stringtab, stringtab_size, sym_offset, } } - return end_symtab (text_offset + text_size); + return end_symtab (text_offset + text_size, 0, 0); } int @@ -2310,7 +2249,7 @@ process_one_symbol (type, desc, valu, name) } #endif if (last_source_file) - (void)end_symtab (valu); + (void)end_symtab (valu, 0, 0); start_symtab (name, NULL, valu); break; @@ -2343,7 +2282,7 @@ process_one_symbol (type, desc, valu, name) #ifndef SUN_FIXED_LBRAC_BUG last_pc_address = valu; /* Save for SunOS bug circumcision */ #endif - record_line (desc, valu); + record_line (current_subfile, desc, valu); break; case N_BCOMM: diff --git a/gdb/symmisc.c b/gdb/symmisc.c index fbcc79da615..04d375957b0 100644 --- a/gdb/symmisc.c +++ b/gdb/symmisc.c @@ -172,13 +172,15 @@ print_symtabs (filename) for (s = symtab_list; s; s = s->next) { /* First print the line table. */ - fprintf (outfile, "Symtab for file %s\n\n", s->filename); - fprintf (outfile, "Line table:\n\n"); + fprintf (outfile, "Symtab for file %s\n", s->filename); l = LINETABLE (s); - len = l->nitems; - for (i = 0; i < len; i++) - fprintf (outfile, " line %d at %x\n", l->item[i].line, - l->item[i].pc); + if (l) { + fprintf (outfile, "\nLine table:\n\n"); + len = l->nitems; + for (i = 0; i < len; i++) + fprintf (outfile, " line %d at %x\n", l->item[i].line, + l->item[i].pc); + } /* Now print the block info. */ fprintf (outfile, "\nBlockvector:\n\n"); bv = BLOCKVECTOR (s); diff --git a/gdb/symtab.c b/gdb/symtab.c index 81f7ec10218..709559c2523 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -1489,6 +1489,8 @@ find_pc_line (pc, notcurrent) { /* Find the best line in this symtab. */ l = LINETABLE (s); + if (!l) + continue; len = l->nitems; prev_line = -1; first_line = -1; @@ -1638,6 +1640,8 @@ find_line_common (l, lineno, exact_match) if (lineno <= 0) return -1; + if (l == 0) + return -1; len = l->nitems; for (i = 0; i < len; i++) diff --git a/gdb/symtab.h b/gdb/symtab.h index d220a8398ba..3e66624973d 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -514,7 +514,8 @@ struct symtab struct symtab *next; /* List of all symbol scope blocks for this symtab. */ struct blockvector *blockvector; - /* Table mapping core addresses to line numbers for this file. */ + /* Table mapping core addresses to line numbers for this file. + Can be NULL if none. */ struct linetable *linetable; /* Name of this source file. */ char *filename; @@ -636,7 +637,6 @@ int current_source_line; #define BLOCKLIST(symtab) (symtab)->blockvector #define BLOCKVECTOR(symtab) (symtab)->blockvector -#define LINELIST(symtab) (symtab)->linetable #define LINETABLE(symtab) (symtab)->linetable /* Macros normally used to access components of symbol table structures. */ @@ -916,9 +916,6 @@ void select_source_symtab ( char **make_symbol_completion_list (); -/* The entry point of a file we are reading. */ -extern CORE_ADDR entry_point; - /* Maximum and minimum values of built-in types */ #define MAX_OF_TYPE(t) \ TYPE_UNSIGNED(t) ? UMAX_OF_SIZE(TYPE_LENGTH(t)) : MAX_OF_SIZE(TYPE_LENGTH(t))