Index: gdb/symtab.c |
diff --git a/gdb/symtab.c b/gdb/symtab.c |
index 183e115712437e6ac6f68ce4a9b8ec5c85c95074..aa1e14b09240dd7defe4a09e1c5a1fc79c1afac4 100644 |
--- a/gdb/symtab.c |
+++ b/gdb/symtab.c |
@@ -1,6 +1,6 @@ |
/* Symbol table lookup for the GNU debugger, GDB. |
- Copyright (C) 1986-2004, 2007-2012 Free Software Foundation, Inc. |
+ Copyright (C) 1986-2013 Free Software Foundation, Inc. |
This file is part of GDB. |
@@ -27,7 +27,6 @@ |
#include "symfile.h" |
#include "objfiles.h" |
#include "gdbcmd.h" |
-#include "call-cmds.h" |
#include "gdb_regex.h" |
#include "expression.h" |
#include "language.h" |
@@ -41,6 +40,7 @@ |
#include "go-lang.h" |
#include "p-lang.h" |
#include "addrmap.h" |
+#include "cli/cli-utils.h" |
#include "hashtab.h" |
@@ -50,8 +50,8 @@ |
#include <sys/types.h> |
#include <fcntl.h> |
-#include "gdb_string.h" |
-#include "gdb_stat.h" |
+#include <string.h> |
+#include <sys/stat.h> |
#include <ctype.h> |
#include "cp-abi.h" |
#include "cp-support.h" |
@@ -60,8 +60,10 @@ |
#include "solist.h" |
#include "macrotab.h" |
#include "macroscope.h" |
+#include "ada-lang.h" |
#include "psymtab.h" |
+#include "parser-defs.h" |
/* Prototypes for local functions */ |
@@ -81,7 +83,7 @@ static struct symbol *lookup_symbol_aux (const char *name, |
const struct block *block, |
const domain_enum domain, |
enum language language, |
- int *is_a_field_of_this); |
+ struct field_of_this_result *is_a_field_of_this); |
static |
struct symbol *lookup_symbol_aux_local (const char *name, |
@@ -100,14 +102,12 @@ struct symbol *lookup_symbol_aux_quick (struct objfile *objfile, |
const char *name, |
const domain_enum domain); |
-static void print_msymbol_info (struct minimal_symbol *); |
- |
void _initialize_symtab (void); |
/* */ |
/* When non-zero, print debugging messages related to symtab creation. */ |
-int symtab_create_debug = 0; |
+unsigned int symtab_create_debug = 0; |
/* Non-zero if a file may be known by two different basenames. |
This is the uncommon case, and significantly slows down gdb. |
@@ -144,17 +144,63 @@ multiple_symbols_select_mode (void) |
const struct block *block_found; |
+/* Return the name of a domain_enum. */ |
+ |
+const char * |
+domain_name (domain_enum e) |
+{ |
+ switch (e) |
+ { |
+ case UNDEF_DOMAIN: return "UNDEF_DOMAIN"; |
+ case VAR_DOMAIN: return "VAR_DOMAIN"; |
+ case STRUCT_DOMAIN: return "STRUCT_DOMAIN"; |
+ case LABEL_DOMAIN: return "LABEL_DOMAIN"; |
+ case COMMON_BLOCK_DOMAIN: return "COMMON_BLOCK_DOMAIN"; |
+ default: gdb_assert_not_reached ("bad domain_enum"); |
+ } |
+} |
+ |
+/* Return the name of a search_domain . */ |
+ |
+const char * |
+search_domain_name (enum search_domain e) |
+{ |
+ switch (e) |
+ { |
+ case VARIABLES_DOMAIN: return "VARIABLES_DOMAIN"; |
+ case FUNCTIONS_DOMAIN: return "FUNCTIONS_DOMAIN"; |
+ case TYPES_DOMAIN: return "TYPES_DOMAIN"; |
+ case ALL_DOMAIN: return "ALL_DOMAIN"; |
+ default: gdb_assert_not_reached ("bad search_domain"); |
+ } |
+} |
+ |
+/* Set the primary field in SYMTAB. */ |
+ |
+void |
+set_symtab_primary (struct symtab *symtab, int primary) |
+{ |
+ symtab->primary = primary; |
+ |
+ if (symtab_create_debug && primary) |
+ { |
+ fprintf_unfiltered (gdb_stdlog, |
+ "Created primary symtab %s for %s.\n", |
+ host_address_to_string (symtab), |
+ symtab_to_filename_for_display (symtab)); |
+ } |
+} |
+ |
/* See whether FILENAME matches SEARCH_NAME using the rule that we |
advertise to the user. (The manual's description of linespecs |
- describes what we advertise). SEARCH_LEN is the length of |
- SEARCH_NAME. We assume that SEARCH_NAME is a relative path. |
- Returns true if they match, false otherwise. */ |
+ describes what we advertise). Returns true if they match, false |
+ otherwise. */ |
int |
-compare_filenames_for_search (const char *filename, const char *search_name, |
- int search_len) |
+compare_filenames_for_search (const char *filename, const char *search_name) |
{ |
int len = strlen (filename); |
+ size_t search_len = strlen (search_name); |
if (len < search_len) |
return 0; |
@@ -165,9 +211,20 @@ compare_filenames_for_search (const char *filename, const char *search_name, |
/* Either the names must completely match, or the character |
preceding the trailing SEARCH_NAME segment of FILENAME must be a |
- directory separator. */ |
+ directory separator. |
+ |
+ The check !IS_ABSOLUTE_PATH ensures SEARCH_NAME "/dir/file.c" |
+ cannot match FILENAME "/path//dir/file.c" - as user has requested |
+ absolute path. The sama applies for "c:\file.c" possibly |
+ incorrectly hypothetically matching "d:\dir\c:\file.c". |
+ |
+ The HAS_DRIVE_SPEC purpose is to make FILENAME "c:file.c" |
+ compatible with SEARCH_NAME "file.c". In such case a compiler had |
+ to put the "c:file.c" name into debug info. Such compatibility |
+ works only on GDB built for DOS host. */ |
return (len == search_len |
- || IS_DIR_SEPARATOR (filename[len - search_len - 1]) |
+ || (!IS_ABSOLUTE_PATH (search_name) |
+ && IS_DIR_SEPARATOR (filename[len - search_len - 1])) |
|| (HAS_DRIVE_SPEC (filename) |
&& STRIP_DRIVE_SPEC (filename) == &filename[len - search_len])); |
} |
@@ -175,7 +232,10 @@ compare_filenames_for_search (const char *filename, const char *search_name, |
/* Check for a symtab of a specific name by searching some symtabs. |
This is a helper function for callbacks of iterate_over_symtabs. |
- The return value, NAME, FULL_PATH, REAL_PATH, CALLBACK, and DATA |
+ 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. |
@@ -185,7 +245,6 @@ compare_filenames_for_search (const char *filename, const char *search_name, |
int |
iterate_over_some_symtabs (const char *name, |
- const char *full_path, |
const char *real_path, |
int (*callback) (struct symtab *symtab, |
void *data), |
@@ -195,73 +254,44 @@ iterate_over_some_symtabs (const char *name, |
{ |
struct symtab *s = NULL; |
const char* base_name = lbasename (name); |
- int name_len = strlen (name); |
- int is_abs = IS_ABSOLUTE_PATH (name); |
for (s = first; s != NULL && s != after_last; s = s->next) |
{ |
- /* Exact match is always ok. */ |
- if (FILENAME_CMP (name, s->filename) == 0) |
+ if (compare_filenames_for_search (s->filename, name)) |
{ |
if (callback (s, data)) |
return 1; |
+ continue; |
} |
- if (!is_abs && compare_filenames_for_search (s->filename, name, name_len)) |
+ /* 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; |
+ 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 the user gave us an absolute path, try to find the file in |
- this symtab and use its absolute path. */ |
- |
- if (full_path != NULL) |
- { |
- const char *fp = symtab_to_fullname (s); |
- |
- if (fp != NULL && FILENAME_CMP (full_path, fp) == 0) |
- { |
- if (callback (s, data)) |
- return 1; |
- } |
- |
- if (fp != NULL && !is_abs && compare_filenames_for_search (fp, name, |
- name_len)) |
- { |
- if (callback (s, data)) |
- return 1; |
- } |
- } |
- |
- if (real_path != NULL) |
- { |
- char *fullname = symtab_to_fullname (s); |
- |
- if (fullname != NULL) |
- { |
- char *rp = gdb_realpath (fullname); |
- |
- make_cleanup (xfree, rp); |
- if (FILENAME_CMP (real_path, rp) == 0) |
- { |
- if (callback (s, data)) |
- return 1; |
- } |
+ /* 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); |
- if (!is_abs && compare_filenames_for_search (rp, name, name_len)) |
- { |
- if (callback (s, data)) |
- return 1; |
- } |
- } |
- } |
+ 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; |
@@ -280,25 +310,22 @@ iterate_over_symtabs (const char *name, |
void *data), |
void *data) |
{ |
- struct symtab *s = NULL; |
struct objfile *objfile; |
char *real_path = NULL; |
- char *full_path = NULL; |
struct cleanup *cleanups = make_cleanup (null_cleanup, NULL); |
/* Here we are interested in canonicalizing an absolute path, not |
absolutizing a relative path. */ |
if (IS_ABSOLUTE_PATH (name)) |
{ |
- full_path = xfullpath (name); |
- make_cleanup (xfree, full_path); |
real_path = gdb_realpath (name); |
make_cleanup (xfree, real_path); |
+ gdb_assert (IS_ABSOLUTE_PATH (real_path)); |
} |
ALL_OBJFILES (objfile) |
{ |
- if (iterate_over_some_symtabs (name, full_path, real_path, callback, data, |
+ if (iterate_over_some_symtabs (name, real_path, callback, data, |
objfile->symtabs, NULL)) |
{ |
do_cleanups (cleanups); |
@@ -314,7 +341,6 @@ iterate_over_symtabs (const char *name, |
if (objfile->sf |
&& objfile->sf->qf->map_symtabs_matching_filename (objfile, |
name, |
- full_path, |
real_path, |
callback, |
data)) |
@@ -402,19 +428,20 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id) |
if (len == 0) |
{ |
- sprintf (buf, "__%s%s", const_prefix, volatile_prefix); |
+ xsnprintf (buf, sizeof (buf), "__%s%s", const_prefix, volatile_prefix); |
} |
else if (physname[0] == 't' || physname[0] == 'Q') |
{ |
/* The physname for template and qualified methods already includes |
the class name. */ |
- sprintf (buf, "__%s%s", const_prefix, volatile_prefix); |
+ xsnprintf (buf, sizeof (buf), "__%s%s", const_prefix, volatile_prefix); |
newname = NULL; |
len = 0; |
} |
else |
{ |
- sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len); |
+ xsnprintf (buf, sizeof (buf), "__%s%s%d", const_prefix, |
+ volatile_prefix, len); |
} |
mangled_name_len = ((is_constructor ? 0 : strlen (field_name)) |
+ strlen (buf) + len + strlen (physname) + 1); |
@@ -441,15 +468,15 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id) |
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 |
@@ -459,16 +486,29 @@ symbol_init_cplus_specific (struct general_symbol_info *gsymbol, |
void |
symbol_set_demangled_name (struct general_symbol_info *gsymbol, |
- char *name, |
- struct objfile *objfile) |
+ const char *name, |
+ 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; |
} |
@@ -485,8 +525,14 @@ symbol_get_demangled_name (const struct general_symbol_info *gsymbol) |
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; |
} |
@@ -495,7 +541,8 @@ symbol_get_demangled_name (const struct general_symbol_info *gsymbol) |
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 |
@@ -504,7 +551,12 @@ symbol_set_language (struct general_symbol_info *gsymbol, |
|| 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; |
@@ -520,7 +572,7 @@ symbol_set_language (struct general_symbol_info *gsymbol, |
/* Objects of this type are stored in the demangled name hash table. */ |
struct demangled_name_entry |
{ |
- char *mangled; |
+ const char *mangled; |
char demangled[1]; |
}; |
@@ -557,7 +609,7 @@ create_demangled_names_hash (struct objfile *objfile) |
Choosing a much larger table size wastes memory, and saves only about |
1% in symbol reading. */ |
- objfile->demangled_names_hash = htab_create_alloc |
+ objfile->per_bfd->demangled_names_hash = htab_create_alloc |
(256, hash_demangled_name_entry, eq_demangled_name_entry, |
NULL, xcalloc, xfree); |
} |
@@ -592,7 +644,7 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol, |
|| 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; |
@@ -602,8 +654,8 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol, |
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; |
@@ -641,6 +693,42 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol, |
symbols). Just the mangling standard is not standardized across compilers |
and there is no DW_AT_producer available for inferiors with only the ELF |
symbols to check the mangling kind. */ |
+ |
+ /* Check for Ada symbols last. See comment below explaining why. */ |
+ |
+ if (gsymbol->language == language_auto) |
+ { |
+ const char *demangled = ada_decode (mangled); |
+ |
+ if (demangled != mangled && demangled != NULL && demangled[0] != '<') |
+ { |
+ /* Set the gsymbol language to Ada, but still return NULL. |
+ Two reasons for that: |
+ |
+ 1. For Ada, we prefer computing the symbol's decoded name |
+ on the fly rather than pre-compute it, in order to save |
+ memory (Ada projects are typically very large). |
+ |
+ 2. There are some areas in the definition of the GNAT |
+ encoding where, with a bit of bad luck, we might be able |
+ to decode a non-Ada symbol, generating an incorrect |
+ demangled name (Eg: names ending with "TB" for instance |
+ are identified as task bodies and so stripped from |
+ the decoded name returned). |
+ |
+ Returning NULL, here, helps us get a little bit of |
+ the best of both worlds. Because we're last, we should |
+ not affect any of the other languages that were able to |
+ demangle the symbol before us; we get to correctly tag |
+ Ada symbols as such; and even if we incorrectly tagged |
+ a non-Ada symbol, which should be rare, any routing |
+ through the Ada language should be transparent (Ada |
+ tries to behave much like C/C++ with non-Ada symbols). */ |
+ gsymbol->language = language_ada; |
+ return NULL; |
+ } |
+ } |
+ |
return NULL; |
} |
@@ -652,7 +740,7 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol, |
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, |
+ comes from the per-BFD storage_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 |
@@ -688,6 +776,7 @@ symbol_set_names (struct general_symbol_info *gsymbol, |
/* The length of lookup_name. */ |
int lookup_len; |
struct demangled_name_entry entry; |
+ struct objfile_per_bfd_storage *per_bfd = objfile->per_bfd; |
if (gsymbol->language == language_ada) |
{ |
@@ -703,18 +792,18 @@ symbol_set_names (struct general_symbol_info *gsymbol, |
gsymbol->name = linkage_name; |
else |
{ |
- char *name = obstack_alloc (&objfile->objfile_obstack, len + 1); |
+ char *name = obstack_alloc (&per_bfd->storage_obstack, len + 1); |
memcpy (name, linkage_name, len); |
name[len] = '\0'; |
gsymbol->name = name; |
} |
- symbol_set_demangled_name (gsymbol, NULL, NULL); |
+ symbol_set_demangled_name (gsymbol, NULL, &per_bfd->storage_obstack); |
return; |
} |
- if (objfile->demangled_names_hash == NULL) |
+ if (per_bfd->demangled_names_hash == NULL) |
create_demangled_names_hash (objfile); |
/* The stabs reader generally provides names that are not |
@@ -752,9 +841,9 @@ symbol_set_names (struct general_symbol_info *gsymbol, |
linkage_name_copy = linkage_name; |
} |
- entry.mangled = (char *) lookup_name; |
+ entry.mangled = lookup_name; |
slot = ((struct demangled_name_entry **) |
- htab_find_slot (objfile->demangled_names_hash, |
+ htab_find_slot (per_bfd->demangled_names_hash, |
&entry, INSERT)); |
/* If this name is not in the hash table, add it. */ |
@@ -779,23 +868,26 @@ symbol_set_names (struct general_symbol_info *gsymbol, |
us better bcache hit rates for partial symbols. */ |
if (!copy_name && lookup_name == linkage_name) |
{ |
- *slot = obstack_alloc (&objfile->objfile_obstack, |
+ *slot = obstack_alloc (&per_bfd->storage_obstack, |
offsetof (struct demangled_name_entry, |
demangled) |
+ demangled_len + 1); |
- (*slot)->mangled = (char *) lookup_name; |
+ (*slot)->mangled = lookup_name; |
} |
else |
{ |
+ char *mangled_ptr; |
+ |
/* 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, |
+ *slot = obstack_alloc (&per_bfd->storage_obstack, |
offsetof (struct demangled_name_entry, |
demangled) |
+ lookup_len + demangled_len + 2); |
- (*slot)->mangled = &((*slot)->demangled[demangled_len + 1]); |
- strcpy ((*slot)->mangled, lookup_name); |
+ mangled_ptr = &((*slot)->demangled[demangled_len + 1]); |
+ strcpy (mangled_ptr, lookup_name); |
+ (*slot)->mangled = mangled_ptr; |
} |
if (demangled_name != NULL) |
@@ -809,9 +901,10 @@ symbol_set_names (struct general_symbol_info *gsymbol, |
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, |
+ &per_bfd->storage_obstack); |
else |
- symbol_set_demangled_name (gsymbol, NULL, objfile); |
+ symbol_set_demangled_name (gsymbol, NULL, &per_bfd->storage_obstack); |
} |
/* Return the source code name of a symbol. In languages where |
@@ -832,11 +925,7 @@ symbol_natural_name (const struct general_symbol_info *gsymbol) |
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; |
} |
@@ -862,9 +951,7 @@ symbol_demangled_name (const struct general_symbol_info *gsymbol) |
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; |
@@ -977,7 +1064,7 @@ find_pc_sect_symtab_via_partial (CORE_ADDR pc, struct obj_section *section) |
/* 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 |
@@ -1016,10 +1103,7 @@ fixup_section (struct general_symbol_info *ginfo, |
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 |
@@ -1059,20 +1143,31 @@ fixup_section (struct general_symbol_info *ginfo, |
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; |
} |
} |
@@ -1084,9 +1179,6 @@ fixup_symbol_section (struct symbol *sym, struct objfile *objfile) |
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)); |
@@ -1094,6 +1186,9 @@ fixup_symbol_section (struct symbol *sym, struct objfile *objfile) |
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); |
@@ -1150,7 +1245,7 @@ demangle_for_lookup (const char *name, enum language lang, |
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; |
@@ -1170,8 +1265,8 @@ demangle_for_lookup (const char *name, enum language lang, |
} |
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; |
@@ -1223,7 +1318,7 @@ demangle_for_lookup (const char *name, enum language lang, |
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 field_of_this_result *is_a_field_of_this) |
{ |
const char *modified_name; |
struct symbol *returnval; |
@@ -1241,7 +1336,8 @@ lookup_symbol_in_language (const char *name, const struct block *block, |
struct symbol * |
lookup_symbol (const char *name, const struct block *block, |
- domain_enum domain, int *is_a_field_of_this) |
+ domain_enum domain, |
+ struct field_of_this_result *is_a_field_of_this) |
{ |
return lookup_symbol_in_language (name, block, domain, |
current_language->la_language, |
@@ -1276,24 +1372,68 @@ lookup_language_this (const struct language_defn *lang, |
return NULL; |
} |
+/* Given TYPE, a structure/union, |
+ return 1 if the component named NAME from the ultimate target |
+ structure/union is defined, otherwise, return 0. */ |
+ |
+static int |
+check_field (struct type *type, const char *name, |
+ struct field_of_this_result *is_a_field_of_this) |
+{ |
+ int i; |
+ |
+ /* The type may be a stub. */ |
+ CHECK_TYPEDEF (type); |
+ |
+ for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--) |
+ { |
+ const char *t_field_name = TYPE_FIELD_NAME (type, i); |
+ |
+ if (t_field_name && (strcmp_iw (t_field_name, name) == 0)) |
+ { |
+ is_a_field_of_this->type = type; |
+ is_a_field_of_this->field = &TYPE_FIELD (type, i); |
+ return 1; |
+ } |
+ } |
+ |
+ /* C++: If it was not found as a data field, then try to return it |
+ as a pointer to a method. */ |
+ |
+ for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; --i) |
+ { |
+ if (strcmp_iw (TYPE_FN_FIELDLIST_NAME (type, i), name) == 0) |
+ { |
+ is_a_field_of_this->type = type; |
+ is_a_field_of_this->fn_field = &TYPE_FN_FIELDLIST (type, i); |
+ return 1; |
+ } |
+ } |
+ |
+ for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--) |
+ if (check_field (TYPE_BASECLASS (type, i), name, is_a_field_of_this)) |
+ return 1; |
+ |
+ return 0; |
+} |
+ |
/* Behave like lookup_symbol except that NAME is the natural name |
(e.g., demangled name) of the symbol that we're looking for. */ |
static struct symbol * |
lookup_symbol_aux (const char *name, const struct block *block, |
const domain_enum domain, enum language language, |
- int *is_a_field_of_this) |
+ struct field_of_this_result *is_a_field_of_this) |
{ |
struct symbol *sym; |
const struct language_defn *langdef; |
/* Make sure we do something sensible with is_a_field_of_this, since |
the callers that set this parameter to some non-null value will |
- certainly use it later and expect it to be either 0 or 1. |
- If we don't set it, the contents of is_a_field_of_this are |
- undefined. */ |
+ certainly use it later. If we don't set it, the contents of |
+ is_a_field_of_this are undefined. */ |
if (is_a_field_of_this != NULL) |
- *is_a_field_of_this = 0; |
+ memset (is_a_field_of_this, 0, sizeof (*is_a_field_of_this)); |
/* Search specified block and its superiors. Don't search |
STATIC_BLOCK or GLOBAL_BLOCK. */ |
@@ -1307,7 +1447,10 @@ lookup_symbol_aux (const char *name, const struct block *block, |
langdef = language_def (language); |
- if (is_a_field_of_this != NULL) |
+ /* Don't do this check if we are searching for a struct. It will |
+ not be found by check_field, but will be found by other |
+ means. */ |
+ if (is_a_field_of_this != NULL && domain != STRUCT_DOMAIN) |
{ |
struct symbol *sym = lookup_language_this (langdef, block); |
@@ -1327,11 +1470,8 @@ lookup_symbol_aux (const char *name, const struct block *block, |
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; |
- } |
+ if (check_field (t, name, is_a_field_of_this)) |
+ return NULL; |
} |
} |
@@ -1512,10 +1652,6 @@ lookup_symbol_aux_objfile (struct objfile *objfile, int block_index, |
const struct block *block; |
struct symtab *s; |
- if (objfile->sf) |
- objfile->sf->qf->pre_expand_symtabs_matching (objfile, block_index, |
- name, domain); |
- |
ALL_OBJFILE_PRIMARY_SYMTABS (objfile, s) |
{ |
bv = BLOCKVECTOR (s); |
@@ -1593,6 +1729,20 @@ lookup_symbol_in_objfile_from_linkage_name (struct objfile *objfile, |
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. */ |
@@ -1615,30 +1765,7 @@ lookup_symbol_aux_quick (struct objfile *objfile, int kind, |
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->filename, name, name); |
- } |
+ error_in_psymtab_expansion (kind, name, symtab); |
return fixup_symbol_section (sym, objfile); |
} |
@@ -1767,7 +1894,7 @@ lookup_symbol_global (const char *name, |
lookup_data.name = name; |
lookup_data.domain = domain; |
gdbarch_iterate_over_objfiles_in_search_order |
- (objfile != NULL ? get_objfile_arch (objfile) : target_gdbarch, |
+ (objfile != NULL ? get_objfile_arch (objfile) : target_gdbarch (), |
lookup_symbol_global_iterator_cb, &lookup_data, objfile); |
return lookup_data.result; |
@@ -1826,24 +1953,8 @@ basic_lookup_transparent_type_quick (struct objfile *objfile, int kind, |
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->filename, name, name); |
- } |
+ error_in_psymtab_expansion (kind, name, symtab); |
+ |
if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym))) |
return SYMBOL_TYPE (sym); |
@@ -1873,11 +1984,6 @@ basic_lookup_transparent_type (const char *name) |
ALL_OBJFILES (objfile) |
{ |
- if (objfile->sf) |
- objfile->sf->qf->pre_expand_symtabs_matching (objfile, |
- GLOBAL_BLOCK, |
- name, STRUCT_DOMAIN); |
- |
ALL_OBJFILE_PRIMARY_SYMTABS (objfile, s) |
{ |
bv = BLOCKVECTOR (s); |
@@ -1906,10 +2012,6 @@ basic_lookup_transparent_type (const char *name) |
ALL_OBJFILES (objfile) |
{ |
- if (objfile->sf) |
- objfile->sf->qf->pre_expand_symtabs_matching (objfile, STATIC_BLOCK, |
- name, STRUCT_DOMAIN); |
- |
ALL_OBJFILE_PRIMARY_SYMTABS (objfile, s) |
{ |
bv = BLOCKVECTOR (s); |
@@ -1932,29 +2034,6 @@ basic_lookup_transparent_type (const char *name) |
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 |
@@ -2013,16 +2092,13 @@ lookup_block_symbol (const struct block *block, const char *name, |
} |
} |
-/* Iterate over the symbols named NAME, matching DOMAIN, starting with |
- BLOCK. |
+/* Iterate over the symbols named NAME, matching DOMAIN, in BLOCK. |
For each symbol that matches, CALLBACK is called. The symbol and |
DATA are passed to the callback. |
If CALLBACK returns zero, the iteration ends. Otherwise, the |
- search continues. This function iterates upward through blocks. |
- When the outermost block has been finished, the function |
- returns. */ |
+ search continues. */ |
void |
iterate_over_symbols (const struct block *block, const char *name, |
@@ -2030,24 +2106,19 @@ iterate_over_symbols (const struct block *block, const char *name, |
symbol_found_callback_ftype *callback, |
void *data) |
{ |
- while (block) |
- { |
- struct block_iterator iter; |
- struct symbol *sym; |
+ struct block_iterator iter; |
+ struct symbol *sym; |
- for (sym = block_iter_name_first (block, name, &iter); |
- sym != NULL; |
- sym = block_iter_name_next (name, &iter)) |
+ for (sym = block_iter_name_first (block, name, &iter); |
+ sym != NULL; |
+ sym = block_iter_name_next (name, &iter)) |
+ { |
+ if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), |
+ SYMBOL_DOMAIN (sym), domain)) |
{ |
- if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), |
- SYMBOL_DOMAIN (sym), domain)) |
- { |
- if (!callback (sym, data)) |
- return; |
- } |
+ if (!callback (sym, data)) |
+ return; |
} |
- |
- block = BLOCK_SUPERBLOCK (block); |
} |
} |
@@ -2062,18 +2133,15 @@ find_pc_sect_symtab (CORE_ADDR pc, struct obj_section *section) |
struct symtab *s = NULL; |
struct symtab *best_s = NULL; |
struct objfile *objfile; |
- struct program_space *pspace; |
CORE_ADDR distance = 0; |
struct minimal_symbol *msymbol; |
- pspace = current_program_space; |
- |
/* If we know that this is not a text address, return failure. This is |
necessary because we loop based on the block's high and low code |
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 |
@@ -2133,7 +2201,8 @@ find_pc_sect_symtab (CORE_ADDR pc, struct obj_section *section) |
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) |
@@ -2148,6 +2217,8 @@ find_pc_sect_symtab (CORE_ADDR pc, struct obj_section *section) |
if (best_s != NULL) |
return (best_s); |
+ /* Not found in symtabs, search the "quick" symtabs (e.g. psymtabs). */ |
+ |
ALL_OBJFILES (objfile) |
{ |
struct symtab *result; |
@@ -2202,7 +2273,7 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent) |
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; |
@@ -2218,7 +2289,6 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent) |
we will use a line one less than this, |
with a range from the start of that file to the first line's pc. */ |
struct linetable_entry *alt = NULL; |
- struct symtab *alt_symtab = 0; |
/* Info on best line seen in this file. */ |
@@ -2289,11 +2359,12 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent) |
* 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: |
@@ -2309,7 +2380,7 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent) |
; |
/* 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", |
@@ -2363,10 +2434,7 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent) |
/* Is this file's first line closer than the first lines of other files? |
If so, record this file, and its first line, as best alternate. */ |
if (item->pc > pc && (!alt || item->pc < alt->pc)) |
- { |
- alt = item; |
- alt_symtab = s; |
- } |
+ alt = item; |
for (i = 0; i < len; i++, item++) |
{ |
@@ -2502,13 +2570,10 @@ find_line_symtab (struct symtab *symtab, int line, |
ALL_OBJFILES (objfile) |
{ |
if (objfile->sf) |
- objfile->sf->qf->expand_symtabs_with_filename (objfile, |
- symtab->filename); |
+ objfile->sf->qf->expand_symtabs_with_fullname (objfile, |
+ symtab_to_fullname (symtab)); |
} |
- /* Get symbol full file name if possible. */ |
- symtab_to_fullname (symtab); |
- |
ALL_SYMTABS (objfile, s) |
{ |
struct linetable *l; |
@@ -2516,9 +2581,8 @@ find_line_symtab (struct symtab *symtab, int line, |
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) |
+ if (FILENAME_CMP (symtab_to_fullname (symtab), |
+ symtab_to_fullname (s)) != 0) |
continue; |
l = LINETABLE (s); |
ind = find_line_common (l, line, &exact, 0); |
@@ -2561,8 +2625,7 @@ VEC (CORE_ADDR) * |
find_pcs_for_symtab_line (struct symtab *symtab, int line, |
struct linetable_entry **best_item) |
{ |
- int start = 0, ix; |
- struct symbol *previous_function = NULL; |
+ int start = 0; |
VEC (CORE_ADDR) *result = NULL; |
/* First, collect all the PCs that are at this line. */ |
@@ -2771,7 +2834,7 @@ find_function_start_sal (struct symbol *sym, int funfirstline) |
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 |
@@ -2782,7 +2845,7 @@ find_function_start_sal (struct symbol *sym, int funfirstline) |
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) |
@@ -2810,7 +2873,7 @@ skip_prologue_sal (struct symtab_and_line *sal) |
struct block *b, *function_block; |
int force_skip, skip; |
- /* Do not change the SAL is PC was specified explicitly. */ |
+ /* Do not change the SAL if PC was specified explicitly. */ |
if (sal->explicit_pc) |
return; |
@@ -2823,25 +2886,25 @@ skip_prologue_sal (struct symtab_and_line *sal) |
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); |
@@ -2886,8 +2949,8 @@ skip_prologue_sal (struct symtab_and_line *sal) |
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; |
@@ -3249,7 +3312,7 @@ sources_info (char *ignore, int from_tty) |
{ |
const char *fullname = symtab_to_fullname (s); |
- output_source_filename (fullname ? fullname : s->filename, &data); |
+ output_source_filename (fullname, &data); |
} |
printf_filtered ("\n\n"); |
@@ -3265,8 +3328,11 @@ sources_info (char *ignore, int from_tty) |
do_cleanups (cleanups); |
} |
+/* Compare FILE against all the NFILES entries of FILES. If BASENAMES is |
+ non-zero compare only lbasename of FILES. */ |
+ |
static int |
-file_matches (const char *file, char *files[], int nfiles) |
+file_matches (const char *file, char *files[], int nfiles, int basenames) |
{ |
int i; |
@@ -3274,7 +3340,9 @@ file_matches (const char *file, char *files[], int nfiles) |
{ |
for (i = 0; i < nfiles; i++) |
{ |
- if (filename_cmp (files[i], lbasename (file)) == 0) |
+ if (compare_filenames_for_search (file, (basenames |
+ ? lbasename (files[i]) |
+ : files[i]))) |
return 1; |
} |
} |
@@ -3299,64 +3367,89 @@ free_search_symbols (struct symbol_search *symbols) |
} |
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 = FILENAME_CMP (sym_a->symtab->filename, sym_b->symtab->filename); |
+ if (c != 0) |
+ return c; |
+ |
+ 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)); |
+ 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. */ |
+/* 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 struct symbol_search * |
-sort_search_symbols (struct symbol_search *prevtail, int nfound) |
+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 (compare_search_syms (&symbols[j - 1], &symbols[i]) != 0) |
+ 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 |
@@ -3374,11 +3467,12 @@ struct search_symbols_data |
/* A callback for expand_symtabs_matching. */ |
static int |
-search_symbols_file_matches (const char *filename, void *user_data) |
+search_symbols_file_matches (const char *filename, void *user_data, |
+ int basenames) |
{ |
struct search_symbols_data *data = user_data; |
- return file_matches (filename, data->files, data->nfiles); |
+ return file_matches (filename, data->files, data->nfiles, basenames); |
} |
/* A callback for expand_symtabs_matching. */ |
@@ -3403,8 +3497,9 @@ search_symbols_name_matches (const char *symname, void *user_data) |
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, |
@@ -3432,10 +3527,10 @@ 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. */ |
@@ -3449,8 +3544,7 @@ search_symbols (char *regexp, enum search_domain kind, |
ourtype3 = types3[kind]; |
ourtype4 = types4[kind]; |
- sr = *matches = NULL; |
- tail = NULL; |
+ *matches = NULL; |
datum.preg_p = 0; |
if (regexp != NULL) |
@@ -3522,8 +3616,6 @@ search_symbols (char *regexp, enum search_domain kind, |
&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, |
@@ -3572,14 +3664,16 @@ search_symbols (char *regexp, enum search_domain kind, |
} |
} |
+ 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) |
{ |
@@ -3587,7 +3681,14 @@ search_symbols (char *regexp, enum search_domain kind, |
QUIT; |
- if (file_matches (real_symtab->filename, files, nfiles) |
+ /* Check first sole REAL_SYMTAB->FILENAME. It does not need to be |
+ a substring of symtab_to_fullname as it may contain "./" etc. */ |
+ if ((file_matches (real_symtab->filename, files, nfiles, 0) |
+ || ((basenames_may_differ |
+ || file_matches (lbasename (real_symtab->filename), |
+ files, nfiles, 1)) |
+ && file_matches (symtab_to_fullname (real_symtab), |
+ files, nfiles, 0))) |
&& ((!datum.preg_p |
|| regexec (&datum.preg, SYMBOL_NATURAL_NAME (sym), 0, |
NULL, 0) == 0) |
@@ -3607,39 +3708,30 @@ search_symbols (char *regexp, enum search_domain kind, |
&& 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. */ |
@@ -3671,18 +3763,16 @@ search_symbols (char *regexp, enum search_domain kind, |
== 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; |
@@ -3695,7 +3785,7 @@ search_symbols (char *regexp, enum search_domain kind, |
discard_cleanups (retval_chain); |
do_cleanups (old_chain); |
- *matches = sr; |
+ *matches = found; |
} |
/* Helper function for symtab_symbol_info, this function uses |
@@ -3705,12 +3795,14 @@ search_symbols (char *regexp, enum search_domain kind, |
static void |
print_symbol_info (enum search_domain kind, |
struct symtab *s, struct symbol *sym, |
- int block, char *last) |
+ int block, const char *last) |
{ |
- if (last == NULL || filename_cmp (last, s->filename) != 0) |
+ const char *s_filename = symtab_to_filename_for_display (s); |
+ |
+ if (last == NULL || filename_cmp (last, s_filename) != 0) |
{ |
fputs_filtered ("\nFile ", gdb_stdout); |
- fputs_filtered (s->filename, gdb_stdout); |
+ fputs_filtered (s_filename, gdb_stdout); |
fputs_filtered (":\n", gdb_stdout); |
} |
@@ -3739,20 +3831,20 @@ print_symbol_info (enum search_domain kind, |
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 |
@@ -3768,29 +3860,30 @@ symtab_symbol_info (char *regexp, enum search_domain kind, int from_tty) |
struct symbol_search *symbols; |
struct symbol_search *p; |
struct cleanup *old_chain; |
- char *last_filename = NULL; |
+ const char *last_filename = NULL; |
int first = 1; |
gdb_assert (kind <= TYPES_DOMAIN); |
/* 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); |
- printf_filtered (regexp |
- ? "All %ss matching regular expression \"%s\":\n" |
- : "All defined %ss:\n", |
- classnames[kind], regexp); |
+ if (regexp != NULL) |
+ printf_filtered (_("All %ss matching regular expression \"%s\":\n"), |
+ classnames[kind], regexp); |
+ else |
+ printf_filtered (_("All defined %ss:\n"), classnames[kind]); |
for (p = symbols; p != NULL; p = p->next) |
{ |
QUIT; |
- if (p->msymbol != NULL) |
+ if (p->msymbol.minsym != NULL) |
{ |
if (first) |
{ |
- printf_filtered ("\nNon-debugging symbols:\n"); |
+ printf_filtered (_("\nNon-debugging symbols:\n")); |
first = 0; |
} |
print_msymbol_info (p->msymbol); |
@@ -3802,7 +3895,7 @@ symtab_symbol_info (char *regexp, enum search_domain kind, int from_tty) |
p->symbol, |
p->block, |
last_filename); |
- last_filename = p->symtab->filename; |
+ last_filename = symtab_to_filename_for_display (p->symtab); |
} |
} |
@@ -3871,22 +3964,23 @@ rbreak_command (char *regexp, int from_tty) |
file_name[colon_index--] = 0; |
files = &file_name; |
nfiles = 1; |
- regexp = colon + 1; |
- while (isspace (*regexp)) regexp++; |
+ regexp = skip_spaces (colon + 1); |
} |
} |
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) |
{ |
- int newlen = (strlen (p->symtab->filename) |
+ const char *fullname = symtab_to_fullname (p->symtab); |
+ |
+ int newlen = (strlen (fullname) |
+ strlen (SYMBOL_LINKAGE_NAME (p->symbol)) |
+ 4); |
@@ -3895,7 +3989,7 @@ rbreak_command (char *regexp, int from_tty) |
string = xrealloc (string, newlen); |
len = newlen; |
} |
- strcpy (string, p->symtab->filename); |
+ strcpy (string, fullname); |
strcat (string, ":'"); |
strcat (string, SYMBOL_LINKAGE_NAME (p->symbol)); |
strcat (string, "'"); |
@@ -3904,11 +3998,11 @@ rbreak_command (char *regexp, int from_tty) |
p->symtab, |
p->symbol, |
p->block, |
- p->symtab->filename); |
+ symtab_to_filename_for_display (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) |
{ |
@@ -3916,12 +4010,12 @@ rbreak_command (char *regexp, int from_tty) |
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)); |
} |
} |
@@ -4001,8 +4095,6 @@ completion_list_add_name (const char *symname, |
const char *sym_text, int sym_text_len, |
const char *text, const char *word) |
{ |
- int newsize; |
- |
/* Clip symbols that cannot match. */ |
if (!compare_symbol_name (symname, sym_text, sym_text_len)) |
return; |
@@ -4100,8 +4192,8 @@ completion_list_objc_symbol (struct minimal_symbol *msymbol, |
/* Break the non-quoted text based on the characters which are in |
symbols. FIXME: This should probably be language-specific. */ |
-static char * |
-language_search_unquoted_string (char *text, char *p) |
+static const char * |
+language_search_unquoted_string (const char *text, const char *p) |
{ |
for (; p > text; --p) |
{ |
@@ -4117,7 +4209,7 @@ language_search_unquoted_string (char *text, char *p) |
p -= 2; /* Beginning of a method name. */ |
else if (p[-1] == ' ' || p[-1] == '(' || p[-1] == ')') |
{ /* Might be part of a method name. */ |
- char *t = p; |
+ const char *t = p; |
/* Seeing a ' ' or a '(' is not conclusive evidence |
that we are in the middle of a method name. However, |
@@ -4144,8 +4236,9 @@ language_search_unquoted_string (char *text, char *p) |
} |
static void |
-completion_list_add_fields (struct symbol *sym, char *sym_text, |
- int sym_text_len, char *text, char *word) |
+completion_list_add_fields (struct symbol *sym, const char *sym_text, |
+ int sym_text_len, const char *text, |
+ const char *word) |
{ |
if (SYMBOL_CLASS (sym) == LOC_TYPEDEF) |
{ |
@@ -4166,10 +4259,10 @@ completion_list_add_fields (struct symbol *sym, char *sym_text, |
needed by completion_list_add_name. */ |
struct add_name_data |
{ |
- char *sym_text; |
+ const char *sym_text; |
int sym_text_len; |
- char *text; |
- char *word; |
+ const char *text; |
+ const char *word; |
}; |
/* A callback used with macro_for_each and macro_for_each_in_scope. |
@@ -4198,8 +4291,10 @@ expand_partial_symbol_name (const char *name, void *user_data) |
} |
VEC (char_ptr) * |
-default_make_symbol_completion_list_break_on (char *text, char *word, |
- const char *break_on) |
+default_make_symbol_completion_list_break_on (const char *text, |
+ const char *word, |
+ const char *break_on, |
+ enum type_code code) |
{ |
/* Problem: All of the symbols have to be copied because readline |
frees them. I'm not going to worry about this; hopefully there |
@@ -4213,7 +4308,7 @@ default_make_symbol_completion_list_break_on (char *text, char *word, |
const struct block *surrounding_static_block, *surrounding_global_block; |
struct block_iterator iter; |
/* The symbol we are completing on. Points in same buffer as text. */ |
- char *sym_text; |
+ const char *sym_text; |
/* Length of sym_text. */ |
int sym_text_len; |
struct add_name_data datum; |
@@ -4221,9 +4316,9 @@ default_make_symbol_completion_list_break_on (char *text, char *word, |
/* Now look for the symbol we are supposed to complete on. */ |
{ |
- char *p; |
+ const char *p; |
char quote_found; |
- char *quote_pos = NULL; |
+ const char *quote_pos = NULL; |
/* First see if this is a quoted string. */ |
quote_found = '\0'; |
@@ -4306,13 +4401,18 @@ default_make_symbol_completion_list_break_on (char *text, char *word, |
anything that isn't a text symbol (everything else will be |
handled by the psymtab code above). */ |
- ALL_MSYMBOLS (objfile, msymbol) |
- { |
- QUIT; |
- COMPLETION_LIST_ADD_SYMBOL (msymbol, sym_text, sym_text_len, text, word); |
+ if (code == TYPE_CODE_UNDEF) |
+ { |
+ ALL_MSYMBOLS (objfile, msymbol) |
+ { |
+ QUIT; |
+ COMPLETION_LIST_ADD_SYMBOL (msymbol, sym_text, sym_text_len, text, |
+ word); |
- completion_list_objc_symbol (msymbol, sym_text, sym_text_len, text, word); |
- } |
+ completion_list_objc_symbol (msymbol, sym_text, sym_text_len, text, |
+ word); |
+ } |
+ } |
/* Search upwards from currently selected frame (so that we can |
complete on local vars). Also catch fields of types defined in |
@@ -4329,10 +4429,17 @@ default_make_symbol_completion_list_break_on (char *text, char *word, |
ALL_BLOCK_SYMBOLS (b, iter, sym) |
{ |
- COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, |
- word); |
- completion_list_add_fields (sym, sym_text, sym_text_len, text, |
- word); |
+ if (code == TYPE_CODE_UNDEF) |
+ { |
+ COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, |
+ word); |
+ completion_list_add_fields (sym, sym_text, sym_text_len, text, |
+ word); |
+ } |
+ else if (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN |
+ && TYPE_CODE (SYMBOL_TYPE (sym)) == code) |
+ COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, |
+ word); |
} |
/* Stop when we encounter an enclosing function. Do not stop for |
@@ -4345,13 +4452,16 @@ default_make_symbol_completion_list_break_on (char *text, char *word, |
/* Add fields from the file's types; symbols will be added below. */ |
- if (surrounding_static_block != NULL) |
- ALL_BLOCK_SYMBOLS (surrounding_static_block, iter, sym) |
- completion_list_add_fields (sym, sym_text, sym_text_len, text, word); |
+ if (code == TYPE_CODE_UNDEF) |
+ { |
+ if (surrounding_static_block != NULL) |
+ ALL_BLOCK_SYMBOLS (surrounding_static_block, iter, sym) |
+ completion_list_add_fields (sym, sym_text, sym_text_len, text, word); |
- if (surrounding_global_block != NULL) |
- ALL_BLOCK_SYMBOLS (surrounding_global_block, iter, sym) |
- completion_list_add_fields (sym, sym_text, sym_text_len, text, word); |
+ if (surrounding_global_block != NULL) |
+ ALL_BLOCK_SYMBOLS (surrounding_global_block, iter, sym) |
+ completion_list_add_fields (sym, sym_text, sym_text_len, text, word); |
+ } |
/* Go through the symtabs and check the externs and statics for |
symbols which match. */ |
@@ -4362,7 +4472,10 @@ default_make_symbol_completion_list_break_on (char *text, char *word, |
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK); |
ALL_BLOCK_SYMBOLS (b, iter, sym) |
{ |
- COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word); |
+ if (code == TYPE_CODE_UNDEF |
+ || (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN |
+ && TYPE_CODE (SYMBOL_TYPE (sym)) == code)) |
+ COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word); |
} |
} |
@@ -4372,11 +4485,17 @@ default_make_symbol_completion_list_break_on (char *text, char *word, |
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK); |
ALL_BLOCK_SYMBOLS (b, iter, sym) |
{ |
- COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word); |
+ if (code == TYPE_CODE_UNDEF |
+ || (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN |
+ && TYPE_CODE (SYMBOL_TYPE (sym)) == code)) |
+ COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word); |
} |
} |
- if (current_language->la_macro_expansion == macro_expansion_c) |
+ /* Skip macros if we are completing a struct tag -- arguable but |
+ usually what is expected. */ |
+ if (current_language->la_macro_expansion == macro_expansion_c |
+ && code == TYPE_CODE_UNDEF) |
{ |
struct macro_scope *scope; |
@@ -4404,9 +4523,10 @@ default_make_symbol_completion_list_break_on (char *text, char *word, |
} |
VEC (char_ptr) * |
-default_make_symbol_completion_list (char *text, char *word) |
+default_make_symbol_completion_list (const char *text, const char *word, |
+ enum type_code code) |
{ |
- return default_make_symbol_completion_list_break_on (text, word, ""); |
+ return default_make_symbol_completion_list_break_on (text, word, "", code); |
} |
/* Return a vector of all symbols (regardless of class) which begin by |
@@ -4414,9 +4534,24 @@ default_make_symbol_completion_list (char *text, char *word) |
is NULL. */ |
VEC (char_ptr) * |
-make_symbol_completion_list (char *text, char *word) |
+make_symbol_completion_list (const char *text, const char *word) |
+{ |
+ return current_language->la_make_symbol_completion_list (text, word, |
+ TYPE_CODE_UNDEF); |
+} |
+ |
+/* Like make_symbol_completion_list, but only return STRUCT_DOMAIN |
+ symbols whose type code is CODE. */ |
+ |
+VEC (char_ptr) * |
+make_symbol_completion_type (const char *text, const char *word, |
+ enum type_code code) |
{ |
- return current_language->la_make_symbol_completion_list (text, word); |
+ gdb_assert (code == TYPE_CODE_UNION |
+ || code == TYPE_CODE_STRUCT |
+ || code == TYPE_CODE_CLASS |
+ || code == TYPE_CODE_ENUM); |
+ return current_language->la_make_symbol_completion_list (text, word, code); |
} |
/* Like make_symbol_completion_list, but suitable for use as a |
@@ -4424,7 +4559,7 @@ make_symbol_completion_list (char *text, char *word) |
VEC (char_ptr) * |
make_symbol_completion_list_fn (struct cmd_list_element *ignore, |
- char *text, char *word) |
+ const char *text, const char *word) |
{ |
return make_symbol_completion_list (text, word); |
} |
@@ -4433,23 +4568,24 @@ make_symbol_completion_list_fn (struct cmd_list_element *ignore, |
defined in a source file FILE. */ |
VEC (char_ptr) * |
-make_file_symbol_completion_list (char *text, char *word, char *srcfile) |
+make_file_symbol_completion_list (const char *text, const char *word, |
+ const char *srcfile) |
{ |
struct symbol *sym; |
struct symtab *s; |
struct block *b; |
struct block_iterator iter; |
/* The symbol we are completing on. Points in same buffer as text. */ |
- char *sym_text; |
+ const char *sym_text; |
/* 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. */ |
{ |
- char *p; |
+ const char *p; |
char quote_found; |
- char *quote_pos = NULL; |
+ const char *quote_pos = NULL; |
/* First see if this is a quoted string. */ |
quote_found = '\0'; |
@@ -4531,7 +4667,7 @@ make_file_symbol_completion_list (char *text, char *word, char *srcfile) |
list as necessary. */ |
static void |
-add_filename_to_list (const char *fname, char *text, char *word, |
+add_filename_to_list (const char *fname, const char *text, const char *word, |
VEC (char_ptr) **list) |
{ |
char *new; |
@@ -4582,8 +4718,8 @@ not_interesting_fname (const char *fname) |
struct add_partial_filename_data |
{ |
struct filename_seen_cache *filename_seen_cache; |
- char *text; |
- char *word; |
+ const char *text; |
+ const char *word; |
int text_len; |
VEC (char_ptr) **list; |
}; |
@@ -4622,7 +4758,7 @@ maybe_add_partial_symtab_filename (const char *filename, const char *fullname, |
NULL. */ |
VEC (char_ptr) * |
-make_source_files_completion_list (char *text, char *word) |
+make_source_files_completion_list (const char *text, const char *word) |
{ |
struct symtab *s; |
struct objfile *objfile; |
@@ -4825,6 +4961,10 @@ skip_prologue_using_sal (struct gdbarch *gdbarch, CORE_ADDR func_addr) |
line mark the prologue -> body transition. */ |
if (sal.line >= prologue_sal.line) |
break; |
+ /* Likewise if we are in a different symtab altogether |
+ (e.g. within a file included via #include). */ |
+ if (sal.symtab != prologue_sal.symtab) |
+ break; |
/* The line number is smaller. Check that it's from the |
same function, not something inlined. If it's inlined, |
@@ -4978,9 +5118,157 @@ producer_is_realview (const char *producer) |
return 0; |
} |
+ |
+ |
+/* 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; |
+} |
+ |
+ |
+ |
+/* 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; |
+} |
+ |
+ |
+ |
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) |
@@ -5038,13 +5326,15 @@ one base name, and gdb will do file name comparisons more efficiently."), |
NULL, NULL, |
&setlist, &showlist); |
- add_setshow_boolean_cmd ("symtab-create", no_class, &symtab_create_debug, |
- _("Set debugging of symbol table creation."), |
- _("Show debugging of symbol table creation."), _("\ |
-When enabled, debugging messages are printed when building symbol tables."), |
- NULL, |
- NULL, |
- &setdebuglist, &showdebuglist); |
+ add_setshow_zuinteger_cmd ("symtab-create", no_class, &symtab_create_debug, |
+ _("Set debugging of symbol table creation."), |
+ _("Show debugging of symbol table creation."), _("\ |
+When enabled (non-zero), debugging messages are printed when building\n\ |
+symbol tables. A value of 1 (one) normally provides enough information.\n\ |
+A value greater than 1 provides more verbose information."), |
+ NULL, |
+ NULL, |
+ &setdebuglist, &showdebuglist); |
observer_attach_executable_changed (symtab_observer_executable_changed); |
} |