📄 dbxread.c
字号:
/* Given a name, value pair, find the corresponding bincl in the list. Return the partial symtab associated with that header_file_location. */static struct partial_symtab *find_corresponding_bincl_psymtab (name, instance) char *name; int instance;{ struct header_file_location *bincl; for (bincl = bincl_list; bincl < next_bincl; bincl++) if (bincl->instance == instance && !strcmp (name, bincl->name)) return bincl->pst; return (struct partial_symtab *) 0;}/* Free the storage allocated for the bincl list. */static voidfree_bincl_list (objfile) struct objfile *objfile;{ mfree (objfile -> md, (PTR)bincl_list); bincls_allocated = 0;}/* Given pointers to an a.out symbol table in core containing dbx style data, setup partial_symtab's describing each source file for which debugging information is available. SYMFILE_NAME is the name of the file we are reading from and SECTION_OFFSETS is the set of offsets for the various sections of the file (a set of zeros if the mainline program). */static voidread_dbx_symtab (section_offsets, objfile, text_addr, text_size) struct section_offsets *section_offsets; struct objfile *objfile; CORE_ADDR text_addr; int text_size;{ register struct internal_nlist *bufp = 0; /* =0 avoids gcc -Wall glitch */ register char *namestring; int nsl; int past_first_source_file = 0; CORE_ADDR last_o_file_start = 0; struct cleanup *old_chain; bfd *abfd;#ifdef GDB_TARGET_IS_HPPA /* HP stuff */ struct symbol_dictionary_record *hp_bufp; int hp_symnum; /* A hack: the first text symbol in the debugging library */ int dbsubc_addr = 0;#endif /* End of the text segment of the executable file. */ CORE_ADDR end_of_text_addr; /* Current partial symtab */ struct partial_symtab *pst; /* List of current psymtab's include files */ char **psymtab_include_list; int includes_allocated; int includes_used; /* Index within current psymtab dependency list */ struct partial_symtab **dependency_list; int dependencies_used, dependencies_allocated; /* FIXME. We probably want to change stringtab_global rather than add this while processing every symbol entry. FIXME. */ file_string_table_offset = 0; next_file_string_table_offset = 0;#ifdef GDB_TARGET_IS_HPPA stringtab_global = HP_STRINGTAB (objfile);#else stringtab_global = DBX_STRINGTAB (objfile);#endif pst = (struct partial_symtab *) 0; includes_allocated = 30; includes_used = 0; psymtab_include_list = (char **) alloca (includes_allocated * sizeof (char *)); dependencies_allocated = 30; dependencies_used = 0; dependency_list = (struct partial_symtab **) alloca (dependencies_allocated * sizeof (struct partial_symtab *)); old_chain = make_cleanup (free_objfile, objfile); /* Init bincl list */ init_bincl_list (20, objfile); make_cleanup (free_bincl_list, objfile); last_source_file = NULL;#ifdef END_OF_TEXT_DEFAULT end_of_text_addr = END_OF_TEXT_DEFAULT;#else end_of_text_addr = text_addr + section_offsets->offsets[SECT_OFF_TEXT] + text_size; /* Relocate */#endif symfile_bfd = objfile->obfd; /* For next_text_symbol */ abfd = objfile->obfd; symbuf_end = symbuf_idx = 0; next_symbol_text_func = dbx_next_symbol_text;#ifdef GDB_TARGET_IS_HPPA /* On pa machines, the global symbols are all in the regular HP-UX symbol table. Read them in first. */ hp_symbuf_end = hp_symbuf_idx = 0; bfd_seek (abfd, HP_SYMTAB_OFFSET (objfile), L_SET); for (hp_symnum = 0; hp_symnum < HP_SYMCOUNT (objfile); hp_symnum++) { int dbx_type; QUIT; if (hp_symbuf_idx == hp_symbuf_end) fill_hp_symbuf (abfd); hp_bufp = &hp_symbuf[hp_symbuf_idx++]; switch (hp_bufp->symbol_type) { case ST_SYM_EXT: case ST_ARG_EXT: continue; case ST_CODE: case ST_PRI_PROG: case ST_SEC_PROG: case ST_ENTRY: case ST_MILLICODE: dbx_type = N_TEXT; hp_bufp->symbol_value &= ~3; /* clear out permission bits */ break; case ST_DATA: dbx_type = N_DATA; break;#ifdef KERNELDEBUG case ST_ABSOLUTE: { extern int kernel_debugging; if (!kernel_debugging) continue; dbx_type = N_ABS; break; }#endif default: continue; } /* Use the address of dbsubc to finish the last psymtab. */ if (hp_bufp->symbol_type == ST_CODE && HP_STRINGTAB (objfile)[hp_bufp->name.n_strx] == '_' && !strcmp (HP_STRINGTAB (objfile) + hp_bufp->name.n_strx, "_dbsubc")) dbsubc_addr = hp_bufp->symbol_value; if (hp_bufp->symbol_scope == SS_UNIVERSAL) { if (hp_bufp->name.n_strx > HP_STRINGTAB_SIZE (objfile)) error ("Invalid symbol data; bad HP string table offset: %d", hp_bufp->name.n_strx); /* A hack, but gets the job done. */ if (!strcmp (hp_bufp->name.n_strx + HP_STRINGTAB (objfile), "$START$")) objfile -> ei.entry_file_lowpc = hp_bufp->symbol_value; if (!strcmp (hp_bufp->name.n_strx + HP_STRINGTAB (objfile), "_sr4export")) objfile -> ei.entry_file_highpc = hp_bufp->symbol_value; record_minimal_symbol (hp_bufp->name.n_strx + HP_STRINGTAB (objfile), hp_bufp->symbol_value, dbx_type | N_EXT, objfile); } } bfd_seek (abfd, DBX_SYMTAB_OFFSET (objfile), L_SET);#endif for (symnum = 0; symnum < DBX_SYMCOUNT (objfile); symnum++) { /* Get the symbol for this run and pull out some info */ QUIT; /* allow this to be interruptable */ if (symbuf_idx == symbuf_end) fill_symbuf (abfd); bufp = &symbuf[symbuf_idx++]; /* * Special case to speed up readin. */ if (bufp->n_type == (unsigned char)N_SLINE) continue; SWAP_SYMBOL (bufp, abfd); /* Ok. There is a lot of code duplicated in the rest of this switch statement (for efficiency reasons). Since I don't like duplicating code, I will do my penance here, and describe the code which is duplicated: *) The assignment to namestring. *) The call to strchr. *) The addition of a partial symbol the the two partial symbol lists. This last is a large section of code, so I've imbedded it in the following macro. */ /* Set namestring based on bufp. If the string table index is invalid, give a fake name, and print a single error message per symbol file read, rather than abort the symbol reading or flood the user with messages. *//*FIXME: Too many adds and indirections in here for the inner loop. */#define SET_NAMESTRING()\ if (((unsigned)bufp->n_strx + file_string_table_offset) >= \ DBX_STRINGTAB_SIZE (objfile)) { \ complain (&string_table_offset_complaint, (char *) symnum); \ namestring = "foo"; \ } else \ namestring = bufp->n_strx + file_string_table_offset + \ DBX_STRINGTAB (objfile)#define CUR_SYMBOL_TYPE bufp->n_type#define CUR_SYMBOL_VALUE bufp->n_value#define DBXREAD_ONLY#define START_PSYMTAB(ofile,secoff,fname,low,symoff,global_syms,static_syms)\ start_psymtab(ofile, secoff, fname, low, symoff, global_syms, static_syms)#define END_PSYMTAB(pst,ilist,ninc,c_off,c_text,dep_list,n_deps)\ end_psymtab(pst,ilist,ninc,c_off,c_text,dep_list,n_deps)#include "partial-stab.h" } /* If there's stuff to be cleaned up, clean it up. */#ifndef GDB_TARGET_IS_HPPA if (DBX_SYMCOUNT (objfile) > 0 /* We have some syms *//*FIXME, does this have a bug at start address 0? */ && last_o_file_start && objfile -> ei.entry_point < bufp->n_value && objfile -> ei.entry_point >= last_o_file_start) { objfile -> ei.entry_file_lowpc = last_o_file_start; objfile -> ei.entry_file_highpc = bufp->n_value; }#endif if (pst) {#ifdef GDB_TARGET_IS_HPPA end_psymtab (pst, psymtab_include_list, includes_used, symnum * symbol_size, dbsubc_addr, dependency_list, dependencies_used);#else end_psymtab (pst, psymtab_include_list, includes_used, symnum * symbol_size, end_of_text_addr, dependency_list, dependencies_used);#endif } free_bincl_list (objfile); discard_cleanups (old_chain);}/* Allocate and partially fill a partial symtab. It will be completely filled at the end of the symbol list. SYMFILE_NAME is the name of the symbol-file we are reading from, and ADDR is the address relative to which its symbols are (incremental) or 0 (normal). */struct partial_symtab *start_psymtab (objfile, section_offsets, filename, textlow, ldsymoff, global_syms, static_syms) struct objfile *objfile; struct section_offsets *section_offsets; char *filename; CORE_ADDR textlow; int ldsymoff; struct partial_symbol *global_syms; struct partial_symbol *static_syms;{ struct partial_symtab *result = start_psymtab_common(objfile, section_offsets, filename, textlow, global_syms, static_syms); result->read_symtab_private = (char *) obstack_alloc (&objfile -> psymbol_obstack, sizeof (struct symloc)); LDSYMOFF(result) = ldsymoff; result->read_symtab = dbx_psymtab_to_symtab; SYMBOL_SIZE(result) = symbol_size; SYMBOL_OFFSET(result) = symbol_table_offset; STRING_OFFSET(result) = string_table_offset; FILE_STRING_OFFSET(result) = file_string_table_offset; /* If we're handling an ELF file, drag some section-relocation info for this source file out of the ELF symbol table, to compensate for Sun brain death. This replaces the section_offsets in this psymtab, if successful. */#ifdef notdef elfstab_offset_sections (objfile, result);#endif return result;}/* Close off the current usage of a partial_symbol table entry. This involves setting the correct number of includes (with a realloc), setting the high text mark, setting the symbol length in the executable, and setting the length of the global and static lists of psymbols. The global symbols and static symbols are then seperately sorted. Then the partial symtab is put on the global list. *** List variables and peculiarities of same. *** */voidend_psymtab (pst, include_list, num_includes, capping_symbol_offset, capping_text, dependency_list, number_dependencies) struct partial_symtab *pst; char **include_list; int num_includes; int capping_symbol_offset; CORE_ADDR capping_text; struct partial_symtab **dependency_list; int number_dependencies;/* struct partial_symbol *capping_global, *capping_static;*/{ int i; struct partial_symtab *p1; struct objfile *objfile = pst -> objfile; if (capping_symbol_offset != -1) LDSYMLEN(pst) = capping_symbol_offset - LDSYMOFF(pst); pst->texthigh = capping_text; /* Under Solaris, the N_SO symbols always have a value of 0, instead of the usual address of the .o file. Therefore, we have to do some tricks to fill in texthigh and textlow. The first trick is in partial-stab.h: if we see a static or global function, and the textlow for the current pst is still 0, then we use that function's address for the textlow of the pst. Now, to fill in texthigh, we remember the last function seen in the .o file (also in partial-stab.h). Also, there's a hack in bfd/elf.c and gdb/elfread.c to pass the ELF st_size field to here via the misc_info field. Therefore, we can fill in a reliable texthigh by taking the address plus size of the last function in the file. Unfortunately, that does not cover the case where the last function in the file is static. See the paragraph below for more comments on this situation. Finally, if we have a valid textlow for the current file, we run down the partial_symtab_list filling in previous texthighs that are still unknown. */ if (pst->texthigh == 0 && last_function_name) { char *p; int n; struct minimal_symbol *minsym; p = strchr (last_function_name, ':'); if (p == NULL) p = last_function_name; n = p - last_function_name; p = alloca (n + 1); strncpy (p, last_function_name, n); p[n] = 0; minsym = lookup_minimal_symbol (p, objfile); if (minsym) { pst->texthigh = minsym->address + (int)minsym->info; } else { /* This file ends with a static function, and it's difficult to imagine how hard it would be to track down the elf symbol. Luckily, most of the time no one will notice, since the next file will likely be compiled with -g, so the code below will copy the first fuction's start address back to our texthigh variable. (Also, if this file is the last one in a dynamically linked program, texthigh already has the right value.) If the next file isn't compiled with -g, then the last function in this file winds up owning all of the text space up to the next -g file, or the end (minus shared libraries). This only matters for single stepping, and even then it will still work, except that it will single step through all of the covered functions, instead of setting breakpoints around them as it usualy does. This makes it
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -