From 3bf57d210832b28e9361990830eb722a619f031b Mon Sep 17 00:00:00 2001 From: "gdb-2.8" Date: Sat, 3 Sep 1988 08:00:00 +0100 Subject: gdb-2.8 --- gdb/dbxread.c | 1309 ++++++++++++++++++++------------------------------------- 1 file changed, 448 insertions(+), 861 deletions(-) (limited to 'gdb/dbxread.c') diff --git a/gdb/dbxread.c b/gdb/dbxread.c index 084135f..0ac4ff8 100644 --- a/gdb/dbxread.c +++ b/gdb/dbxread.c @@ -1,6 +1,5 @@ /* Read dbx symbol tables and convert to internal format, for GDB. Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc. - Hacked by Michael Tiemann (tiemann@mcc.com) GDB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to anyone @@ -29,6 +28,7 @@ anyone else from sharing it farther. Help stamp out software hoarding! #include #include #include +#include #include "defs.h" #include "initialize.h" #include "symtab.h" @@ -51,9 +51,44 @@ static void hash_symsegs (); extern struct symtab *read_symsegs (); extern void free_all_symtabs (); -/* C++ */ -static struct type **read_args (); +/* Macro for number of symbol table entries (in usual a.out format). + Some machines override this definition. */ +#ifndef NUMBER_OF_SYMBOLS +#define NUMBER_OF_SYMBOLS (hdr.a_syms / sizeof (struct nlist)) +#endif + +/* Macro for file-offset of symbol table (in usual a.out format). */ +#ifndef SYMBOL_TABLE_OFFSET +#define SYMBOL_TABLE_OFFSET N_SYMOFF (hdr) +#endif + +/* Macro for file-offset of string table (in usual a.out format). */ +#ifndef STRING_TABLE_OFFSET +#define STRING_TABLE_OFFSET (N_SYMOFF (hdr) + hdr.a_syms) +#endif + +/* Macro to store the length of the string table data in INTO. */ +#ifndef READ_STRING_TABLE_SIZE +#define READ_STRING_TABLE_SIZE(INTO) \ +{ val = myread (desc, &INTO, sizeof INTO); \ + if (val < 0) perror_with_name (name); } +#endif +/* Macro to declare variables to hold the file's header data. */ +#ifndef DECLARE_FILE_HEADERS +#define DECLARE_FILE_HEADERS struct exec hdr +#endif + +/* Macro to read the header data from descriptor DESC and validate it. + NAME is the file name, for error messages. */ +#ifndef READ_FILE_HEADERS +#define READ_FILE_HEADERS(DESC, NAME) \ +{ val = myread (DESC, &hdr, sizeof hdr); \ + if (val < 0) perror_with_name (NAME); \ + if (N_BADMAG (hdr)) \ + error ("File \"%s\" not in executable format.", NAME); } +#endif + START_FILE /* Chain of symtabs made from reading the file's symsegs. @@ -102,14 +137,7 @@ static struct subfile *subfiles; static struct subfile *current_subfile; -/* The addresses of the symbol table stream and the string table - of the object file we are reading (as copied into core). */ - -static FILE *nlist_stream_global; -static int nlist_size_global; -static char *stringtab_global; - -/* The index in nlist_global of the last dbx symbol to be processed. */ +/* Count symbols as they are processed, for error messages. */ static int symnum; @@ -141,7 +169,7 @@ static int prev_line_number; static int line_vector_length; -/* Chain of global symbols whose values are not known yet. +/* Hash table of global symbols whose values are not known yet. They are chained thru the SYMBOL_VALUE, since we don't have the correct data for that slot yet. */ @@ -152,12 +180,18 @@ static struct symbol *global_sym_chain[HASHSIZE]; We don't create a struct block for the context until we know how long to make it. */ +#define PENDINGSIZE 100 + struct pending { struct pending *next; - struct symbol *symbol; + int nsyms; + struct symbol *symbol[PENDINGSIZE]; }; +/* List of free `struct pending' structures for reuse. */ +struct pending *free_pendings; + /* Here are the three lists that symbols are put on. */ struct pending *file_symbols; /* static at top level, and types */ @@ -166,12 +200,11 @@ struct pending *global_symbols; /* global functions and variables */ struct pending *local_symbols; /* everything local to lexical context */ -/* List of unclosed lexical contexts +/* Stack representing unclosed lexical contexts (that will become blocks, eventually). */ struct context_stack { - struct context_stack *next; struct pending *locals; struct pending_block *old_blocks; struct symbol *name; @@ -181,6 +214,13 @@ struct context_stack struct context_stack *context_stack; +/* Index of first unused entry in context stack. */ +int context_stack_depth; + +/* Currently allocated size of context stack. */ + +int context_stack_size; + /* Nonzero if within a function (so symbols should be local, if nothing says specifically). */ @@ -202,6 +242,53 @@ extern CORE_ADDR first_object_file_end; /* From blockframe.c */ /* File name symbols were loaded from. */ static char *symfile; + +static int +xxmalloc (n) +{ + int v = malloc (n); + if (v == 0) + abort (); + return v; +} + +/* Make a copy of the string at PTR with SIZE characters in the symbol obstack + (and add a null character at the end in the copy). + Returns the address of the copy. */ + +static char * +obsavestring (ptr, size) + char *ptr; + int size; +{ + register char *p = (char *) obstack_alloc (symbol_obstack, size + 1); + /* Open-coded bcopy--saves function call time. + These strings are usually short. */ + { + register char *p1 = ptr; + register char *p2 = p; + char *end = ptr + size; + while (p1 != end) + *p2++ = *p1++; + } + p[size] = 0; + return p; +} + +/* Concatenate strings S1, S2 and S3; return the new string. + Space is found in the symbol_obstack. */ + +static char * +obconcat (s1, s2, s3) + char *s1, *s2, *s3; +{ + register int len = strlen (s1) + strlen (s2) + strlen (s3) + 1; + register char *val = (char *) obstack_alloc (symbol_obstack, len); + strcpy (val, s1); + strcat (val, s2); + strcat (val, s3); + return val; +} /* Support for Sun changes to dbx symbol format */ @@ -269,11 +356,11 @@ static void init_header_files () { n_allocated_header_files = 10; - header_files = (struct header_file *) xmalloc (10 * sizeof (struct header_file)); + header_files = (struct header_file *) xxmalloc (10 * sizeof (struct header_file)); n_header_files = 0; n_allocated_this_object_header_files = 10; - this_object_header_files = (int *) xmalloc (10 * sizeof (int)); + this_object_header_files = (int *) xxmalloc (10 * sizeof (int)); } /* At the end of reading dbx symbols, free our tables. */ @@ -396,7 +483,7 @@ add_new_header_file (name, instance) header_files[i].instance = instance; header_files[i].length = 10; header_files[i].vector - = (struct type **) xmalloc (10 * sizeof (struct type *)); + = (struct type **) xxmalloc (10 * sizeof (struct type *)); bzero (header_files[i].vector, 10 * sizeof (struct type *)); add_this_object_header_file (i); @@ -474,7 +561,6 @@ dbx_alloc_type (typenums) type = (struct type *) obstack_alloc (symbol_obstack, sizeof (struct type)); bzero (type, sizeof (struct type)); - TYPE_VPTR_FIELDNO (type) = -1; *type_addr = type; } return type; @@ -507,15 +593,64 @@ add_symbol_to_list (symbol, listhead) struct symbol *symbol; struct pending **listhead; { - register struct pending *link - = (struct pending *) xmalloc (sizeof (struct pending)); + /* We keep PENDINGSIZE symbols in each link of the list. + If we don't have a link with room in it, add a new link. */ + if (*listhead == 0 || (*listhead)->nsyms == PENDINGSIZE) + { + register struct pending *link; + if (free_pendings) + { + link = free_pendings; + free_pendings = link->next; + } + else + link = (struct pending *) xxmalloc (sizeof (struct pending)); - link->next = *listhead; - link->symbol = symbol; - *listhead = link; + link->next = *listhead; + *listhead = link; + link->nsyms = 0; + } + + (*listhead)->symbol[(*listhead)->nsyms++] = symbol; +} + +/* At end of reading syms, or in case of quit, + really free as many `struct pending's as we can easily find. */ + +static void +really_free_pendings () +{ + struct pending *next, *next1; + struct pending_block *bnext, *bnext1; + + for (next = free_pendings; next; next = next1) + { + next1 = next->next; + free (next); + } + free_pendings = 0; + + for (bnext = pending_blocks; bnext; bnext = bnext1) + { + bnext1 = bnext->next; + free (bnext); + } + pending_blocks = 0; + + for (next = file_symbols; next; next = next1) + { + next1 = next->next; + free (next); + } + for (next = global_symbols; next; next = next1) + { + next1 = next->next; + free (next); + } } /* Take one of the lists of symbols and make a block from it. + Keep the order the symbols have in the list (reversed from the input file). Put the block on the list of pending blocks. */ static void @@ -533,7 +668,7 @@ finish_block (symbol, listhead, old_blocks, start, end) /* Count the length of the list of symbols. */ - for (next = *listhead, i = 0; next; next = next->next, i++); + for (next = *listhead, i = 0; next; i += next->nsyms, next = next->next); block = (struct block *) obstack_alloc (symbol_obstack, sizeof (struct block) + (i - 1) * sizeof (struct symbol *)); @@ -542,7 +677,11 @@ finish_block (symbol, listhead, old_blocks, start, end) BLOCK_NSYMS (block) = i; for (next = *listhead; next; next = next->next) - BLOCK_SYM (block, --i) = next->symbol; + { + register int j; + for (j = next->nsyms - 1; j >= 0; j--) + BLOCK_SYM (block, --i) = next->symbol[j]; + } BLOCK_START (block) = start; BLOCK_END (block) = end; @@ -558,12 +697,13 @@ finish_block (symbol, listhead, old_blocks, start, end) else BLOCK_FUNCTION (block) = 0; - /* Now free the links of the list, and empty the list. */ + /* Now "free" the links of the list, and empty the list. */ for (next = *listhead; next; next = next1) { next1 = next->next; - free (next); + next->next = free_pendings; + free_pendings = next; } *listhead = 0; @@ -583,7 +723,10 @@ finish_block (symbol, listhead, old_blocks, start, end) Put it after opblock, or at the beginning if opblock is 0. This puts the block in the list after all its subblocks. */ - pblock = (struct pending_block *) xmalloc (sizeof (struct pending_block)); + /* Allocate in the symbol_obstack to save time. + It wastes a little space. */ + pblock = (struct pending_block *) obstack_alloc (symbol_obstack, + sizeof (struct pending_block)); pblock->block = block; if (opblock) { @@ -620,6 +763,7 @@ make_blockvector () for (next = pending_blocks; next; next = next->next) BLOCKVECTOR_BLOCK (blockvector, --i) = next->block; +#if 0 /* Now we make the links in the obstack, so don't free them. */ /* Now free the links of the list, and empty the list. */ for (next = pending_blocks; next; next = next1) @@ -627,6 +771,7 @@ make_blockvector () next1 = next->next; free (next); } +#endif pending_blocks = 0; return blockvector; @@ -680,9 +825,14 @@ start_symtab (name, start_addr) last_source_start_addr = start_addr; file_symbols = 0; global_symbols = 0; - context_stack = 0; within_function = 0; + /* Context stack is initially empty, with room for 10 levels. */ + context_stack + = (struct context_stack *) xxmalloc (10 * sizeof (struct context_stack)); + context_stack_size = 10; + context_stack_depth = 0; + new_object_header_files (); for (s = symseg_chain; s; s = s->next) @@ -693,7 +843,7 @@ start_symtab (name, start_addr) return; type_vector_length = 160; - type_vector = (struct typevector *) xmalloc (sizeof (struct typevector) + type_vector_length * sizeof (struct type *)); + type_vector = (struct typevector *) xxmalloc (sizeof (struct typevector) + type_vector_length * sizeof (struct type *)); bzero (type_vector->type, type_vector_length * sizeof (struct type *)); /* Initialize the list of sub source files with one entry @@ -745,12 +895,12 @@ start_subfile (name) 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 (int)); + xxmalloc (sizeof (struct linetable) + line_vector_length * sizeof (int)); /* 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 = (struct subfile *) xxmalloc (sizeof (struct subfile)); subfile->next = subfiles; subfile->name = savestring (name, strlen (name)); subfile->line_vector = line_vector; @@ -770,7 +920,6 @@ end_symtab (end_addr) CORE_ADDR end_addr; { register struct symtab *symtab; - register struct context_stack *cstk; register struct blockvector *blockvector; register struct subfile *subfile; register struct linetable *lv; @@ -783,15 +932,17 @@ end_symtab (end_addr) return; } - /* Finish the lexical context of the last function in the file. */ + /* Finish the lexical context of the last function in the file; + pop the context stack. */ - if (context_stack) + if (context_stack_depth > 0) { - cstk = context_stack; + register struct context_stack *cstk; + context_stack_depth--; + cstk = &context_stack[context_stack_depth]; /* Make a block for the local symbols within. */ finish_block (cstk->name, &local_symbols, cstk->old_blocks, cstk->start_addr, end_addr); - free (cstk); } /* Finish defining all the blocks of this symtab. */ @@ -806,7 +957,7 @@ end_symtab (end_addr) for (subfile = subfiles; subfile; subfile = nextsub) { - symtab = (struct symtab *) xmalloc (sizeof (struct symtab)); + symtab = (struct symtab *) xxmalloc (sizeof (struct symtab)); symtab->free_ptr = 0; /* Fill in its components. */ @@ -860,7 +1011,7 @@ static void push_subfile () { register struct subfile_stack *tem - = (struct subfile_stack *) xmalloc (sizeof (struct subfile_stack)); + = (struct subfile_stack *) xxmalloc (sizeof (struct subfile_stack)); tem->next = subfile_stack; subfile_stack = tem; @@ -929,7 +1080,7 @@ record_misc_function (name, address) if (misc_bunch_index == MISC_BUNCH_SIZE) { - new = (struct misc_bunch *) xmalloc (sizeof (struct misc_bunch)); + new = (struct misc_bunch *) xxmalloc (sizeof (struct misc_bunch)); misc_bunch_index = 0; new->next = misc_bunch; misc_bunch = new; @@ -979,7 +1130,7 @@ condense_misc_bunches () misc_function_vector = (struct misc_function *) - xmalloc (misc_count * sizeof (struct misc_function)); + xxmalloc (misc_count * sizeof (struct misc_function)); j = 0; bunch = misc_bunch; @@ -989,9 +1140,9 @@ condense_misc_bunches () { misc_function_vector[j] = bunch->contents[i]; misc_function_vector[j].name - = concat (misc_function_vector[j].name - + (misc_function_vector[j].name[0] == '_' ? offset : 0), - "", ""); + = obconcat (misc_function_vector[j].name + + (misc_function_vector[j].name[0] == '_' ? offset : 0), + "", ""); j++; } bunch = bunch->next; @@ -1013,9 +1164,16 @@ static int compare_symbols (s1, s2) struct symbol **s1, **s2; { - /* Names that are less should come first. */ - register int namediff = strcmp (SYMBOL_NAME (*s1), SYMBOL_NAME (*s2)); + register int namediff; + + /* Compare the initial characters. */ + namediff = SYMBOL_NAME (*s1)[0] - SYMBOL_NAME (*s2)[0]; + if (namediff != 0) return namediff; + + /* If they match, compare the rest of the names. */ + namediff = strcmp (SYMBOL_NAME (*s1), SYMBOL_NAME (*s2)); if (namediff != 0) return namediff; + /* For symbols of the same name, registers should come first. */ return ((SYMBOL_CLASS (*s2) == LOC_REGISTER) - (SYMBOL_CLASS (*s1) == LOC_REGISTER)); @@ -1025,7 +1183,7 @@ static void sort_syms () { register struct symtab *s; - register int i, nbl; + int i, nbl; register struct blockvector *bv; register struct block *b; @@ -1036,8 +1194,21 @@ sort_syms () for (i = 0; i < nbl; i++) { b = BLOCKVECTOR_BLOCK (bv, i); - qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b), - sizeof (struct symbol *), compare_symbols); + if (BLOCK_SHOULD_SORT (b)) + qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b), + sizeof (struct symbol *), compare_symbols); + else + { + int lastindex = BLOCK_NSYMS (b) - 1; + register int j; + for (j = (lastindex - 1) / 2; j >= 0; j--) + { + register struct symbol *sym; + sym = BLOCK_SYM (b, j); + BLOCK_SYM (b, j) = BLOCK_SYM (b, lastindex - j); + BLOCK_SYM (b, lastindex - j) = sym; + } + } } } } @@ -1050,7 +1221,7 @@ symbol_file_command (name) char *name; { register int desc; - struct exec hdr; + DECLARE_FILE_HEADERS; struct nlist *nlist; char *stringtab; long buffer; @@ -1058,6 +1229,7 @@ symbol_file_command (name) extern void close (); struct cleanup *old_chain; struct symtab *symseg; + struct stat statbuf; dont_repeat (); @@ -1072,10 +1244,6 @@ symbol_file_command (name) if (symtab_list && !query ("Load new symbol table from \"%s\"? ", name)) error ("Not confirmed."); - if (symfile) - free (symfile); - symfile = 0; - { char *absolute_name; desc = openp (getenv ("PATH"), 1, name, O_RDONLY, 0, &absolute_name); @@ -1088,17 +1256,15 @@ symbol_file_command (name) old_chain = make_cleanup (close, desc); make_cleanup (free_current_contents, &name); - val = myread (desc, &hdr, sizeof hdr); - if (val < 0) - perror_with_name (name); + READ_FILE_HEADERS (desc, name); - if (N_BADMAG (hdr)) - error ("File \"%s\" not in executable format.", name); - - if (hdr.a_syms == 0) + if (NUMBER_OF_SYMBOLS == 0) { + if (symfile) + free (symfile); + symfile = 0; free_all_symtabs (); - printf ("%s does not have a symbol-table.\n", name); + printf ("%s has no symbol-table; symbols discarded.\n", name); fflush (stdout); return; } @@ -1107,21 +1273,18 @@ symbol_file_command (name) fflush (stdout); /* Now read the string table, all at once. */ - val = lseek (desc, N_SYMOFF (hdr) + hdr.a_syms, 0); - if (val < 0) - perror_with_name (name); - val = myread (desc, &buffer, sizeof buffer); + val = lseek (desc, STRING_TABLE_OFFSET, 0); if (val < 0) perror_with_name (name); - stringtab = (char *) alloca (buffer); + stat (name, &statbuf); + READ_STRING_TABLE_SIZE (buffer); + if (buffer >= 0 && buffer < statbuf.st_size) + stringtab = (char *) alloca (buffer); + else + stringtab = NULL; if (stringtab == NULL) - { - free_all_symtabs (); - printf("%s: symbol table too large for alloca: %d bytes.\n", name, - buffer); - fflush (stdout); - return; - } + error ("ridiculous string table size: %d bytes", name, buffer); + bcopy (&buffer, stringtab, sizeof buffer); val = myread (desc, stringtab + sizeof buffer, buffer - sizeof buffer); if (val < 0) @@ -1129,8 +1292,14 @@ symbol_file_command (name) /* Throw away the old symbol table. */ + if (symfile) + free (symfile); + symfile = 0; free_all_symtabs (); + /* Empty the hash table of global syms looking for values. */ + bzero (global_sym_chain, sizeof global_sym_chain); + #ifdef READ_GDB_SYMSEGS /* That puts us at the symsegs. Read them. */ symseg_chain = read_symsegs (desc, name); @@ -1148,7 +1317,7 @@ symbol_file_command (name) int j; struct source *source = sv->source[i]; struct symtab *sp1 - = (struct symtab *) xmalloc (sizeof (struct symtab)); + = (struct symtab *) xxmalloc (sizeof (struct symtab)); bcopy (symseg, sp1, sizeof (struct symtab)); sp1->filename = savestring (source->name, strlen (source->name)); @@ -1168,7 +1337,7 @@ symbol_file_command (name) #endif /* Position to read the symbol table. Do not read it all at once. */ - val = lseek (desc, N_SYMOFF (hdr), 0); + val = lseek (desc, SYMBOL_TABLE_OFFSET, 0); if (val < 0) perror_with_name (name); @@ -1176,11 +1345,17 @@ symbol_file_command (name) make_cleanup (discard_misc_bunches, 0); init_header_files (); make_cleanup (free_header_files, 0); + free_pendings = 0; + pending_blocks = 0; + file_symbols = 0; + global_symbols = 0; + make_cleanup (really_free_pendings, 0); /* Now that the symbol table data of the executable file are all in core, process them and define symbols accordingly. Closes desc. */ - read_dbx_symtab (desc, stringtab, hdr.a_syms / sizeof (struct nlist)); + read_dbx_symtab (desc, stringtab, NUMBER_OF_SYMBOLS); + close (desc); /* Sort symbols alphabetically within each block. */ @@ -1223,6 +1398,49 @@ get_sym_file () return symfile; } +/* Buffer for reading the symbol table entries. */ +static struct nlist symbuf[2048]; +static int symbuf_idx; +static int symbuf_end; + +/* I/O descriptor for reading the symbol table. */ +static int symtab_input_desc; + +/* The address of the string table + of the object file we are reading (as copied into core). */ +static char *stringtab_global; + +/* Refill the symbol table input buffer + and set the variables that control fetching entries from it. + Reports an error if no data available. + This function can read past the end of the symbol table + (into the string table) but this does no harm. */ + +static int +fill_symbuf () +{ + int nbytes = myread (symtab_input_desc, symbuf, sizeof (symbuf)); + if (nbytes <= 0) + error ("error or end of file reading symbol table"); + symbuf_end = nbytes / sizeof (struct nlist); + symbuf_idx = 0; + return 1; +} + +/* dbx allows the text of a symbol name to be continued into the + next symbol name! When such a continuation is encountered + (a \ at the end of the text of a name) + call this function to get the continuation. */ + +static char * +next_symbol_text () +{ + if (symbuf_idx == symbuf_end) + fill_symbuf (); + symnum++; + return symbuf[symbuf_idx++].n_un.n_strx + stringtab_global; +} + /* Given pointers to a a.out symbol table in core containing dbx style data, analyze them and create struct symtab's describing the symbols. NLISTLEN is the number of symbols in the symbol table. @@ -1235,8 +1453,6 @@ read_dbx_symtab (desc, stringtab, nlistlen) register char *stringtab; register int nlistlen; { - FILE *stream = fdopen (desc, "r"); - struct nlist buf; register char *namestring; register struct symbol *sym, *prev; int hash; @@ -1248,49 +1464,70 @@ read_dbx_symtab (desc, stringtab, nlistlen) #endif old_chain = make_cleanup (free_all_symtabs, 0); - nlist_stream_global = stream; - nlist_size_global = nlistlen; stringtab_global = stringtab; last_source_file = 0; - bzero (global_sym_chain, sizeof global_sym_chain); + +#ifdef END_OF_TEXT_DEFAULT + end_of_text_addr = END_OF_TEXT_DEFAULT; +#endif + + symtab_input_desc = desc; + symbuf_end = symbuf_idx = 0; for (symnum = 0; symnum < nlistlen; symnum++) { + struct nlist *bufp; + int type; + QUIT; /* allow this to be interruptable */ - fread (&buf, sizeof buf, 1, stream); - namestring = buf.n_un.n_strx ? buf.n_un.n_strx + stringtab : ""; - if (buf.n_type & N_STAB) - process_one_symbol (buf.n_type, buf.n_desc, - buf.n_value, namestring); + if (symbuf_idx == symbuf_end) + fill_symbuf (); + bufp = &symbuf[symbuf_idx++]; + type = bufp->n_type; + namestring = bufp->n_un.n_strx ? bufp->n_un.n_strx + stringtab : ""; + + if (type & N_STAB) + process_one_symbol (type, bufp->n_desc, + bufp->n_value, namestring); /* A static text symbol whose name ends in ".o" - can only mean the start of another object file. + or begins with "-l" means the start of another object file. So end the symtab of the source file we have been processing. This is how we avoid counting the libraries as part or the last source file. Also this way we find end of first object file (crt0). */ - else if (buf.n_type == N_TEXT - && !strcmp (namestring + strlen (namestring) - 2, ".o")) + else if ( +#ifdef N_NBTEXT + (type == N_NBTEXT) +#else + (type == N_TEXT) +#endif + && (!strcmp (namestring + strlen (namestring) - 2, ".o") + || !strncmp (namestring, "-l", 2))) { if (num_object_files++ == 1) - first_object_file_end = buf.n_value; + first_object_file_end = bufp->n_value; if (last_source_file) - end_symtab (buf.n_value); + end_symtab (bufp->n_value); } - else if (buf.n_type & N_EXT || buf.n_type == N_TEXT) + else if (type & N_EXT || type == N_TEXT +#ifdef N_NBTEXT + || type == N_NBTEXT +#endif + ) { int used_up = 0; /* Record the location of _etext. */ - if (buf.n_type == (N_TEXT | N_EXT) + if (type == (N_TEXT | N_EXT) && !strcmp (namestring, "_etext")) - end_of_text_addr = buf.n_value; + end_of_text_addr = bufp->n_value; /* Global symbol: see if we came across a dbx definition for a corresponding symbol. If so, store the value. Remove syms from the chain when their values are stored, but search the whole chain, as there may be several syms from different files with the same name. */ - if (buf.n_type & N_EXT) + if (type & N_EXT) { prev = 0; #ifdef NAMES_HAVE_UNDERSCORE @@ -1319,7 +1556,7 @@ read_dbx_symtab (desc, stringtab, nlistlen) else global_sym_chain[hash] = (struct symbol *) SYMBOL_VALUE (sym); - SYMBOL_VALUE (sym) = buf.n_value; + SYMBOL_VALUE (sym) = bufp->n_value; if (prev) sym = (struct symbol *) SYMBOL_VALUE (prev); else @@ -1337,34 +1574,19 @@ read_dbx_symtab (desc, stringtab, nlistlen) /* Defined global or text symbol: record as a misc function if it didn't give its address to a debugger symbol above. */ - if (buf.n_type <= (N_TYPE | N_EXT) - && buf.n_type != N_EXT + if (type <= (N_TYPE | N_EXT) + && type != N_EXT && ! used_up) - record_misc_function (namestring, buf.n_value); + record_misc_function (namestring, bufp->n_value); } } if (last_source_file) end_symtab (end_of_text_addr); - fclose (stream); discard_cleanups (old_chain); } -/* dbx allows the text of a symbol name to be continued into the - next symbol name! When such a continuation is encountered - (a \ at the end of the text of a name) - call this function to get the continuation. */ - -static char * -next_symbol_text () -{ - struct nlist buf; - fread (&buf, sizeof buf, 1, nlist_stream_global); - symnum++; - return buf.n_un.n_strx + stringtab_global; -} - static int hashname (name) char *name; @@ -1382,7 +1604,9 @@ hashname (name) if (c) total += p[3] << 6; } - + + /* Ensure result is positive. */ + if (total < 0) total += (1000 << 6); return total % HASHSIZE; } @@ -1428,16 +1652,23 @@ process_one_symbol (type, desc, value, name) char *name; { register struct context_stack *new; - + /* Something is wrong if we see real data before seeing a source file name. */ - + + if (last_source_file == 0 && type != N_SO) + { #ifdef N_NSYMS - if (type == N_NSYMS) return; + /* This code is used on Ultrix; ignore this sym. */ + if (type == N_NSYMS) + return; #endif - if (type != N_SO && last_source_file == 0) - error ("Invalid symbol data: does not start by identifying a source file."); + if (type == N_ENTRY) + /* This code appears in libraries on Gould machines. */ + return; + error ("Invalid symbol data: does not start by identifying a source file."); + } switch (type) { @@ -1447,22 +1678,21 @@ process_one_symbol (type, desc, value, name) a new function. We must process its "name" normally for dbx, but also record the start of a new lexical context, and possibly also the end of the lexical context for the previous function. */ - new = context_stack; + within_function = 1; - if (new) + if (context_stack_depth > 0) { + new = &context_stack[--context_stack_depth]; /* Make a block for the local symbols within. */ finish_block (new->name, &local_symbols, new->old_blocks, new->start_addr, value); } - else - { - new = (struct context_stack *) xmalloc (sizeof (struct context_stack)); - new->next = 0; - new->depth = -1; - context_stack = new; - } - new->locals = 0; + /* Stack must be empty now. */ + if (context_stack_depth != 0) + error ("Invalid symbol data: unmatched N_LBRAC before symtab pos %d.", + symnum); + + new = &context_stack[context_stack_depth++]; new->old_blocks = pending_blocks; new->start_addr = value; new->name = define_symbol (value, name, desc); @@ -1472,10 +1702,18 @@ process_one_symbol (type, desc, value, name) case N_LBRAC: /* This "symbol" just indicates the start of an inner lexical context within a function. */ - new = (struct context_stack *) xmalloc (sizeof (struct context_stack)); + + if (context_stack_depth == context_stack_size) + { + context_stack_size *= 2; + context_stack + = (struct context_stack *) xrealloc (context_stack, + context_stack_size + * sizeof (struct context_stack)); + } + + new = &context_stack[context_stack_depth++]; new->depth = desc; - new->next = context_stack; - context_stack = new; new->locals = local_symbols; new->old_blocks = pending_blocks; new->start_addr = value; @@ -1486,11 +1724,11 @@ process_one_symbol (type, desc, value, name) case N_RBRAC: /* This "symbol" just indicates the end of an inner lexical context that was started with N_RBRAC. */ - new = context_stack; - if (new == 0 || desc != new->depth) + new = &context_stack[--context_stack_depth]; + if (desc != new->depth) error ("Invalid symbol data: N_LBRAC/N_RBRAC symbol mismatch, symtab pos %d.", symnum); local_symbols = new->locals; - context_stack = new->next; + /* If this is not the outermost LBRAC...RBRAC pair in the function, its local symbols preceded it, and are the ones just recovered from the context stack. Defined the block for them. @@ -1498,7 +1736,7 @@ process_one_symbol (type, desc, value, name) If this is the outermost LBRAC...RBRAC pair, there is no need to do anything; leave the symbols that preceded it to be attached to the function's own block. */ - if (local_symbols && context_stack->next) + if (local_symbols && context_stack_depth > 1) { /* Muzzle a compiler bug that makes end > start. */ if (new->start_addr > value) @@ -1508,7 +1746,6 @@ process_one_symbol (type, desc, value, name) new->start_addr + last_source_start_addr, value + last_source_start_addr); } - free (new); break; case N_FN: @@ -1557,313 +1794,18 @@ process_one_symbol (type, desc, value, name) record_line (desc, value); break; + case N_BCOMM: + case N_ECOMM: + case N_ECOML: + case N_LENG: + break; + default: if (name) define_symbol (value, name, desc); } } -/************************ READ_ADDL_SYM() ***********************************/ - -static void -read_addl_syms (desc, stringtab, nlistlen, text_addr, text_size) - int desc; - register char *stringtab; - register int nlistlen; - unsigned text_addr; - int text_size; -{ - FILE *stream = fdopen (desc, "r"); - struct nlist buf; - register char *namestring; - register struct symbol *sym, *prev; - int hash; - int num_object_files = 0; - -#ifdef N_BINCL - subfile_stack = 0; -#endif - - nlist_stream_global = stream; - nlist_size_global = nlistlen; - stringtab_global = stringtab; - last_source_file = 0; - bzero (global_sym_chain, sizeof global_sym_chain); - - for (symnum = 0; symnum < nlistlen; symnum++) - { - unsigned type; - - fread (&buf, sizeof buf, 1, stream); - - type = buf.n_type & N_TYPE; - if( (type == N_TEXT) || (type == N_DATA) || (type == N_BSS) ) - { - buf.n_value += text_addr; - } /* Right?? ###### */ - - - namestring = buf.n_un.n_strx ? buf.n_un.n_strx + stringtab : ""; - if (buf.n_type & N_STAB) - process_one_symbol (buf.n_type, buf.n_desc, - buf.n_value, namestring); - /* A static text symbol whose name ends in ".o" - can only mean the start of another object file. - So end the symtab of the source file we have been processing. - This is how we avoid counting the libraries as part - or the last source file. - Also this way we find end of first object file (crt0). */ - else if (buf.n_type == N_TEXT - && !strcmp (namestring + strlen (namestring) - 2, ".o")) - { - if (num_object_files++ == 1) - first_object_file_end = buf.n_value; - if (last_source_file) - { - end_symtab (buf.n_value); /* All this not used##### */ - } - } - else if (buf.n_type & N_EXT || buf.n_type == N_TEXT) - { - int used_up = 0; - - /* Record the location of _etext. */ - if (buf.n_type == (N_TEXT | N_EXT) - && !strcmp (namestring, "_etext")) - { - end_of_text_addr = buf.n_value; - } - - /* Global symbol: see if we came across a dbx definition - for a corresponding symbol. If so, store the value. - Remove syms from the chain when their values are stored, - but search the whole chain, as there may be several syms - from different files with the same name. */ - if (buf.n_type & N_EXT) - { - prev = 0; -#ifdef NAMES_HAVE_UNDERSCORE - hash = hashname (namestring + 1); -#else /* not NAMES_HAVE_UNDERSCORE */ - hash = hashname (namestring); -#endif /* not NAMES_HAVE_UNDERSCORE */ - for (sym = global_sym_chain[hash]; - sym;) - { - if ( -#ifdef NAMES_HAVE_UNDERSCORE - *namestring == '_' - && namestring[1] == SYMBOL_NAME (sym)[0] - && - !strcmp (namestring + 2, SYMBOL_NAME (sym) + 1) -#else /* NAMES_HAVE_UNDERSCORE */ - namestring[0] == SYMBOL_NAME (sym)[0] - && - !strcmp (namestring + 1, SYMBOL_NAME (sym) + 1) -#endif /* NAMES_HAVE_UNDERSCORE */ - ) - { - if (prev) - SYMBOL_VALUE (prev) = SYMBOL_VALUE (sym); - else - global_sym_chain[hash] - = (struct symbol *) SYMBOL_VALUE (sym); - SYMBOL_VALUE (sym) = buf.n_value; - if (prev) - sym = (struct symbol *) SYMBOL_VALUE (prev); - else - sym = global_sym_chain[hash]; - - used_up = 1; - } - else - { - prev = sym; - sym = (struct symbol *) SYMBOL_VALUE (sym); - } - } - } - - /* Defined global or text symbol: record as a misc function - if it didn't give its address to a debugger symbol above. */ - if (buf.n_type <= (N_TYPE | N_EXT) - && buf.n_type != N_EXT - && ! used_up) - record_misc_function (namestring, buf.n_value); - } - } - - if (last_source_file) - { - end_symtab (text_addr + text_size); - } - - fclose (stream); -} - -/***************************** CONDENSE_ADDL_MISC_BUNCHES *******************/ - -static void -condense_addl_misc_bunches () -{ - register int i, j; - register struct misc_bunch *bunch; -#ifdef NAMES_HAVE_UNDERSCORE - int offset = 1; -#else - int offset = 0; -#endif - - misc_function_vector - = (struct misc_function *) xrealloc (misc_function_vector, - (misc_count + misc_function_count) * sizeof (struct misc_function)); - - j = misc_function_count; - bunch = misc_bunch; - while (bunch) - { - for (i = 0; i < misc_bunch_index; i++) - { - misc_function_vector[j] = bunch->contents[i]; - misc_function_vector[j].name - = concat (misc_function_vector[j].name - + (misc_function_vector[j].name[0] == '_' ? offset : 0), - "", ""); - j++; - } - bunch = bunch->next; - misc_bunch_index = MISC_BUNCH_SIZE; - } - - misc_function_count += misc_count; - - /* Sort the misc functions by address. */ - - qsort (misc_function_vector, misc_function_count, - sizeof (struct misc_function), compare_misc_functions); -} - -/**************************** ADD_FILE_COMMAND() ****************************/ -/* This function allows the addition of incrementally linked object files. */ - -void -add_file_command (arg_string) - char* arg_string; -{ - register int desc; - struct exec hdr; - struct nlist *nlist; - char *stringtab; - long buffer; - register int val; - extern void close (); - struct cleanup *old_chain; - char* name; - unsigned text_addr; - - if (arg_string == 0) - error ("add-file takes a file name and an address"); - - for( ; *arg_string == ' '; arg_string++ ); - name = arg_string; - for( ; *arg_string && *arg_string != ' ' ; arg_string++ ); - *arg_string++ = (char) 0; - - if (name[0] == 0) - error ("add-file takes a file name and an address"); - - text_addr = parse_and_eval_address (arg_string); - - dont_repeat (); - - if (query ("add symbol table from filename \"%s\" at text_addr = 0x%x\n", name, text_addr)) - { - desc = open (name, O_RDONLY); - if (desc < 0) - perror_with_name (name); - - old_chain = make_cleanup (close, desc); - make_cleanup (free_current_contents, &name); - - val = myread (desc, &hdr, sizeof hdr); - if (val < 0) - perror_with_name (name); - - if (N_BADMAG (hdr)) - error ("File \"%s\" has a bad header.", name); - - if (hdr.a_syms == 0) - { - printf ("%s does not have a symbol-table.\n", name); - fflush (stdout); - return; - } - - /* Now read the string table, all at once. */ - val = lseek (desc, N_SYMOFF (hdr) + hdr.a_syms, 0); - if (val < 0) - perror_with_name (name); - val = myread (desc, &buffer, sizeof buffer); - if (val < 0) - perror_with_name (name); - stringtab = (char *) alloca (buffer); - bcopy (&buffer, stringtab, sizeof buffer); - val = myread (desc, stringtab + sizeof buffer, buffer - sizeof buffer); - if (val < 0) - perror_with_name (name); - - /* That puts us at the symsegs. Read them. ########## Also need other - changes if they exist. */ - - /* Position to read the symbol table. Do not read it all at once. */ - val = lseek (desc, N_SYMOFF (hdr), 0); - if (val < 0) - perror_with_name (name); - - printf ("Reading symbol data from %s...", name); - fflush (stdout); - - init_misc_functions (); - make_cleanup (discard_misc_bunches, 0); - init_header_files (); - make_cleanup (free_header_files, 0); - - read_addl_syms (desc, stringtab, hdr.a_syms / sizeof(struct nlist), - text_addr, hdr.a_text) ; - - /* Sort symbols alphabetically within each block. */ - - sort_syms (); - - /* Go over the all misc functions and install them in vector. */ - - condense_addl_misc_bunches (); - - /* Don't allow char * to have a typename (else would get caddr_t.) */ - - TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0; - - /* Make a default for file to list. */ - - select_source_symtab (symtab_list); - - do_cleanups (old_chain); - - /* Free the symtabs made by read_symsegs, but not their contents, - which have been copied into symtabs on symtab_list. */ - while (symseg_chain) - { - register struct symtab *s = symseg_chain->next; - free (symseg_chain); - symseg_chain = s; - } - - printf ("done.\n"); - fflush (stdout); - } - else error ("Not confirmed."); -} - static struct symbol * define_symbol (value, string, desc) int value; @@ -1876,8 +1818,20 @@ define_symbol (value, string, desc) int deftype; register int i; - bzero (sym, sizeof (struct symbol)); - SYMBOL_NAME (sym) = obstack_copy0 (symbol_obstack, string, p - string); + /* Ignore syms with empty names. */ + if (string[0] == 0) + return 0; + + SYMBOL_NAME (sym) + = (char *) obstack_alloc (symbol_obstack, ((p - string) + 1)); + /* Open-coded bcopy--saves function call time. */ + { + register char *p1 = string; + register char *p2 = SYMBOL_NAME (sym); + while (p1 != p) + *p2++ = *p1++; + *p2++ = '\0'; + } p++; /* Determine the type of name being defined. */ if ((*p >= '0' && *p <= '9') || *p == '(') @@ -1935,7 +1889,15 @@ define_symbol (value, string, desc) = lookup_pointer_type (lookup_function_type (read_type (&p))); } else - SYMBOL_TYPE (sym) = read_type (&p); + { + struct type *type = read_type (&p); + + if ((deftype == 'F' || deftype == 'f') + && TYPE_CODE (type) != TYPE_CODE_FUNC) + SYMBOL_TYPE (sym) = lookup_function_type (type); + else + SYMBOL_TYPE (sym) = type; + } switch (deftype) { @@ -2014,17 +1976,9 @@ define_symbol (value, string, desc) SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0 && (TYPE_FLAGS (SYMBOL_TYPE (sym)) & TYPE_FLAG_PERM) == 0) - TYPE_NAME (SYMBOL_TYPE (sym)) = concat (SYMBOL_NAME (sym), "", ""); - /* C++ vagaries: we may have a type which is derived from - a base type which did not have its name defined when the - derived class was output. We fill in the derived class's - base part member's name here in that case. */ - else if ((TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT - || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION) - && TYPE_BASECLASS (SYMBOL_TYPE (sym)) - && TYPE_FIELD_NAME (SYMBOL_TYPE (sym), 0) == 0) - TYPE_FIELD_NAME (SYMBOL_TYPE (sym), 0) = TYPE_NAME (TYPE_BASECLASS (SYMBOL_TYPE (sym))); - + TYPE_NAME (SYMBOL_TYPE (sym)) = + obsavestring (SYMBOL_NAME (sym), + strlen (SYMBOL_NAME (sym))); add_symbol_to_list (sym, &file_symbols); break; @@ -2035,12 +1989,12 @@ define_symbol (value, string, desc) if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0 && (TYPE_FLAGS (SYMBOL_TYPE (sym)) & TYPE_FLAG_PERM) == 0) TYPE_NAME (SYMBOL_TYPE (sym)) - = concat ("", - (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_ENUM - ? "enum " - : (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT - ? "struct " : "union ")), - SYMBOL_NAME (sym)); + = obconcat ("", + (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_ENUM + ? "enum " + : (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT + ? "struct " : "union ")), + SYMBOL_NAME (sym)); add_symbol_to_list (sym, &file_symbols); break; @@ -2128,10 +2082,6 @@ read_type (pp) break; } /* Skip the name the cross-ref points to. */ - /* Note: for C++, the cross reference may be to a base type which - has not yet been seen. In this case, we skip to the comma, - which will mark the end of the base class name. (The ':' - at the end of the base class name will be skipped as well.) */ *pp = (char *) index (*pp, ','); /* Just allocate the type and leave it zero if nothing known */ return dbx_alloc_type (typenums); @@ -2160,27 +2110,6 @@ read_type (pp) smash_to_pointer_type (type, read_type (pp)); break; - case '@': - { - struct type *domain = read_type (pp); - char c; - struct type *memtype; - - if (*(*pp)++ != ',') - error ("invalid member type data format, at symtab pos %d.", - symnum); - - memtype = read_type (pp); - type = dbx_alloc_type (typenums); - smash_to_member_type (type, domain, memtype); - } - break; - - case '&': - type = dbx_alloc_type (typenums); - smash_to_reference_type (type, read_type (pp)); - break; - case 'f': type = dbx_alloc_type (typenums); smash_to_function_type (type, read_type (pp)); @@ -2274,23 +2203,9 @@ read_struct_type (pp, type) struct nextfield { struct nextfield *next; - int visibility; struct field field; }; - struct next_fnfield - { - struct next_fnfield *next; - int visibility; - struct fn_field fn_field; - }; - - struct next_fnfieldlist - { - struct next_fnfieldlist *next; - struct fn_fieldlist fn_fieldlist; - }; - register struct nextfield *list = 0; struct nextfield *new; int totalsize; @@ -2299,72 +2214,20 @@ read_struct_type (pp, type) int nfields = 0; register int n; - register struct next_fnfieldlist *mainlist = 0; - int nfn_fields = 0; - struct type *baseclass = NULL; - int read_possible_virtual_info = 0; - TYPE_CODE (type) = TYPE_CODE_STRUCT; /* First comes the total size in bytes. */ TYPE_LENGTH (type) = read_number (pp, 0); - /* C++: Now, if the class is a derived class, then the next character - will be a '!', followed by the type of the base class. Allocate - pretend that that base class is a sub-structure of this one, - with its field name being the type name of the derived class. This - cannot cause a naming conflict, since field names cannot be - type names. This will magically recurse itself to gound terms - when all is read and done. */ - if (**pp == '!') - { - *pp += 1; - - switch (*(*pp)++) - { - case '0': - break; - case '1': - TYPE_VIA_PROTECTED (type) = 1; - break; - case '2': - TYPE_VIA_PUBLIC (type) = 1; - break; - default: - error ("Invalid symbol data: bad visibility format at symtab pos %d.", - symnum); - } - - if (**pp == '\\') *pp = next_symbol_text (); - new = (struct nextfield *) alloca (sizeof (struct nextfield)); - new->next = list; - list = new; - - baseclass = read_type (pp); - list->field.type = baseclass; - list->field.name = TYPE_NAME (baseclass); - *pp += 1; /* skip ',' */ - list->field.bitpos = 0; - list->field.bitsize = 0; /* this should be an unpacked field! */ - nfields++; - } - - /* Now come the fields, as NAME:?TYPENUM,BITPOS,BITSIZE; for each one. - At the end, we see a semicolon instead of a field. - - In C++, this may wind up being NAME:?TYPENUM:PHYSNAME; for - a static field. - - The `?' is a placeholder for one of '+' (public visibility), - '0' (protected visibility), and '-' (private visibility). */ + /* Now come the fields, as NAME:TYPENUM,BITPOS,BITSIZE; for each one. + At the end, we see a semicolon instead of a field. */ while (**pp != ';') { - int visibility; - /* Check for and handle cretinous dbx symbol name continuation! */ - if (**pp == '\\') *pp = next_symbol_text (); + if (**pp == '\\') + *pp = next_symbol_text (); /* Get space to record the next field's data. */ new = (struct nextfield *) alloca (sizeof (struct nextfield)); @@ -2374,49 +2237,10 @@ read_struct_type (pp, type) /* Read the data. */ p = *pp; while (*p != ':') p++; - list->field.name = savestring (*pp, p - *pp); - - /* Check to see if we have hit the methods yet. */ - if (p[1] == ':') - break; - + list->field.name = obsavestring (*pp, p - *pp); *pp = p + 1; - - /* This means we have a visibility for a field coming. */ - if (**pp == '/') - { - switch (*++*pp) - { - case '0': - visibility = 0; - *pp += 1; - break; - - case '1': - visibility = 1; - *pp += 1; - break; - - case '2': - visibility = 2; - *pp += 1; - break; - } - } - /* else normal dbx-style format. */ - list->field.type = read_type (pp); - if (**pp == ':') - { - list->field.bitpos = (long)-1; - p = ++(*pp); - while (*p != ';') p++; - list->field.bitsize = (long) savestring (*pp, p - *pp); - *pp = p + 1; - nfields++; - continue; - } - else if (**pp != ',') + if (**pp != ',') error ("Invalid symbol data: bad structure-type format at symtab pos %d.", symnum); (*pp)++; /* Skip the comma. */ @@ -2424,11 +2248,12 @@ read_struct_type (pp, type) list->field.bitsize = read_number (pp, ';'); /* Detect an unpacked field and mark it as such. dbx gives a bit size for all fields. - Also detect forward refs to structures and unions, + Note that forward refs cannot be packed, and treat enums as if they had the width of ints. */ + if (TYPE_CODE (list->field.type) != TYPE_CODE_INT + && TYPE_CODE (list->field.type) != TYPE_CODE_ENUM) + list->field.bitsize = 0; if ((list->field.bitsize == 8 * TYPE_LENGTH (list->field.type) - || TYPE_CODE (list->field.type) == TYPE_CODE_STRUCT - || TYPE_CODE (list->field.type) == TYPE_CODE_UNION || (TYPE_CODE (list->field.type) == TYPE_CODE_ENUM && list->field.bitsize == 8 * TYPE_LENGTH (builtin_type_int))) && @@ -2437,218 +2262,18 @@ read_struct_type (pp, type) nfields++; } - /* Now come the method fields, as NAME::methods - where each method is of the form TYPENUM,ARGS,...:PHYSNAME; - At the end, we see a semicolon instead of a field. - - For the case of overloaded operators, the format is - OPERATOR::*.methods, where OPERATOR is the string "operator", - `*' holds the place for an operator name (such as `+=') - and `.' marks the end of the operator name. */ - if (p[1] == ':') - { - /* Now, read in the methods. To simplify matters, we - "unread" the name that has been read, so that we can - start from the top. */ - - p = *pp; - - /* chill the list of fields: the last entry (at the head) - is a partially constructed entry which we now scrub. */ - list = list->next; - - /* For each list of method lists... */ - do - { - int i; - struct next_fnfield *sublist = 0; - struct fn_field *fn_fields = 0; - int length = 0; - struct next_fnfieldlist *new_mainlist = - (struct next_fnfieldlist *)alloca (sizeof (struct next_fnfieldlist)); - - /* read in the name. */ - while (*p != ':') p++; - if ((*pp)[0] == 'o' && (*pp)[1] == 'p' && (*pp)[2] == '$') - { - static char opname[32] = "operator "; - char *o = opname + 9; - - /* Skip past '::'. */ - p += 2; - while (*p != '.') - *o++ = *p++; - new_mainlist->fn_fieldlist.name = savestring (opname, o - opname); - /* Skip past '.' */ - *pp = p + 1; - } - else - { - i = 0; - new_mainlist->fn_fieldlist.name = savestring (*pp, p - *pp); - /* Skip past '::'. */ - *pp = p + 2; - } - - do - { - struct next_fnfield *new_sublist = - (struct next_fnfield *)alloca (sizeof (struct next_fnfield)); - - /* Check for and handle cretinous dbx symbol name continuation! */ - if (**pp == '\\') *pp = next_symbol_text (); - - new_sublist->fn_field.type = read_type (pp); - new_sublist->fn_field.args = read_args (pp, ':'); - p = *pp; - while (*p != ';') p++; - new_sublist->fn_field.physname = savestring (*pp, p - *pp); - *pp = p + 1; - new_sublist->visibility = *(*pp)++ - '0'; - if (**pp == '\\') *pp = next_symbol_text (); - - if (*(*pp)++ == '*') - new_sublist->fn_field.voffset = read_number (pp, ';') + 1; - else - new_sublist->fn_field.voffset = 0; - - new_sublist->next = sublist; - sublist = new_sublist; - length++; - } - while (**pp != ';'); - - *pp += 1; - - new_mainlist->fn_fieldlist.fn_fields = - (struct fn_field *) obstack_alloc (symbol_obstack, - sizeof (struct fn_field) * length); - TYPE_FN_PRIVATE_BITS (new_mainlist->fn_fieldlist) = - (int *) obstack_alloc (symbol_obstack, - sizeof (int) * (1 + (length >> 5))); - - TYPE_FN_PROTECTED_BITS (new_mainlist->fn_fieldlist) = - (int *) obstack_alloc (symbol_obstack, - sizeof (int) * (1 + (length >> 5))); - - for (i = length; sublist; sublist = sublist->next) - { - new_mainlist->fn_fieldlist.fn_fields[--i] = sublist->fn_field; - if (sublist->visibility == 0) - B_SET (new_mainlist->fn_fieldlist.private_fn_field_bits, i); - else if (sublist->visibility == 1) - B_SET (new_mainlist->fn_fieldlist.protected_fn_field_bits, i); - } - - new_mainlist->fn_fieldlist.length = length; - new_mainlist->next = mainlist; - mainlist = new_mainlist; - nfn_fields++; - } - while (**pp != ';'); - - *pp += 2; - - if (**pp == '~') - { - read_possible_virtual_info = 1; - *pp += 1; - } - if (**pp == '-') - { - TYPE_HAS_DESTRUCTOR (type) = 1; - TYPE_HAS_CONSTRUCTOR (type) = 1; - *pp += 1; - } - else if (**pp == '+') - { - TYPE_HAS_CONSTRUCTOR (type) = 1; - *pp += 1; - } - } - else *pp += 1; + (*pp)++; /* Skip the terminating ';'. */ /* Now create the vector of fields, and record how big it is. */ TYPE_NFIELDS (type) = nfields; TYPE_FIELDS (type) = (struct field *) obstack_alloc (symbol_obstack, sizeof (struct field) * nfields); - TYPE_FIELD_PRIVATE_BITS (type) = - (int *) obstack_alloc (symbol_obstack, - sizeof (int) * (1 + (nfields >> 5))); - TYPE_FIELD_PROTECTED_BITS (type) = - (int *) obstack_alloc (symbol_obstack, - sizeof (int) * (1 + (nfields >> 5))); - - TYPE_NFN_FIELDS (type) = nfn_fields; - TYPE_NFN_FIELDS_TOTAL (type) = nfn_fields; - if (baseclass) - TYPE_NFN_FIELDS_TOTAL (type) += TYPE_NFN_FIELDS_TOTAL (baseclass); - - TYPE_FN_FIELDLISTS (type) = - (struct fn_fieldlist *) obstack_alloc (symbol_obstack, - sizeof (struct fn_fieldlist) * nfn_fields); /* Copy the saved-up fields into the field vector. */ for (n = nfields; list; list = list->next) - { - TYPE_FIELD (type, --n) = list->field; - if (list->visibility == 0) - SET_TYPE_FIELD_PRIVATE (type, n); - else if (list->visibility == 1) - SET_TYPE_FIELD_PROTECTED (type, n); - } - - for (n = nfn_fields; mainlist; mainlist = mainlist->next) - TYPE_FN_FIELDLISTS (type)[--n] = mainlist->fn_fieldlist; - - TYPE_BASECLASS (type) = baseclass; - - if (read_possible_virtual_info) - { - /* Read either a '%' or the final ';'. */ - if (*(*pp)++ == '%') - { - /* Now we must record the virtual function table pointer's - field information. */ - - struct type *t; - int i; - - t = read_type (pp); - p = (*pp)++; - while (*p != ';') p++; - TYPE_VPTR_BASETYPE (type) = t; - if (type == t) - { - if (TYPE_FIELD_NAME (t, 0) == 0) - TYPE_VPTR_FIELDNO (type) = i = 0; - else for (i = TYPE_NFIELDS (t) - 1; i >= 0; --i) - if (! strncmp (TYPE_FIELD_NAME (t, i), *pp, - strlen (TYPE_FIELD_NAME (t, i)))) - { - TYPE_VPTR_FIELDNO (type) = i; - break; - } - if (i < 0) - error ("virtual function table field not found"); - } - else - TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (TYPE_BASECLASS (type)); - *pp = p; - } - else - { - TYPE_VPTR_BASETYPE (type) = 0; - TYPE_VPTR_FIELDNO (type) = -1; - } - } - else - { - TYPE_VPTR_BASETYPE (type) = 0; - TYPE_VPTR_FIELDNO (type) = -1; - } + TYPE_FIELD (type, --n) = list->field; return type; } @@ -2669,12 +2294,14 @@ read_enum_type (pp, type) int nsyms = 0; struct pending **symlist; struct pending *osyms, *syms; + int o_nsyms; if (within_function) symlist = &local_symbols; else symlist = &file_symbols; osyms = *symlist; + o_nsyms = osyms ? osyms->nsyms : 0; /* Read the value-names and their values. The input syntax is NAME:VALUE,NAME:VALUE, and so on. @@ -2682,15 +2309,16 @@ read_enum_type (pp, type) while (**pp && **pp != ';') { /* Check for and handle cretinous dbx symbol name continuation! */ - if (**pp == '\\') *pp = next_symbol_text (); + if (**pp == '\\') + *pp = next_symbol_text (); p = *pp; while (*p != ':') p++; - name = savestring (*pp, p - *pp); + name = obsavestring (*pp, p - *pp); *pp = p + 1; n = read_number (pp, ','); - sym = (struct symbol *) xmalloc (sizeof (struct symbol)); + sym = (struct symbol *) obstack_alloc (symbol_obstack, sizeof (struct symbol)); bzero (sym, sizeof (struct symbol)); SYMBOL_NAME (sym) = name; SYMBOL_CLASS (sym) = LOC_CONST; @@ -2714,13 +2342,22 @@ read_enum_type (pp, type) to cause them to be defined. osyms contains the old value of that symlist; everything up to there was defined by us. */ - for (syms = *symlist, n = nsyms; syms != osyms; syms = syms->next) + for (syms = *symlist, n = nsyms; syms; syms = syms->next) { - SYMBOL_TYPE (syms->symbol) = type; - TYPE_FIELD_NAME (type, --n) = SYMBOL_NAME (syms->symbol); - TYPE_FIELD_VALUE (type, n) = SYMBOL_VALUE (syms->symbol); - TYPE_FIELD_BITPOS (type, n) = 0; - TYPE_FIELD_BITSIZE (type, n) = 0; + int j = 0; + if (syms == osyms) + j = o_nsyms; + for (; j < syms->nsyms; j++) + { + struct symbol *sym = syms->symbol[j]; + SYMBOL_TYPE (sym) = type; + TYPE_FIELD_NAME (type, --n) = SYMBOL_NAME (sym); + TYPE_FIELD_VALUE (type, n) = SYMBOL_VALUE (sym); + TYPE_FIELD_BITPOS (type, n) = 0; + TYPE_FIELD_BITSIZE (type, n) = 0; + } + if (syms == osyms) + break; } return type; @@ -2855,53 +2492,6 @@ read_number (pp, end) return n * sign; } -/* Read in an argument list. This is a list of types. It is terminated with - a ':', FYI. Return the list of types read in. */ -static struct type ** -read_args (pp, end) - char **pp; - int end; -{ - struct type *types[1024], **rval; /* allow for fns of 1023 parameters */ - int n = 0; - - while (**pp != end) - { - if (**pp != ',') - error ("Invalid argument list: no ',', at symtab pos %d", symnum); - *pp += 1; - types[n++] = read_type (pp); - } - *pp += 1; /* get past `end' (the ':' character) */ - - if (n == 1) - { - rval = (struct type **) xmalloc (2 * sizeof (struct type *)); - } - else if (TYPE_CODE (types[n-1]) != TYPE_CODE_VOID) - { - rval = (struct type **) xmalloc ((n + 1) * sizeof (struct type *)); - bzero (rval + n, sizeof (struct type *)); - } - else - { - rval = (struct type **) xmalloc (n * sizeof (struct type *)); - } - bcopy (types, rval, n * sizeof (struct type *)); - return rval; -} - -/* This function is really horrible, but to avoid it, there would need - to be more filling in of forward references. */ -int -fill_in_vptr_fieldno (type) - struct type *type; -{ - if (TYPE_VPTR_FIELDNO (type) < 0) - TYPE_VPTR_FIELDNO (type) = fill_in_vptr_fieldno (TYPE_BASECLASS (type)); - return TYPE_VPTR_FIELDNO (type); -} - static initialize () { @@ -2909,9 +2499,6 @@ initialize () add_com ("symbol-file", class_files, symbol_file_command, "Load symbol table (in dbx format) from executable file FILE."); - - add_com ("add-file", class_files, add_file_command, - "Load the symbols from FILE, assuming its codes is at TEXT_START.") ; } END_FILE -- cgit v1.1