/* 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
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008
Free Software Foundation, Inc.
This file is part of GDB.
#include "filenames.h" /* for FILENAME_CMP */
#include "objc-lang.h"
#include "ada-lang.h"
+#include "p-lang.h"
+#include "addrmap.h"
#include "hashtab.h"
const struct block *block,
const domain_enum domain,
enum language language,
- int *is_a_field_of_this,
- struct symtab **symtab);
+ int *is_a_field_of_this);
static
struct symbol *lookup_symbol_aux_local (const char *name,
const char *linkage_name,
const struct block *block,
- const domain_enum domain,
- struct symtab **symtab);
+ const domain_enum domain);
static
struct symbol *lookup_symbol_aux_symtabs (int block_index,
const char *name,
const char *linkage_name,
- const domain_enum domain,
- struct symtab **symtab);
+ const domain_enum domain);
static
struct symbol *lookup_symbol_aux_psymtabs (int block_index,
const char *name,
const char *linkage_name,
- const domain_enum domain,
- struct symtab **symtab);
-
-#if 0
-static
-struct symbol *lookup_symbol_aux_minsyms (const char *name,
- const char *linkage_name,
- const domain_enum domain,
- int *is_a_field_of_this,
- struct symtab **symtab);
-#endif
-
-static void fixup_section (struct general_symbol_info *, struct objfile *);
+ const domain_enum domain);
static int file_matches (char *, char **, int);
/* */
+/* Allow the user to configure the debugger behavior with respect
+ to multiple-choice menus when more than one symbol matches during
+ a symbol lookup. */
+
+const char multiple_symbols_ask[] = "ask";
+const char multiple_symbols_all[] = "all";
+const char multiple_symbols_cancel[] = "cancel";
+static const char *multiple_symbols_modes[] =
+{
+ multiple_symbols_ask,
+ multiple_symbols_all,
+ multiple_symbols_cancel,
+ NULL
+};
+static const char *multiple_symbols_mode = multiple_symbols_all;
+
+/* Read-only accessor to AUTO_SELECT_MODE. */
+
+const char *
+multiple_symbols_select_mode (void)
+{
+ return multiple_symbols_mode;
+}
+
/* The single non-language-specific builtin type */
struct type *builtin_type_error;
if (objfile->demangled_names_hash == NULL)
create_demangled_names_hash (objfile);
+ if (gsymbol->language == language_ada)
+ {
+ /* In Ada, we do the symbol lookups using the mangled name, so
+ we can save some space by not storing the demangled name.
+
+ As a side note, we have also observed some overlap between
+ the C++ mangling and Ada mangling, similarly to what has
+ 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';
+ gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+
+ return;
+ }
+
/* 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. */
gsymbol->language_specific.cplus_specific.demangled_name = NULL;
}
-/* Initialize the demangled name of GSYMBOL if possible. Any required space
- to store the name is obtained from the specified obstack. The function
- symbol_set_names, above, should be used instead where possible for more
- efficient memory usage. */
-
-void
-symbol_init_demangled_name (struct general_symbol_info *gsymbol,
- struct obstack *obstack)
-{
- char *mangled = gsymbol->name;
- char *demangled = NULL;
-
- demangled = symbol_find_demangled_name (gsymbol, mangled);
- if (gsymbol->language == language_cplus
- || gsymbol->language == language_java
- || gsymbol->language == language_objc)
- {
- if (demangled)
- {
- gsymbol->language_specific.cplus_specific.demangled_name
- = obsavestring (demangled, strlen (demangled), obstack);
- xfree (demangled);
- }
- else
- gsymbol->language_specific.cplus_specific.demangled_name = NULL;
- }
- else
- {
- /* Unknown language; just clean up quietly. */
- if (demangled)
- xfree (demangled);
- }
-}
-
/* Return the source code name of a symbol. In languages where
demangling is necessary, this is the demangled name. */
sal->line = 0;
sal->pc = 0;
sal->end = 0;
+ sal->explicit_pc = 0;
+ sal->explicit_line = 0;
}
\f
return 0;
}
+/* Find which partial symtab contains PC and SECTION starting at psymtab PST.
+ We may find a different psymtab than PST. See FIND_PC_SECT_PSYMTAB. */
+
+struct partial_symtab *
+find_pc_sect_psymtab_closer (CORE_ADDR pc, asection *section,
+ struct partial_symtab *pst,
+ struct minimal_symbol *msymbol)
+{
+ struct objfile *objfile = pst->objfile;
+ struct partial_symtab *tpst;
+ struct partial_symtab *best_pst = pst;
+ CORE_ADDR best_addr = pst->textlow;
+
+ /* An objfile that has its functions reordered might have
+ many partial symbol tables containing the PC, but
+ we want the partial symbol table that contains the
+ function containing the PC. */
+ if (!(objfile->flags & OBJF_REORDERED) &&
+ section == 0) /* can't validate section this way */
+ return pst;
+
+ 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)
+ {
+ struct partial_symbol *p;
+ CORE_ADDR this_addr;
+
+ /* NOTE: This assumes that every psymbol has a
+ corresponding msymbol, which is not necessarily
+ true; the debug info might be much richer than the
+ object's symbol table. */
+ p = find_pc_sect_psymbol (tpst, pc, section);
+ if (p != NULL
+ && SYMBOL_VALUE_ADDRESS (p)
+ == SYMBOL_VALUE_ADDRESS (msymbol))
+ return tpst;
+
+ /* Also accept the textlow value of a psymtab as a
+ "symbol", to provide some support for partial
+ symbol tables with line information but no debug
+ symbols (e.g. those produced by an assembler). */
+ if (p != NULL)
+ this_addr = SYMBOL_VALUE_ADDRESS (p);
+ else
+ this_addr = tpst->textlow;
+
+ /* Check whether it is closer than our current
+ BEST_ADDR. 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 (this_addr > best_addr)
+ {
+ best_addr = this_addr;
+ best_pst = tpst;
+ }
+ }
+ }
+ return best_pst;
+}
+
/* 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
struct partial_symtab *
find_pc_sect_psymtab (CORE_ADDR pc, asection *section)
{
- struct partial_symtab *pst;
struct objfile *objfile;
struct minimal_symbol *msymbol;
|| msymbol->type == mst_file_bss))
return NULL;
- ALL_PSYMTABS (objfile, pst)
- {
- if (pc >= pst->textlow && pc < pst->texthigh)
+ /* Try just the PSYMTABS_ADDRMAP mapping first as it has better granularity
+ than the later used TEXTLOW/TEXTHIGH one. */
+
+ ALL_OBJFILES (objfile)
+ if (objfile->psymtabs_addrmap != NULL)
{
- struct partial_symtab *tpst;
- struct partial_symtab *best_pst = pst;
- CORE_ADDR best_addr = pst->textlow;
-
- /* An objfile that has its functions reordered might have
- many partial symbol tables containing the PC, but
- we want the partial symbol table that contains the
- function containing the PC. */
- if (!(objfile->flags & OBJF_REORDERED) &&
- section == 0) /* can't validate section this way */
- return (pst);
-
- 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)
+ struct partial_symtab *pst;
+
+ pst = addrmap_find (objfile->psymtabs_addrmap, pc);
+ if (pst != NULL)
{
- if (pc >= tpst->textlow && pc < tpst->texthigh)
+ /* FIXME: addrmaps currently do not handle overlayed sections,
+ so fall back to the non-addrmap case if we're debugging
+ overlays and the addrmap returned the wrong section. */
+ if (overlay_debugging && msymbol && section)
{
struct partial_symbol *p;
- CORE_ADDR this_addr;
-
/* NOTE: This assumes that every psymbol has a
corresponding msymbol, which is not necessarily
true; the debug info might be much richer than the
object's symbol table. */
- p = find_pc_sect_psymbol (tpst, pc, section);
- if (p != NULL
- && SYMBOL_VALUE_ADDRESS (p)
- == SYMBOL_VALUE_ADDRESS (msymbol))
- return (tpst);
-
- /* Also accept the textlow value of a psymtab as a
- "symbol", to provide some support for partial
- symbol tables with line information but no debug
- symbols (e.g. those produced by an assembler). */
- if (p != NULL)
- this_addr = SYMBOL_VALUE_ADDRESS (p);
- else
- this_addr = tpst->textlow;
-
- /* Check whether it is closer than our current
- BEST_ADDR. 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 (this_addr > best_addr)
- {
- best_addr = this_addr;
- best_pst = tpst;
- }
+ p = find_pc_sect_psymbol (pst, pc, section);
+ if (!p
+ || SYMBOL_VALUE_ADDRESS (p)
+ != SYMBOL_VALUE_ADDRESS (msymbol))
+ continue;
}
+
+ /* We do not try to call FIND_PC_SECT_PSYMTAB_CLOSER as
+ PSYMTABS_ADDRMAP we used has already the best 1-byte
+ granularity and FIND_PC_SECT_PSYMTAB_CLOSER may mislead us into
+ a worse chosen section due to the TEXTLOW/TEXTHIGH ranges
+ overlap. */
+
+ return pst;
}
- return (best_pst);
}
- }
- return (NULL);
+
+ /* Existing PSYMTABS_ADDRMAP mapping is present even for PARTIAL_SYMTABs
+ which still have no corresponding full SYMTABs read. But it is not
+ present for non-DWARF2 debug infos not supporting PSYMTABS_ADDRMAP in GDB
+ so far. */
+
+ ALL_OBJFILES (objfile)
+ {
+ struct partial_symtab *pst;
+
+ /* Check even OBJFILE with non-zero PSYMTABS_ADDRMAP as only several of
+ its CUs may be missing in PSYMTABS_ADDRMAP as they may be varying
+ debug info type in single OBJFILE. */
+
+ ALL_OBJFILE_PSYMTABS (objfile, pst)
+ if (pc >= pst->textlow && pc < pst->texthigh)
+ {
+ struct partial_symtab *best_pst;
+
+ best_pst = find_pc_sect_psymtab_closer (pc, section, pst,
+ msymbol);
+ if (best_pst != NULL)
+ return best_pst;
+ }
+ }
+
+ return NULL;
}
/* Find which partial symtab contains PC. Return 0 if none.
out of the minimal symbols and stash that in the debug symbol. */
static void
-fixup_section (struct general_symbol_info *ginfo, struct objfile *objfile)
+fixup_section (struct general_symbol_info *ginfo,
+ CORE_ADDR addr, struct objfile *objfile)
{
struct minimal_symbol *msym;
- msym = lookup_minimal_symbol (ginfo->name, NULL, objfile);
+ /* First, check whether a minimal symbol with the same name exists
+ and points to the same address. The address check is required
+ e.g. on PowerPC64, where the minimal symbol for a function will
+ point to the function descriptor, while the debug symbol will
+ point to the actual function code. */
+ msym = lookup_minimal_symbol_by_pc_name (addr, ginfo->name, objfile);
if (msym)
{
ginfo->bfd_section = SYMBOL_BFD_SECTION (msym);
ginfo->section = SYMBOL_SECTION (msym);
}
- else if (objfile)
+ else
{
/* Static, function-local variables do appear in the linker
(minimal) symbols, but are frequently given names that won't
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;
struct symbol *
fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
{
+ CORE_ADDR addr;
+
if (!sym)
return NULL;
if (SYMBOL_BFD_SECTION (sym))
return sym;
- fixup_section (&sym->ginfo, objfile);
+ /* 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;
+
+ /* We should have an objfile by now. */
+ gdb_assert (objfile);
+
+ switch (SYMBOL_CLASS (sym))
+ {
+ case LOC_STATIC:
+ case LOC_LABEL:
+ addr = SYMBOL_VALUE_ADDRESS (sym);
+ break;
+ case LOC_BLOCK:
+ addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+ break;
+
+ default:
+ /* Nothing else will be listed in the minsyms -- no use looking
+ it up. */
+ return sym;
+ }
+
+ fixup_section (&sym->ginfo, addr, objfile);
return sym;
}
struct partial_symbol *
fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile)
{
+ CORE_ADDR addr;
+
if (!psym)
return NULL;
if (SYMBOL_BFD_SECTION (psym))
return psym;
- fixup_section (&psym->ginfo, objfile);
+ gdb_assert (objfile);
+
+ switch (SYMBOL_CLASS (psym))
+ {
+ case LOC_STATIC:
+ case LOC_LABEL:
+ case LOC_BLOCK:
+ addr = SYMBOL_VALUE_ADDRESS (psym);
+ break;
+ default:
+ /* Nothing else will be listed in the minsyms -- no use looking
+ it up. */
+ return psym;
+ }
+
+ fixup_section (&psym->ginfo, addr, objfile);
return psym;
}
/* Find the definition for a specified symbol name NAME
in domain DOMAIN, visible from lexical block BLOCK.
Returns the struct symbol pointer, or zero if no symbol is found.
- If SYMTAB is non-NULL, store the symbol table in which the
- symbol was found there, or NULL if not found.
C++: if IS_A_FIELD_OF_THIS is nonzero on entry, check to see if
NAME is a field of the current implied argument `this'. If so set
*IS_A_FIELD_OF_THIS to 1, otherwise set it to zero.
struct symbol *
lookup_symbol_in_language (const char *name, const struct block *block,
const domain_enum domain, enum language lang,
- int *is_a_field_of_this,
- struct symtab **symtab)
+ int *is_a_field_of_this)
{
char *demangled_name = NULL;
const char *modified_name = NULL;
}
returnval = lookup_symbol_aux (modified_name, mangled_name, block,
- domain, lang,
- is_a_field_of_this, symtab);
+ domain, lang, is_a_field_of_this);
if (needtofreename)
xfree (demangled_name);
- /* Override the returned symtab with the symbol's specific one. */
- if (returnval != NULL && symtab != NULL)
- *symtab = SYMBOL_SYMTAB (returnval);
-
return returnval;
}
struct symbol *
lookup_symbol (const char *name, const struct block *block,
- domain_enum domain, int *is_a_field_of_this,
- struct symtab **symtab)
+ domain_enum domain, int *is_a_field_of_this)
{
return lookup_symbol_in_language (name, block, domain,
current_language->la_language,
- is_a_field_of_this, symtab);
+ is_a_field_of_this);
}
/* Behave like lookup_symbol except that NAME is the natural name
static struct symbol *
lookup_symbol_aux (const char *name, const char *linkage_name,
const struct block *block, const domain_enum domain,
- enum language language,
- int *is_a_field_of_this, struct symtab **symtab)
+ enum language language, int *is_a_field_of_this)
{
struct symbol *sym;
const struct language_defn *langdef;
/* Search specified block and its superiors. Don't search
STATIC_BLOCK or GLOBAL_BLOCK. */
- sym = lookup_symbol_aux_local (name, linkage_name, block, domain,
- symtab);
+ sym = lookup_symbol_aux_local (name, linkage_name, block, domain);
if (sym != NULL)
return sym;
langdef = language_def (language);
- if (langdef->la_value_of_this != NULL
- && is_a_field_of_this != NULL)
+ if (langdef->la_name_of_this != NULL && is_a_field_of_this != NULL
+ && block != NULL)
{
- struct value *v = langdef->la_value_of_this (0);
-
- if (v && check_field (v, name))
+ struct symbol *sym = NULL;
+ /* 'this' is only defined in the function's block, so find the
+ enclosing function block. */
+ for (; block && !BLOCK_FUNCTION (block);
+ block = BLOCK_SUPERBLOCK (block));
+
+ if (block && !dict_empty (BLOCK_DICT (block)))
+ sym = lookup_block_symbol (block, langdef->la_name_of_this,
+ NULL, VAR_DOMAIN);
+ if (sym)
{
- *is_a_field_of_this = 1;
- if (symtab != NULL)
- *symtab = NULL;
- return NULL;
+ struct type *t = sym->type;
+
+ /* I'm not really sure that type of this can ever
+ be typedefed; just be safe. */
+ CHECK_TYPEDEF (t);
+ if (TYPE_CODE (t) == TYPE_CODE_PTR
+ || TYPE_CODE (t) == TYPE_CODE_REF)
+ t = TYPE_TARGET_TYPE (t);
+
+ if (TYPE_CODE (t) != TYPE_CODE_STRUCT
+ && TYPE_CODE (t) != TYPE_CODE_UNION)
+ error (_("Internal error: `%s' is not an aggregate"),
+ langdef->la_name_of_this);
+
+ if (check_field (t, name))
+ {
+ *is_a_field_of_this = 1;
+ return NULL;
+ }
}
}
/* Now do whatever is appropriate for LANGUAGE to look
up static and global variables. */
- sym = langdef->la_lookup_symbol_nonlocal (name, linkage_name,
- block, domain, symtab);
+ sym = langdef->la_lookup_symbol_nonlocal (name, linkage_name, block, domain);
if (sym != NULL)
return sym;
desired name as a file-level static, then do psymtab-to-symtab
conversion on the fly and return the found symbol. */
- sym = lookup_symbol_aux_symtabs (STATIC_BLOCK, name, linkage_name,
- domain, symtab);
+ sym = lookup_symbol_aux_symtabs (STATIC_BLOCK, name, linkage_name, domain);
if (sym != NULL)
return sym;
- sym = lookup_symbol_aux_psymtabs (STATIC_BLOCK, name, linkage_name,
- domain, symtab);
+ sym = lookup_symbol_aux_psymtabs (STATIC_BLOCK, name, linkage_name, domain);
if (sym != NULL)
return sym;
- if (symtab != NULL)
- *symtab = NULL;
return NULL;
}
static struct symbol *
lookup_symbol_aux_local (const char *name, const char *linkage_name,
const struct block *block,
- const domain_enum domain,
- struct symtab **symtab)
+ const domain_enum domain)
{
struct symbol *sym;
const struct block *static_block = block_static_block (block);
while (block != static_block)
{
- sym = lookup_symbol_aux_block (name, linkage_name, block, domain,
- symtab);
+ sym = lookup_symbol_aux_block (name, linkage_name, block, domain);
if (sym != NULL)
return sym;
block = BLOCK_SUPERBLOCK (block);
return NULL;
}
-/* Look up a symbol in a block; if found, locate its symtab, fixup the
- symbol, and set block_found appropriately. */
+/* Look up a symbol in a block; if found, fixup the symbol, and set
+ block_found appropriately. */
struct symbol *
lookup_symbol_aux_block (const char *name, const char *linkage_name,
const struct block *block,
- const domain_enum domain,
- struct symtab **symtab)
+ const domain_enum domain)
{
struct symbol *sym;
- struct objfile *objfile = NULL;
- struct blockvector *bv;
- struct block *b;
- struct symtab *s = NULL;
sym = lookup_block_symbol (block, name, linkage_name, domain);
if (sym)
{
block_found = block;
- if (symtab != NULL)
- {
- /* Search the list of symtabs for one which contains the
- address of the start of this block. */
- ALL_PRIMARY_SYMTABS (objfile, s)
- {
- bv = BLOCKVECTOR (s);
- b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- if (BLOCK_START (b) <= BLOCK_START (block)
- && BLOCK_END (b) > BLOCK_START (block))
- goto found;
- }
- found:
- *symtab = s;
- }
-
- return fixup_symbol_section (sym, objfile);
+ return fixup_symbol_section (sym, NULL);
}
return NULL;
lookup_global_symbol_from_objfile (const struct objfile *objfile,
const char *name,
const char *linkage_name,
- const domain_enum domain,
- struct symtab **symtab)
+ const domain_enum domain)
{
struct symbol *sym;
struct blockvector *bv;
if (sym)
{
block_found = block;
- if (symtab != NULL)
- *symtab = s;
return fixup_symbol_section (sym, (struct objfile *)objfile);
}
}
bv = BLOCKVECTOR (s);
block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
sym = lookup_block_symbol (block, name, linkage_name, domain);
- if (symtab != NULL)
- *symtab = s;
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);
+
return NULL;
}
static struct symbol *
lookup_symbol_aux_symtabs (int block_index,
const char *name, const char *linkage_name,
- const domain_enum domain,
- struct symtab **symtab)
+ const domain_enum domain)
{
struct symbol *sym;
struct objfile *objfile;
if (sym)
{
block_found = block;
- if (symtab != NULL)
- *symtab = s;
return fixup_symbol_section (sym, objfile);
}
}
static struct symbol *
lookup_symbol_aux_psymtabs (int block_index, const char *name,
const char *linkage_name,
- const domain_enum domain,
- struct symtab **symtab)
+ const domain_enum domain)
{
struct symbol *sym;
struct objfile *objfile;
block_index == GLOBAL_BLOCK ? "global" : "static",
name, ps->filename, name, name);
}
- if (symtab != NULL)
- *symtab = s;
return fixup_symbol_section (sym, objfile);
}
}
return NULL;
}
-#if 0
-/* Check for the possibility of the symbol being a function or a
- mangled variable that is stored in one of the minimal symbol
- tables. Eventually, all global symbols might be resolved in this
- way. */
-
-/* NOTE: carlton/2002-12-05: At one point, this function was part of
- lookup_symbol_aux, and what are now 'return' statements within
- lookup_symbol_aux_minsyms returned from lookup_symbol_aux, even if
- sym was NULL. As far as I can tell, this was basically accidental;
- it didn't happen every time that msymbol was non-NULL, but only if
- some additional conditions held as well, and it caused problems
- with HP-generated symbol tables. */
-
-/* NOTE: carlton/2003-05-14: This function was once used as part of
- lookup_symbol. It is currently unnecessary for correctness
- reasons, however, and using it doesn't seem to be any faster than
- using lookup_symbol_aux_psymtabs, so I'm commenting it out. */
-
-static struct symbol *
-lookup_symbol_aux_minsyms (const char *name,
- const char *linkage_name,
- const domain_enum domain,
- int *is_a_field_of_this,
- struct symtab **symtab)
-{
- struct symbol *sym;
- struct blockvector *bv;
- const struct block *block;
- struct minimal_symbol *msymbol;
- struct symtab *s;
-
- if (domain == VAR_DOMAIN)
- {
- msymbol = lookup_minimal_symbol (name, NULL, NULL);
-
- if (msymbol != NULL)
- {
- /* OK, we found a minimal symbol in spite of not finding any
- symbol. There are various possible explanations for
- this. One possibility is the symbol exists in code not
- compiled -g. Another possibility is that the 'psymtab'
- isn't doing its job. A third possibility, related to #2,
- is that we were confused by name-mangling. For instance,
- maybe the psymtab isn't doing its job because it only
- know about demangled names, but we were given a mangled
- name... */
-
- /* We first use the address in the msymbol to try to locate
- the appropriate symtab. Note that find_pc_sect_symtab()
- has a side-effect of doing psymtab-to-symtab expansion,
- for the found symtab. */
- s = find_pc_sect_symtab (SYMBOL_VALUE_ADDRESS (msymbol),
- SYMBOL_BFD_SECTION (msymbol));
- if (s != NULL)
- {
- /* This is a function which has a symtab for its address. */
- bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-
- /* This call used to pass `SYMBOL_LINKAGE_NAME (msymbol)' as the
- `name' argument to lookup_block_symbol. But the name
- of a minimal symbol is always mangled, so that seems
- to be clearly the wrong thing to pass as the
- unmangled name. */
- sym =
- lookup_block_symbol (block, name, linkage_name, domain);
- /* We kept static functions in minimal symbol table as well as
- in static scope. We want to find them in the symbol table. */
- if (!sym)
- {
- block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- sym = lookup_block_symbol (block, name,
- linkage_name, domain);
- }
-
- /* NOTE: carlton/2002-12-04: The following comment was
- taken from a time when two versions of this function
- were part of the body of lookup_symbol_aux: this
- comment was taken from the version of the function
- that was #ifdef HPUXHPPA, and the comment was right
- before the 'return NULL' part of lookup_symbol_aux.
- (Hence the "Fall through and return 0" comment.)
- Elena did some digging into the situation for
- Fortran, and she reports:
-
- "I asked around (thanks to Jeff Knaggs), and I think
- the story for Fortran goes like this:
-
- "Apparently, in older Fortrans, '_' was not part of
- the user namespace. g77 attached a final '_' to
- procedure names as the exported symbols for linkage
- (foo_) , but the symbols went in the debug info just
- like 'foo'. The rationale behind this is not
- completely clear, and maybe it was done to other
- symbols as well, not just procedures." */
-
- /* If we get here with sym == 0, the symbol was
- found in the minimal symbol table
- but not in the symtab.
- Fall through and return 0 to use the msymbol
- definition of "foo_".
- (Note that outer code generally follows up a call
- to this routine with a call to lookup_minimal_symbol(),
- so a 0 return means we'll just flow into that other routine).
-
- This happens for Fortran "foo_" symbols,
- which are "foo" in the symtab.
-
- This can also happen if "asm" is used to make a
- regular symbol but not a debugging symbol, e.g.
- asm(".globl _main");
- asm("_main:");
- */
-
- if (symtab != NULL && sym != NULL)
- *symtab = s;
- return fixup_symbol_section (sym, s->objfile);
- }
- }
- }
-
- return NULL;
-}
-#endif /* 0 */
-
/* A default version of lookup_symbol_nonlocal for use by languages
that can't think of anything better to do. This implements the C
lookup rules. */
basic_lookup_symbol_nonlocal (const char *name,
const char *linkage_name,
const struct block *block,
- const domain_enum domain,
- struct symtab **symtab)
+ const domain_enum domain)
{
struct symbol *sym;
than that one, so I don't think we should worry about that for
now. */
- sym = lookup_symbol_static (name, linkage_name, block, domain, symtab);
+ sym = lookup_symbol_static (name, linkage_name, block, domain);
if (sym != NULL)
return sym;
- return lookup_symbol_global (name, linkage_name, block, domain, symtab);
+ return lookup_symbol_global (name, linkage_name, block, domain);
}
/* Lookup a symbol in the static block associated to BLOCK, if there
lookup_symbol_static (const char *name,
const char *linkage_name,
const struct block *block,
- const domain_enum domain,
- struct symtab **symtab)
+ const domain_enum domain)
{
const struct block *static_block = block_static_block (block);
if (static_block != NULL)
- return lookup_symbol_aux_block (name, linkage_name, static_block,
- domain, symtab);
+ return lookup_symbol_aux_block (name, linkage_name, static_block, domain);
else
return NULL;
}
lookup_symbol_global (const char *name,
const char *linkage_name,
const struct block *block,
- const domain_enum domain,
- struct symtab **symtab)
+ const domain_enum domain)
{
struct symbol *sym = NULL;
struct objfile *objfile = NULL;
/* Call library-specific lookup procedure. */
objfile = lookup_objfile_from_block (block);
if (objfile != NULL)
- sym = solib_global_lookup (objfile, name, linkage_name, domain, symtab);
+ sym = solib_global_lookup (objfile, name, linkage_name, domain);
if (sym != NULL)
return sym;
- sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name,
- domain, symtab);
+ sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name, domain);
if (sym != NULL)
return sym;
- return lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, linkage_name,
- domain, symtab);
+ return lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, linkage_name, domain);
+}
+
+int
+symbol_matches_domain (enum language symbol_language,
+ domain_enum symbol_domain,
+ domain_enum domain)
+{
+ /* For C++ "struct foo { ... }" also defines a typedef for "foo".
+ A Java class declaration also defines a typedef for the class.
+ Similarly, any Ada type declaration implicitly defines a typedef. */
+ if (symbol_language == language_cplus
+ || symbol_language == language_java
+ || symbol_language == language_ada)
+ {
+ if ((domain == VAR_DOMAIN || domain == STRUCT_DOMAIN)
+ && symbol_domain == STRUCT_DOMAIN)
+ return 1;
+ }
+ /* For all other languages, strict match is required. */
+ return (symbol_domain == domain);
}
/* Look, in partial_symtab PST, for symbol whose natural name is NAME.
? strcmp (SYMBOL_LINKAGE_NAME (*top), linkage_name) == 0
: SYMBOL_MATCHES_SEARCH_NAME (*top,name)))
{
- if (SYMBOL_DOMAIN (*top) == domain)
- {
- return (*top);
- }
+ if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
+ SYMBOL_DOMAIN (*top), domain))
+ return (*top);
top++;
}
}
{
for (psym = start; psym < start + length; psym++)
{
- if (domain == SYMBOL_DOMAIN (*psym))
+ if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym),
+ SYMBOL_DOMAIN (*psym), domain))
{
if (linkage_name != NULL
? strcmp (SYMBOL_LINKAGE_NAME (*psym), linkage_name) == 0
sym != NULL;
sym = dict_iter_name_next (name, &iter))
{
- if (SYMBOL_DOMAIN (sym) == domain
+ if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
+ SYMBOL_DOMAIN (sym), domain)
&& (linkage_name != NULL
? strcmp (SYMBOL_LINKAGE_NAME (sym), linkage_name) == 0 : 1))
return sym;
sym != NULL;
sym = dict_iter_name_next (name, &iter))
{
- if (SYMBOL_DOMAIN (sym) == domain
+ if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
+ SYMBOL_DOMAIN (sym), domain)
&& (linkage_name != NULL
? strcmp (SYMBOL_LINKAGE_NAME (sym), linkage_name) == 0 : 1))
{
sym_found = sym;
- if (SYMBOL_CLASS (sym) != LOC_ARG &&
- SYMBOL_CLASS (sym) != LOC_LOCAL_ARG &&
- SYMBOL_CLASS (sym) != LOC_REF_ARG &&
- SYMBOL_CLASS (sym) != LOC_REGPARM &&
- SYMBOL_CLASS (sym) != LOC_REGPARM_ADDR &&
- SYMBOL_CLASS (sym) != LOC_BASEREG_ARG &&
- SYMBOL_CLASS (sym) != LOC_COMPUTED_ARG)
+ if (!SYMBOL_IS_ARGUMENT (sym))
{
break;
}
* So I commented out the warning. RT */
/* warning ("In stub for %s; unable to find real function/line info", SYMBOL_LINKAGE_NAME (msymbol)) */ ;
/* fall through */
- else if (SYMBOL_VALUE (mfunsym) == SYMBOL_VALUE (msymbol))
+ else if (SYMBOL_VALUE_ADDRESS (mfunsym) == SYMBOL_VALUE_ADDRESS (msymbol))
/* Avoid infinite recursion */
/* See above comment about why warning is commented out */
/* warning ("In stub for %s; unable to find real function/line info", SYMBOL_LINKAGE_NAME (msymbol)) */ ;
/* fall through */
else
- return find_pc_line (SYMBOL_VALUE (mfunsym), 0);
+ return find_pc_line (SYMBOL_VALUE_ADDRESS (mfunsym), 0);
}
struct objfile *objfile;
struct symtab *s;
+ struct partial_symtab *p;
if (best_index >= 0)
best = best_linetable->item[best_index].line;
else
best = 0;
+ ALL_PSYMTABS (objfile, p)
+ {
+ if (strcmp (symtab->filename, p->filename) != 0)
+ continue;
+ PSYMTAB_TO_SYMTAB (p);
+ }
+
ALL_SYMTABS (objfile, s)
{
struct linetable *l;
int best_index = -1;
int best = 0;
+ *exact_match = 0;
+
if (lineno <= 0)
return -1;
if (l == 0)
}
/* If we got here, we didn't get an exact match. */
-
- *exact_match = 0;
return best_index;
}
return sal.symtab != 0;
}
+/* Given a function start address PC and SECTION, find the first
+ address after the function prologue. */
+CORE_ADDR
+find_function_start_pc (struct gdbarch *gdbarch,
+ CORE_ADDR pc, asection *section)
+{
+ /* If the function is in an unmapped overlay, use its unmapped LMA address,
+ so that gdbarch_skip_prologue has something unique to work on. */
+ if (section_is_overlay (section) && !section_is_mapped (section))
+ pc = overlay_unmapped_address (pc, section);
+
+ pc += gdbarch_deprecated_function_start_offset (gdbarch);
+ pc = gdbarch_skip_prologue (gdbarch, pc);
+
+ /* For overlays, map pc back into its mapped VMA range. */
+ pc = overlay_mapped_address (pc, section);
+
+ return pc;
+}
+
/* Given a function symbol SYM, find the symtab and line for the start
of the function.
If the argument FUNFIRSTLINE is nonzero, we want the first line
struct symtab_and_line
find_function_start_sal (struct symbol *sym, int funfirstline)
{
+ struct block *block = SYMBOL_BLOCK_VALUE (sym);
+ struct objfile *objfile = lookup_objfile_from_block (block);
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
+
CORE_ADDR pc;
struct symtab_and_line sal;
- pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
- fixup_symbol_section (sym, NULL);
+ pc = BLOCK_START (block);
+ fixup_symbol_section (sym, objfile);
if (funfirstline)
- { /* skip "first line" of function (which is actually its prologue) */
- asection *section = SYMBOL_BFD_SECTION (sym);
- /* If function is in an unmapped overlay, use its unmapped LMA
- address, so that gdbarch_skip_prologue has something unique to work
- on */
- if (section_is_overlay (section) &&
- !section_is_mapped (section))
- pc = overlay_unmapped_address (pc, section);
-
- pc += gdbarch_deprecated_function_start_offset (current_gdbarch);
- pc = gdbarch_skip_prologue (current_gdbarch, pc);
-
- /* For overlays, map pc back into its mapped VMA range */
- pc = overlay_mapped_address (pc, section);
+ {
+ /* Skip "first line" of function (which is actually its prologue). */
+ pc = find_function_start_pc (gdbarch, pc, SYMBOL_BFD_SECTION (sym));
}
sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0);
/* Check if gdbarch_skip_prologue left us in mid-line, and the next
line is still part of the same function. */
if (sal.pc != pc
- && BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= sal.end
- && sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym)))
+ && BLOCK_START (block) <= sal.end
+ && sal.end < BLOCK_END (block))
{
/* First pc of next line */
pc = sal.end;
/* Recalculate the line number (might not be N+1). */
sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0);
}
+
+ /* On targets with executable formats that don't have a concept of
+ constructors (ELF with .init has, PE doesn't), gcc emits a call
+ to `__main' in `main' between the prologue and before user
+ code. */
+ if (funfirstline
+ && gdbarch_skip_main_prologue_p (current_gdbarch)
+ && SYMBOL_LINKAGE_NAME (sym)
+ && strcmp (SYMBOL_LINKAGE_NAME (sym), "main") == 0)
+ {
+ pc = gdbarch_skip_main_prologue (current_gdbarch, pc);
+ /* Recalculate the line number (might not be N+1). */
+ sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0);
+ }
+
sal.pc = pc;
return sal;
if (kind == FUNCTIONS_DOMAIN
|| lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol),
(struct block *) NULL,
- VAR_DOMAIN,
- 0, (struct symtab **) NULL)
+ VAR_DOMAIN, 0)
== NULL)
found_misc = 1;
}
{
/* Variables/Absolutes: Look up by name */
if (lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol),
- (struct block *) NULL, VAR_DOMAIN,
- 0, (struct symtab **) NULL) == NULL)
+ (struct block *) NULL, VAR_DOMAIN, 0)
+ == NULL)
{
/* match */
psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search));
}
else
{
- break_command (SYMBOL_LINKAGE_NAME (p->msymbol), from_tty);
+ char *string = alloca (strlen (SYMBOL_LINKAGE_NAME (p->msymbol))
+ + 3);
+ strcpy (string, "'");
+ strcat (string, SYMBOL_LINKAGE_NAME (p->msymbol));
+ strcat (string, "'");
+
+ break_command (string, from_tty);
printf_filtered ("<function, no debug info> %s;\n",
SYMBOL_PRINT_NAME (p->msymbol));
}
return p;
}
-
-/* Return a NULL terminated array of all symbols (regardless of class)
- which begin by matching TEXT. If the answer is no symbols, then
- the return value is an array which contains only a NULL pointer.
-
- Problem: All of the symbols have to be copied because readline frees them.
- I'm not going to worry about this; hopefully there won't be that many. */
-
char **
-make_symbol_completion_list (char *text, char *word)
+default_make_symbol_completion_list (char *text, char *word)
{
+ /* Problem: All of the symbols have to be copied because readline
+ frees them. I'm not going to worry about this; hopefully there
+ won't be that many. */
+
struct symbol *sym;
struct symtab *s;
struct partial_symtab *ps;
/* Length of sym_text. */
int sym_text_len;
- /* Now look for the symbol we are supposed to complete on.
- FIXME: This should be language-specific. */
+ /* Now look for the symbol we are supposed to complete on. */
{
char *p;
char quote_found;
return (return_val);
}
+/* Return a NULL terminated array of all symbols (regardless of class)
+ which begin by matching TEXT. If the answer is no symbols, then
+ the return value is an array which contains only a NULL pointer. */
+
+char **
+make_symbol_completion_list (char *text, char *word)
+{
+ return current_language->la_make_symbol_completion_list (text, word);
+}
+
/* Like make_symbol_completion_list, but returns a list of symbols
defined in a source file FILE. */
static void
find_main_name (void)
{
- char *new_main_name;
+ const char *new_main_name;
/* Try to see if the main procedure is in Ada. */
/* FIXME: brobecker/2005-03-07: Another way of doing this would
return;
}
+ new_main_name = pascal_main_name ();
+ if (new_main_name != NULL)
+ {
+ set_main_name (new_main_name);
+ return;
+ }
+
/* The languages above didn't identify the name of the main procedure.
Fallback to "main". */
set_main_name ("main");
set_main_name (NULL);
}
+/* Helper to expand_line_sal below. Appends new sal to SAL,
+ initializing it from SYMTAB, LINENO and PC. */
+static void
+append_expanded_sal (struct symtabs_and_lines *sal,
+ struct symtab *symtab,
+ int lineno, CORE_ADDR pc)
+{
+ CORE_ADDR func_addr, func_end;
+
+ sal->sals = xrealloc (sal->sals,
+ sizeof (sal->sals[0])
+ * (sal->nelts + 1));
+ init_sal (sal->sals + sal->nelts);
+ sal->sals[sal->nelts].symtab = symtab;
+ sal->sals[sal->nelts].section = NULL;
+ sal->sals[sal->nelts].end = 0;
+ sal->sals[sal->nelts].line = lineno;
+ sal->sals[sal->nelts].pc = pc;
+ ++sal->nelts;
+}
+
+/* Compute a set of all sals in
+ the entire program that correspond to same file
+ and line as SAL and return those. If there
+ are several sals that belong to the same block,
+ only one sal for the block is included in results. */
+
+struct symtabs_and_lines
+expand_line_sal (struct symtab_and_line sal)
+{
+ struct symtabs_and_lines ret, this_line;
+ int i, j;
+ struct objfile *objfile;
+ struct partial_symtab *psymtab;
+ struct symtab *symtab;
+ int lineno;
+ int deleted = 0;
+ struct block **blocks = NULL;
+ int *filter;
+
+ ret.nelts = 0;
+ ret.sals = NULL;
+
+ if (sal.symtab == NULL || sal.line == 0 || sal.pc != 0)
+ {
+ ret.sals = xmalloc (sizeof (struct symtab_and_line));
+ ret.sals[0] = sal;
+ ret.nelts = 1;
+ return ret;
+ }
+ else
+ {
+ struct linetable_entry *best_item = 0;
+ struct symtab *best_symtab = 0;
+ int exact = 0;
+
+ lineno = sal.line;
+
+ /* We meed to find all symtabs for a file which name
+ is described by sal. We cannot just directly
+ iterate over symtabs, since a symtab might not be
+ yet created. We also cannot iterate over psymtabs,
+ calling PSYMTAB_TO_SYMTAB and working on that symtab,
+ since PSYMTAB_TO_SYMTAB will return NULL for psymtab
+ corresponding to an included file. Therefore, we do
+ first pass over psymtabs, reading in those with
+ the right name. Then, we iterate over symtabs, knowing
+ that all symtabs we're interested in are loaded. */
+
+ ALL_PSYMTABS (objfile, psymtab)
+ {
+ if (strcmp (sal.symtab->filename,
+ psymtab->filename) == 0)
+ PSYMTAB_TO_SYMTAB (psymtab);
+ }
+
+
+ /* For each symtab, we add all pcs to ret.sals. I'm actually
+ not sure what to do if we have exact match in one symtab,
+ and non-exact match on another symtab.
+ */
+ ALL_SYMTABS (objfile, symtab)
+ {
+ if (strcmp (sal.symtab->filename,
+ symtab->filename) == 0)
+ {
+ struct linetable *l;
+ int len;
+ l = LINETABLE (symtab);
+ if (!l)
+ continue;
+ len = l->nitems;
+
+ for (j = 0; j < len; j++)
+ {
+ struct linetable_entry *item = &(l->item[j]);
+
+ if (item->line == lineno)
+ {
+ exact = 1;
+ append_expanded_sal (&ret, symtab, lineno, item->pc);
+ }
+ else if (!exact && item->line > lineno
+ && (best_item == NULL || item->line < best_item->line))
+
+ {
+ best_item = item;
+ best_symtab = symtab;
+ }
+ }
+ }
+ }
+ if (!exact && best_item)
+ append_expanded_sal (&ret, best_symtab, lineno, best_item->pc);
+ }
+
+ /* For optimized code, compiler can scatter one source line accross
+ disjoint ranges of PC values, even when no duplicate functions
+ or inline functions are involved. For example, 'for (;;)' inside
+ non-template non-inline non-ctor-or-dtor function can result
+ in two PC ranges. In this case, we don't want to set breakpoint
+ on first PC of each range. To filter such cases, we use containing
+ blocks -- for each PC found above we see if there are other PCs
+ that are in the same block. If yes, the other PCs are filtered out. */
+
+ filter = xmalloc (ret.nelts * sizeof (int));
+ blocks = xmalloc (ret.nelts * sizeof (struct block *));
+ for (i = 0; i < ret.nelts; ++i)
+ {
+ filter[i] = 1;
+ blocks[i] = block_for_pc (ret.sals[i].pc);
+ }
+
+ for (i = 0; i < ret.nelts; ++i)
+ if (blocks[i] != NULL)
+ for (j = i+1; j < ret.nelts; ++j)
+ if (blocks[j] == blocks[i])
+ {
+ filter[j] = 0;
+ ++deleted;
+ break;
+ }
+
+ {
+ struct symtab_and_line *final =
+ xmalloc (sizeof (struct symtab_and_line) * (ret.nelts-deleted));
+
+ for (i = 0, j = 0; i < ret.nelts; ++i)
+ if (filter[i])
+ final[j++] = ret.sals[i];
+
+ ret.nelts -= deleted;
+ xfree (ret.sals);
+ ret.sals = final;
+ }
+
+ return ret;
+}
+
+
void
_initialize_symtab (void)
{
All global and static variable names, or those matching REGEXP."));
}
+ add_setshow_enum_cmd ("multiple-symbols", no_class,
+ multiple_symbols_modes, &multiple_symbols_mode,
+ _("\
+Set the debugger behavior when more than one symbol are possible matches\n\
+in an expression."), _("\
+Show how the debugger handles ambiguities in expressions."), _("\
+Valid values are \"ask\", \"all\", \"cancel\", and the default is \"all\"."),
+ NULL, NULL, &setlist, &showlist);
+
/* Initialize the one built-in type that isn't language dependent... */
builtin_type_error = init_type (TYPE_CODE_ERROR, 0, 0,
"<unknown type>", (struct objfile *) NULL);