/* Symbol table lookup for the GNU debugger, GDB.
Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
- 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2009
- Free Software Foundation, Inc.
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2009,
+ 2010 Free Software Foundation, Inc.
This file is part of GDB.
/* Functions to initialize a symbol's mangled name. */
+/* Objects of this type are stored in the demangled name hash table. */
+struct demangled_name_entry
+{
+ char *mangled;
+ char demangled[1];
+};
+
+/* Hash function for the demangled name hash. */
+static hashval_t
+hash_demangled_name_entry (const void *data)
+{
+ const struct demangled_name_entry *e = data;
+ return htab_hash_string (e->mangled);
+}
+
+/* Equality function for the demangled name hash. */
+static int
+eq_demangled_name_entry (const void *a, const void *b)
+{
+ const struct demangled_name_entry *da = a;
+ const struct demangled_name_entry *db = b;
+ return strcmp (da->mangled, db->mangled) == 0;
+}
+
/* Create the hash table used for demangled names. Each hash entry is
a pair of strings; one for the mangled name and one for the demangled
name. The entry is hashed via just the mangled name. */
1% in symbol reading. */
objfile->demangled_names_hash = htab_create_alloc
- (256, htab_hash_string, (int (*) (const void *, const void *)) streq,
+ (256, hash_demangled_name_entry, eq_demangled_name_entry,
NULL, xcalloc, xfree);
}
}
/* 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 objfile_obstack.
- LINKAGE_NAME is copied, so the pointer can be discarded after
- calling this function. */
+ on LINKAGE_NAME and LEN. Ordinarily, NAME is copied onto the
+ objfile's obstack; but if COPY_NAME is 0 and if NAME is
+ NUL-terminated, then this function assumes that NAME is already
+ correctly saved (either permanently or with a lifetime tied to the
+ objfile), and it will not be copied.
+
+ The hash table corresponding to OBJFILE 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. */
/* We have to be careful when dealing with Java names: when we run
into a Java minimal symbol, we don't know it's a Java symbol, so it
void
symbol_set_names (struct general_symbol_info *gsymbol,
- const char *linkage_name, int len, struct objfile *objfile)
+ const char *linkage_name, int len, int copy_name,
+ struct objfile *objfile)
{
- char **slot;
+ struct demangled_name_entry **slot;
/* A 0-terminated copy of the linkage name. */
const char *linkage_name_copy;
/* A copy of the linkage name that might have a special Java prefix
const char *lookup_name;
/* The length of lookup_name. */
int lookup_len;
-
- if (objfile->demangled_names_hash == NULL)
- create_demangled_names_hash (objfile);
+ struct demangled_name_entry entry;
if (gsymbol->language == language_ada)
{
been observed with Java. Because we don't store the demangled
name with the symbol, we don't need to use the same trick
as Java. */
- gsymbol->name = obstack_alloc (&objfile->objfile_obstack, len + 1);
- memcpy (gsymbol->name, linkage_name, len);
- gsymbol->name[len] = '\0';
+ if (!copy_name)
+ gsymbol->name = (char *) linkage_name;
+ else
+ {
+ gsymbol->name = obstack_alloc (&objfile->objfile_obstack, len + 1);
+ memcpy (gsymbol->name, linkage_name, len);
+ gsymbol->name[len] = '\0';
+ }
gsymbol->language_specific.cplus_specific.demangled_name = NULL;
return;
}
+ if (objfile->demangled_names_hash == NULL)
+ create_demangled_names_hash (objfile);
+
/* The stabs reader generally provides names that are not
NUL-terminated; most of the other readers don't do this, so we
can just use the given copy, unless we're in the Java case. */
linkage_name_copy = linkage_name;
}
- slot = (char **) htab_find_slot (objfile->demangled_names_hash,
- lookup_name, INSERT);
+ entry.mangled = (char *) lookup_name;
+ slot = ((struct demangled_name_entry **)
+ htab_find_slot (objfile->demangled_names_hash,
+ &entry, INSERT));
/* If this name is not in the hash table, add it. */
if (*slot == NULL)
linkage_name_copy);
int demangled_len = demangled_name ? strlen (demangled_name) : 0;
- /* 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->objfile_obstack,
- lookup_len + demangled_len + 2);
- memcpy (*slot, lookup_name, lookup_len + 1);
+ /* Suppose we have demangled_name==NULL, copy_name==0, and
+ lookup_name==linkage_name. In this case, we already have the
+ mangled name saved, and we don't have a demangled name. So,
+ you might think we could save a little space by not recording
+ this in the hash table at all.
+
+ It turns out that it is actually important to still save such
+ an entry in the hash table, because storing this name gives
+ us better backache hit rates for partial symbols. */
+ if (!copy_name && lookup_name == linkage_name)
+ {
+ *slot = obstack_alloc (&objfile->objfile_obstack,
+ offsetof (struct demangled_name_entry,
+ demangled)
+ + demangled_len + 1);
+ (*slot)->mangled = (char *) lookup_name;
+ }
+ else
+ {
+ /* If we must copy the mangled name, put it directly after
+ the demangled name so we can have a single
+ allocation. */
+ *slot = obstack_alloc (&objfile->objfile_obstack,
+ offsetof (struct demangled_name_entry,
+ demangled)
+ + lookup_len + demangled_len + 2);
+ (*slot)->mangled = &((*slot)->demangled[demangled_len + 1]);
+ strcpy ((*slot)->mangled, lookup_name);
+ }
+
if (demangled_name != NULL)
{
- memcpy (*slot + lookup_len + 1, demangled_name, demangled_len + 1);
+ strcpy ((*slot)->demangled, demangled_name);
xfree (demangled_name);
}
else
- (*slot)[lookup_len + 1] = '\0';
+ (*slot)->demangled[0] = '\0';
}
- gsymbol->name = *slot + lookup_len - len;
- if ((*slot)[lookup_len + 1] != '\0')
+ gsymbol->name = (*slot)->mangled + lookup_len - len;
+ if ((*slot)->demangled[0] != '\0')
gsymbol->language_specific.cplus_specific.demangled_name
- = &(*slot)[lookup_len + 1];
+ = (*slot)->demangled;
else
gsymbol->language_specific.cplus_specific.demangled_name = NULL;
}
psymtabs. */
struct symbol *
-lookup_global_symbol_from_objfile (const struct objfile *objfile,
+lookup_global_symbol_from_objfile (const struct objfile *main_objfile,
const char *name,
const char *linkage_name,
const domain_enum domain)
{
+ const struct objfile *objfile;
struct symbol *sym;
struct blockvector *bv;
const struct block *block;
struct symtab *s;
struct partial_symtab *ps;
- /* Go through symtabs. */
- ALL_OBJFILE_SYMTABS (objfile, s)
- {
- bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, name, linkage_name, domain);
- if (sym)
- {
- block_found = block;
- return fixup_symbol_section (sym, (struct objfile *)objfile);
- }
- }
-
- /* Now go through psymtabs. */
- ALL_OBJFILE_PSYMTABS (objfile, ps)
- {
- if (!ps->readin
- && lookup_partial_symbol (ps, name, linkage_name,
- 1, domain))
- {
- s = PSYMTAB_TO_SYMTAB (ps);
- bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, name, linkage_name, domain);
- return fixup_symbol_section (sym, (struct objfile *)objfile);
- }
- }
-
- if (objfile->separate_debug_objfile)
- return lookup_global_symbol_from_objfile (objfile->separate_debug_objfile,
- name, linkage_name, domain);
+ for (objfile = main_objfile;
+ objfile;
+ objfile = objfile_separate_debug_iterate (main_objfile, objfile))
+ {
+ /* Go through symtabs. */
+ ALL_OBJFILE_SYMTABS (objfile, s)
+ {
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ sym = lookup_block_symbol (block, name, linkage_name, domain);
+ if (sym)
+ {
+ block_found = block;
+ return fixup_symbol_section (sym, (struct objfile *)objfile);
+ }
+ }
+
+ /* Now go through psymtabs. */
+ ALL_OBJFILE_PSYMTABS (objfile, ps)
+ {
+ if (!ps->readin
+ && lookup_partial_symbol (ps, name, linkage_name,
+ 1, domain))
+ {
+ s = PSYMTAB_TO_SYMTAB (ps);
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ sym = lookup_block_symbol (block, name, linkage_name, domain);
+ return fixup_symbol_section (sym, (struct objfile *)objfile);
+ }
+ }
+ }
return NULL;
}
ALL_PSYMTABS (objfile, p)
{
- if (strcmp (symtab->filename, p->filename) != 0)
+ if (FILENAME_CMP (symtab->filename, p->filename) != 0)
continue;
PSYMTAB_TO_SYMTAB (p);
}
+ /* Get symbol full file name if possible. */
+ symtab_to_fullname (symtab);
+
ALL_SYMTABS (objfile, s)
{
struct linetable *l;
int ind;
- if (strcmp (symtab->filename, s->filename) != 0)
+ if (FILENAME_CMP (symtab->filename, s->filename) != 0)
continue;
+ if (symtab->fullname != NULL
+ && symtab_to_fullname (s) != NULL
+ && FILENAME_CMP (symtab->fullname, s->fullname) != 0)
+ continue;
l = LINETABLE (s);
ind = find_line_common (l, line, &exact);
if (ind >= 0)
&& ((regexp == NULL
|| re_exec (SYMBOL_NATURAL_NAME (*psym)) != 0)
&& ((kind == VARIABLES_DOMAIN && SYMBOL_CLASS (*psym) != LOC_TYPEDEF
- && SYMBOL_CLASS (*psym) != LOC_BLOCK)
+ && SYMBOL_CLASS (*psym) != LOC_UNRESOLVED
+ && SYMBOL_CLASS (*psym) != LOC_BLOCK
+ && SYMBOL_CLASS (*psym) != LOC_CONST)
|| (kind == FUNCTIONS_DOMAIN && SYMBOL_CLASS (*psym) == LOC_BLOCK)
|| (kind == TYPES_DOMAIN && SYMBOL_CLASS (*psym) == LOC_TYPEDEF))))
{
&& ((regexp == NULL
|| re_exec (SYMBOL_NATURAL_NAME (sym)) != 0)
&& ((kind == VARIABLES_DOMAIN && SYMBOL_CLASS (sym) != LOC_TYPEDEF
+ && SYMBOL_CLASS (sym) != LOC_UNRESOLVED
&& SYMBOL_CLASS (sym) != LOC_BLOCK
&& SYMBOL_CLASS (sym) != LOC_CONST)
|| (kind == FUNCTIONS_DOMAIN && SYMBOL_CLASS (sym) == LOC_BLOCK)
}
/* Helper to expand_line_sal below. Search in the symtabs for any
- linetable entry that exactly matches FILENAME and LINENO and append
- them to RET. If there is at least one match, return 1; otherwise,
- return 0, and return the best choice in BEST_ITEM and BEST_SYMTAB. */
+ linetable entry that exactly matches FULLNAME and LINENO and append
+ them to RET. If FULLNAME is NULL or if a symtab has no full name,
+ use FILENAME and LINENO instead. If there is at least one match,
+ return 1; otherwise, return 0, and return the best choice in BEST_ITEM
+ and BEST_SYMTAB. */
static int
-append_exact_match_to_sals (char *filename, int lineno,
+append_exact_match_to_sals (char *filename, char *fullname, int lineno,
struct symtabs_and_lines *ret,
struct linetable_entry **best_item,
struct symtab **best_symtab)
ALL_PSPACES (pspace)
ALL_PSPACE_SYMTABS (pspace, objfile, symtab)
{
- if (strcmp (filename, symtab->filename) == 0)
+ if (FILENAME_CMP (filename, symtab->filename) == 0)
{
struct linetable *l;
int len;
+ if (fullname != NULL
+ && symtab_to_fullname (symtab) != NULL
+ && FILENAME_CMP (fullname, symtab->fullname) != 0)
+ continue;
l = LINETABLE (symtab);
if (!l)
continue;
ALL_PSPACES (pspace)
ALL_PSPACE_PSYMTABS (pspace, objfile, psymtab)
{
- if (strcmp (match_filename, psymtab->filename) == 0)
+ if (FILENAME_CMP (match_filename, psymtab->filename) == 0)
{
set_current_program_space (pspace);
/* Now search the symtab for exact matches and append them. If
none is found, append the best_item and all its exact
matches. */
- exact = append_exact_match_to_sals (match_filename, lineno,
+ symtab_to_fullname (sal.symtab);
+ exact = append_exact_match_to_sals (sal.symtab->filename,
+ sal.symtab->fullname, lineno,
&ret, &best_item, &best_symtab);
if (!exact && best_item)
- append_exact_match_to_sals (best_symtab->filename, best_item->line,
+ append_exact_match_to_sals (best_symtab->filename,
+ best_symtab->fullname, best_item->line,
&ret, &best_item, &best_symtab);
}