-LOCAL FUNCTION
-
- end_symtab -- finish processing for a compilation unit
-
-SYNOPSIS
-
- static void end_symtab (char *filename, long language)
-
-DESCRIPTION
-
- Complete the symbol table entry for the current compilation
- unit. Make the struct symtab and put it on the list of all
- such symtabs.
-
- */
-
-static void
-DEFUN(end_symtab, (filename, language, objfile),
- char *filename AND long language AND struct objfile *objfile)
-{
- struct symtab *symtab;
- struct blockvector *blockvector;
- int nbytes;
-
- /* Ignore a file that has no functions with real debugging info. */
- if (global_symbols == NULL && scopetree -> block == NULL)
- {
- free (line_vector);
- line_vector = NULL;
- line_vector_length = -1;
- freescope (scopetree);
- scope = scopetree = NULL;
- }
-
- /* Create the blockvector that points to all the file's blocks. */
-
- blockvector = make_blockvector ();
-
- /* Now create the symtab object for this source file. */
-
- symtab = allocate_symtab (savestring (filename, strlen (filename)),
- objfile);
-
- symtab -> free_ptr = 0;
-
- /* Fill in its components. */
- symtab -> blockvector = blockvector;
- symtab -> free_code = free_linetable;
-
- /* Save the line number information. */
-
- line_vector -> nitems = line_vector_index;
- nbytes = sizeof (struct linetable);
- if (line_vector_index > 1)
- {
- nbytes += (line_vector_index - 1) * sizeof (struct linetable_entry);
- }
- symtab -> linetable = (struct linetable *) xrealloc (line_vector, nbytes);
-
- /* FIXME: The following may need to be expanded for other languages */
- switch (language)
- {
- case LANG_C89:
- case LANG_C:
- symtab -> language = language_c;
- break;
- case LANG_C_PLUS_PLUS:
- symtab -> language = language_cplus;
- break;
- default:
- ;
- }
-
- /* Link the new symtab into the list of such. */
- symtab -> next = symtab_list;
- symtab_list = symtab;
-
- /* Recursively free the scope tree */
- freescope (scopetree);
- scope = scopetree = NULL;
-
- /* Reinitialize for beginning of new file. */
- line_vector = 0;
- line_vector_length = -1;
-}
-
-/*
-
-LOCAL FUNCTION
-
- scopecount -- count the number of enclosed scopes
-
-SYNOPSIS
-
- static int scopecount (struct scopenode *node)
-
-DESCRIPTION
-
- Given pointer to a node, compute the size of the subtree which is
- rooted in this node, which also happens to be the number of scopes
- to the subtree.
- */
-
-static int
-DEFUN(scopecount, (node), struct scopenode *node)
-{
- int count = 0;
-
- if (node != NULL)
- {
- count += scopecount (node -> child);
- count += scopecount (node -> sibling);
- count++;
- }
- return (count);
-}
-
-/*
-
-LOCAL FUNCTION
-
- openscope -- start a new lexical block scope
-
-SYNOPSIS
-
- static void openscope (struct symbol *namesym, CORE_ADDR lowpc,
- CORE_ADDR highpc)
-
-DESCRIPTION
-
- Start a new scope by allocating a new scopenode, adding it as the
- next child of the current scope (if any) or as the root of the
- scope tree, and then making the new node the current scope node.
- */
-
-static void
-DEFUN(openscope, (namesym, lowpc, highpc),
- struct symbol *namesym AND
- CORE_ADDR lowpc AND
- CORE_ADDR highpc)
-{
- struct scopenode *new;
- struct scopenode *child;
-
- new = (struct scopenode *) xmalloc (sizeof (*new));
- (void) memset (new, 0, sizeof (*new));
- new -> namesym = namesym;
- new -> lowpc = lowpc;
- new -> highpc = highpc;
- if (scope == NULL)
- {
- scopetree = new;
- }
- else if ((child = scope -> child) == NULL)
- {
- scope -> child = new;
- new -> parent = scope;
- }
- else
- {
- while (child -> sibling != NULL)
- {
- child = child -> sibling;
- }
- child -> sibling = new;
- new -> parent = scope;
- }
- scope = new;
-}
-
-/*
-
-LOCAL FUNCTION
-
- freescope -- free a scope tree rooted at the given node
-
-SYNOPSIS
-
- static void freescope (struct scopenode *node)
-
-DESCRIPTION
-
- Given a pointer to a node in the scope tree, free the subtree
- rooted at that node. First free all the children and sibling
- nodes, and then the node itself. Used primarily for cleaning
- up after ourselves and returning memory to the system.
- */
-
-static void
-DEFUN(freescope, (node), struct scopenode *node)
-{
- if (node != NULL)
- {
- freescope (node -> child);
- freescope (node -> sibling);
- free (node);
- }
-}
-
-/*
-
-LOCAL FUNCTION
-
- buildblock -- build a new block from pending symbols list
-
-SYNOPSIS
-
- static struct block *buildblock (struct pending_symbol *syms)
-
-DESCRIPTION
-
- Given a pointer to a list of symbols, build a new block and free
- the symbol list structure. Also check each symbol to see if it
- is the special symbol that flags that this block was compiled by
- gcc, and if so, mark the block appropriately.
- */
-
-static struct block *
-DEFUN(buildblock, (syms), struct pending_symbol *syms)
-{
- struct pending_symbol *next, *next1;
- int i;
- struct block *newblock;
- int nbytes;
-
- for (next = syms, i = 0 ; next ; next = next -> next, i++) {;}
-
- /* Allocate a new block */
-
- nbytes = sizeof (struct block);
- if (i > 1)
- {
- nbytes += (i - 1) * sizeof (struct symbol *);
- }
- newblock = (struct block *) obstack_alloc (symbol_obstack, nbytes);
- (void) memset (newblock, 0, nbytes);
-
- /* Copy the symbols into the block. */
-
- BLOCK_NSYMS (newblock) = i;
- for (next = syms ; next ; next = next -> next)
- {
- BLOCK_SYM (newblock, --i) = next -> symbol;
- if (STREQ (GCC_COMPILED_FLAG_SYMBOL, SYMBOL_NAME (next -> symbol)) ||
- STREQ (GCC2_COMPILED_FLAG_SYMBOL, SYMBOL_NAME (next -> symbol)))
- {
- BLOCK_GCC_COMPILED (newblock) = 1;
- }
- }
-
- /* Now free the links of the list, and empty the list. */
-
- for (next = syms ; next ; next = next1)
- {
- next1 = next -> next;
- free (next);
- }
-
- return (newblock);
-}
-
-/*
-
-LOCAL FUNCTION
-
- closescope -- close a lexical block scope
-
-SYNOPSIS
-
- static void closescope (void)
-
-DESCRIPTION
-
- Close the current lexical block scope. Closing the current scope
- is as simple as moving the current scope pointer up to the parent
- of the current scope pointer. But we also take this opportunity
- to build the block for the current scope first, since we now have
- all of it's symbols.
- */
-
-static void
-DEFUN_VOID(closescope)
-{
- struct scopenode *child;
-
- if (scope == NULL)
- {
- error ("DWARF parse error, too many close scopes");
- }
- else
- {
- if (scope -> parent == NULL)
- {
- global_symbol_block = buildblock (global_symbols);
- global_symbols = NULL;
- BLOCK_START (global_symbol_block) = scope -> lowpc + baseaddr;
- BLOCK_END (global_symbol_block) = scope -> highpc + baseaddr;
- }
- scope -> block = buildblock (scope -> symbols);
- scope -> symbols = NULL;
- BLOCK_START (scope -> block) = scope -> lowpc + baseaddr;
- BLOCK_END (scope -> block) = scope -> highpc + baseaddr;
-
- /* Put the local block in as the value of the symbol that names it. */
-
- if (scope -> namesym)
- {
- SYMBOL_BLOCK_VALUE (scope -> namesym) = scope -> block;
- BLOCK_FUNCTION (scope -> block) = scope -> namesym;
- }
-
- /* Install this scope's local block as the superblock of all child
- scope blocks. */
-
- for (child = scope -> child ; child ; child = child -> sibling)
- {
- BLOCK_SUPERBLOCK (child -> block) = scope -> block;
- }
-
- scope = scope -> parent;
- }
-}
-
-/*
-
-LOCAL FUNCTION
-
- record_line -- record a line number entry in the line vector
-
-SYNOPSIS
-
- static void record_line (int line, CORE_ADDR pc)
-
-DESCRIPTION
-
- Given a line number and the corresponding pc value, record
- this pair in the line number vector, expanding the vector as
- necessary.
- */
-
-static void
-DEFUN(record_line, (line, pc), int line AND CORE_ADDR pc)
-{
- struct linetable_entry *e;
- int nbytes;
-
- /* Make sure line vector is big enough. */
-
- if (line_vector_index + 2 >= line_vector_length)
- {
- line_vector_length *= 2;
- nbytes = sizeof (struct linetable);
- nbytes += (line_vector_length * sizeof (struct linetable_entry));
- line_vector = (struct linetable *) xrealloc (line_vector, nbytes);
- }
- e = line_vector -> item + line_vector_index++;
- e -> line = line;
- e -> pc = pc;
-}
-
-/*
-