Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
836 lines (797 sloc) 26.2 KB
From 26ab3460862e21669d1ddd90bdf3f10dcad80cd0 Mon Sep 17 00:00:00 2001
From: Andrei Warkentin <andreiw@motorola.com>
Date: Tue, 24 May 2011 17:31:10 -0500
Subject: [PATCH] GDB: Fourth prototype of symbol file scope ("module scope" in other debuggers).
Works, you can do stuff like -
Print &'DxeCore.dll'::gST
Scoping works from current scope, so as you would expect, doing above
command in a deeper stack frame from a different EFI module would
result in the expected resulted (gST from that module).
Added list-symbol-files command, which shows currently loaded
modules. It can take optional arguments, which are either object
names or source files, in the later case modules containing this
source are show.
Signed-off-by: Andrei Warkentin <andreiw@motorola.com>
---
gdb/completer.c | 80 ++++++++++----
gdb/completer.h | 2 +
gdb/linespec.c | 3 +-
gdb/objfiles.c | 52 +++++++++
gdb/objfiles.h | 2 +
gdb/symfile.c | 136 +++++++++++++++++++++++
gdb/symtab.c | 328 ++++++++++++++++++++++++++++++++++++++++++++-----------
gdb/symtab.h | 4 +-
8 files changed, 521 insertions(+), 86 deletions(-)
diff --git a/gdb/completer.c b/gdb/completer.c
index 53275c0..efe5797 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -189,6 +189,26 @@ filename_completer (struct cmd_list_element *ignore, char *text, char *word)
return return_val;
}
+/* Complete on (multiple) symbol or source files. */
+char **
+files_completer (struct cmd_list_element *ignore, char *text, char *word)
+{
+ char *text_start;
+
+ text_start = word;
+ while (text_start != text)
+ {
+ if (*text_start == ' ')
+ break;
+ text_start--;
+ }
+
+ if (text_start != text)
+ text_start++;
+
+ return make_files_completion_list (text_start, word);
+}
+
/* Complete on locations, which might be of two possible forms:
file:line
@@ -199,9 +219,10 @@ filename_completer (struct cmd_list_element *ignore, char *text, char *word)
char **
location_completer (struct cmd_list_element *ignore, char *text, char *word)
{
- int n_syms = 0, n_files = 0;
- char ** fn_list = NULL;
- char ** list = NULL;
+ int n_syms = 0, o_syms = 0, n_files = 0;
+ char **fn_list = NULL;
+ char **list = NULL;
+ char **obj_sym_list = NULL;
char *p;
int quote_found = 0;
int quoted = *text == '\'' || *text == '"';
@@ -272,6 +293,10 @@ location_completer (struct cmd_list_element *ignore, char *text, char *word)
symbols as well as on files. */
if (colon)
{
+ obj_sym_list = make_objfile_symbol_completion_list (symbol_start,
+ word,
+ file_to_match);
+
list = make_file_symbol_completion_list (symbol_start, word,
file_to_match);
xfree (file_to_match);
@@ -283,17 +308,30 @@ location_completer (struct cmd_list_element *ignore, char *text, char *word)
name, they cannot be asking for completion on files. */
if (strcspn (text,
gdb_completer_file_name_break_characters) == text_len)
- fn_list = make_source_files_completion_list (text, text);
+ fn_list = make_files_completion_list (text, text);
}
- /* How many completions do we have in both lists? */
+ /* How many completions do we have in all lists? */
+ if (obj_sym_list)
+ for (; obj_sym_list[o_syms]; o_syms++)
+ ;
if (fn_list)
- for ( ; fn_list[n_files]; n_files++)
+ for (; fn_list[n_files]; n_files++)
;
if (list)
- for ( ; list[n_syms]; n_syms++)
+ for (; list[n_syms]; n_syms++)
;
+ /* Catenate obj_sym_list with list */
+ if (o_syms)
+ {
+ list = xrealloc (list, (n_syms + o_syms + 1) * sizeof (char *));
+ memcpy (list + n_syms, obj_sym_list, (o_syms + 1) * sizeof (char *));
+ xfree (obj_sym_list);
+ n_syms += o_syms;
+ o_syms = 0;
+ }
+
/* Make list[] large enough to hold both lists, then catenate
fn_list[] onto the end of list[]. */
if (n_syms && n_files)
@@ -305,20 +343,20 @@ location_completer (struct cmd_list_element *ignore, char *text, char *word)
else if (n_files)
{
/* If we only have file names as possible completion, we should
- bring them in sync with what rl_complete expects. The
- problem is that if the user types "break /foo/b TAB", and the
- possible completions are "/foo/bar" and "/foo/baz"
- rl_complete expects us to return "bar" and "baz", without the
- leading directories, as possible completions, because `word'
- starts at the "b". But we ignore the value of `word' when we
- call make_source_files_completion_list above (because that
- would not DTRT when the completion results in both symbols
- and file names), so make_source_files_completion_list returns
- the full "/foo/bar" and "/foo/baz" strings. This produces
- wrong results when, e.g., there's only one possible
- completion, because rl_complete will prepend "/foo/" to each
- candidate completion. The loop below removes that leading
- part. */
+ bring them in sync with what rl_complete expects. The
+ problem is that if the user types "break /foo/b TAB", and the
+ possible completions are "/foo/bar" and "/foo/baz"
+ rl_complete expects us to return "bar" and "baz", without the
+ leading directories, as possible completions, because `word'
+ starts at the "b". But we ignore the value of `word' when we
+ call make_files_completion_list above (because that
+ would not DTRT when the completion results in both symbols
+ and file names), so make_files_completion_list returns
+ the full "/foo/bar" and "/foo/baz" strings. This produces
+ wrong results when, e.g., there's only one possible
+ completion, because rl_complete will prepend "/foo/" to each
+ candidate completion. The loop below removes that leading
+ part. */
for (n_files = 0; fn_list[n_files]; n_files++)
{
memmove (fn_list[n_files], fn_list[n_files] + (word - text),
diff --git a/gdb/completer.h b/gdb/completer.h
index 8175304..ae3c98d 100644
--- a/gdb/completer.h
+++ b/gdb/completer.h
@@ -27,6 +27,8 @@ extern char **filename_completer (struct cmd_list_element *, char *, char *);
extern char **expression_completer (struct cmd_list_element *, char *, char *);
+extern char **files_completer (struct cmd_list_element *, char *, char *);
+
extern char **location_completer (struct cmd_list_element *, char *, char *);
extern char **command_completer (struct cmd_list_element *, char *, char *);
diff --git a/gdb/linespec.c b/gdb/linespec.c
index 75a74e2..e5b689e 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -1115,7 +1115,6 @@ locate_first_half (char **argptr, int *is_quote_enclosed)
return p;
}
-
/* Here's where we recognise an Objective-C Selector. An Objective C
@@ -1591,7 +1590,7 @@ symtab_from_filename (char **argptr, char *p, int is_quote_enclosed,
if (!have_full_symbols () && !have_partial_symbols ())
throw_error (NOT_FOUND_ERROR,
_("No symbol table is loaded. Use the \"file\" command."));
- throw_error (NOT_FOUND_ERROR, _("No source file named %s."), copy);
+ throw_error (NOT_FOUND_ERROR, _("No file named %s."), copy);
}
/* Discard the file name from the arg. */
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
index c2763c2..8fa8e07 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -28,6 +28,7 @@
#include "symtab.h"
#include "symfile.h"
#include "objfiles.h"
+#include "filenames.h"
#include "gdb-stabs.h"
#include "target.h"
#include "bcache.h"
@@ -53,6 +54,57 @@
#include "observer.h"
#include "complaints.h"
+struct objfile *
+lookup_objfile (const char *name)
+{
+ struct objfile *objfile;
+ char *real_path = NULL;
+ char *full_path = NULL;
+ char *found = 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);
+ }
+
+ ALL_OBJFILES (objfile)
+ {
+ if (FILENAME_CMP (name, objfile->name) == 0)
+ {
+ return objfile;
+ }
+
+ if (full_path != NULL)
+ {
+ if (FILENAME_CMP (full_path, xfullpath (objfile->name)) == 0)
+ {
+ return objfile;
+ }
+ }
+ if (real_path != NULL)
+ {
+ if (FILENAME_CMP (real_path, gdb_realpath (objfile->name)) == 0)
+ {
+ return objfile;
+ }
+ }
+ }
+
+ if (lbasename (name) == name)
+ ALL_OBJFILES (objfile)
+ {
+ if (FILENAME_CMP (lbasename (objfile->name), name) == 0)
+ return objfile;
+ }
+
+ return NULL;
+}
+
/* Prototypes for local functions */
static void objfile_alloc_data (struct objfile *objfile);
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
index c689622..354f5d8 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -533,6 +533,8 @@ extern void *objfile_data (struct objfile *objfile,
extern struct bfd *gdb_bfd_ref (struct bfd *abfd);
extern void gdb_bfd_unref (struct bfd *abfd);
+
+struct objfile *lookup_objfile (const char *name);
/* Traverse all object files in the current program space.
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 9c28fb0..c184328 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -2012,6 +2012,138 @@ print_transfer_performance (struct ui_file *stream,
ui_out_text (uiout, ".\n");
}
+/* Helper for list_symbol_files. */
+static void
+list_symbol_file (struct objfile *objfile)
+{
+ const char *name;
+ struct gdbarch *gdbarch;
+ struct obj_section *osect;
+
+ gdbarch = get_objfile_arch (objfile);
+ printf_filtered("\t%s\n", objfile->name);
+ ALL_OBJFILE_OSECTIONS (objfile, osect)
+ {
+ name = bfd_section_name (objfile->obfd, osect->the_bfd_section);
+ printf_filtered ("\t\t%s, [", name);
+ puts_filtered (paddress (gdbarch, obj_section_addr (osect)));
+ puts_filtered ("-");
+ puts_filtered (paddress (gdbarch, obj_section_endaddr (osect)));
+ puts_filtered (")\n");
+ }
+}
+
+/* List loaded symbol files .*/
+static void
+list_symbol_files (char *args, int from_tty)
+{
+ struct partial_symtab *ps;
+ struct objfile *objfile;
+ char *arg, **argv;
+ int argcnt = 0;
+ char *real_path = NULL;
+ char *full_path = NULL;
+
+ argv = gdb_buildargv (args);
+ make_cleanup_freeargv (argv);
+
+ if (args != NULL)
+ {
+ for (arg = argv[0], argcnt = 0; arg != NULL; arg = argv[++argcnt])
+ {
+ printf_filtered ("%s:\n", arg);
+ objfile = lookup_objfile (arg);
+ if (objfile)
+ {
+ list_symbol_file (objfile);
+ continue;
+ }
+
+ if (IS_ABSOLUTE_PATH (arg))
+ {
+ full_path = xfullpath (arg);
+ make_cleanup (xfree, full_path);
+ real_path = gdb_realpath (arg);
+ make_cleanup (xfree, real_path);
+ }
+
+ ALL_OBJFILES (objfile)
+ {
+ ALL_OBJFILE_PSYMTABS (objfile, ps)
+ {
+ if (FILENAME_CMP (arg, ps->filename) == 0)
+ {
+ list_symbol_file (ps->objfile);
+ break;
+ }
+
+ if (full_path != NULL)
+ {
+ psymtab_to_fullname (ps);
+ if (ps->fullname != NULL
+ && FILENAME_CMP (full_path, ps->fullname) == 0)
+ {
+ list_symbol_file (ps->objfile);
+ break;
+ }
+ }
+
+ if (real_path != NULL)
+ {
+ char *rp = NULL;
+ psymtab_to_fullname (ps);
+ if (ps->fullname != NULL)
+ {
+ rp = gdb_realpath (ps->fullname);
+ make_cleanup (xfree, rp);
+ }
+ if (rp != NULL
+ && FILENAME_CMP (real_path, rp) == 0)
+ {
+ list_symbol_file (ps->objfile);
+ break;
+ }
+ }
+ }
+
+ if (ps != NULL)
+ break;
+ }
+
+ if (objfile)
+ continue;
+
+ ALL_OBJFILES (objfile)
+ {
+ ALL_OBJFILE_PSYMTABS (objfile, ps)
+ {
+ if (lbasename (arg) == arg)
+ {
+ if (FILENAME_CMP (lbasename (ps->filename), arg) == 0)
+ {
+ list_symbol_file (ps->objfile);
+ break;
+ }
+ }
+ }
+
+ if (ps != NULL)
+ break;
+ }
+
+ if (objfile != NULL)
+ continue;
+
+ error ("No file matching %s.", arg);
+ }
+ }
+ else
+ {
+ ALL_OBJFILES (objfile)
+ list_symbol_file (objfile);
+ }
+}
+
/* This function allows the addition of incrementally linked object files.
It does not modify any state in the target, only in the debugger. */
/* Note: ezannoni 2000-04-13 This function/command used to have a
@@ -3803,6 +3935,10 @@ _initialize_symfile (void)
{
struct cmd_list_element *c;
+ c = add_cmd ("list-symbol-files", class_files, list_symbol_files, _("\
+List loaded symbol files\n."), &cmdlist);
+ set_cmd_completer (c, files_completer);
+
c = add_cmd ("symbol-file", class_files, symbol_file_command, _("\
Load symbol table from executable file FILE.\n\
The `file' command can also load symbol tables, as well as setting the file\n\
diff --git a/gdb/symtab.c b/gdb/symtab.c
index e69edb9..723d76a 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -165,6 +165,19 @@ lookup_symtab (const char *name)
char *real_path = NULL;
char *full_path = NULL;
+ /* First check if path is a symbol file name. We'll just return
+ the first symbol for the associated objfile, and
+ lookup_symbol_global will do the right thing when looking up
+ symbols. */
+ objfile = lookup_objfile (name);
+ if (objfile)
+ {
+ PSYMTAB_TO_SYMTAB (objfile->psymtabs);
+ s = objfile->symtabs;
+ if (s != NULL)
+ return s;
+ }
+
/* Here we are interested in canonicalizing an absolute path, not
absolutizing a relative path. */
if (IS_ABSOLUTE_PATH (name))
@@ -1720,9 +1733,16 @@ lookup_symbol_global (const char *name,
/* Call library-specific lookup procedure. */
objfile = lookup_objfile_from_block (block);
if (objfile != NULL)
- sym = solib_global_lookup (objfile, name, linkage_name, domain);
- if (sym != NULL)
- return sym;
+ {
+ sym = lookup_global_symbol_from_objfile (objfile,
+ name, linkage_name, domain);
+ if (sym != NULL)
+ return sym;
+
+ 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);
if (sym != NULL)
@@ -4083,6 +4103,165 @@ default_make_symbol_completion_list (char *text, char *word)
return (return_val);
}
+char **
+make_objfile_symbol_completion_list (char *text, char *word, char *objname)
+{
+ /* 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;
+ struct minimal_symbol *msymbol;
+ struct objfile *objfile;
+ struct block *b;
+ /* const struct block *surrounding_static_block, *surrounding_global_block; */
+ struct dict_iterator iter;
+ struct partial_symbol **psym;
+ /* The symbol we are completing on. Points in same buffer as text. */
+ char *sym_text;
+ /* Length of sym_text. */
+ int sym_text_len;
+
+ objfile = lookup_objfile (objname);
+ if (!objfile)
+ /* No such loaded symbol file. */
+ {
+ return_val = (char **) xmalloc (sizeof (char *));
+ return_val[0] = NULL;
+ return return_val;
+ }
+
+ /* Now look for the symbol we are supposed to complete on. */
+ {
+ char *p;
+ char quote_found;
+ char *quote_pos = NULL;
+
+ /* First see if this is a quoted string. */
+ quote_found = '\0';
+ for (p = text; *p != '\0'; ++p)
+ {
+ if (quote_found != '\0')
+ {
+ if (*p == quote_found)
+ /* Found close quote. */
+ quote_found = '\0';
+ else if (*p == '\\' && p[1] == quote_found)
+ /* A backslash followed by the quote character
+ doesn't end the string. */
+ ++p;
+ }
+ else if (*p == '\'' || *p == '"')
+ {
+ quote_found = *p;
+ quote_pos = p;
+ }
+ }
+ if (quote_found == '\'')
+ /* A string within single quotes can be a symbol, so complete on it. */
+ sym_text = quote_pos + 1;
+ else if (quote_found == '"')
+ /* A double-quoted string is never a symbol, nor does it make sense
+ to complete it any other way. */
+ {
+ return_val = (char **) xmalloc (sizeof (char *));
+ return_val[0] = NULL;
+ return return_val;
+ }
+ else
+ {
+ /* It is not a quoted string. Break it based on the characters
+ which are in symbols. */
+ while (p > text)
+ {
+ if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0'
+ || p[-1] == ':')
+ --p;
+ else
+ break;
+ }
+ sym_text = p;
+ }
+ }
+
+ sym_text_len = strlen (sym_text);
+
+ return_val_size = 100;
+ return_val_index = 0;
+ return_val = (char **) xmalloc ((return_val_size + 1) * sizeof (char *));
+ return_val[0] = NULL;
+
+ /* Look through the partial symtabs for all symbols which begin
+ by matching SYM_TEXT. Add each one that you find to the list. */
+
+ ALL_OBJFILE_PSYMTABS (objfile, ps)
+ {
+ /* If the psymtab's been read in we'll get it when we search
+ through the blockvector. */
+ if (ps->readin)
+ continue;
+
+ for (psym = objfile->global_psymbols.list + ps->globals_offset;
+ psym < (objfile->global_psymbols.list + ps->globals_offset
+ + ps->n_global_syms); psym++)
+ {
+ /* If interrupted, then quit. */
+ QUIT;
+ COMPLETION_LIST_ADD_SYMBOL (*psym, sym_text, sym_text_len, text,
+ word);
+ }
+
+ for (psym = objfile->static_psymbols.list + ps->statics_offset;
+ psym < (objfile->static_psymbols.list + ps->statics_offset
+ + ps->n_static_syms); psym++)
+ {
+ QUIT;
+ COMPLETION_LIST_ADD_SYMBOL (*psym, sym_text, sym_text_len, text,
+ word);
+ }
+ }
+
+ /* At this point scan through the misc symbol vectors and add each
+ symbol you find to the list. Eventually we want to ignore
+ anything that isn't a text symbol (everything else will be
+ handled by the psymtab code above). */
+
+ ALL_OBJFILE_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);
+ }
+
+ /* Go through the symtabs and check the externs and statics for
+ symbols which match. */
+
+ ALL_OBJFILE_SYMTABS (objfile, s) if ((s)->primary)
+ {
+ QUIT;
+ 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);
+ }
+ }
+
+ ALL_OBJFILE_SYMTABS (objfile, s) if ((s)->primary)
+ {
+ QUIT;
+ 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);
+ }
+ }
+
+ 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. */
@@ -4205,7 +4384,7 @@ make_file_symbol_completion_list (char *text, char *word, char *srcfile)
return (return_val);
}
-/* A helper function for make_source_files_completion_list. It adds
+/* A helper function for make_files_completion_list. It adds
another file name to a list of possible completions, growing the
list as necessary. */
@@ -4270,7 +4449,7 @@ not_interesting_fname (const char *fname)
the return value is an array which contains only a NULL pointer. */
char **
-make_source_files_completion_list (char *text, char *word)
+make_files_completion_list (char *text, char *word)
{
struct symtab *s;
struct partial_symtab *ps;
@@ -4287,78 +4466,103 @@ make_source_files_completion_list (char *text, char *word)
if (!have_full_symbols () && !have_partial_symbols ())
return list;
- ALL_SYMTABS (objfile, s)
+ ALL_OBJFILES (objfile)
{
- if (not_interesting_fname (s->filename))
- continue;
- if (!filename_seen (s->filename, 1, &first)
+ if (!filename_seen (objfile->name, 1, &first)
#if HAVE_DOS_BASED_FILE_SYSTEM
- && strncasecmp (s->filename, text, text_len) == 0
+ && strncasecmp (objfile->name, text, text_len) == 0
#else
- && strncmp (s->filename, text, text_len) == 0
+ && strncmp (objfile->name, text, text_len) == 0
#endif
- )
- {
- /* This file matches for a completion; add it to the current
- list of matches. */
- add_filename_to_list (s->filename, text, word,
- &list, &list_used, &list_alloced);
- }
- else
- {
- /* NOTE: We allow the user to type a base name when the
- debug info records leading directories, but not the other
- way around. This is what subroutines of breakpoint
- command do when they parse file names. */
- base_name = lbasename (s->filename);
- if (base_name != s->filename
- && !filename_seen (base_name, 1, &first)
+ )
+ {
+ add_filename_to_list (objfile->name, text, word,
+ &list, &list_used, &list_alloced);
+ }
+ else if (!filename_seen (lbasename (objfile->name), 1, &first)
#if HAVE_DOS_BASED_FILE_SYSTEM
- && strncasecmp (base_name, text, text_len) == 0
+ && strncasecmp (lbasename (objfile->name), text, text_len) == 0
#else
- && strncmp (base_name, text, text_len) == 0
+ && strncmp (lbasename (objfile->name), text, text_len) == 0
#endif
- )
- add_filename_to_list (base_name, text, word,
- &list, &list_used, &list_alloced);
- }
- }
+ )
+ {
+ add_filename_to_list (lbasename (objfile->name), text, word,
+ &list, &list_used, &list_alloced);
+ }
- ALL_PSYMTABS (objfile, ps)
- {
- if (not_interesting_fname (ps->filename))
- continue;
- if (!ps->readin)
- {
- if (!filename_seen (ps->filename, 1, &first)
+ ALL_OBJFILE_SYMTABS (objfile, s)
+ {
+ if (not_interesting_fname (s->filename))
+ continue;
+ if (!filename_seen (s->filename, 1, &first)
#if HAVE_DOS_BASED_FILE_SYSTEM
- && strncasecmp (ps->filename, text, text_len) == 0
+ && strncasecmp (s->filename, text, text_len) == 0
#else
- && strncmp (ps->filename, text, text_len) == 0
+ && strncmp (s->filename, text, text_len) == 0
#endif
- )
- {
- /* This file matches for a completion; add it to the
- current list of matches. */
- add_filename_to_list (ps->filename, text, word,
- &list, &list_used, &list_alloced);
+ )
+ {
+ /* This file matches for a completion; add it to the current
+ list of matches. */
+ add_filename_to_list (s->filename, text, word,
+ &list, &list_used, &list_alloced);
+ }
+ else
+ {
+ /* NOTE: We allow the user to type a base name when the
+ debug info records leading directories, but not the other
+ way around. This is what subroutines of breakpoint
+ command do when they parse file names. */
+ base_name = lbasename (s->filename);
+ if (base_name != s->filename
+ && !filename_seen (base_name, 1, &first)
+#if HAVE_DOS_BASED_FILE_SYSTEM
+ && strncasecmp (base_name, text, text_len) == 0
+#else
+ && strncmp (base_name, text, text_len) == 0
+#endif
+ )
+ add_filename_to_list (base_name, text, word,
+ &list, &list_used, &list_alloced);
+ }
+ }
- }
- else
- {
- base_name = lbasename (ps->filename);
- if (base_name != ps->filename
- && !filename_seen (base_name, 1, &first)
+ ALL_OBJFILE_PSYMTABS (objfile, ps)
+ {
+ if (not_interesting_fname (ps->filename))
+ continue;
+ if (!ps->readin)
+ {
+ if (!filename_seen (ps->filename, 1, &first)
#if HAVE_DOS_BASED_FILE_SYSTEM
- && strncasecmp (base_name, text, text_len) == 0
+ && strncasecmp (ps->filename, text, text_len) == 0
#else
- && strncmp (base_name, text, text_len) == 0
+ && strncmp (ps->filename, text, text_len) == 0
#endif
- )
- add_filename_to_list (base_name, text, word,
- &list, &list_used, &list_alloced);
- }
- }
+ )
+ {
+ /* This file matches for a completion; add it to the
+ current list of matches. */
+ add_filename_to_list (ps->filename, text, word,
+ &list, &list_used, &list_alloced);
+ }
+ else
+ {
+ base_name = lbasename (ps->filename);
+ if (base_name != ps->filename
+ && !filename_seen (base_name, 1, &first)
+#if HAVE_DOS_BASED_FILE_SYSTEM
+ && strncasecmp (base_name, text, text_len) == 0
+#else
+ && strncmp (base_name, text, text_len) == 0
+#endif
+ )
+ add_filename_to_list (base_name, text, word,
+ &list, &list_used, &list_alloced);
+ }
+ }
+ }
}
return list;
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 167dfe8..eb2544d 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -1292,9 +1292,11 @@ extern char **make_symbol_completion_list (char *, char *);
extern char **make_symbol_completion_list_fn (struct cmd_list_element *,
char *, char *);
+extern char **make_objfile_symbol_completion_list (char *, char *, char *);
+
extern char **make_file_symbol_completion_list (char *, char *, char *);
-extern char **make_source_files_completion_list (char *, char *);
+extern char **make_files_completion_list (char *, char *);
/* symtab.c */
--
1.7.0.4