/* Generic symbol file reading for the GNU debugger, GDB.
- Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
+ Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
This file is part of GDB.
#include "objfiles.h"
#include "gdbcmd.h"
#include "breakpoint.h"
+#include "language.h"
+#include "complaints.h"
+#include "demangle.h"
#include <obstack.h>
#include <assert.h>
#include <sys/stat.h>
#include <ctype.h>
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
/* Global variables owned by this file */
int readnow_symbol_files; /* Read full symbols immediately */
+struct complaint oldsyms_complaint = {
+ "Replacing old symbols for `%s'", 0, 0
+};
+
+struct complaint empty_symtab_complaint = {
+ "Empty symbol table found for `%s'", 0, 0
+};
+
/* External variables and functions referenced. */
extern int info_verbose;
/* Functions this file defines */
+static void
+set_initial_language PARAMS ((void));
+
static void
load_command PARAMS ((char *, int));
static void
find_sym_fns PARAMS ((struct objfile *));
-void
-clear_symtab_users_once PARAMS ((void));
-
/* List of all available sym_fns. On gdb startup, each object file reader
calls add_symtab_fns() to register information on each format it is
prepared to read. */
int symbol_reloading = 0;
#endif
-/* Structure to manage complaints about symbol file contents. */
-
-struct complaint complaint_root[1] = {
- {(char *) 0, 0, complaint_root},
-};
-
-/* Some actual complaints. */
-
-struct complaint oldsyms_complaint = {
- "Replacing old symbols for `%s'", 0, 0 };
-
-struct complaint empty_symtab_complaint = {
- "Empty symbol table found for `%s'", 0, 0 };
-
\f
-/* In the following sort, we always make sure that
- register debug symbol declarations always come before regular
- debug symbol declarations (as might happen when parameters are
- then put into registers by the compiler).
-
- Since this function is called from within qsort, in an ANSI environment
+/* Since this function is called from within qsort, in an ANSI environment
it must conform to the prototype for qsort, which specifies that the
comparison function takes two "void *" pointers. */
const PTR s2p;
{
register struct symbol **s1, **s2;
- register int namediff;
s1 = (struct symbol **) s1p;
s2 = (struct symbol **) s2p;
- /* Compare the initial characters. */
- namediff = SYMBOL_NAME (*s1)[0] - SYMBOL_NAME (*s2)[0];
- if (namediff != 0) return namediff;
-
- /* If they match, compare the rest of the names. */
- namediff = strcmp (SYMBOL_NAME (*s1), SYMBOL_NAME (*s2));
- if (namediff != 0) return namediff;
-
- /* For symbols of the same name, registers should come first. */
- return ((SYMBOL_CLASS (*s2) == LOC_REGISTER)
- - (SYMBOL_CLASS (*s1) == LOC_REGISTER));
+ return (STRCMP (SYMBOL_NAME (*s1), SYMBOL_NAME (*s2)));
}
/*
}
else
{
- return (strcmp (st1 + 2, st2 + 2));
+ return (STRCMP (st1 + 2, st2 + 2));
}
}
struct obstack *obstackp;
{
register char *p = (char *) obstack_alloc (obstackp, size + 1);
- /* Open-coded bcopy--saves function call time.
+ /* Open-coded memcpy--saves function call time.
These strings are usually short. */
{
register char *p1 = ptr;
{
struct section_offsets *section_offsets;
asection *lowest_sect;
-
- /* There is a distinction between having no symbol table
- (we refuse to read the file, leaving the old set of symbols around)
- and having no debugging symbols in your symbol table (we read
- the file and end up with a mostly empty symbol table).
-
- FIXME: This strategy works correctly when the debugging symbols are
- intermixed with "normal" symbols. However, when the debugging symbols
- are separate, such as with ELF/DWARF, it is perfectly plausible for
- the symbol table to be missing but still have all the DWARF info
- intact. Thus in general it is wrong to assume that having no symbol
- table implies no debugging information. */
-
- if (!(bfd_get_file_flags (objfile -> obfd) & HAS_SYMS))
- return;
+ struct cleanup *old_chain;
init_entry_point_info (objfile);
find_sym_fns (objfile);
+ /* Make sure that partially constructed symbol tables will be cleaned up
+ if an error occurs during symbol reading. */
+ old_chain = make_cleanup (free_objfile, objfile);
+
if (mainline)
{
+ /* We will modify the main symbol table, make sure that all its users
+ will be cleaned up if an error occurs during symbol reading. */
+ make_cleanup (clear_symtab_users, 0);
+
/* Since no error yet, throw away the old symbol table. */
if (symfile_objfile != NULL)
warning ("no loadable sections found in added symbol-file %s",
objfile->name);
else if (0 == bfd_get_section_name (objfile->obfd, lowest_sect)
- || 0 != strcmp(".text",
+ || !STREQ (".text",
bfd_get_section_name (objfile->obfd, lowest_sect)))
warning ("Lowest section in %s is %s at 0x%x",
objfile->name,
(*objfile -> sf -> sym_init) (objfile);
clear_complaints (1, verbo);
+
+ /* If objfile->sf->sym_offsets doesn't set this, we don't care
+ (currently). */
+ objfile->num_sections = 0; /* krp-FIXME: why zero? */
section_offsets = (*objfile -> sf -> sym_offsets) (objfile, addr);
+ objfile->section_offsets = section_offsets;
+
+#ifndef IBM6000_TARGET
+ /* This is a SVR4/SunOS specific hack, I think. In any event, it
+ screws RS/6000. sym_offsets should be doing this sort of thing,
+ because it knows the mapping between bfd sections and
+ section_offsets. */
+ /* This is a hack. As far as I can tell, section offsets are not
+ target dependent. They are all set to addr with a couple of
+ exceptions. The exceptions are sysvr4 shared libraries, whose
+ offsets are kept in solib structures anyway and rs6000 xcoff
+ which handles shared libraries in a completely unique way.
+
+ Section offsets are built similarly, except that they are built
+ by adding addr in all cases because there is no clear mapping
+ from section_offsets into actual sections. Note that solib.c
+ has a different algorythm for finding section offsets.
+
+ These should probably all be collapsed into some target
+ independent form of shared library support. FIXME. */
+
+ if (addr)
+ {
+ struct obj_section *s;
+
+ for (s = objfile->sections; s < objfile->sections_end; ++s)
+ {
+ s->addr -= s->offset;
+ s->addr += addr;
+ s->endaddr -= s->offset;
+ s->endaddr += addr;
+ s->offset += addr;
+ }
+ }
+#endif /* not IBM6000_TARGET */
+
(*objfile -> sf -> sym_read) (objfile, section_offsets, mainline);
/* Don't allow char * to have a typename (else would get caddr_t.) */
that this does not mean we found any symbols... */
objfile -> flags |= OBJF_SYMS;
+
+ /* Discard cleanups as symbol reading was successful. */
+
+ discard_cleanups (old_chain);
}
-/* Perform required actions immediately after either reading in the initial
+/* Perform required actions after either reading in the initial
symbols for a new objfile, or mapping in the symbols from a reusable
objfile. */
int mainline;
int verbo;
{
+
+ /* If this is the main symbol file we have to clean up all users of the
+ old main symbol file. Otherwise it is sufficient to fixup all the
+ breakpoints that may have been redefined by this symbol file. */
if (mainline)
{
/* OK, make it the "real" symbol file. */
symfile_objfile = objfile;
- }
- /* If we have wiped out any old symbol tables, clean up. */
- clear_symtab_users_once ();
+ clear_symtab_users ();
+ }
+ else
+ {
+ breakpoint_re_set ();
+ }
/* We're done reading the symbol file; finish off complaints. */
clear_complaints (0, verbo);
-
- /* Fixup all the breakpoints that may have been redefined by this
- symbol file. */
-
- breakpoint_re_set ();
}
/* Process a symbol file, as either the main file or as a dynamically
struct partial_symtab *psymtab;
bfd *abfd;
- /* Open a bfd for the file and then check to see if the file has a
- symbol table. There is a distinction between having no symbol table
- (we refuse to read the file, leaving the old set of symbols around)
- and having no debugging symbols in the symbol table (we read the file
- and end up with a mostly empty symbol table, but with lots of stuff in
- the minimal symbol table). We need to make the decision about whether
- to continue with the file before allocating and building a objfile.
-
- FIXME: This strategy works correctly when the debugging symbols are
- intermixed with "normal" symbols. However, when the debugging symbols
- are separate, such as with ELF/DWARF, it is perfectly plausible for
- the symbol table to be missing but still have all the DWARF info
- intact. Thus in general it is wrong to assume that having no symbol
- table implies no debugging information. */
+ /* Open a bfd for the file, and give user a chance to burp if we'd be
+ interactively wiping out any existing symbols. */
abfd = symfile_bfd_open (name);
- if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
- {
- error ("%s has no symbol-table", name);
- }
if ((have_full_symbols () || have_partial_symbols ())
&& mainline
&& from_tty
&& !query ("Load new symbol table from \"%s\"? ", name))
error ("Not confirmed.");
-
- /* Getting new symbols may change our opinion about what is
- frameless. */
-
- reinit_frame_cache ();
objfile = allocate_objfile (abfd, mapped);
syms_from_objfile (objfile, addr, mainline, from_tty);
}
- new_symfile_objfile (objfile, mainline, from_tty);
-
/* We now have at least a partial symbol table. Check to see if the
user requested that all symbols be read on initial access via either
the gdb startup command line or on a per symbol file basis. Expand
fflush (stdout);
}
+ new_symfile_objfile (objfile, mainline, from_tty);
+
+ /* Getting new symbols may change our opinion about what is
+ frameless. */
+
+ reinit_frame_cache ();
+
return (objfile);
}
error ("Not confirmed.");
free_all_objfiles ();
symfile_objfile = NULL;
- current_source_symtab = NULL;
- current_source_line = 0;
if (from_tty)
{
- printf_filtered ("No symbol file now.\n");
+ printf ("No symbol file now.\n");
}
}
else
cleanups = make_cleanup (freeargv, (char *) argv);
while (*argv != NULL)
{
- if (strcmp (*argv, "-mapped") == 0)
+ if (STREQ (*argv, "-mapped"))
{
mapped = 1;
}
- else if (strcmp (*argv, "-readnow") == 0)
+ else if (STREQ (*argv, "-readnow"))
{
readnow = 1;
}
else
{
symbol_file_add (name, from_tty, (CORE_ADDR)0, 1, mapped, readnow);
+ set_initial_language ();
}
do_cleanups (cleanups);
}
}
+/* Set the initial language.
+
+ A better solution would be to record the language in the psymtab when reading
+ partial symbols, and then use it (if known) to set the language. This would
+ be a win for formats that encode the language in an easily discoverable place,
+ such as DWARF. For stabs, we can jump through hoops looking for specially
+ named symbols or try to intuit the language from the specific type of stabs
+ we find, but we can't do that until later when we read in full symbols.
+ FIXME. */
+
+static void
+set_initial_language ()
+{
+ struct partial_symtab *pst;
+ enum language lang = language_unknown;
+
+ pst = find_main_psymtab ();
+ if (pst != NULL)
+ {
+ if (pst -> filename != NULL)
+ {
+ lang = deduce_language_from_filename (pst -> filename);
+ }
+ if (lang == language_unknown)
+ {
+ /* Make C the default language */
+ lang = language_c;
+ }
+ set_language (lang);
+ expected_language = current_language; /* Don't warn the user */
+ }
+}
+
/* Open file specified by NAME and hand it off to BFD for preliminary
analysis. Result is a newly initialized bfd *, which includes a newly
malloc'd` copy of NAME (tilde-expanded and made absolute).
name = tilde_expand (name); /* Returns 1st new malloc'd copy */
/* Look down path for it, allocate 2nd new malloc'd copy. */
- desc = openp (getenv ("PATH"), 1, name, O_RDONLY, 0, &absolute_name);
+ desc = openp (getenv ("PATH"), 1, name, O_RDONLY | O_BINARY, 0, &absolute_name);
if (desc < 0)
{
make_cleanup (free, name);
name = absolute_name; /* Keep 2nd malloc'd copy in bfd */
/* It'll be freed in free_objfile(). */
- sym_bfd = bfd_fdopenr (name, NULL, desc);
+ sym_bfd = bfd_fdopenr (name, gnutarget, desc);
if (!sym_bfd)
{
close (desc);
error ("\"%s\": can't open to read symbols: %s.", name,
bfd_errmsg (bfd_error));
}
+ sym_bfd->cacheable = true;
if (!bfd_check_format (sym_bfd, bfd_object))
{
target_load (arg, from_tty);
}
+/* This version of "load" should be usable for any target. Currently
+ it is just used for remote targets, not inftarg.c or core files,
+ on the theory that only in that case is it useful.
+
+ Avoiding xmodem and the like seems like a win (a) because we don't have
+ to worry about finding it, and (b) On VMS, fork() is very slow and so
+ we don't want to run a subprocess. On the other hand, I'm not sure how
+ performance compares. */
+void
+generic_load (filename, from_tty)
+ char *filename;
+ int from_tty;
+{
+ struct cleanup *old_cleanups;
+ asection *s;
+ bfd *loadfile_bfd = bfd_openr (filename, gnutarget);
+ if (loadfile_bfd == NULL)
+ {
+ perror_with_name (filename);
+ return;
+ }
+ old_cleanups = make_cleanup (bfd_close, loadfile_bfd);
+
+ if (!bfd_check_format (loadfile_bfd, bfd_object))
+ {
+ error ("\"%s\" is not an object file: %s", filename,
+ bfd_errmsg (bfd_error));
+ }
+
+ for (s = loadfile_bfd->sections; s; s = s->next)
+ {
+ if (s->flags & SEC_LOAD)
+ {
+ bfd_size_type size;
+
+ size = bfd_get_section_size_before_reloc (s);
+ if (size > 0)
+ {
+ char *buffer;
+ struct cleanup *old_chain;
+ bfd_vma vma;
+
+ buffer = xmalloc (size);
+ old_chain = make_cleanup (free, buffer);
+
+ vma = bfd_get_section_vma (loadfile_bfd, s);
+
+ /* Is this really necessary? I guess it gives the user something
+ to look at during a long download. */
+ printf_filtered ("Loading section %s, size 0x%x vma 0x%x\n",
+ bfd_get_section_name (loadfile_bfd, s),
+ size, vma);
+
+ bfd_get_section_contents (loadfile_bfd, s, buffer, 0, size);
+
+ target_write_memory (vma, buffer, size);
+
+ do_cleanups (old_chain);
+ }
+ }
+ }
+
+ /* We were doing this in remote-mips.c, I suspect it is right
+ for other targets too. */
+ write_pc (loadfile_bfd->start_address);
+
+ /* FIXME: are we supposed to call symbol_file_add or not? According to
+ a comment from remote-mips.c (where a call to symbol_file_add was
+ commented out), making the call confuses GDB if more than one file is
+ loaded in. remote-nindy.c had no call to symbol_file_add, but remote-vx.c
+ does. */
+
+ do_cleanups (old_cleanups);
+}
+
/* This function allows the addition of incrementally linked object files.
It does not modify any state in the target, only in the debugger. */
{
name = arg;
}
- else if (strcmp (arg, "-mapped") == 0)
+ else if (STREQ (arg, "-mapped"))
{
mapped = 1;
}
- else if (strcmp (arg, "-readnow") == 0)
+ else if (STREQ (arg, "-readnow"))
{
readnow = 1;
}
if (reread_one)
breakpoint_re_set ();
}
-\f
-/* Functions to handle complaints during symbol reading. */
-
-/* How many complaints about a particular thing should be printed before
- we stop whining about it? Default is no whining at all, since so many
- systems have ill-constructed symbol files. */
-
-static unsigned stop_whining = 0;
-
-/* Should each complaint be self explanatory, or should we assume that
- a series of complaints is being produced?
- case 0: self explanatory message.
- case 1: First message of a series that must start off with explanation.
- case 2: Subsequent message, when user already knows we are reading
- symbols and we can just state our piece. */
-static int complaint_series = 0;
-
-/* Print a complaint about the input symbols, and link the complaint block
- into a chain for later handling. */
-
-void
-complain (complaint, val)
- struct complaint *complaint;
- char *val;
-{
- complaint->counter++;
- if (complaint->next == 0) {
- complaint->next = complaint_root->next;
- complaint_root->next = complaint;
- }
- if (complaint->counter > stop_whining)
- return;
- wrap_here ("");
-
- switch (complaint_series + (info_verbose << 1)) {
-
- /* Isolated messages, must be self-explanatory. */
- case 0:
- puts_filtered ("During symbol reading, ");
- wrap_here("");
- printf_filtered (complaint->message, val);
- puts_filtered (".\n");
- break;
-
- /* First of a series, without `set verbose'. */
- case 1:
- puts_filtered ("During symbol reading...");
- printf_filtered (complaint->message, val);
- puts_filtered ("...");
- wrap_here("");
- complaint_series++;
- break;
-
- /* Subsequent messages of a series, or messages under `set verbose'.
- (We'll already have produced a "Reading in symbols for XXX..." message
- and will clean up at the end with a newline.) */
- default:
- printf_filtered (complaint->message, val);
- puts_filtered ("...");
- wrap_here("");
- }
-}
-
-/* Clear out all complaint counters that have ever been incremented.
- If sym_reading is 1, be less verbose about successive complaints,
- since the messages are appearing all together during a command that
- reads symbols (rather than scattered around as psymtabs get fleshed
- out into symtabs at random times). If noisy is 1, we are in a
- noisy symbol reading command, and our caller will print enough
- context for the user to figure it out. */
-
-void
-clear_complaints (sym_reading, noisy)
- int sym_reading;
- int noisy;
-{
- struct complaint *p;
-
- for (p = complaint_root->next; p != complaint_root; p = p->next)
- p->counter = 0;
-
- if (!sym_reading && !noisy && complaint_series > 1) {
- /* Terminate previous series, since caller won't. */
- puts_filtered ("\n");
- }
-
- complaint_series = sym_reading? 1 + noisy: 0;
-}
\f
enum language
deduce_language_from_filename (filename)
char *filename;
{
- char *c = strrchr (filename, '.');
+ char *c;
- if (!c) ; /* Get default. */
- else if(!strcmp(c,".mod"))
- return language_m2;
- else if(!strcmp(c,".c"))
- return language_c;
- else if(!strcmp(c,".cc") || !strcmp(c,".C"))
- return language_cplus;
+ if (0 == filename)
+ ; /* Get default */
+ else if (0 == (c = strrchr (filename, '.')))
+ ; /* Get default. */
+ else if(STREQ(c,".mod"))
+ return language_m2;
+ else if(STREQ(c,".c"))
+ return language_c;
+ else if(STREQ(c,".cc") || STREQ(c,".C"))
+ return language_cplus;
+ else if(STREQ(c,".ch") || STREQ(c,".c186") || STREQ(c,".c286"))
+ return language_chill;
return language_unknown; /* default */
}
}
\f
+/* Reset all data structures in gdb which may contain references to symbol
+ table date. */
+
+void
+clear_symtab_users ()
+{
+ /* Someday, we should do better than this, by only blowing away
+ the things that really need to be blown. */
+ clear_value_history ();
+ clear_displays ();
+ clear_internalvars ();
+ breakpoint_re_set ();
+ set_default_breakpoint (0, 0, 0, 0);
+ current_source_symtab = 0;
+ current_source_line = 0;
+}
+
/* clear_symtab_users_once:
This function is run after symbol reading, or from a cleanup.
reading, is because the cleanup protects us in case of errors, but is
discarded if symbol reading is successful. */
+#if 0
+/* FIXME: As free_named_symtabs is currently a big noop this function
+ is no longer needed. */
+static void
+clear_symtab_users_once PARAMS ((void));
+
static int clear_symtab_users_queued;
static int clear_symtab_users_done;
-void
+static void
clear_symtab_users_once ()
{
/* Enforce once-per-`do_cleanups'-semantics */
return;
clear_symtab_users_done = clear_symtab_users_queued;
- printf_filtered ("Resetting debugger state after updating old symbol tables\n");
-
- /* Someday, we should do better than this, by only blowing away
- the things that really need to be blown. */
- clear_value_history ();
- clear_displays ();
- clear_internalvars ();
- breakpoint_re_set ();
- set_default_breakpoint (0, 0, 0, 0);
- current_source_symtab = 0;
+ clear_symtab_users ();
}
+#endif
/* Delete the specified psymtab, and any others that reference it. */
cashier_psymtab (pst)
struct partial_symtab *pst;
{
- struct partial_symtab *ps, *pprev;
+ struct partial_symtab *ps, *pprev = NULL;
int i;
/* Find its previous psymtab in the chain */
again2:
for (ps = partial_symtab_list; ps; ps = ps->next) {
- if (!strcmp (name, ps->filename)) {
+ if (STREQ (name, ps->filename)) {
cashier_psymtab (ps); /* Blow it away...and its little dog, too. */
goto again2; /* Must restart, chain has been munged */
}
for (s = symtab_list; s; s = s->next)
{
- if (!strcmp (name, s->filename))
+ if (STREQ (name, s->filename))
break;
prev = s;
}
/* Debugging versions of functions that are usually inline macros
(see symfile.h). */
-#if 0 /* Don't quite work nowadays... */
+#if !INLINE_ADD_PSYMBOL
/* Add a symbol with a long value to a psymtab.
Since one arg is a struct, we pass in a ptr and deref it (sigh). */
void
-add_psymbol_to_list (name, namelength, namespace, class, list, val)
+add_psymbol_to_list (name, namelength, namespace, class, list, val, language,
+ objfile)
char *name;
int namelength;
enum namespace namespace;
enum address_class class;
struct psymbol_allocation_list *list;
long val;
+ enum language language;
+ struct objfile *objfile;
{
- ADD_PSYMBOL_VT_TO_LIST (name, namelength, namespace, class, (*list), val,
- SYMBOL_VALUE);
+ register struct partial_symbol *psym;
+ register char *demangled_name;
+
+ if (list->next >= list->list + list->size)
+ {
+ extend_psymbol_list (list,objfile);
+ }
+ psym = list->next++;
+
+ SYMBOL_NAME (psym) =
+ (char *) obstack_alloc (&objfile->psymbol_obstack, namelength + 1);
+ memcpy (SYMBOL_NAME (psym), name, namelength);
+ SYMBOL_NAME (psym)[namelength] = '\0';
+ SYMBOL_VALUE (psym) = val;
+ SYMBOL_LANGUAGE (psym) = language;
+ PSYMBOL_NAMESPACE (psym) = namespace;
+ PSYMBOL_CLASS (psym) = class;
+ SYMBOL_INIT_DEMANGLED_NAME (psym, &objfile->psymbol_obstack);
}
/* Add a symbol with a CORE_ADDR value to a psymtab. */
void
-add_psymbol_addr_to_list (name, namelength, namespace, class, list, val)
+add_psymbol_addr_to_list (name, namelength, namespace, class, list, val,
+ language, objfile)
char *name;
int namelength;
enum namespace namespace;
enum address_class class;
struct psymbol_allocation_list *list;
CORE_ADDR val;
+ enum language language;
+ struct objfile *objfile;
{
- ADD_PSYMBOL_VT_TO_LIST (name, namelength, namespace, class, (*list), val,
- SYMBOL_VALUE_ADDRESS);
+ register struct partial_symbol *psym;
+ register char *demangled_name;
+
+ if (list->next >= list->list + list->size)
+ {
+ extend_psymbol_list (list,objfile);
+ }
+ psym = list->next++;
+
+ SYMBOL_NAME (psym) =
+ (char *) obstack_alloc (&objfile->psymbol_obstack, namelength + 1);
+ memcpy (SYMBOL_NAME (psym), name, namelength);
+ SYMBOL_NAME (psym)[namelength] = '\0';
+ SYMBOL_VALUE_ADDRESS (psym) = val;
+ SYMBOL_LANGUAGE (psym) = language;
+ PSYMBOL_NAMESPACE (psym) = namespace;
+ PSYMBOL_CLASS (psym) = class;
+ SYMBOL_INIT_DEMANGLED_NAME (psym, &objfile->psymbol_obstack);
}
-#endif /* 0 */
+#endif /* !INLINE_ADD_PSYMBOL */
+
\f
void
_initialize_symfile ()
{
-
- add_com ("symbol-file", class_files, symbol_file_command,
+ struct cmd_list_element *c;
+
+ 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\
-to execute.");
+to execute.", &cmdlist);
+ c->completer = filename_completer;
- add_com ("add-symbol-file", class_files, add_symbol_file_command,
+ c = add_cmd ("add-symbol-file", class_files, add_symbol_file_command,
"Load the symbols from FILE, assuming FILE has been dynamically loaded.\n\
-The second argument provides the starting address of the file's text.");
+The second argument provides the starting address of the file's text.",
+ &cmdlist);
+ c->completer = filename_completer;
- add_com ("load", class_files, load_command,
+ c = add_cmd ("load", class_files, load_command,
"Dynamically load FILE into the running program, and record its symbols\n\
-for access from GDB.");
-
- add_show_from_set
- (add_set_cmd ("complaints", class_support, var_zinteger,
- (char *)&stop_whining,
- "Set max number of complaints about incorrect symbols.",
- &setlist),
- &showlist);
+for access from GDB.", &cmdlist);
+ c->completer = filename_completer;
add_show_from_set
(add_set_cmd ("symbol-reloading", class_support, var_boolean,