X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fsymtab.c;h=7684bf9c637f73af60b7e1014b16fbaaef21198c;hb=7d97d5e2b81a23dd6ce2376094f8c7fe574693a8;hp=d984a35420544d8f5cdeb160951f0885602a4ea8;hpb=32470760e9475763d4bac42d39b5ed191bd96ff5;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/symtab.c b/gdb/symtab.c index d984a35420..7684bf9c63 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -1,7 +1,7 @@ /* Symbol table lookup for the GNU debugger, GDB. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, - 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -114,11 +114,9 @@ struct symbol *lookup_symbol_aux_minsyms (const char *name, struct symtab **symtab); #endif -static struct symbol *find_active_alias (struct symbol *sym, CORE_ADDR addr); - -/* This flag is used in hppa-tdep.c, and set in hp-symtab-read.c */ -/* Signals the presence of objects compiled by HP compilers */ -int hp_som_som_object_present = 0; +/* This flag is used in hppa-tdep.c, and set in hp-symtab-read.c. + Signals the presence of objects compiled by HP compilers. */ +int deprecated_hp_som_som_object_present = 0; static void fixup_section (struct general_symbol_info *, struct objfile *); @@ -183,21 +181,25 @@ got_symtab: if (full_path != NULL) { - const char *fp = symtab_to_filename (s); - if (FILENAME_CMP (full_path, fp) == 0) - { - return s; - } + const char *fp = symtab_to_fullname (s); + if (fp != NULL && FILENAME_CMP (full_path, fp) == 0) + { + return s; + } } if (real_path != NULL) { - char *rp = gdb_realpath (symtab_to_filename (s)); - make_cleanup (xfree, rp); - if (FILENAME_CMP (real_path, rp) == 0) - { - return s; - } + char *fullname = symtab_to_fullname (s); + if (fullname != NULL) + { + char *rp = gdb_realpath (fullname); + make_cleanup (xfree, rp); + if (FILENAME_CMP (real_path, rp) == 0) + { + return s; + } + } } } @@ -345,7 +347,7 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id) is_full_physname_constructor = is_constructor_name (physname); is_constructor = - is_full_physname_constructor || (newname && STREQ (field_name, newname)); + is_full_physname_constructor || (newname && strcmp (field_name, newname) == 0); if (!is_destructor) is_destructor = (strncmp (physname, "__dt", 4) == 0); @@ -429,9 +431,9 @@ create_demangled_names_hash (struct objfile *objfile) Choosing a much larger table size wastes memory, and saves only about 1% in symbol reading. */ - objfile->demangled_names_hash = htab_create_alloc_ex + objfile->demangled_names_hash = htab_create_alloc (256, htab_hash_string, (int (*) (const void *, const void *)) streq, - NULL, objfile->md, xmcalloc, xmfree); + NULL, xcalloc, xfree); } /* Try to determine the demangled name for a symbol, based on the @@ -487,7 +489,7 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol, /* Set both the mangled and demangled (if any) names for GSYMBOL based on LINKAGE_NAME and LEN. The hash table corresponding to OBJFILE - is used, and the memory comes from that objfile's symbol_obstack. + is used, and the memory comes from that objfile's objfile_obstack. LINKAGE_NAME is copied, so the pointer can be discarded after calling this function. */ @@ -574,7 +576,7 @@ symbol_set_names (struct general_symbol_info *gsymbol, /* If there is a demangled name, place it right after the mangled name. Otherwise, just place a second zero byte after the end of the mangled name. */ - *slot = obstack_alloc (&objfile->symbol_obstack, + *slot = obstack_alloc (&objfile->objfile_obstack, lookup_len + demangled_len + 2); memcpy (*slot, lookup_name, lookup_len + 1); if (demangled_name != NULL) @@ -661,6 +663,14 @@ symbol_demangled_name (struct general_symbol_info *gsymbol) return NULL; } +/* Return the search name of a symbol---generally the demangled or + linkage name of the symbol, depending on how it will be searched for. + If there is no distinct demangled name, then returns the same value + (same pointer) as SYMBOL_LINKAGE_NAME. */ +char *symbol_search_name (const struct general_symbol_info *gsymbol) { + return symbol_natural_name (gsymbol); +} + /* Initialize the structure fields to zero values. */ void init_sal (struct symtab_and_line *sal) @@ -674,8 +684,10 @@ init_sal (struct symtab_and_line *sal) -/* Find which partial symtab on contains PC and SECTION. Return 0 if none. */ - +/* Find which partial symtab contains PC and SECTION. Return 0 if + none. We return the psymtab that contains a symbol whose address + exactly matches PC, or, if we cannot find an exact match, the + psymtab that contains a symbol whose address is closest to PC. */ struct partial_symtab * find_pc_sect_psymtab (CORE_ADDR pc, asection *section) { @@ -700,6 +712,8 @@ find_pc_sect_psymtab (CORE_ADDR pc, asection *section) if (pc >= pst->textlow && pc < pst->texthigh) { struct partial_symtab *tpst; + struct partial_symtab *best_pst = pst; + struct partial_symbol *best_psym = NULL; /* An objfile that has its functions reordered might have many partial symbol tables containing the PC, but @@ -712,6 +726,13 @@ find_pc_sect_psymtab (CORE_ADDR pc, asection *section) if (msymbol == NULL) return (pst); + /* The code range of partial symtabs sometimes overlap, so, in + the loop below, we need to check all partial symtabs and + find the one that fits better for the given PC address. We + select the partial symtab that contains a symbol whose + address is closest to the PC address. By closest we mean + that find_pc_sect_symbol returns the symbol with address + that is closest and still less than the given PC. */ for (tpst = pst; tpst != NULL; tpst = tpst->next) { if (pc >= tpst->textlow && pc < tpst->texthigh) @@ -723,9 +744,33 @@ find_pc_sect_psymtab (CORE_ADDR pc, asection *section) && SYMBOL_VALUE_ADDRESS (p) == SYMBOL_VALUE_ADDRESS (msymbol)) return (tpst); + if (p != NULL) + { + /* We found a symbol in this partial symtab which + matches (or is closest to) PC, check whether it + is closer than our current BEST_PSYM. Since + this symbol address is necessarily lower or + equal to PC, the symbol closer to PC is the + symbol which address is the highest. */ + /* This way we return the psymtab which contains + such best match symbol. This can help in cases + where the symbol information/debuginfo is not + complete, like for instance on IRIX6 with gcc, + where no debug info is emitted for + statics. (See also the nodebug.exp + testcase.) */ + if (best_psym == NULL + || SYMBOL_VALUE_ADDRESS (p) + > SYMBOL_VALUE_ADDRESS (best_psym)) + { + best_psym = p; + best_pst = tpst; + } + } + } } - return (pst); + return (best_pst); } } return (NULL); @@ -835,6 +880,62 @@ fixup_section (struct general_symbol_info *ginfo, struct objfile *objfile) ginfo->bfd_section = SYMBOL_BFD_SECTION (msym); ginfo->section = SYMBOL_SECTION (msym); } + else if (objfile) + { + /* Static, function-local variables do appear in the linker + (minimal) symbols, but are frequently given names that won't + be found via lookup_minimal_symbol(). E.g., it has been + observed in frv-uclinux (ELF) executables that a static, + function-local variable named "foo" might appear in the + linker symbols as "foo.6" or "foo.3". Thus, there is no + point in attempting to extend the lookup-by-name mechanism to + handle this case due to the fact that there can be multiple + names. + + So, instead, search the section table when lookup by name has + failed. The ``addr'' and ``endaddr'' fields may have already + been relocated. If so, the relocation offset (i.e. the + ANOFFSET value) needs to be subtracted from these values when + performing the comparison. We unconditionally subtract it, + because, when no relocation has been performed, the ANOFFSET + value will simply be zero. + + The address of the symbol whose section we're fixing up HAS + NOT BEEN adjusted (relocated) yet. It can't have been since + the section isn't yet known and knowing the section is + necessary in order to add the correct relocation value. In + other words, we wouldn't even be in this function (attempting + to compute the section) if it were already known. + + Note that it is possible to search the minimal symbols + (subtracting the relocation value if necessary) to find the + matching minimal symbol, but this is overkill and much less + efficient. It is not necessary to find the matching minimal + symbol, only its section. + + Note that this technique (of doing a section table search) + can fail when unrelocated section addresses overlap. For + this reason, we still attempt a lookup by name prior to doing + a search of the section table. */ + + CORE_ADDR addr; + struct obj_section *s; + + addr = ginfo->value.address; + + ALL_OBJFILE_OSECTIONS (objfile, s) + { + int idx = s->the_bfd_section->index; + CORE_ADDR offset = ANOFFSET (objfile->section_offsets, idx); + + if (s->addr - offset <= addr && addr < s->endaddr - offset) + { + ginfo->bfd_section = s->the_bfd_section; + ginfo->section = idx; + return; + } + } + } } struct symbol * @@ -1434,7 +1535,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, { do_linear_search = 1; } - if (strcmp_iw_ordered (SYMBOL_NATURAL_NAME (*center), name) >= 0) + if (strcmp_iw_ordered (SYMBOL_SEARCH_NAME (*center), name) >= 0) { top = center; } @@ -1449,7 +1550,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, while (top <= real_top && (linkage_name != NULL ? strcmp (SYMBOL_LINKAGE_NAME (*top), linkage_name) == 0 - : SYMBOL_MATCHES_NATURAL_NAME (*top,name))) + : SYMBOL_MATCHES_SEARCH_NAME (*top,name))) { if (SYMBOL_DOMAIN (*top) == domain) { @@ -1470,7 +1571,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, { if (linkage_name != NULL ? strcmp (SYMBOL_LINKAGE_NAME (*psym), linkage_name) == 0 - : SYMBOL_MATCHES_NATURAL_NAME (*psym, name)) + : SYMBOL_MATCHES_SEARCH_NAME (*psym, name)) { return (*psym); } @@ -1482,15 +1583,23 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, } /* Look up a type named NAME in the struct_domain. The type returned - must not be opaque -- i.e., must have at least one field defined + must not be opaque -- i.e., must have at least one field + defined. */ - This code was modelled on lookup_symbol -- the parts not relevant to looking - up types were just left out. In particular it's assumed here that types - are available in struct_domain and only at file-static or global blocks. */ +struct type * +lookup_transparent_type (const char *name) +{ + return current_language->la_lookup_transparent_type (name); +} +/* The standard implementation of lookup_transparent_type. This code + was modeled on lookup_symbol -- the parts not relevant to looking + up types were just left out. In particular it's assumed here that + types are available in struct_domain and only at file-static or + global blocks. */ struct type * -lookup_transparent_type (const char *name) +basic_lookup_transparent_type (const char *name) { struct symbol *sym; struct symtab *s = NULL; @@ -1668,29 +1777,6 @@ lookup_block_symbol (const struct block *block, const char *name, && (linkage_name != NULL ? strcmp (SYMBOL_LINKAGE_NAME (sym), linkage_name) == 0 : 1)) { - /* If SYM has aliases, then use any alias that is active - at the current PC. If no alias is active at the current - PC, then use the main symbol. - - ?!? Is checking the current pc correct? Is this routine - ever called to look up a symbol from another context? - - FIXME: No, it's not correct. If someone sets a - conditional breakpoint at an address, then the - breakpoint's `struct expression' should refer to the - `struct symbol' appropriate for the breakpoint's - address, which may not be the PC. - - Even if it were never called from another context, - it's totally bizarre for lookup_symbol's behavior to - depend on the value of the inferior's current PC. We - should pass in the appropriate PC as well as the - block. The interface to lookup_symbol should change - to require the caller to provide a PC. */ - - if (SYMBOL_ALIASES (sym)) - sym = find_active_alias (sym, read_pc ()); - sym_found = sym; if (SYMBOL_CLASS (sym) != LOC_ARG && SYMBOL_CLASS (sym) != LOC_LOCAL_ARG && @@ -1708,38 +1794,6 @@ lookup_block_symbol (const struct block *block, const char *name, } } -/* Given a main symbol SYM and ADDR, search through the alias - list to determine if an alias is active at ADDR and return - the active alias. - - If no alias is active, then return SYM. */ - -static struct symbol * -find_active_alias (struct symbol *sym, CORE_ADDR addr) -{ - struct range_list *r; - struct alias_list *aliases; - - /* If we have aliases, check them first. */ - aliases = SYMBOL_ALIASES (sym); - - while (aliases) - { - if (!SYMBOL_RANGES (aliases->sym)) - return aliases->sym; - for (r = SYMBOL_RANGES (aliases->sym); r; r = r->next) - { - if (r->start <= addr && r->end > addr) - return aliases->sym; - } - aliases = aliases->next; - } - - /* Nothing found, return the main symbol. */ - return sym; -} - - /* Find the symtab associated with PC and SECTION. Look through the psymtabs and read in another symtab if necessary. */ @@ -1872,7 +1926,7 @@ find_pc_symtab (CORE_ADDR pc) /* If it's worth the effort, we could be using a binary search. */ struct symtab_and_line -find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent) +find_pc_sect_line (CORE_ADDR pc, struct bfd_section *section, int notcurrent) { struct symtab *s; struct linetable *l; @@ -1969,7 +2023,7 @@ find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent) if (MSYMBOL_TYPE (msymbol) == mst_solib_trampoline) { mfunsym = lookup_minimal_symbol_text (SYMBOL_LINKAGE_NAME (msymbol), - NULL, NULL); + NULL); if (mfunsym == NULL) /* I eliminated this warning since it is coming out * in the following situation: @@ -2182,7 +2236,7 @@ find_line_symtab (struct symtab *symtab, int line, int *index, int *exact_match) struct linetable *l; int ind; - if (!STREQ (symtab->filename, s->filename)) + if (strcmp (symtab->filename, s->filename) != 0) continue; l = LINETABLE (s); ind = find_line_common (l, line, &exact); @@ -2363,7 +2417,7 @@ find_function_start_sal (struct symbol *sym, int funfirstline) !section_is_mapped (section)) pc = overlay_unmapped_address (pc, section); - pc += FUNCTION_START_OFFSET; + pc += DEPRECATED_FUNCTION_START_OFFSET; pc = SKIP_PROLOGUE (pc); /* For overlays, map pc back into its mapped VMA range */ @@ -2371,10 +2425,6 @@ find_function_start_sal (struct symbol *sym, int funfirstline) } sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0); -#ifdef PROLOGUE_FIRSTLINE_OVERLAP - /* Convex: no need to suppress code on first line, if any */ - sal.pc = pc; -#else /* Check if SKIP_PROLOGUE left us in mid-line, and the next line is still part of the same function. */ if (sal.pc != pc @@ -2387,7 +2437,6 @@ find_function_start_sal (struct symbol *sym, int funfirstline) sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0); } sal.pc = pc; -#endif return sal; } @@ -3914,6 +3963,60 @@ in_prologue (CORE_ADDR pc, CORE_ADDR func_start) return func_addr <= pc && pc < sal.end; } +/* Given PC at the function's start address, attempt to find the + prologue end using SAL information. Return zero if the skip fails. + + A non-optimized prologue traditionally has one SAL for the function + and a second for the function body. A single line function has + them both pointing at the same line. + + An optimized prologue is similar but the prologue may contain + instructions (SALs) from the instruction body. Need to skip those + while not getting into the function body. + + The functions end point and an increasing SAL line are used as + indicators of the prologue's endpoint. + + This code is based on the function refine_prologue_limit (versions + found in both ia64 and ppc). */ + +CORE_ADDR +skip_prologue_using_sal (CORE_ADDR func_addr) +{ + struct symtab_and_line prologue_sal; + CORE_ADDR start_pc; + CORE_ADDR end_pc; + + /* Get an initial range for the function. */ + find_pc_partial_function (func_addr, NULL, &start_pc, &end_pc); + start_pc += DEPRECATED_FUNCTION_START_OFFSET; + + prologue_sal = find_pc_line (start_pc, 0); + if (prologue_sal.line != 0) + { + while (prologue_sal.end < end_pc) + { + struct symtab_and_line sal; + + sal = find_pc_line (prologue_sal.end, 0); + if (sal.line == 0) + break; + /* Assume that a consecutive SAL for the same (or larger) + line mark the prologue -> body transition. */ + if (sal.line >= prologue_sal.line) + break; + /* The case in which compiler's optimizer/scheduler has + moved instructions into the prologue. We look ahead in + the function looking for address ranges whose + corresponding line number is less the first one that we + found for the function. This is more conservative then + refine_prologue_limit which scans a large number of SALs + looking for any in the prologue */ + prologue_sal = sal; + } + } + return prologue_sal.end; +} struct symtabs_and_lines decode_line_spec (char *string, int funfirstline) @@ -3930,7 +4033,7 @@ decode_line_spec (char *string, int funfirstline) sals = decode_line_1 (&string, funfirstline, cursal.symtab, cursal.line, - (char ***) NULL); + (char ***) NULL, NULL); if (*string) error ("Junk at end of line specification: %s", string);