📄 buildsym.c
字号:
voidpatch_subfile_names (subfile, name) struct subfile *subfile; char *name;{ if (subfile != NULL && subfile->dirname == NULL && subfile->name != NULL && subfile->name[strlen(subfile->name)-1] == '/') { subfile->dirname = subfile->name; subfile->name = strdup (name); }}/* 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, but using a stack rather than in an arbitrary order. */voidpush_subfile (){ register struct subfile_stack *tem = (struct subfile_stack *) xmalloc (sizeof (struct subfile_stack)); tem->next = subfile_stack; subfile_stack = tem; if (current_subfile == NULL || current_subfile->name == NULL) { abort (); } tem->name = current_subfile->name;}char *pop_subfile (){ register char *name; register struct subfile_stack *link = subfile_stack; if (link == NULL) { abort (); } name = link->name; subfile_stack = link->next; free ((PTR)link); return (name);}/* Manage the vector of line numbers for each subfile. */voidrecord_line (subfile, line, pc) register struct subfile *subfile; int line; CORE_ADDR pc;{ struct linetable_entry *e; /* Ignore the dummy line number in libg.o */ if (line == 0xffff) { return; } /* 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 (subfile->line_vector->nitems + 1 >= subfile->line_vector_length) { subfile->line_vector_length *= 2; subfile->line_vector = (struct linetable *) xrealloc ((char *) subfile->line_vector, (sizeof (struct linetable) + subfile->line_vector_length * sizeof (struct linetable_entry))); } 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 intcompare_line_numbers (ln1p, ln2p) const PTR ln1p; const PTR ln2p;{ return (((struct linetable_entry *) ln1p) -> line - ((struct linetable_entry *) ln2p) -> line);}/* Start a new symtab for a new source file. Called, for example, when a stabs symbol of type N_SO is seen, or when a DWARF TAG_compile_unit DIE is seen. It indicates the start of data for one original source file. */voidstart_symtab (name, dirname, start_addr) char *name; char *dirname; CORE_ADDR start_addr;{ last_source_file = name; last_source_start_addr = start_addr; file_symbols = NULL; global_symbols = NULL; within_function = 0; /* Context stack is initially empty. Allocate first one with room for 10 levels; reuse it forever afterward. */ if (context_stack == NULL) { context_stack_size = INITIAL_CONTEXT_STACK_SIZE; context_stack = (struct context_stack *) xmalloc (context_stack_size * sizeof (struct context_stack)); } context_stack_depth = 0; /* Initialize the list of sub source files with one entry for this file (the top-level source file). */ subfiles = NULL; current_subfile = NULL; start_subfile (name, dirname);}/* Finish the symbol definitions for one main source file, close off all the lexical contexts for that file (creating struct block's for them), then make the struct symtab 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. 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 compilation unit that has exactly one DIE, a TAG_compile_unit DIE. This can happen when we link in an object file that was compiled from an empty source file. Returning NULL is probably not the correct thing to do, because then gdb will never know about this empty file (FIXME). */struct symtab *end_symtab (end_addr, sort_pending, sort_linevec, objfile) CORE_ADDR end_addr; int sort_pending; int sort_linevec; struct objfile *objfile;{ register struct symtab *symtab; register struct blockvector *blockvector; register struct subfile *subfile; register struct context_stack *cstk; struct subfile *nextsub; /* Finish the lexical context of the last function in the file; pop the context stack. */ if (context_stack_depth > 0) { 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, objfile); /* Debug: if context stack still has something in it, we are in trouble. */ if (context_stack_depth > 0) { abort (); } } /* It is unfortunate that in xcoff, 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 && pending_blocks) { /* 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). FIXME: Stabs specific. */ cleanup_undefined_types (); finish_global_stabs (objfile); if (pending_blocks == NULL && file_symbols == NULL && global_symbols == NULL) { /* Ignore symtabs that have no functions with real debugging info */ blockvector = NULL; } else { /* Define the STATIC_BLOCK & GLOBAL_BLOCK, and build the blockvector. */ finish_block (0, &file_symbols, 0, last_source_start_addr, end_addr, objfile); finish_block (0, &global_symbols, 0, last_source_start_addr, end_addr, objfile); blockvector = make_blockvector (objfile); }#ifdef PROCESS_LINENUMBER_HOOK PROCESS_LINENUMBER_HOOK (); /* Needed for xcoff. */#endif /* 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) { int linetablesize; /* If we have blocks of symbols, make a symtab. Otherwise, just ignore this file and any line number info in it. */ symtab = NULL; if (blockvector) { if (subfile->line_vector) { /* First, shrink the linetable to make more memory. */ linetablesize = sizeof (struct linetable) + subfile->line_vector->nitems * sizeof (struct linetable_entry); subfile->line_vector = (struct linetable *) xrealloc ((char *) subfile->line_vector, linetablesize); 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, objfile); /* Fill in its components. */ symtab->blockvector = blockvector; if (subfile->line_vector) { /* Reallocate the line table on the symbol obstack */ symtab->linetable = (struct linetable *) obstack_alloc (&objfile -> symbol_obstack, linetablesize); memcpy (symtab->linetable, subfile->line_vector, linetablesize); } else { symtab->linetable = NULL; } if (subfile->dirname) { /* Reallocate the dirname on the symbol obstack */ symtab->dirname = (char *) obstack_alloc (&objfile -> symbol_obstack, strlen (subfile -> dirname) + 1); strcpy (symtab->dirname, subfile->dirname); } else { symtab->dirname = NULL; } symtab->free_code = free_linetable; symtab->free_ptr = NULL;#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). */ symtab->nonreloc = TRUE;#endif } if (subfile->name != NULL) { free ((PTR) subfile->name); } if (subfile->dirname != NULL) { free ((PTR) subfile->dirname); } if (subfile->line_vector != NULL) { free ((PTR) subfile->line_vector); } nextsub = subfile->next; free ((PTR)subfile); }#ifdef IBM6000_TARGET /* all include symbol tables are non-relocatable, except the main source file's. */ if (symtab) { symtab->nonreloc = FALSE; }#endif last_source_file = NULL; current_subfile = NULL; return (symtab);}/* Push a context block. Args are an identifying nesting level (checkable when you pop it), and the starting PC address of this context. */struct context_stack *push_context (desc, valu) int desc; CORE_ADDR valu;{ register struct context_stack *new; if (context_stack_depth == context_stack_size) { context_stack_size *= 2; context_stack = (struct context_stack *) xrealloc ((char *) context_stack, (context_stack_size * sizeof (struct context_stack))); } new = &context_stack[context_stack_depth++]; new->depth = desc; new->locals = local_symbols; new->old_blocks = pending_blocks; new->start_addr = valu; new->name = NULL; local_symbols = NULL; return (new);}/* Initialize anything that needs initializing when starting to read a fresh piece of a symbol file, e.g. reading in the stuff corresponding to a psymtab. */voidbuildsym_init (){ free_pendings = NULL; file_symbols = NULL; global_symbols = NULL; pending_blocks = NULL;}/* Initialize anything that needs initializing when a completely new symbol file is specified (not just adding some symbols from another file, e.g. a shared library). */voidbuildsym_new_init (){ buildsym_init ();}/* Initializer for this module */void_initialize_buildsym (){}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -