📄 dbxread.c
字号:
pretty slow, but at least it doesn't fail. We can fix this with a fairly big change to bfd, but we need to coordinate better with Cygnus if we want to do that. FIXME. */ } last_function_name = NULL; } /* this test will be true if the last .o file is only data */ if (pst->textlow == 0) pst->textlow = pst->texthigh; /* If we know our own starting text address, then walk through all other psymtabs for this objfile, and if any didn't know their ending text address, set it to our starting address. Take care to not set our own ending address to our starting address, nor to set addresses on `dependency' files that have both textlow and texthigh zero. */ if (pst->textlow) { ALL_OBJFILE_PSYMTABS (objfile, p1) { if (p1->texthigh == 0 && p1->textlow != 0 && p1 != pst) { p1->texthigh = pst->textlow; /* if this file has only data, then make textlow match texthigh */ if (p1->textlow == 0) p1->textlow = p1->texthigh; } } } /* End of kludge for patching Solaris textlow and texthigh. */ pst->n_global_syms = objfile->global_psymbols.next - (objfile->global_psymbols.list + pst->globals_offset); pst->n_static_syms = objfile->static_psymbols.next - (objfile->static_psymbols.list + pst->statics_offset); pst->number_of_dependencies = number_dependencies; if (number_dependencies) { pst->dependencies = (struct partial_symtab **) obstack_alloc (&objfile->psymbol_obstack, number_dependencies * sizeof (struct partial_symtab *)); memcpy (pst->dependencies, dependency_list, number_dependencies * sizeof (struct partial_symtab *)); } else pst->dependencies = 0; for (i = 0; i < num_includes; i++) { struct partial_symtab *subpst = allocate_psymtab (include_list[i], objfile); subpst->section_offsets = pst->section_offsets; subpst->read_symtab_private = (char *) obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc)); LDSYMOFF(subpst) = LDSYMLEN(subpst) = subpst->textlow = subpst->texthigh = 0; /* We could save slight bits of space by only making one of these, shared by the entire set of include files. FIXME-someday. */ subpst->dependencies = (struct partial_symtab **) obstack_alloc (&objfile->psymbol_obstack, sizeof (struct partial_symtab *)); subpst->dependencies[0] = pst; subpst->number_of_dependencies = 1; subpst->globals_offset = subpst->n_global_syms = subpst->statics_offset = subpst->n_static_syms = 0; subpst->readin = 0; subpst->symtab = 0; subpst->read_symtab = dbx_psymtab_to_symtab; } sort_pst_symbols (pst); /* If there is already a psymtab or symtab for a file of this name, remove it. (If there is a symtab, more drastic things also happen.) This happens in VxWorks. */ free_named_symtabs (pst->filename); if (num_includes == 0 && number_dependencies == 0 && pst->n_global_syms == 0 && pst->n_static_syms == 0) { /* Throw away this psymtab, it's empty. We can't deallocate it, since it is on the obstack, but we can forget to chain it on the list. */ struct partial_symtab *prev_pst; /* First, snip it out of the psymtab chain */ if (pst->objfile->psymtabs == pst) pst->objfile->psymtabs = pst->next; else for (prev_pst = pst->objfile->psymtabs; prev_pst; prev_pst = pst->next) if (prev_pst->next == pst) prev_pst->next = pst->next; /* Next, put it on a free list for recycling */ pst->next = pst->objfile->free_psymtabs; pst->objfile->free_psymtabs = pst; }}static voiddbx_psymtab_to_symtab_1 (pst) struct partial_symtab *pst;{ struct cleanup *old_chain; int i; if (!pst) return; if (pst->readin) { fprintf (stderr, "Psymtab for %s already read in. Shouldn't happen.\n", pst->filename); return; } /* Read in all partial symtabs on which this one is dependent */ for (i = 0; i < pst->number_of_dependencies; i++) if (!pst->dependencies[i]->readin) { /* Inform about additional files that need to be read in. */ if (info_verbose) { fputs_filtered (" ", stdout); wrap_here (""); fputs_filtered ("and ", stdout); wrap_here (""); printf_filtered ("%s...", pst->dependencies[i]->filename); wrap_here (""); /* Flush output */ fflush (stdout); } dbx_psymtab_to_symtab_1 (pst->dependencies[i]); } if (LDSYMLEN(pst)) /* Otherwise it's a dummy */ { /* Init stuff necessary for reading in symbols */ stabsread_init (); buildsym_init (); old_chain = make_cleanup (really_free_pendings, 0); file_string_table_offset = FILE_STRING_OFFSET (pst);#ifdef GDB_TARGET_IS_HPPA symbol_size = obj_dbx_symbol_entry_size (pst->objfile->obfd);#else symbol_size = SYMBOL_SIZE (pst);#endif /* Read in this file's symbols */ bfd_seek (pst->objfile->obfd, SYMBOL_OFFSET (pst), L_SET); pst->symtab = read_ofile_symtab (pst->objfile, LDSYMOFF(pst), LDSYMLEN(pst), pst->textlow, pst->texthigh - pst->textlow, pst->section_offsets); sort_symtab_syms (pst->symtab); do_cleanups (old_chain); } pst->readin = 1;}/* Read in all of the symbols for a given psymtab for real. Be verbose about it if the user wants that. */static voiddbx_psymtab_to_symtab (pst) struct partial_symtab *pst;{ bfd *sym_bfd; if (!pst) return; if (pst->readin) { fprintf (stderr, "Psymtab for %s already read in. Shouldn't happen.\n", pst->filename); return; } if (LDSYMLEN(pst) || pst->number_of_dependencies) { /* Print the message now, before reading the string table, to avoid disconcerting pauses. */ if (info_verbose) { printf_filtered ("Reading in symbols for %s...", pst->filename); fflush (stdout); } sym_bfd = pst->objfile->obfd; next_symbol_text_func = dbx_next_symbol_text; dbx_psymtab_to_symtab_1 (pst); /* Match with global symbols. This only needs to be done once, after all of the symtabs and dependencies have been read in. */ scan_file_globals (pst->objfile); /* Finish up the debug error message. */ if (info_verbose) printf_filtered ("done.\n"); }}/* Read in a defined section of a specific object file's symbols. DESC is the file descriptor for the file, positioned at the beginning of the symtab SYM_OFFSET is the offset within the file of the beginning of the symbols we want to read SYM_SIZE is the size of the symbol info to read in. TEXT_OFFSET is the beginning of the text segment we are reading symbols for TEXT_SIZE is the size of the text segment read in. SECTION_OFFSETS are the relocation offsets which get added to each symbol. */static struct symtab *read_ofile_symtab (objfile, sym_offset, sym_size, text_offset, text_size, section_offsets) struct objfile *objfile; int sym_offset; int sym_size; CORE_ADDR text_offset; int text_size; struct section_offsets *section_offsets;{ register char *namestring; register struct internal_nlist *bufp; unsigned char type; unsigned max_symnum; register bfd *abfd; struct symtab *rtn; current_objfile = objfile; subfile_stack = NULL;#ifdef GDB_TARGET_IS_HPPA stringtab_global = HP_STRINGTAB (objfile);#else stringtab_global = DBX_STRINGTAB (objfile);#endif last_source_file = NULL; abfd = objfile->obfd; symfile_bfd = objfile->obfd; /* Implicit param to next_text_symbol */ symbuf_end = symbuf_idx = 0; /* It is necessary to actually read one symbol *before* the start of this symtab's symbols, because the GCC_COMPILED_FLAG_SYMBOL occurs before the N_SO symbol. Detecting this in read_dbx_symtab would slow down initial readin, so we look for it here instead. */ if (!processing_acc_compilation && sym_offset >= (int)symbol_size) { bfd_seek (symfile_bfd, sym_offset - symbol_size, L_INCR); fill_symbuf (abfd); bufp = &symbuf[symbuf_idx++]; SWAP_SYMBOL (bufp, abfd); SET_NAMESTRING (); processing_gcc_compilation = 0; if (bufp->n_type == N_TEXT) { if (strcmp (namestring, GCC_COMPILED_FLAG_SYMBOL) == 0) processing_gcc_compilation = 1; else if (strcmp (namestring, GCC2_COMPILED_FLAG_SYMBOL) == 0) processing_gcc_compilation = 2; } /* Try to select a C++ demangling based on the compilation unit producer. */ if (processing_gcc_compilation) {#if 1 /* Works, but is experimental. -fnf */ if (AUTO_DEMANGLING) { set_demangling_style (GNU_DEMANGLING_STYLE_STRING); }#endif } } else { /* The N_SO starting this symtab is the first symbol, so we better not check the symbol before it. I'm not this can happen, but it doesn't hurt to check for it. */ bfd_seek (symfile_bfd, sym_offset, L_INCR); processing_gcc_compilation = 0; } if (symbuf_idx == symbuf_end) fill_symbuf (abfd); bufp = &symbuf[symbuf_idx]; if (bufp->n_type != (unsigned char)N_SO) error("First symbol in segment of executable not a source symbol"); max_symnum = sym_size / symbol_size; for (symnum = 0; symnum < max_symnum; symnum++) { QUIT; /* Allow this to be interruptable */ if (symbuf_idx == symbuf_end) fill_symbuf(abfd); bufp = &symbuf[symbuf_idx++]; SWAP_SYMBOL (bufp, abfd); type = bufp->n_type; SET_NAMESTRING (); if (type & N_STAB) { process_one_symbol (type, bufp->n_desc, bufp->n_value, namestring, section_offsets, objfile); } /* We skip checking for a new .o or -l file; that should never happen in this routine. */ else if (type == N_TEXT) { /* I don't think this code will ever be executed, because the GCC_COMPILED_FLAG_SYMBOL usually is right before the N_SO symbol which starts this source file. However, there is no reason not to accept the GCC_COMPILED_FLAG_SYMBOL anywhere. */ if (strcmp (namestring, GCC_COMPILED_FLAG_SYMBOL) == 0) processing_gcc_compilation = 1; else if (strcmp (namestring, GCC2_COMPILED_FLAG_SYMBOL) == 0) processing_gcc_compilation = 2;#if 1 /* Works, but is experimental. -fnf */ if (AUTO_DEMANGLING) { set_demangling_style (GNU_DEMANGLING_STYLE_STRING); }#endif } else if (type & N_EXT || type == (unsigned char)N_TEXT || type == (unsigned char)N_NBTEXT ) { /* Global symbol: see if we came across a dbx defintion 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. */ /* This is probably not true. Since the files will be read in one at a time, each reference to a global symbol will be satisfied in each file as it appears. So we skip this section. */ ; } } current_objfile = NULL; /* In a Solaris elf file, this variable, which comes from the value of the N_SO symbol, will still be 0. Luckily, text_offset, which comes from pst->textlow is correct. */ if (last_source_start_addr == 0) last_source_start_addr = text_offset; rtn = end_symtab (text_offset + text_size, 0, 0, objfile); end_stabs (); return (rtn);}/* This handles a single symbol from the symbol-file, building symbols into a GDB symtab. It takes these arguments and an implicit argument. TYPE is the type field of the ".stab" symbol entry. DESC is the desc field of the ".stab" entry. VALU is the value field of the ".stab" entry. NAME is the symbol name, in our address space. SECTION_OFFSETS is a set of amounts by which the sections of this object file were relocated when it was loaded into memory. All symbols that refer to memory locations need to be offset by these amounts. OBJFILE is the object file from which we are reading symbols. It is used in end_symtab. */voidprocess_one_symbol (type, desc, valu, name, section_offsets, objfile)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -