const char *name,
const domain_enum domain);
-static void print_msymbol_info (struct minimal_symbol *);
-
void _initialize_symtab (void);
/* */
/* Check for a symtab of a specific name by searching some symtabs.
This is a helper function for callbacks of iterate_over_symtabs.
+ If NAME is not absolute, then REAL_PATH is NULL
+ If NAME is absolute, then REAL_PATH is the gdb_realpath form of NAME.
+
The return value, NAME, REAL_PATH, CALLBACK, and DATA
are identical to the `map_symtabs_matching_filename' method of
quick_symbol_functions.
continue;
}
- /* Before we invoke realpath, which can get expensive when many
- files are involved, do a quick comparison of the basenames. */
- if (! basenames_may_differ
- && FILENAME_CMP (base_name, lbasename (s->filename)) != 0)
- continue;
-
- if (compare_filenames_for_search (symtab_to_fullname (s), name))
- {
- if (callback (s, data))
- return 1;
+ /* Before we invoke realpath, which can get expensive when many
+ files are involved, do a quick comparison of the basenames. */
+ if (! basenames_may_differ
+ && FILENAME_CMP (base_name, lbasename (s->filename)) != 0)
continue;
- }
- /* If the user gave us an absolute path, try to find the file in
- this symtab and use its absolute path. */
+ if (compare_filenames_for_search (symtab_to_fullname (s), name))
+ {
+ if (callback (s, data))
+ return 1;
+ continue;
+ }
- if (real_path != NULL)
- {
- const char *fullname = symtab_to_fullname (s);
+ /* If the user gave us an absolute path, try to find the file in
+ this symtab and use its absolute path. */
+ if (real_path != NULL)
+ {
+ const char *fullname = symtab_to_fullname (s);
- gdb_assert (IS_ABSOLUTE_PATH (real_path));
- gdb_assert (IS_ABSOLUTE_PATH (name));
- if (FILENAME_CMP (real_path, fullname) == 0)
- {
- if (callback (s, data))
- return 1;
- continue;
- }
- }
+ gdb_assert (IS_ABSOLUTE_PATH (real_path));
+ gdb_assert (IS_ABSOLUTE_PATH (name));
+ if (FILENAME_CMP (real_path, fullname) == 0)
+ {
+ if (callback (s, data))
+ return 1;
+ continue;
+ }
+ }
}
return 0;
static void
symbol_init_cplus_specific (struct general_symbol_info *gsymbol,
- struct objfile *objfile)
+ struct obstack *obstack)
{
/* A language_specific structure should not have been previously
initialized. */
gdb_assert (gsymbol->language_specific.cplus_specific == NULL);
- gdb_assert (objfile != NULL);
+ gdb_assert (obstack != NULL);
gsymbol->language_specific.cplus_specific =
- OBSTACK_ZALLOC (&objfile->objfile_obstack, struct cplus_specific);
+ OBSTACK_ZALLOC (obstack, struct cplus_specific);
}
/* Set the demangled name of GSYMBOL to NAME. NAME must be already
void
symbol_set_demangled_name (struct general_symbol_info *gsymbol,
const char *name,
- struct objfile *objfile)
+ struct obstack *obstack)
{
if (gsymbol->language == language_cplus)
{
if (gsymbol->language_specific.cplus_specific == NULL)
- symbol_init_cplus_specific (gsymbol, objfile);
+ symbol_init_cplus_specific (gsymbol, obstack);
gsymbol->language_specific.cplus_specific->demangled_name = name;
}
+ else if (gsymbol->language == language_ada)
+ {
+ if (name == NULL)
+ {
+ gsymbol->ada_mangled = 0;
+ gsymbol->language_specific.obstack = obstack;
+ }
+ else
+ {
+ gsymbol->ada_mangled = 1;
+ gsymbol->language_specific.mangled_lang.demangled_name = name;
+ }
+ }
else
gsymbol->language_specific.mangled_lang.demangled_name = name;
}
else
return NULL;
}
- else
- return gsymbol->language_specific.mangled_lang.demangled_name;
+ else if (gsymbol->language == language_ada)
+ {
+ if (!gsymbol->ada_mangled)
+ return NULL;
+ /* Fall through. */
+ }
+
+ return gsymbol->language_specific.mangled_lang.demangled_name;
}
\f
void
symbol_set_language (struct general_symbol_info *gsymbol,
- enum language language)
+ enum language language,
+ struct obstack *obstack)
{
gsymbol->language = language;
if (gsymbol->language == language_d
|| gsymbol->language == language_objc
|| gsymbol->language == language_fortran)
{
- symbol_set_demangled_name (gsymbol, NULL, NULL);
+ symbol_set_demangled_name (gsymbol, NULL, obstack);
+ }
+ else if (gsymbol->language == language_ada)
+ {
+ gdb_assert (gsymbol->ada_mangled == 0);
+ gsymbol->language_specific.obstack = obstack;
}
else if (gsymbol->language == language_cplus)
gsymbol->language_specific.cplus_specific = NULL;
|| gsymbol->language == language_auto)
{
demangled =
- cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI);
+ gdb_demangle (mangled, DMGL_PARAMS | DMGL_ANSI);
if (demangled != NULL)
{
gsymbol->language = language_cplus;
if (gsymbol->language == language_java)
{
demangled =
- cplus_demangle (mangled,
- DMGL_PARAMS | DMGL_ANSI | DMGL_JAVA);
+ gdb_demangle (mangled,
+ DMGL_PARAMS | DMGL_ANSI | DMGL_JAVA);
if (demangled != NULL)
{
gsymbol->language = language_java;
name[len] = '\0';
gsymbol->name = name;
}
- symbol_set_demangled_name (gsymbol, NULL, NULL);
+ symbol_set_demangled_name (gsymbol, NULL, &objfile->objfile_obstack);
return;
}
gsymbol->name = (*slot)->mangled + lookup_len - len;
if ((*slot)->demangled[0] != '\0')
- symbol_set_demangled_name (gsymbol, (*slot)->demangled, objfile);
+ symbol_set_demangled_name (gsymbol, (*slot)->demangled,
+ &objfile->objfile_obstack);
else
- symbol_set_demangled_name (gsymbol, NULL, objfile);
+ symbol_set_demangled_name (gsymbol, NULL, &objfile->objfile_obstack);
}
/* Return the source code name of a symbol. In languages where
return symbol_get_demangled_name (gsymbol);
break;
case language_ada:
- if (symbol_get_demangled_name (gsymbol) != NULL)
- return symbol_get_demangled_name (gsymbol);
- else
- return ada_decode_symbol (gsymbol);
- break;
+ return ada_decode_symbol (gsymbol);
default:
break;
}
dem_name = symbol_get_demangled_name (gsymbol);
break;
case language_ada:
- dem_name = symbol_get_demangled_name (gsymbol);
- if (dem_name == NULL)
- dem_name = ada_decode_symbol (gsymbol);
+ dem_name = ada_decode_symbol (gsymbol);
break;
default:
break;
/* If we know that this is not a text address, return failure. This is
necessary because we loop based on texthigh and textlow, which do
not include the data ranges. */
- msymbol = lookup_minimal_symbol_by_pc_section (pc, section);
+ msymbol = lookup_minimal_symbol_by_pc_section (pc, section).minsym;
if (msymbol
&& (MSYMBOL_TYPE (msymbol) == mst_data
|| MSYMBOL_TYPE (msymbol) == mst_bss
point to the actual function code. */
msym = lookup_minimal_symbol_by_pc_name (addr, ginfo->name, objfile);
if (msym)
- {
- ginfo->obj_section = SYMBOL_OBJ_SECTION (msym);
- ginfo->section = SYMBOL_SECTION (msym);
- }
+ ginfo->section = SYMBOL_SECTION (msym);
else
{
/* Static, function-local variables do appear in the linker
a search of the section table. */
struct obj_section *s;
+ int fallback = -1;
ALL_OBJFILE_OSECTIONS (objfile, s)
{
- int idx = s->the_bfd_section->index;
+ int idx = s - objfile->sections;
CORE_ADDR offset = ANOFFSET (objfile->section_offsets, idx);
+ if (fallback == -1)
+ fallback = idx;
+
if (obj_section_addr (s) - offset <= addr
&& addr < obj_section_endaddr (s) - offset)
{
- ginfo->obj_section = s;
ginfo->section = idx;
return;
}
}
+
+ /* If we didn't find the section, assume it is in the first
+ section. If there is no allocated section, then it hardly
+ matters what we pick, so just pick zero. */
+ if (fallback == -1)
+ ginfo->section = 0;
+ else
+ ginfo->section = fallback;
}
}
if (!sym)
return NULL;
- if (SYMBOL_OBJ_SECTION (sym))
- return sym;
-
/* We either have an OBJFILE, or we can get at it from the sym's
symtab. Anything else is a bug. */
gdb_assert (objfile || SYMBOL_SYMTAB (sym));
if (objfile == NULL)
objfile = SYMBOL_SYMTAB (sym)->objfile;
+ if (SYMBOL_OBJ_SECTION (objfile, sym))
+ return sym;
+
/* We should have an objfile by now. */
gdb_assert (objfile);
lookup, so we can always binary search. */
if (lang == language_cplus)
{
- demangled_name = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
+ demangled_name = gdb_demangle (name, DMGL_ANSI | DMGL_PARAMS);
if (demangled_name)
{
modified_name = demangled_name;
}
else if (lang == language_java)
{
- demangled_name = cplus_demangle (name,
- DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
+ demangled_name = gdb_demangle (name,
+ DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
if (demangled_name)
{
modified_name = demangled_name;
return NULL;
}
+/* A helper function that throws an exception when a symbol was found
+ in a psymtab but not in a symtab. */
+
+static void ATTRIBUTE_NORETURN
+error_in_psymtab_expansion (int kind, const char *name, struct symtab *symtab)
+{
+ error (_("\
+Internal: %s symbol `%s' found in %s psymtab but not in symtab.\n\
+%s may be an inlined function, or may be a template function\n \
+(if a template, try specifying an instantiation: %s<type>)."),
+ kind == GLOBAL_BLOCK ? "global" : "static",
+ name, symtab_to_filename_for_display (symtab), name, name);
+}
+
/* A helper function for lookup_symbol_aux that interfaces with the
"quick" symbol table functions. */
block = BLOCKVECTOR_BLOCK (bv, kind);
sym = lookup_block_symbol (block, name, domain);
if (!sym)
- {
- /* This shouldn't be necessary, but as a last resort try
- looking in the statics even though the psymtab claimed
- the symbol was global, or vice-versa. It's possible
- that the psymtab gets it wrong in some cases. */
-
- /* FIXME: carlton/2002-09-30: Should we really do that?
- If that happens, isn't it likely to be a GDB error, in
- which case we should fix the GDB error rather than
- silently dealing with it here? So I'd vote for
- removing the check for the symbol in the other
- block. */
- block = BLOCKVECTOR_BLOCK (bv,
- kind == GLOBAL_BLOCK ?
- STATIC_BLOCK : GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, name, domain);
- if (!sym)
- error (_("\
-Internal: %s symbol `%s' found in %s psymtab but not in symtab.\n\
-%s may be an inlined function, or may be a template function\n\
-(if a template, try specifying an instantiation: %s<type>)."),
- kind == GLOBAL_BLOCK ? "global" : "static",
- name, symtab_to_filename_for_display (symtab), name, name);
- }
+ error_in_psymtab_expansion (kind, name, symtab);
return fixup_symbol_section (sym, objfile);
}
block = BLOCKVECTOR_BLOCK (bv, kind);
sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
if (!sym)
- {
- int other_kind = kind == GLOBAL_BLOCK ? STATIC_BLOCK : GLOBAL_BLOCK;
-
- /* This shouldn't be necessary, but as a last resort
- * try looking in the 'other kind' even though the psymtab
- * claimed the symbol was one thing. It's possible that
- * the psymtab gets it wrong in some cases.
- */
- block = BLOCKVECTOR_BLOCK (bv, other_kind);
- sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
- if (!sym)
- /* FIXME; error is wrong in one case. */
- error (_("\
-Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\
-%s may be an inlined function, or may be a template function\n\
-(if a template, try specifying an instantiation: %s<type>)."),
- name, symtab_to_filename_for_display (symtab), name, name);
- }
+ error_in_psymtab_expansion (kind, name, symtab);
+
if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
return SYMBOL_TYPE (sym);
return (struct type *) 0;
}
-/* Find the name of the file containing main(). */
-/* FIXME: What about languages without main() or specially linked
- executables that have no main() ? */
-
-const char *
-find_main_filename (void)
-{
- struct objfile *objfile;
- char *name = main_name ();
-
- ALL_OBJFILES (objfile)
- {
- const char *result;
-
- if (!objfile->sf)
- continue;
- result = objfile->sf->qf->find_symbol_file (objfile, name);
- if (result)
- return result;
- }
- return (NULL);
-}
-
/* Search BLOCK for symbol NAME in DOMAIN.
Note that if NAME is the demangled form of a C++ symbol, we will fail
addresses, which do not include the data ranges, and because
we call find_pc_sect_psymtab which has a similar restriction based
on the partial_symtab's texthigh and textlow. */
- msymbol = lookup_minimal_symbol_by_pc_section (pc, section);
+ msymbol = lookup_minimal_symbol_by_pc_section (pc, section).minsym;
if (msymbol
&& (MSYMBOL_TYPE (msymbol) == mst_data
|| MSYMBOL_TYPE (msymbol) == mst_bss
ALL_BLOCK_SYMBOLS (b, iter, sym)
{
fixup_symbol_section (sym, objfile);
- if (matching_obj_sections (SYMBOL_OBJ_SECTION (sym), section))
+ if (matching_obj_sections (SYMBOL_OBJ_SECTION (objfile, sym),
+ section))
break;
}
if (sym == NULL)
struct linetable_entry *item;
struct symtab_and_line val;
struct blockvector *bv;
- struct minimal_symbol *msymbol;
+ struct bound_minimal_symbol msymbol;
struct minimal_symbol *mfunsym;
struct objfile *objfile;
* infinite recursion.
*/
msymbol = lookup_minimal_symbol_by_pc (pc);
- if (msymbol != NULL)
- if (MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
+ if (msymbol.minsym != NULL)
+ if (MSYMBOL_TYPE (msymbol.minsym) == mst_solib_trampoline)
{
- mfunsym = lookup_minimal_symbol_text (SYMBOL_LINKAGE_NAME (msymbol),
- NULL);
+ mfunsym
+ = lookup_minimal_symbol_text (SYMBOL_LINKAGE_NAME (msymbol.minsym),
+ NULL);
if (mfunsym == NULL)
/* I eliminated this warning since it is coming out
* in the following situation:
;
/* fall through */
else if (SYMBOL_VALUE_ADDRESS (mfunsym)
- == SYMBOL_VALUE_ADDRESS (msymbol))
+ == SYMBOL_VALUE_ADDRESS (msymbol.minsym))
/* Avoid infinite recursion */
/* See above comment about why warning is commented out. */
/* warning ("In stub for %s; unable to find real function/line info",
fixup_symbol_section (sym, NULL);
sal = find_pc_sect_line (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)),
- SYMBOL_OBJ_SECTION (sym), 0);
+ SYMBOL_OBJ_SECTION (SYMBOL_OBJFILE (sym), sym), 0);
/* We always should have a line for the function start address.
If we don't, something is odd. Create a plain SAL refering
init_sal (&sal);
sal.pspace = current_program_space;
sal.pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
- sal.section = SYMBOL_OBJ_SECTION (sym);
+ sal.section = SYMBOL_OBJ_SECTION (SYMBOL_OBJFILE (sym), sym);
}
if (funfirstline)
fixup_symbol_section (sym, NULL);
pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
- section = SYMBOL_OBJ_SECTION (sym);
+ section = SYMBOL_OBJ_SECTION (SYMBOL_OBJFILE (sym), sym);
name = SYMBOL_LINKAGE_NAME (sym);
objfile = SYMBOL_SYMTAB (sym)->objfile;
}
else
{
- struct minimal_symbol *msymbol
+ struct bound_minimal_symbol msymbol
= lookup_minimal_symbol_by_pc_section (sal->pc, sal->section);
- if (msymbol == NULL)
+ if (msymbol.minsym == NULL)
{
do_cleanups (old_chain);
return;
}
- pc = SYMBOL_VALUE_ADDRESS (msymbol);
- section = SYMBOL_OBJ_SECTION (msymbol);
- name = SYMBOL_LINKAGE_NAME (msymbol);
- objfile = msymbol_objfile (msymbol);
+ objfile = msymbol.objfile;
+ pc = SYMBOL_VALUE_ADDRESS (msymbol.minsym);
+ section = SYMBOL_OBJ_SECTION (objfile, msymbol.minsym);
+ name = SYMBOL_LINKAGE_NAME (msymbol.minsym);
}
gdbarch = get_objfile_arch (objfile);
if (skip && start_sal.pc != pc
&& (sym ? (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= start_sal.end
&& start_sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym)))
- : (lookup_minimal_symbol_by_pc_section (start_sal.end, section)
- == lookup_minimal_symbol_by_pc_section (pc, section))))
+ : (lookup_minimal_symbol_by_pc_section (start_sal.end, section).minsym
+ == lookup_minimal_symbol_by_pc_section (pc, section).minsym)))
{
/* First pc of next line */
pc = start_sal.end;
}
static void
-do_free_search_symbols_cleanup (void *symbols)
+do_free_search_symbols_cleanup (void *symbolsp)
{
+ struct symbol_search *symbols = *(struct symbol_search **) symbolsp;
+
free_search_symbols (symbols);
}
struct cleanup *
-make_cleanup_free_search_symbols (struct symbol_search *symbols)
+make_cleanup_free_search_symbols (struct symbol_search **symbolsp)
{
- return make_cleanup (do_free_search_symbols_cleanup, symbols);
+ return make_cleanup (do_free_search_symbols_cleanup, symbolsp);
}
-/* Helper function for sort_search_symbols and qsort. Can only
+/* Helper function for sort_search_symbols_remove_dups and qsort. Can only
sort symbols, not minimal symbols. */
static int
compare_search_syms (const void *sa, const void *sb)
{
- struct symbol_search **sym_a = (struct symbol_search **) sa;
- struct symbol_search **sym_b = (struct symbol_search **) sb;
+ struct symbol_search *sym_a = *(struct symbol_search **) sa;
+ struct symbol_search *sym_b = *(struct symbol_search **) sb;
+ int c;
+
+ c = strcmp (sym_a->symtab->filename, sym_b->symtab->filename);
+ if (c != 0)
+ return c;
- return strcmp (SYMBOL_PRINT_NAME ((*sym_a)->symbol),
- SYMBOL_PRINT_NAME ((*sym_b)->symbol));
+ if (sym_a->block != sym_b->block)
+ return sym_a->block - sym_b->block;
+
+ return strcmp (SYMBOL_PRINT_NAME (sym_a->symbol),
+ SYMBOL_PRINT_NAME (sym_b->symbol));
}
-/* Sort the ``nfound'' symbols in the list after prevtail. Leave
- prevtail where it is, but update its next pointer to point to
- the first of the sorted symbols. */
+/* Helper function for sort_search_symbols_remove_dups.
+ Return TRUE if symbols A, B are equal. */
-static struct symbol_search *
-sort_search_symbols (struct symbol_search *prevtail, int nfound)
+static int
+search_symbols_equal (const struct symbol_search *a,
+ const struct symbol_search *b)
+{
+ return (strcmp (a->symtab->filename, b->symtab->filename) == 0
+ && a->block == b->block
+ && strcmp (SYMBOL_PRINT_NAME (a->symbol),
+ SYMBOL_PRINT_NAME (b->symbol)) == 0);
+}
+
+/* Sort the NFOUND symbols in list FOUND and remove duplicates.
+ The duplicates are freed, and the new list is returned in
+ *NEW_HEAD, *NEW_TAIL. */
+
+static void
+sort_search_symbols_remove_dups (struct symbol_search *found, int nfound,
+ struct symbol_search **new_head,
+ struct symbol_search **new_tail)
{
struct symbol_search **symbols, *symp, *old_next;
- int i;
+ int i, j, nunique;
+ gdb_assert (found != NULL && nfound > 0);
+
+ /* Build an array out of the list so we can easily sort them. */
symbols = (struct symbol_search **) xmalloc (sizeof (struct symbol_search *)
* nfound);
- symp = prevtail->next;
+ symp = found;
for (i = 0; i < nfound; i++)
{
+ gdb_assert (symp != NULL);
+ gdb_assert (symp->block >= 0 && symp->block <= 1);
symbols[i] = symp;
symp = symp->next;
}
- /* Generally NULL. */
- old_next = symp;
+ gdb_assert (symp == NULL);
qsort (symbols, nfound, sizeof (struct symbol_search *),
compare_search_syms);
- symp = prevtail;
- for (i = 0; i < nfound; i++)
+ /* Collapse out the dups. */
+ for (i = 1, j = 1; i < nfound; ++i)
{
- symp->next = symbols[i];
- symp = symp->next;
+ if (! search_symbols_equal (symbols[j - 1], symbols[i]))
+ symbols[j++] = symbols[i];
+ else
+ xfree (symbols[i]);
}
- symp->next = old_next;
+ nunique = j;
+ symbols[j - 1]->next = NULL;
+
+ /* Rebuild the linked list. */
+ for (i = 0; i < nunique - 1; i++)
+ symbols[i]->next = symbols[i + 1];
+ symbols[nunique - 1]->next = NULL;
+ *new_head = symbols[0];
+ *new_tail = symbols[nunique - 1];
xfree (symbols);
- return symp;
}
/* An object of this type is passed as the user_data to the
free_search_symbols should be called when *MATCHES is no longer needed.
- The results are sorted locally; each symtab's global and static blocks are
- separately alphabetized. */
+ Within each file the results are sorted locally; each symtab's global and
+ static blocks are separately alphabetized.
+ Duplicate entries are removed. */
void
search_symbols (char *regexp, enum search_domain kind,
enum minimal_symbol_type ourtype2;
enum minimal_symbol_type ourtype3;
enum minimal_symbol_type ourtype4;
- struct symbol_search *sr;
- struct symbol_search *psr;
+ struct symbol_search *found;
struct symbol_search *tail;
struct search_symbols_data datum;
+ int nfound;
/* OLD_CHAIN .. RETVAL_CHAIN is always freed, RETVAL_CHAIN .. current
CLEANUP_CHAIN is freed only in the case of an error. */
ourtype3 = types3[kind];
ourtype4 = types4[kind];
- sr = *matches = NULL;
- tail = NULL;
+ *matches = NULL;
datum.preg_p = 0;
if (regexp != NULL)
&datum);
}
- retval_chain = old_chain;
-
/* Here, we search through the minimal symbol tables for functions
and variables that match, and force their symbols to be read.
This is in particular necessary for demangled variable names,
}
}
+ found = NULL;
+ tail = NULL;
+ nfound = 0;
+ retval_chain = make_cleanup_free_search_symbols (&found);
+
ALL_PRIMARY_SYMTABS (objfile, s)
{
bv = BLOCKVECTOR (s);
for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
{
- struct symbol_search *prevtail = tail;
- int nfound = 0;
-
b = BLOCKVECTOR_BLOCK (bv, i);
ALL_BLOCK_SYMBOLS (b, iter, sym)
{
&& SYMBOL_CLASS (sym) == LOC_TYPEDEF))))
{
/* match */
- psr = (struct symbol_search *)
+ struct symbol_search *psr = (struct symbol_search *)
xmalloc (sizeof (struct symbol_search));
psr->block = i;
psr->symtab = real_symtab;
psr->symbol = sym;
- psr->msymbol = NULL;
+ memset (&psr->msymbol, 0, sizeof (psr->msymbol));
psr->next = NULL;
if (tail == NULL)
- sr = psr;
+ found = psr;
else
tail->next = psr;
tail = psr;
nfound ++;
}
}
- if (nfound > 0)
- {
- if (prevtail == NULL)
- {
- struct symbol_search dummy;
-
- dummy.next = sr;
- tail = sort_search_symbols (&dummy, nfound);
- sr = dummy.next;
-
- make_cleanup_free_search_symbols (sr);
- }
- else
- tail = sort_search_symbols (prevtail, nfound);
- }
}
}
+ if (found != NULL)
+ {
+ sort_search_symbols_remove_dups (found, nfound, &found, &tail);
+ /* Note: nfound is no longer useful beyond this point. */
+ }
+
/* If there are no eyes, avoid all contact. I mean, if there are
no debug symbols, then print directly from the msymbol_vector. */
== NULL)
{
/* match */
- psr = (struct symbol_search *)
+ struct symbol_search *psr = (struct symbol_search *)
xmalloc (sizeof (struct symbol_search));
psr->block = i;
- psr->msymbol = msymbol;
+ psr->msymbol.minsym = msymbol;
+ psr->msymbol.objfile = objfile;
psr->symtab = NULL;
psr->symbol = NULL;
psr->next = NULL;
if (tail == NULL)
- {
- sr = psr;
- make_cleanup_free_search_symbols (sr);
- }
+ found = psr;
else
tail->next = psr;
tail = psr;
discard_cleanups (retval_chain);
do_cleanups (old_chain);
- *matches = sr;
+ *matches = found;
}
/* Helper function for symtab_symbol_info, this function uses
for non-debugging symbols to gdb_stdout. */
static void
-print_msymbol_info (struct minimal_symbol *msymbol)
+print_msymbol_info (struct bound_minimal_symbol msymbol)
{
- struct gdbarch *gdbarch = get_objfile_arch (msymbol_objfile (msymbol));
+ struct gdbarch *gdbarch = get_objfile_arch (msymbol.objfile);
char *tmp;
if (gdbarch_addr_bit (gdbarch) <= 32)
- tmp = hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol)
+ tmp = hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol.minsym)
& (CORE_ADDR) 0xffffffff,
8);
else
- tmp = hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol),
+ tmp = hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol.minsym),
16);
printf_filtered ("%s %s\n",
- tmp, SYMBOL_PRINT_NAME (msymbol));
+ tmp, SYMBOL_PRINT_NAME (msymbol.minsym));
}
/* This is the guts of the commands "info functions", "info types", and
/* Must make sure that if we're interrupted, symbols gets freed. */
search_symbols (regexp, kind, 0, (char **) NULL, &symbols);
- old_chain = make_cleanup_free_search_symbols (symbols);
+ old_chain = make_cleanup_free_search_symbols (&symbols);
if (regexp != NULL)
printf_filtered (_("All %ss matching regular expression \"%s\":\n"),
{
QUIT;
- if (p->msymbol != NULL)
+ if (p->msymbol.minsym != NULL)
{
if (first)
{
}
search_symbols (regexp, FUNCTIONS_DOMAIN, nfiles, files, &ss);
- old_chain = make_cleanup_free_search_symbols (ss);
+ old_chain = make_cleanup_free_search_symbols (&ss);
make_cleanup (free_current_contents, &string);
start_rbreak_breakpoints ();
make_cleanup (do_end_rbreak_breakpoints, NULL);
for (p = ss; p != NULL; p = p->next)
{
- if (p->msymbol == NULL)
+ if (p->msymbol.minsym == NULL)
{
const char *fullname = symtab_to_fullname (p->symtab);
}
else
{
- int newlen = (strlen (SYMBOL_LINKAGE_NAME (p->msymbol)) + 3);
+ int newlen = (strlen (SYMBOL_LINKAGE_NAME (p->msymbol.minsym)) + 3);
if (newlen > len)
{
len = newlen;
}
strcpy (string, "'");
- strcat (string, SYMBOL_LINKAGE_NAME (p->msymbol));
+ strcat (string, SYMBOL_LINKAGE_NAME (p->msymbol.minsym));
strcat (string, "'");
break_command (string, from_tty);
printf_filtered ("<function, no debug info> %s;\n",
- SYMBOL_PRINT_NAME (p->msymbol));
+ SYMBOL_PRINT_NAME (p->msymbol.minsym));
}
}
return 0;
}
+\f
+
+/* The next index to hand out in response to a registration request. */
+
+static int next_aclass_value = LOC_FINAL_VALUE;
+
+/* The maximum number of "aclass" registrations we support. This is
+ constant for convenience. */
+#define MAX_SYMBOL_IMPLS (LOC_FINAL_VALUE + 10)
+
+/* The objects representing the various "aclass" values. The elements
+ from 0 up to LOC_FINAL_VALUE-1 represent themselves, and subsequent
+ elements are those registered at gdb initialization time. */
+
+static struct symbol_impl symbol_impl[MAX_SYMBOL_IMPLS];
+
+/* The globally visible pointer. This is separate from 'symbol_impl'
+ so that it can be const. */
+
+const struct symbol_impl *symbol_impls = &symbol_impl[0];
+
+/* Make sure we saved enough room in struct symbol. */
+
+gdb_static_assert (MAX_SYMBOL_IMPLS <= (1 << SYMBOL_ACLASS_BITS));
+
+/* Register a computed symbol type. ACLASS must be LOC_COMPUTED. OPS
+ is the ops vector associated with this index. This returns the new
+ index, which should be used as the aclass_index field for symbols
+ of this type. */
+
+int
+register_symbol_computed_impl (enum address_class aclass,
+ const struct symbol_computed_ops *ops)
+{
+ int result = next_aclass_value++;
+
+ gdb_assert (aclass == LOC_COMPUTED);
+ gdb_assert (result < MAX_SYMBOL_IMPLS);
+ symbol_impl[result].aclass = aclass;
+ symbol_impl[result].ops_computed = ops;
+
+ /* Sanity check OPS. */
+ gdb_assert (ops != NULL);
+ gdb_assert (ops->tracepoint_var_ref != NULL);
+ gdb_assert (ops->describe_location != NULL);
+ gdb_assert (ops->read_needs_frame != NULL);
+ gdb_assert (ops->read_variable != NULL);
+
+ return result;
+}
+
+/* Register a function with frame base type. ACLASS must be LOC_BLOCK.
+ OPS is the ops vector associated with this index. This returns the
+ new index, which should be used as the aclass_index field for symbols
+ of this type. */
+
+int
+register_symbol_block_impl (enum address_class aclass,
+ const struct symbol_block_ops *ops)
+{
+ int result = next_aclass_value++;
+
+ gdb_assert (aclass == LOC_BLOCK);
+ gdb_assert (result < MAX_SYMBOL_IMPLS);
+ symbol_impl[result].aclass = aclass;
+ symbol_impl[result].ops_block = ops;
+
+ /* Sanity check OPS. */
+ gdb_assert (ops != NULL);
+ gdb_assert (ops->find_frame_base_location != NULL);
+
+ return result;
+}
+
+/* Register a register symbol type. ACLASS must be LOC_REGISTER or
+ LOC_REGPARM_ADDR. OPS is the register ops vector associated with
+ this index. This returns the new index, which should be used as
+ the aclass_index field for symbols of this type. */
+
+int
+register_symbol_register_impl (enum address_class aclass,
+ const struct symbol_register_ops *ops)
+{
+ int result = next_aclass_value++;
+
+ gdb_assert (aclass == LOC_REGISTER || aclass == LOC_REGPARM_ADDR);
+ gdb_assert (result < MAX_SYMBOL_IMPLS);
+ symbol_impl[result].aclass = aclass;
+ symbol_impl[result].ops_register = ops;
+
+ return result;
+}
+
+/* Initialize elements of 'symbol_impl' for the constants in enum
+ address_class. */
+
+static void
+initialize_ordinary_address_classes (void)
+{
+ int i;
+
+ for (i = 0; i < LOC_FINAL_VALUE; ++i)
+ symbol_impl[i].aclass = i;
+}
+
+\f
+
+/* Initialize the symbol SYM. */
+
+void
+initialize_symbol (struct symbol *sym)
+{
+ memset (sym, 0, sizeof (*sym));
+ SYMBOL_SECTION (sym) = -1;
+}
+
+/* Allocate and initialize a new 'struct symbol' on OBJFILE's
+ obstack. */
+
+struct symbol *
+allocate_symbol (struct objfile *objfile)
+{
+ struct symbol *result;
+
+ result = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symbol);
+ SYMBOL_SECTION (result) = -1;
+
+ return result;
+}
+
+/* Allocate and initialize a new 'struct template_symbol' on OBJFILE's
+ obstack. */
+
+struct template_symbol *
+allocate_template_symbol (struct objfile *objfile)
+{
+ struct template_symbol *result;
+
+ result = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct template_symbol);
+ SYMBOL_SECTION (&result->base) = -1;
+
+ return result;
+}
+
+\f
+
void
_initialize_symtab (void)
{
+ initialize_ordinary_address_classes ();
+
add_info ("variables", variables_info, _("\
All global and static variable names, or those matching REGEXP."));
if (dbx_commands)