#define DEV_TTY "/dev/tty"
#endif
+struct psymbol_bcache
+{
+ struct bcache *bcache;
+};
+
/* A fast way to get from a psymtab to its symtab (after the first time). */
#define PSYMTAB_TO_SYMTAB(pst) \
((pst) -> symtab != NULL ? (pst) -> symtab : psymtab_to_symtab (pst))
if (overlay_debugging && msymbol && section)
{
struct partial_symbol *p;
+
/* NOTE: This assumes that every psymbol has a
corresponding msymbol, which is not necessarily
true; the debug info might be much richer than the
return NULL;
}
+static struct symbol *
+expand_one_symtab_matching_psymtabs (struct objfile *objfile,
+ int kind, const char *name,
+ domain_enum domain,
+ struct symbol *(*matcher) (struct symtab *,
+ int,
+ const char *,
+ domain_enum,
+ void *),
+ void *data)
+{
+ return NULL;
+}
+
/* Look, in partial_symtab PST, for symbol whose natural name is NAME.
Check the global symbols if GLOBAL, the static symbols if not. */
-struct partial_symbol *
+static struct partial_symbol *
lookup_partial_symbol (struct partial_symtab *pst, const char *name,
int global, domain_enum domain)
{
- struct partial_symbol *temp;
struct partial_symbol **start, **psym;
struct partial_symbol **top, **real_top, **bottom, **center;
int length = (global ? pst->n_global_syms : pst->n_static_syms);
if (!pst->readin)
{
struct cleanup *back_to = increment_reading_symtab ();
+
(*pst->read_symtab) (pst);
do_cleanups (back_to);
}
static struct symtab *
find_last_source_symtab_from_partial (struct objfile *ofp)
{
- struct symtab *result;
struct partial_symtab *ps;
struct partial_symtab *cs_pst = 0;
{
const char *name = ps->filename;
int len = strlen (name);
+
if (!(len > 2 && (strcmp (&name[len - 2], ".h") == 0
|| strcmp (name, "<<C++-namespaces>>") == 0)))
cs_pst = ps;
{
int i;
struct partial_symtab *ps;
+
i = 0;
ALL_OBJFILE_PSYMTABS (objfile, ps)
{
void (*fun) (const char *, void *), void *data)
{
struct partial_symtab *ps;
+
ALL_OBJFILE_PSYMTABS (objfile, ps)
{
struct partial_symbol **psym;
continue;
fullname = psymtab_to_fullname (ps);
- (*fun) (fullname, ps->filename, data);
+ (*fun) (ps->filename, fullname, data);
}
}
return NULL;
}
-static char *
+static const char *
find_symbol_file_from_partial (struct objfile *objfile, const char *name)
{
struct partial_symtab *pst;
if (global)
{
int U;
+
i = 0;
U = length - 1;
while (U - i > 4)
{
int M = (U + i) >> 1;
struct partial_symbol *psym = start[M];
+
if (SYMBOL_LINKAGE_NAME (psym)[0] < name[0])
i = M + 1;
else if (SYMBOL_LINKAGE_NAME (psym)[0] > name[0])
if (global)
{
int U;
+
i = 0;
U = length - 1;
while (U - i > 4)
{
int M = (U + i) >> 1;
struct partial_symbol *psym = start[M];
+
if (SYMBOL_LINKAGE_NAME (psym)[0] < '_')
i = M + 1;
else if (SYMBOL_LINKAGE_NAME (psym)[0] > '_')
wild_match, is_name_suffix))
{
struct symtab *s = PSYMTAB_TO_SYMTAB (ps);
+
if (s == NULL || !s->primary)
continue;
(*callback) (objfile, s, data);
forget_cached_source_info_partial,
lookup_symtab_via_partial_symtab,
lookup_symbol_aux_psymtabs,
+ expand_one_symtab_matching_psymtabs,
print_psymtab_stats_for_objfile,
dump_psymtabs_for_objfile,
relocate_psymtabs,
return (psymtab);
}
+/* Calculate a hash code for the given partial symbol. The hash is
+ calculated using the symbol's value, language, domain, class
+ and name. These are the values which are set by
+ add_psymbol_to_bcache. */
+
+static unsigned long
+psymbol_hash (const void *addr, int length)
+{
+ unsigned long h = 0;
+ struct partial_symbol *psymbol = (struct partial_symbol *) addr;
+ unsigned int lang = psymbol->ginfo.language;
+ unsigned int domain = PSYMBOL_DOMAIN (psymbol);
+ unsigned int class = PSYMBOL_CLASS (psymbol);
+
+ h = hash_continue (&psymbol->ginfo.value, sizeof (psymbol->ginfo.value), h);
+ h = hash_continue (&lang, sizeof (unsigned int), h);
+ h = hash_continue (&domain, sizeof (unsigned int), h);
+ h = hash_continue (&class, sizeof (unsigned int), h);
+ h = hash_continue (psymbol->ginfo.name, strlen (psymbol->ginfo.name), h);
+
+ return h;
+}
+
+/* Returns true if the symbol at addr1 equals the symbol at addr2.
+ For the comparison this function uses a symbols value,
+ language, domain, class and name. */
+
+static int
+psymbol_compare (const void *addr1, const void *addr2, int length)
+{
+ struct partial_symbol *sym1 = (struct partial_symbol *) addr1;
+ struct partial_symbol *sym2 = (struct partial_symbol *) addr2;
+
+ return (memcmp (&sym1->ginfo.value, &sym1->ginfo.value,
+ sizeof (sym1->ginfo.value)) == 0
+ && sym1->ginfo.language == sym2->ginfo.language
+ && PSYMBOL_DOMAIN (sym1) == PSYMBOL_DOMAIN (sym2)
+ && PSYMBOL_CLASS (sym1) == PSYMBOL_CLASS (sym2)
+ && sym1->ginfo.name == sym2->ginfo.name);
+}
+
+/* Initialize a partial symbol bcache. */
+
+struct psymbol_bcache *
+psymbol_bcache_init (void)
+{
+ struct psymbol_bcache *bcache = XCALLOC (1, struct psymbol_bcache);
+ bcache->bcache = bcache_xmalloc (psymbol_hash, psymbol_compare);
+ return bcache;
+}
+
+/* Free a partial symbol bcache. */
+void
+psymbol_bcache_free (struct psymbol_bcache *bcache)
+{
+ if (bcache == NULL)
+ return;
+
+ bcache_xfree (bcache->bcache);
+ xfree (bcache);
+}
+
+/* Return the internal bcache of the psymbol_bcache BCACHE*/
+
+struct bcache *
+psymbol_bcache_get_bcache (struct psymbol_bcache *bcache)
+{
+ return bcache->bcache;
+}
+
+/* Find a copy of the SYM in BCACHE. If BCACHE has never seen this
+ symbol before, add a copy to BCACHE. In either case, return a pointer
+ to BCACHE's copy of the symbol. If optional ADDED is not NULL, return
+ 1 in case of new entry or 0 if returning an old entry. */
+
+static const struct partial_symbol *
+psymbol_bcache_full (struct partial_symbol *sym,
+ struct psymbol_bcache *bcache,
+ int *added)
+{
+ return bcache_full (sym,
+ sizeof (struct partial_symbol),
+ bcache->bcache,
+ added);
+}
+
/* Helper function, initialises partial symbol structure and stashes
it into objfile's bcache. Note that our caching mechanism will
use all fields of struct partial_symbol to determine hash value of the
enum language language, struct objfile *objfile,
int *added)
{
- /* psymbol is static so that there will be no uninitialized gaps in the
- structure which might contain random data, causing cache misses in
- bcache. */
- static struct partial_symbol psymbol;
-
- /* However, we must ensure that the entire 'value' field has been
- zeroed before assigning to it, because an assignment may not
- write the entire field. */
- memset (&psymbol.ginfo.value, 0, sizeof (psymbol.ginfo.value));
+ struct partial_symbol psymbol;
+
/* val and coreaddr are mutually exclusive, one of them *will* be zero */
if (val != 0)
{
SYMBOL_VALUE_ADDRESS (&psymbol) = coreaddr;
}
SYMBOL_SECTION (&psymbol) = 0;
- SYMBOL_LANGUAGE (&psymbol) = language;
+ SYMBOL_SET_LANGUAGE (&psymbol, language);
PSYMBOL_DOMAIN (&psymbol) = domain;
PSYMBOL_CLASS (&psymbol) = class;
SYMBOL_SET_NAMES (&psymbol, name, namelength, copy_name, objfile);
/* Stash the partial symbol away in the cache */
- return bcache_full (&psymbol, sizeof (struct partial_symbol),
- objfile->psymbol_cache, added);
+ return psymbol_bcache_full (&psymbol,
+ objfile->psymbol_cache,
+ added);
}
/* Helper function, adds partial symbol to the given partial symbol
struct objfile *objfile)
{
int new_size;
+
if (listp->size == 0)
{
new_size = 255;
ALL_PSYMTABS (objfile, ps)
{
struct gdbarch *gdbarch = get_objfile_arch (objfile);
+
s = PSYMTAB_TO_SYMTAB (ps);
if (s == NULL)
continue;