/* GDB routines for manipulating the minimal symbol tables.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+ 2002, 2003, 2004, 2007, 2008, 2009, 2010, 2011
+ Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
This file is part of GDB.
Even when a file contains enough debugging information to build a full
symbol table, these minimal symbols are still useful for quickly mapping
between names and addresses, and vice versa. They are also sometimes used
- to figure out what full symbol table entries need to be read in. */
+ to figure out what full symbol table entries need to be read in. */
#include "defs.h"
msymbol_hash_iw (const char *string)
{
unsigned int hash = 0;
+
while (*string && *string != '(')
{
while (isspace (*string))
msymbol_hash (const char *string)
{
unsigned int hash = 0;
+
for (; *string; ++string)
hash = hash * 67 + *string - 113;
return hash;
{
unsigned int hash
= msymbol_hash (SYMBOL_LINKAGE_NAME (sym)) % MINIMAL_SYMBOL_HASH_SIZE;
+
sym->hash_next = table[hash];
table[hash] = sym;
}
{
if (sym->demangled_hash_next == NULL)
{
- unsigned int hash
- = msymbol_hash_iw (SYMBOL_SEARCH_NAME (sym)) % MINIMAL_SYMBOL_HASH_SIZE;
+ unsigned int hash = msymbol_hash_iw (SYMBOL_SEARCH_NAME (sym))
+ % MINIMAL_SYMBOL_HASH_SIZE;
+
sym->demangled_hash_next = table[hash];
table[hash] = sym;
}
const char *modified_name;
if (sfile != NULL)
- {
- char *p = strrchr (sfile, '/');
- if (p != NULL)
- sfile = p + 1;
- }
+ sfile = lbasename (sfile);
- /* For C++, canonicalize the input name. */
+ /* For C++, canonicalize the input name. */
modified_name = name;
if (current_language->la_language == language_cplus)
{
char *cname = cp_canonicalize_string (name);
+
if (cname)
{
modified_name = cname;
case mst_solib_trampoline:
/* If a trampoline symbol is found, we prefer to
- keep looking for the *real* symbol. If the
+ keep looking for the *real* symbol. If the
actual symbol is not found, then we'll use the
- trampoline entry. */
+ trampoline entry. */
if (trampoline_symbol == NULL)
trampoline_symbol = msymbol;
break;
a binary search. Note that a minimal symbol table always consists
of at least two symbols, a "real" symbol and the terminating
"null symbol". If there are no real symbols, then there is no
- minimal symbol table at all. */
+ minimal symbol table at all. */
if (objfile->minimal_symbol_count > 0)
{
terminates. In essence, we are iterating the test interval
down until the pc value is pushed out of it from the high end.
- Warning: this code is trickier than it would appear at first. */
+ Warning: this code is trickier than it would appear at first. */
- /* Should also require that pc is <= end of objfile. FIXME! */
+ /* Should also require that pc is <= end of objfile. FIXME! */
if (pc >= SYMBOL_VALUE_ADDRESS (&msymbol[lo]))
{
while (SYMBOL_VALUE_ADDRESS (&msymbol[hi]) > pc)
{
- /* pc is still strictly less than highest address */
- /* Note "new" will always be >= lo */
+ /* pc is still strictly less than highest address. */
+ /* Note "new" will always be >= lo. */
new = (lo + hi) / 2;
if ((SYMBOL_VALUE_ADDRESS (&msymbol[new]) >= pc) ||
(lo == new))
/* The minimal symbol indexed by hi now is the best one in this
objfile's minimal symbol table. See if it is the best one
- overall. */
+ overall. */
if (hi >= 0
&& ((best_symbol == NULL) ||
}
/* Backward compatibility: search through the minimal symbol table
- for a matching PC (no section given) */
+ for a matching PC (no section given). */
struct minimal_symbol *
lookup_minimal_symbol_by_pc (CORE_ADDR pc)
{
return lookup_minimal_symbol_by_pc_section (pc, NULL);
}
+
+/* Find the minimal symbol named NAME, and return both the minsym
+ struct and its objfile. This only checks the linkage name. Sets
+ *OBJFILE_P and returns the minimal symbol, if it is found. If it
+ is not found, returns NULL. */
+
+struct minimal_symbol *
+lookup_minimal_symbol_and_objfile (const char *name,
+ struct objfile **objfile_p)
+{
+ struct objfile *objfile;
+ unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
+
+ ALL_OBJFILES (objfile)
+ {
+ struct minimal_symbol *msym;
+
+ for (msym = objfile->msymbol_hash[hash];
+ msym != NULL;
+ msym = msym->hash_next)
+ {
+ if (strcmp (SYMBOL_LINKAGE_NAME (msym), name) == 0)
+ {
+ *objfile_p = objfile;
+ return msym;
+ }
+ }
+ }
+
+ return 0;
+}
\f
-/* Return leading symbol character for a BFD. If BFD is NULL,
+/* Return leading symbol character for a BFD. If BFD is NULL,
return the leading symbol character from the main objfile. */
static int get_symbol_leading_char (bfd *);
/* Prepare to start collecting minimal symbols. Note that presetting
msym_bunch_index to BUNCH_SIZE causes the first call to save a minimal
- symbol to allocate the memory for the first bunch. */
+ symbol to allocate the memory for the first bunch. */
void
init_minimal_symbol_collection (void)
return (NULL);
/* It's safe to strip the leading char here once, since the name
- is also stored stripped in the minimal symbol table. */
+ is also stored stripped in the minimal symbol table. */
if (name[0] == get_symbol_leading_char (objfile->obfd))
{
++name;
msym_bunch = new;
}
msymbol = &msym_bunch->contents[msym_bunch_index];
- SYMBOL_INIT_LANGUAGE_SPECIFIC (msymbol, language_unknown);
- SYMBOL_LANGUAGE (msymbol) = language_auto;
+ SYMBOL_SET_LANGUAGE (msymbol, language_auto);
SYMBOL_SET_NAMES (msymbol, name, name_len, copy_name, objfile);
SYMBOL_VALUE_ADDRESS (msymbol) = address;
MSYMBOL_SIZE (msymbol) = 0;
/* The hash pointers must be cleared! If they're not,
- add_minsym_to_hash_table will NOT add this msymbol to the hash table. */
+ add_minsym_to_hash_table will NOT add this msymbol to the hash table. */
msymbol->hash_next = NULL;
msymbol->demangled_hash_next = NULL;
}
/* Compare two minimal symbols by address and return a signed result based
- on unsigned comparisons, so that we sort into unsigned numeric order.
+ on unsigned comparisons, so that we sort into unsigned numeric order.
Within groups with the same address, sort by name. */
static int
if (SYMBOL_VALUE_ADDRESS (fn1) < SYMBOL_VALUE_ADDRESS (fn2))
{
- return (-1); /* addr 1 is less than addr 2 */
+ return (-1); /* addr 1 is less than addr 2. */
}
else if (SYMBOL_VALUE_ADDRESS (fn1) > SYMBOL_VALUE_ADDRESS (fn2))
{
- return (1); /* addr 1 is greater than addr 2 */
+ return (1); /* addr 1 is greater than addr 2. */
}
else
/* addrs are equal: sort by name */
if (name1 && name2) /* both have names */
return strcmp (name1, name2);
else if (name2)
- return 1; /* fn1 has no name, so it is "less" */
- else if (name1) /* fn2 has no name, so it is "less" */
+ return 1; /* fn1 has no name, so it is "less". */
+ else if (name1) /* fn2 has no name, so it is "less". */
return -1;
else
- return (0); /* neither has a name, so they're equal. */
+ return (0); /* Neither has a name, so they're equal. */
}
}
FIXME: We could allocate the minimal symbol bunches on their own
obstack and then simply blow the obstack away when we are done with
- it. Is it worth the extra trouble though? */
+ it. Is it worth the extra trouble though? */
static void
do_discard_minimal_symbols_cleanup (void *arg)
/* Build (or rebuild) the minimal symbol hash tables. This is necessary
after compacting or sorting the table since the entries move around
- thus causing the internal minimal_symbol pointers to become jumbled. */
+ thus causing the internal minimal_symbol pointers to become jumbled. */
static void
build_minimal_symbol_hash_tables (struct objfile *objfile)
int i;
struct minimal_symbol *msym;
- /* Clear the hash tables. */
+ /* Clear the hash tables. */
for (i = 0; i < MINIMAL_SYMBOL_HASH_SIZE; i++)
{
objfile->msymbol_hash[i] = 0;
objfile->msymbol_demangled_hash[i] = 0;
}
- /* Now, (re)insert the actual entries. */
+ /* Now, (re)insert the actual entries. */
for (i = objfile->minimal_symbol_count, msym = objfile->msymbols;
i > 0;
i--, msym++)
to demangle it, and if successful, record it as a language_cplus symbol
and cache the demangled form on the symbol obstack. Symbols which don't
demangle are marked as language_unknown symbols, which inhibits future
- attempts to demangle them if we later add more minimal symbols. */
+ attempts to demangle them if we later add more minimal symbols. */
void
install_minimal_symbols (struct objfile *objfile)
to the new contiguous array of symbols. Note that we start with the
current, possibly partially filled bunch (thus we use the current
msym_bunch_index for the first bunch we copy over), and thereafter
- each bunch is full. */
+ each bunch is full. */
mcount = objfile->minimal_symbol_count;
to some symbol in the middle of it. Zero out the fields in the
"null symbol" allocated at the end of the array. Note that the
symbol count does *not* include this null symbol, which is why it
- is indexed by mcount and not mcount-1. */
+ is indexed by mcount and not mcount-1. */
SYMBOL_LINKAGE_NAME (&msymbols[mcount]) = NULL;
SYMBOL_VALUE_ADDRESS (&msymbols[mcount]) = 0;
MSYMBOL_TARGET_FLAG_2 (&msymbols[mcount]) = 0;
MSYMBOL_SIZE (&msymbols[mcount]) = 0;
MSYMBOL_TYPE (&msymbols[mcount]) = mst_unknown;
- SYMBOL_INIT_LANGUAGE_SPECIFIC (&msymbols[mcount], language_unknown);
+ SYMBOL_SET_LANGUAGE (&msymbols[mcount], language_unknown);
/* Attach the minimal symbol table to the specified objfile.
The strings themselves are also located in the objfile_obstack
mixing ABIs then the user will need to "set cp-abi"
manually. */
const char *name = SYMBOL_LINKAGE_NAME (&objfile->msymbols[i]);
+
if (name[0] == '_' && name[1] == 'Z'
&& SYMBOL_DEMANGLED_NAME (&objfile->msymbols[i]) != NULL)
{
/* Now build the hash tables; we can't do this incrementally
at an earlier point since we weren't finished with the obstack
yet. (And if the msymbol obstack gets moved, all the internal
- pointers to other msymbols need to be adjusted.) */
+ pointers to other msymbols need to be adjusted.) */
build_minimal_symbol_hash_tables (objfile);
}
}
We may fail to find the right function if a function with the
same name is defined in more than one shared library, but this
- is considered bad programming style. We could return 0 if we find
+ is considered bad programming style. We could return 0 if we find
a duplicate function in case this matters someday. */
CORE_ADDR
SYMBOL_LINKAGE_NAME (tsymbol)) == 0)
{
CORE_ADDR func;
+
func = gdbarch_convert_from_func_ptr_addr
(get_objfile_arch (objfile),
SYMBOL_VALUE_ADDRESS (msymbol),