📄 symtab.c
字号:
I'm not sure whether demangling is needed in the case of nested function in inner blocks; if so this needs to be changed. Don't need to mess with the psymtabs; if we have a block, that file is read in. If we don't, then we deal later with all the psymtab stuff that needs checking. */ if (namespace == VAR_NAMESPACE && block != NULL) { struct block *b; /* Find the right symtab. */ ALL_SYMTABS (objfile, s) { bv = BLOCKVECTOR (s); b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); if (BLOCK_START (b) <= BLOCK_START (block) && BLOCK_END (b) > BLOCK_START (block)) { sym = lookup_demangled_block_symbol (b, name); if (sym) { block_found = b; if (symtab != NULL) *symtab = s; return sym; } } } } /* C++: If requested to do so by the caller, check to see if NAME is a field of `this'. */ if (is_a_field_of_this) { struct value *v = value_of_this (0); *is_a_field_of_this = 0; if (v && check_field (v, name)) { *is_a_field_of_this = 1; if (symtab != NULL) *symtab = NULL; return 0; } } /* Now search all global blocks. Do the symtab's first, then check the psymtab's */ ALL_SYMTABS (objfile, s) { bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); sym = lookup_block_symbol (block, name, namespace); if (sym) { block_found = block; if (symtab != NULL) *symtab = s; return sym; } } /* Check for the possibility of the symbol being a global function that is stored in one of the minimal symbol tables. Eventually, all global symbols might be resolved in this way. */ if (namespace == VAR_NAMESPACE) { msymbol = lookup_minimal_symbol (name, (struct objfile *) NULL); if (msymbol == NULL) { /* Test each minimal symbol to see if the minimal symbol's name is a C++ mangled name that matches a user visible name. */ char *demangled; ALL_MSYMBOLS (objfile, msymbol) { demangled = demangle_and_match (msymbol -> name, name, DMGL_PARAMS | DMGL_ANSI); if (demangled != NULL) { free (demangled); goto found_msym; } } msymbol = NULL; /* Not found */ }found_msym: if (msymbol != NULL) { s = find_pc_symtab (msymbol -> address); /* If S is NULL, there are no debug symbols for this file. Skip this stuff and check for matching static symbols below. */ if (s != NULL) { bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); sym = lookup_block_symbol (block, msymbol -> name, namespace); /* We kept static functions in minimal symbol table as well as in static scope. We want to find them in the symbol table. */ if (!sym) { block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); sym = lookup_block_symbol (block, msymbol -> name, namespace); } /* sym == 0 if symbol was found in the minimal symbol table but not in the symtab. Return 0 to use the msymbol definition of "foo_". This happens for Fortran "foo_" symbols, which are "foo" in the symtab. This can also happen if "asm" is used to make a regular symbol but not a debugging symbol, e.g. asm(".globl _main"); asm("_main:"); */ if (symtab != NULL) *symtab = s; return sym; } } } ALL_PSYMTABS (objfile, ps) { if (!ps->readin && lookup_partial_symbol (ps, name, 1, namespace)) { s = PSYMTAB_TO_SYMTAB(ps); bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); sym = lookup_block_symbol (block, name, namespace); if (!sym) error ("Internal: global symbol `%s' found in %s psymtab but not in symtab", name, ps->filename); if (symtab != NULL) *symtab = s; return sym; } } /* Now search all per-file blocks. Not strictly correct, but more useful than an error. Do the symtabs first, then check the psymtabs */ ALL_SYMTABS (objfile, s) { bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); sym = lookup_block_symbol (block, name, namespace); if (sym) { block_found = block; if (symtab != NULL) *symtab = s; return sym; } } ALL_PSYMTABS (objfile, ps) { if (!ps->readin && lookup_partial_symbol (ps, name, 0, namespace)) { s = PSYMTAB_TO_SYMTAB(ps); bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); sym = lookup_block_symbol (block, name, namespace); if (!sym) error ("Internal: static symbol `%s' found in %s psymtab but not in symtab", name, ps->filename); if (symtab != NULL) *symtab = s; return sym; } } /* Now search all per-file blocks for static mangled symbols. Do the symtabs first, then check the psymtabs. */ if (namespace == VAR_NAMESPACE) { ALL_SYMTABS (objfile, s) { bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); sym = lookup_demangled_block_symbol (block, name); if (sym) { block_found = block; if (symtab != NULL) *symtab = s; return sym; } } ALL_PSYMTABS (objfile, ps) { if (!ps->readin && lookup_demangled_partial_symbol (ps, name)) { s = PSYMTAB_TO_SYMTAB(ps); bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); sym = lookup_demangled_block_symbol (block, name); if (!sym) error ("Internal: mangled static symbol `%s' found in %s psymtab but not in symtab", name, ps->filename); if (symtab != NULL) *symtab = s; return sym; } } } if (symtab != NULL) *symtab = NULL; return 0;}/* Look for a static demangled symbol in block BLOCK. */static struct symbol *lookup_demangled_block_symbol (block, name) register const struct block *block; const char *name;{ register int bot, top; register struct symbol *sym; char *demangled; bot = 0; top = BLOCK_NSYMS (block); while (bot < top) { sym = BLOCK_SYM (block, bot); if (SYMBOL_NAMESPACE (sym) == VAR_NAMESPACE) { demangled = demangle_and_match (SYMBOL_NAME (sym), name, DMGL_PARAMS | DMGL_ANSI); if (demangled != NULL) { free (demangled); return (sym); } } bot++; } return (NULL);}/* Look, in partial_symtab PST, for static mangled symbol NAME. */static struct partial_symbol *lookup_demangled_partial_symbol (pst, name) const struct partial_symtab *pst; const char *name;{ struct partial_symbol *start, *psym; int length = pst->n_static_syms; char *demangled; if (!length) return (struct partial_symbol *) 0; start = pst->objfile->static_psymbols.list + pst->statics_offset; for (psym = start; psym < start + length; psym++) { if (SYMBOL_NAMESPACE (psym) == VAR_NAMESPACE) { demangled = demangle_and_match (SYMBOL_NAME (psym), name, DMGL_PARAMS | DMGL_ANSI); if (demangled != NULL) { free (demangled); return (psym); } } } return (NULL);}/* Look, in partial_symtab PST, for symbol NAME. Check the global symbols if GLOBAL, the static symbols if not */static struct partial_symbol *lookup_partial_symbol (pst, name, global, namespace) struct partial_symtab *pst; const char *name; int global; enum namespace namespace;{ struct partial_symbol *start, *psym; int length = (global ? pst->n_global_syms : pst->n_static_syms); if (!length) return (struct partial_symbol *) 0; start = (global ? pst->objfile->global_psymbols.list + pst->globals_offset : pst->objfile->static_psymbols.list + pst->statics_offset ); if (global) /* This means we can use a binary */ /* search. */ { struct partial_symbol *top, *bottom, *center; /* Binary search. This search is guaranteed to end with center pointing at the earliest partial symbol with the correct name. At that point *all* partial symbols with that name will be checked against the correct namespace. */ bottom = start; top = start + length - 1; while (top > bottom) { center = bottom + (top - bottom) / 2; assert (center < top); if (strcmp (SYMBOL_NAME (center), name) >= 0) top = center; else bottom = center + 1; } assert (top == bottom); while (!strcmp (SYMBOL_NAME (top), name)) { if (SYMBOL_NAMESPACE (top) == namespace) return top; top ++; } } else { /* Can't use a binary search */ for (psym = start; psym < start + length; psym++) if (namespace == SYMBOL_NAMESPACE (psym) && !strcmp (name, SYMBOL_NAME (psym))) return psym; } return (struct partial_symbol *) 0;}/* Find the psymtab containing main(). *//* FIXME: What about languages without main() or specially linked executables that have no main() ? */struct partial_symtab *find_main_psymtab (){ register struct partial_symtab *pst; register struct objfile *objfile; ALL_PSYMTABS (objfile, pst) { if (lookup_partial_symbol (pst, "main", 1, VAR_NAMESPACE)) { return (pst); } } return (NULL);}/* Look for a symbol in block BLOCK. */struct symbol *lookup_block_symbol (block, name, namespace) register const struct block *block; const char *name; const enum namespace namespace;{ register int bot, top, inc; register struct symbol *sym, *parameter_sym; top = BLOCK_NSYMS (block); bot = 0; /* If the blocks's symbols were sorted, start with a binary search. */ if (BLOCK_SHOULD_SORT (block)) { /* First, advance BOT to not far before the first symbol whose name is NAME. */ while (1) { inc = (top - bot + 1); /* No need to keep binary searching for the last few bits worth. */ if (inc < 4) break; inc = (inc >> 1) + bot; sym = BLOCK_SYM (block, inc); if (SYMBOL_NAME (sym)[0] < name[0]) bot = inc; else if (SYMBOL_NAME (sym)[0] > name[0]) top = inc; else if (strcmp (SYMBOL_NAME (sym), name) < 0) bot = inc; else top = inc; } /* Now scan forward until we run out of symbols, find one whose name is greater than NAME, or find one we want. If there is more than one symbol with the right name and namespace, we return the first one. dbxread.c is careful to make sure that if one is a register then it comes first. */ top = BLOCK_NSYMS (block); while (bot < top) { sym = BLOCK_SYM (block, bot); inc = SYMBOL_NAME (sym)[0] - name[0]; if (inc == 0) inc = strcmp (SYMBOL_NAME (sym), name); if (inc == 0 && SYMBOL_NAMESPACE (sym) == namespace) return sym; if (inc > 0) return 0; bot++; } return 0; } /* Here if block isn't sorted. This loop is equivalent to the loop above, but hacked greatly for speed. Note that parameter symbols do not always show up last in the list; this loop makes sure to take anything else other than parameter symbols first; it only uses parameter symbols as a last resort. Note that this only takes up extra computation time on a match. */ parameter_sym = (struct symbol *) 0; top = BLOCK_NSYMS (block); inc = name[0]; while (bot < top) { sym = BLOCK_SYM (block, bot); if (SYMBOL_NAME (sym)[0] == inc && !strcmp (SYMBOL_NAME (sym), name) && SYMBOL_NAMESPACE (sym) == namespace) { if (SYMBOL_CLASS (sym) == LOC_ARG || SYMBOL_CLASS (sym) == LOC_LOCAL_ARG || SYMBOL_CLASS (sym) == LOC_REF_ARG || SYMBOL_CLASS (sym) == LOC_REGPARM) parameter_sym = sym; else return sym; } bot++; } return parameter_sym; /* Will be 0 if not found. */}/* Return the symbol for the function which contains a specified lexical block, described by a struct block BL. */struct symbol *block_function (bl) struct block *bl;{ while (BLOCK_FUNCTION (bl) == 0 && BLOCK_SUPERBLOCK (bl) != 0) bl = BLOCK_SUPERBLOCK (bl); return BLOCK_FUNCTION (bl);}/* Subroutine of find_pc_line */struct symtab *find_pc_symtab (pc) register CORE_ADDR pc;{ register struct block *b; struct blockvector *bv; register struct symtab *s = 0; register struct partial_symtab *ps; register struct objfile *objfile;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -