2001-12-20 Michael Snyder <msnyder@redhat.com>
[external/binutils.git] / gdb / maint.c
1 /* Support for GDB maintenance commands.
2    Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001
3    Free Software Foundation, Inc.
4    Written by Fred Fish at Cygnus Support.
5
6    This file is part of GDB.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 59 Temple Place - Suite 330,
21    Boston, MA 02111-1307, USA.  */
22
23
24 #include "defs.h"
25 #include <ctype.h>
26 #include <signal.h>
27 #include "command.h"
28 #include "gdbcmd.h"
29 #include "symtab.h"
30 #include "gdbtypes.h"
31 #include "demangle.h"
32 #include "gdbcore.h"
33 #include "expression.h"         /* For language.h */
34 #include "language.h"
35 #include "symfile.h"
36 #include "objfiles.h"
37 #include "value.h"
38
39 extern void _initialize_maint_cmds (void);
40
41 static void maintenance_command (char *, int);
42
43 static void maintenance_dump_me (char *, int);
44
45 static void maintenance_internal_error (char *args, int from_tty);
46
47 static void maintenance_demangle (char *, int);
48
49 static void maintenance_time_display (char *, int);
50
51 static void maintenance_space_display (char *, int);
52
53 static void maintenance_info_command (char *, int);
54
55 static void print_section_table (bfd *, asection *, void *);
56
57 static void maintenance_info_sections (char *, int);
58
59 static void maintenance_print_command (char *, int);
60
61 static void maintenance_do_deprecate (char *, int);
62
63 /* Set this to the maximum number of seconds to wait instead of waiting forever
64    in target_wait().  If this timer times out, then it generates an error and
65    the command is aborted.  This replaces most of the need for timeouts in the
66    GDB test suite, and makes it possible to distinguish between a hung target
67    and one with slow communications.  */
68
69 int watchdog = 0;
70
71 /*
72
73    LOCAL FUNCTION
74
75    maintenance_command -- access the maintenance subcommands
76
77    SYNOPSIS
78
79    void maintenance_command (char *args, int from_tty)
80
81    DESCRIPTION
82
83  */
84
85 static void
86 maintenance_command (char *args, int from_tty)
87 {
88   printf_unfiltered ("\"maintenance\" must be followed by the name of a maintenance command.\n");
89   help_list (maintenancelist, "maintenance ", -1, gdb_stdout);
90 }
91
92 #ifndef _WIN32
93 /* ARGSUSED */
94 static void
95 maintenance_dump_me (char *args, int from_tty)
96 {
97   if (query ("Should GDB dump core? "))
98     {
99 #ifdef __DJGPP__
100       /* SIGQUIT by default is ignored, so use SIGABRT instead.  */
101       signal (SIGABRT, SIG_DFL);
102       kill (getpid (), SIGABRT);
103 #else
104       signal (SIGQUIT, SIG_DFL);
105       kill (getpid (), SIGQUIT);
106 #endif
107     }
108 }
109 #endif
110
111 /* Stimulate the internal error mechanism that GDB uses when an
112    internal problem is detected.  Allows testing of the mechanism.
113    Also useful when the user wants to drop a core file but not exit
114    GDB. */
115
116 static void
117 maintenance_internal_error (char *args, int from_tty)
118 {
119   internal_error (__FILE__, __LINE__,
120                   "internal maintenance");
121 }
122
123 /* Someday we should allow demangling for things other than just
124    explicit strings.  For example, we might want to be able to specify
125    the address of a string in either GDB's process space or the
126    debuggee's process space, and have gdb fetch and demangle that
127    string.  If we have a char* pointer "ptr" that points to a string,
128    we might want to be able to given just the name and have GDB
129    demangle and print what it points to, etc.  (FIXME) */
130
131 static void
132 maintenance_demangle (char *args, int from_tty)
133 {
134   char *demangled;
135
136   if (args == NULL || *args == '\0')
137     {
138       printf_unfiltered ("\"maintenance demangle\" takes an argument to demangle.\n");
139     }
140   else
141     {
142       demangled = cplus_demangle (args, DMGL_ANSI | DMGL_PARAMS);
143       if (demangled != NULL)
144         {
145           printf_unfiltered ("%s\n", demangled);
146           xfree (demangled);
147         }
148       else
149         {
150           printf_unfiltered ("Can't demangle \"%s\"\n", args);
151         }
152     }
153 }
154
155 static void
156 maintenance_time_display (char *args, int from_tty)
157 {
158   extern int display_time;
159
160   if (args == NULL || *args == '\0')
161     printf_unfiltered ("\"maintenance time\" takes a numeric argument.\n");
162   else
163     display_time = strtol (args, NULL, 10);
164 }
165
166 static void
167 maintenance_space_display (char *args, int from_tty)
168 {
169   extern int display_space;
170
171   if (args == NULL || *args == '\0')
172     printf_unfiltered ("\"maintenance space\" takes a numeric argument.\n");
173   else
174     display_space = strtol (args, NULL, 10);
175 }
176
177 /* The "maintenance info" command is defined as a prefix, with
178    allow_unknown 0.  Therefore, its own definition is called only for
179    "maintenance info" with no args.  */
180
181 /* ARGSUSED */
182 static void
183 maintenance_info_command (char *arg, int from_tty)
184 {
185   printf_unfiltered ("\"maintenance info\" must be followed by the name of an info command.\n");
186   help_list (maintenanceinfolist, "maintenance info ", -1, gdb_stdout);
187 }
188
189 static int 
190 match_bfd_flags (char *string, flagword flags)
191 {
192   if (flags & SEC_ALLOC)
193     if (strstr (string, "ALLOC"))
194       return 1;
195   if (flags & SEC_LOAD)
196     if (strstr (string, "LOAD"))
197       return 1;
198   if (flags & SEC_RELOC)
199     if (strstr (string, "RELOC"))
200       return 1;
201   if (flags & SEC_READONLY)
202     if (strstr (string, "READONLY"))
203       return 1;
204   if (flags & SEC_CODE)
205     if (strstr (string, "CODE"))
206       return 1;
207   if (flags & SEC_DATA)
208     if (strstr (string, "DATA"))
209       return 1;
210   if (flags & SEC_ROM)
211     if (strstr (string, "ROM"))
212       return 1;
213   if (flags & SEC_CONSTRUCTOR)
214     if (strstr (string, "CONSTRUCTOR"))
215       return 1;
216   if (flags & SEC_HAS_CONTENTS)
217     if (strstr (string, "HAS_CONTENTS"))
218       return 1;
219   if (flags & SEC_NEVER_LOAD)
220     if (strstr (string, "NEVER_LOAD"))
221       return 1;
222   if (flags & SEC_COFF_SHARED_LIBRARY)
223     if (strstr (string, "COFF_SHARED_LIBRARY"))
224       return 1;
225   if (flags & SEC_IS_COMMON)
226     if (strstr (string, "IS_COMMON"))
227       return 1;
228
229   return 0;
230 }
231
232 static void
233 print_bfd_flags (flagword flags)
234 {
235   if (flags & SEC_ALLOC)
236     printf_filtered (" ALLOC");
237   if (flags & SEC_LOAD)
238     printf_filtered (" LOAD");
239   if (flags & SEC_RELOC)
240     printf_filtered (" RELOC");
241   if (flags & SEC_READONLY)
242     printf_filtered (" READONLY");
243   if (flags & SEC_CODE)
244     printf_filtered (" CODE");
245   if (flags & SEC_DATA)
246     printf_filtered (" DATA");
247   if (flags & SEC_ROM)
248     printf_filtered (" ROM");
249   if (flags & SEC_CONSTRUCTOR)
250     printf_filtered (" CONSTRUCTOR");
251   if (flags & SEC_HAS_CONTENTS)
252     printf_filtered (" HAS_CONTENTS");
253   if (flags & SEC_NEVER_LOAD)
254     printf_filtered (" NEVER_LOAD");
255   if (flags & SEC_COFF_SHARED_LIBRARY)
256     printf_filtered (" COFF_SHARED_LIBRARY");
257   if (flags & SEC_IS_COMMON)
258     printf_filtered (" IS_COMMON");
259 }
260
261 static void
262 print_section_info (const char *name, flagword flags, 
263                     CORE_ADDR addr, CORE_ADDR endaddr, 
264                     unsigned long filepos)
265 {
266   /* FIXME-32x64: Need print_address_numeric with field width.  */
267   printf_filtered ("    0x%s", paddr (addr));
268   printf_filtered ("->0x%s", paddr (endaddr));
269   printf_filtered (" at 0x%s",
270                    local_hex_string_custom ((unsigned long) filepos, "08l"));
271   printf_filtered (": %s", name);
272   print_bfd_flags (flags);
273   printf_filtered ("\n");
274 }
275
276 static void
277 print_bfd_section_info (bfd *abfd, 
278                         asection *asect, 
279                         void *arg)
280 {
281   flagword flags = bfd_get_section_flags (abfd, asect);
282   const char *name = bfd_section_name (abfd, asect);
283
284   if (arg == NULL || *((char *) arg) == '\0' ||
285       strstr ((char *) arg, name) ||
286       match_bfd_flags ((char *) arg, flags))
287     {
288       CORE_ADDR addr, endaddr;
289
290       addr = bfd_section_vma (abfd, asect);
291       endaddr = addr + bfd_section_size (abfd, asect);
292       print_section_info (name, flags, addr, endaddr, asect->filepos);
293     }
294 }
295
296 static void
297 print_objfile_section_info (bfd *abfd, 
298                             struct obj_section *asect, 
299                             char *string)
300 {
301   flagword flags = bfd_get_section_flags (abfd, asect->the_bfd_section);
302   const char *name = bfd_section_name (abfd, asect->the_bfd_section);
303
304   if (string == NULL || *string == '\0' ||
305       strstr (string, name) ||
306       match_bfd_flags (string, flags))
307     {
308       print_section_info (name, flags, asect->addr, asect->endaddr, 
309                           asect->the_bfd_section->filepos);
310     }
311 }
312
313 /* ARGSUSED */
314 static void
315 maintenance_info_sections (char *arg, int from_tty)
316 {
317   if (exec_bfd)
318     {
319       printf_filtered ("Exec file:\n");
320       printf_filtered ("    `%s', ", bfd_get_filename (exec_bfd));
321       wrap_here ("        ");
322       printf_filtered ("file type %s.\n", bfd_get_target (exec_bfd));
323       if (arg && *arg && strstr (arg, "ALLOBJ"))
324         {
325           struct objfile *ofile;
326           struct obj_section *osect;
327
328           /* Only this function cares about the 'ALLOBJ' argument; 
329              if 'ALLOBJ' is the only argument, discard it rather than
330              passing it down to print_objfile_section_info (which 
331              wouldn't know how to handle it).  */
332           if (strcmp (arg, "ALLOBJ") == 0)
333             arg = NULL;
334
335           ALL_OBJFILES (ofile)
336             {
337               printf_filtered ("  Object file: %s\n", 
338                                bfd_get_filename (ofile->obfd));
339               ALL_OBJFILE_OSECTIONS (ofile, osect)
340                 {
341                   print_objfile_section_info (ofile->obfd, osect, arg);
342                 }
343             }
344         }
345       else 
346         bfd_map_over_sections (exec_bfd, print_bfd_section_info, arg);
347     }
348
349   if (core_bfd)
350     {
351       printf_filtered ("Core file:\n");
352       printf_filtered ("    `%s', ", bfd_get_filename (core_bfd));
353       wrap_here ("        ");
354       printf_filtered ("file type %s.\n", bfd_get_target (core_bfd));
355       bfd_map_over_sections (core_bfd, print_bfd_section_info, arg);
356     }
357 }
358
359 /* ARGSUSED */
360 void
361 maintenance_print_statistics (char *args, int from_tty)
362 {
363   print_objfile_statistics ();
364   print_symbol_bcache_statistics ();
365 }
366
367 void
368 maintenance_print_architecture (char *args, int from_tty)
369 {
370   if (args == NULL)
371     gdbarch_dump (current_gdbarch, gdb_stdout);
372   else
373     {
374       struct ui_file *file = gdb_fopen (args, "w");
375       if (file == NULL)
376         perror_with_name ("maintenance print architecture");
377       gdbarch_dump (current_gdbarch, file);    
378       ui_file_delete (file);
379     }
380 }
381
382 /* The "maintenance print" command is defined as a prefix, with
383    allow_unknown 0.  Therefore, its own definition is called only for
384    "maintenance print" with no args.  */
385
386 /* ARGSUSED */
387 static void
388 maintenance_print_command (char *arg, int from_tty)
389 {
390   printf_unfiltered ("\"maintenance print\" must be followed by the name of a print command.\n");
391   help_list (maintenanceprintlist, "maintenance print ", -1, gdb_stdout);
392 }
393
394 /* The "maintenance translate-address" command converts a section and address
395    to a symbol.  This can be called in two ways:
396    maintenance translate-address <secname> <addr>
397    or   maintenance translate-address <addr>
398  */
399
400 static void
401 maintenance_translate_address (char *arg, int from_tty)
402 {
403   CORE_ADDR address;
404   asection *sect;
405   char *p;
406   struct minimal_symbol *sym;
407   struct objfile *objfile;
408
409   if (arg == NULL || *arg == 0)
410     error ("requires argument (address or section + address)");
411
412   sect = NULL;
413   p = arg;
414
415   if (!isdigit (*p))
416     {                           /* See if we have a valid section name */
417       while (*p && !isspace (*p))       /* Find end of section name */
418         p++;
419       if (*p == '\000')         /* End of command? */
420         error ("Need to specify <section-name> and <address>");
421       *p++ = '\000';
422       while (isspace (*p))
423         p++;                    /* Skip whitespace */
424
425       ALL_OBJFILES (objfile)
426       {
427         sect = bfd_get_section_by_name (objfile->obfd, arg);
428         if (sect != NULL)
429           break;
430       }
431
432       if (!sect)
433         error ("Unknown section %s.", arg);
434     }
435
436   address = parse_and_eval_address (p);
437
438   if (sect)
439     sym = lookup_minimal_symbol_by_pc_section (address, sect);
440   else
441     sym = lookup_minimal_symbol_by_pc (address);
442
443   if (sym)
444     printf_filtered ("%s+%s\n",
445                      SYMBOL_SOURCE_NAME (sym),
446                      paddr_u (address - SYMBOL_VALUE_ADDRESS (sym)));
447   else if (sect)
448     printf_filtered ("no symbol at %s:0x%s\n", sect->name, paddr (address));
449   else
450     printf_filtered ("no symbol at 0x%s\n", paddr (address));
451
452   return;
453 }
454
455
456 /* When a command is deprecated the user will be warned the first time
457    the command is used.  If possible, a replacement will be
458    offered. */
459
460 static void
461 maintenance_deprecate (char *args, int from_tty)
462 {
463   if (args == NULL || *args == '\0')
464     {
465       printf_unfiltered ("\"maintenance deprecate\" takes an argument, \n\
466 the command you want to deprecate, and optionally the replacement command \n\
467 enclosed in quotes.\n");
468     }
469
470   maintenance_do_deprecate (args, 1);
471
472 }
473
474
475 static void
476 maintenance_undeprecate (char *args, int from_tty)
477 {
478   if (args == NULL || *args == '\0')
479     {
480       printf_unfiltered ("\"maintenance undeprecate\" takes an argument, \n\
481 the command you want to undeprecate.\n");
482     }
483
484   maintenance_do_deprecate (args, 0);
485
486 }
487
488 /* You really shouldn't be using this. It is just for the testsuite.
489    Rather, you should use deprecate_cmd() when the command is created
490    in _initialize_blah().
491
492    This function deprecates a command and optionally assigns it a
493    replacement.  */
494
495 static void
496 maintenance_do_deprecate (char *text, int deprecate)
497 {
498
499   struct cmd_list_element *alias = NULL;
500   struct cmd_list_element *prefix_cmd = NULL;
501   struct cmd_list_element *cmd = NULL;
502
503   char *start_ptr = NULL;
504   char *end_ptr = NULL;
505   int len;
506   char *replacement = NULL;
507
508   if (text == NULL)
509     return;
510
511   if (!lookup_cmd_composition (text, &alias, &prefix_cmd, &cmd))
512     {
513       printf_filtered ("Can't find command '%s' to deprecate.\n", text);
514       return;
515     }
516
517   if (deprecate)
518     {
519       /* look for a replacement command */
520       start_ptr = strchr (text, '\"');
521       if (start_ptr != NULL)
522         {
523           start_ptr++;
524           end_ptr = strrchr (start_ptr, '\"');
525           if (end_ptr != NULL)
526             {
527               len = end_ptr - start_ptr;
528               start_ptr[len] = '\0';
529               replacement = xstrdup (start_ptr);
530             }
531         }
532     }
533
534   if (!start_ptr || !end_ptr)
535     replacement = NULL;
536
537
538   /* If they used an alias, we only want to deprecate the alias.
539
540      Note the MALLOCED_REPLACEMENT test.  If the command's replacement
541      string was allocated at compile time we don't want to free the
542      memory. */
543   if (alias)
544     {
545
546       if (alias->flags & MALLOCED_REPLACEMENT)
547         xfree (alias->replacement);
548
549       if (deprecate)
550         alias->flags |= (DEPRECATED_WARN_USER | CMD_DEPRECATED);
551       else
552         alias->flags &= ~(DEPRECATED_WARN_USER | CMD_DEPRECATED);
553       alias->replacement = replacement;
554       alias->flags |= MALLOCED_REPLACEMENT;
555       return;
556     }
557   else if (cmd)
558     {
559       if (cmd->flags & MALLOCED_REPLACEMENT)
560         xfree (cmd->replacement);
561
562       if (deprecate)
563         cmd->flags |= (DEPRECATED_WARN_USER | CMD_DEPRECATED);
564       else
565         cmd->flags &= ~(DEPRECATED_WARN_USER | CMD_DEPRECATED);
566       cmd->replacement = replacement;
567       cmd->flags |= MALLOCED_REPLACEMENT;
568       return;
569     }
570 }
571
572 /* Maintenance set/show framework.  */
573
574 static struct cmd_list_element *maintenance_set_cmdlist;
575 static struct cmd_list_element *maintenance_show_cmdlist;
576
577 static void
578 maintenance_set_cmd (char *args, int from_tty)
579 {
580   printf_unfiltered ("\"maintenance set\" must be followed by the name of a set command.\n");
581   help_list (maintenance_set_cmdlist, "maintenance set ", -1, gdb_stdout);
582 }
583
584 static void
585 maintenance_show_cmd (char *args, int from_tty)
586 {
587   cmd_show_list (maintenance_show_cmdlist, from_tty, "");
588 }
589
590 #ifdef NOTYET
591 /* Profiling support.  */
592
593 static int maintenance_profile_p;
594
595 static void
596 maintenance_set_profile_cmd (char *args, int from_tty, struct cmd_list_element *c)
597 {
598   maintenance_profile_p = 0;
599   warning ("\"maintenance set profile\" command not supported.\n");
600 }
601 #endif
602
603 void
604 _initialize_maint_cmds (void)
605 {
606   struct cmd_list_element *tmpcmd;
607
608   add_prefix_cmd ("maintenance", class_maintenance, maintenance_command,
609                   "Commands for use by GDB maintainers.\n\
610 Includes commands to dump specific internal GDB structures in\n\
611 a human readable form, to cause GDB to deliberately dump core,\n\
612 to test internal functions such as the C++ demangler, etc.",
613                   &maintenancelist, "maintenance ", 0,
614                   &cmdlist);
615
616   add_com_alias ("mt", "maintenance", class_maintenance, 1);
617
618   add_prefix_cmd ("info", class_maintenance, maintenance_info_command,
619      "Commands for showing internal info about the program being debugged.",
620                   &maintenanceinfolist, "maintenance info ", 0,
621                   &maintenancelist);
622   add_alias_cmd ("i", "info", class_maintenance, 1, &maintenancelist);
623
624   add_cmd ("sections", class_maintenance, maintenance_info_sections,
625            "List the BFD sections of the exec and core files. \n
626 Arguments may be any combination of:\n\
627         [one or more section names]\n\
628         ALLOC LOAD RELOC READONLY CODE DATA ROM CONSTRUCTOR\n\
629         HAS_CONTENTS NEVER_LOAD COFF_SHARED_LIBRARY IS_COMMON\n\
630 Sections matching any argument will be listed (no argument\n\
631 implies all sections).  In addition, the special argument\n\
632         ALLOBJ\n\
633 lists all sections from all object files, including shared libraries.",
634            &maintenanceinfolist);
635
636   add_prefix_cmd ("print", class_maintenance, maintenance_print_command,
637                   "Maintenance command for printing GDB internal state.",
638                   &maintenanceprintlist, "maintenance print ", 0,
639                   &maintenancelist);
640
641   add_prefix_cmd ("set", class_maintenance, maintenance_set_cmd, "\
642 Set GDB internal variables used by the GDB maintainer.\n\
643 Configure variables internal to GDB that aid in GDB's maintenance",
644                   &maintenance_set_cmdlist, "maintenance set ",
645                   0/*allow-unknown*/,
646                   &maintenancelist);
647
648   add_prefix_cmd ("show", class_maintenance, maintenance_show_cmd, "\
649 Show GDB internal variables used by the GDB maintainer.\n\
650 Configure variables internal to GDB that aid in GDB's maintenance",
651                   &maintenance_show_cmdlist, "maintenance show ",
652                   0/*allow-unknown*/,
653                   &maintenancelist);
654
655 #ifndef _WIN32
656   add_cmd ("dump-me", class_maintenance, maintenance_dump_me,
657            "Get fatal error; make debugger dump its core.\n\
658 GDB sets it's handling of SIGQUIT back to SIG_DFL and then sends\n\
659 itself a SIGQUIT signal.",
660            &maintenancelist);
661 #endif
662
663   add_cmd ("internal-error", class_maintenance, maintenance_internal_error,
664            "Give GDB an internal error.\n\
665 Cause GDB to behave as if an internal error was detected.",
666            &maintenancelist);
667
668   add_cmd ("demangle", class_maintenance, maintenance_demangle,
669            "Demangle a C++ mangled name.\n\
670 Call internal GDB demangler routine to demangle a C++ link name\n\
671 and prints the result.",
672            &maintenancelist);
673
674   add_cmd ("time", class_maintenance, maintenance_time_display,
675            "Set the display of time usage.\n\
676 If nonzero, will cause the execution time for each command to be\n\
677 displayed, following the command's output.",
678            &maintenancelist);
679
680   add_cmd ("space", class_maintenance, maintenance_space_display,
681            "Set the display of space usage.\n\
682 If nonzero, will cause the execution space for each command to be\n\
683 displayed, following the command's output.",
684            &maintenancelist);
685
686   add_cmd ("type", class_maintenance, maintenance_print_type,
687            "Print a type chain for a given symbol.\n\
688 For each node in a type chain, print the raw data for each member of\n\
689 the type structure, and the interpretation of the data.",
690            &maintenanceprintlist);
691
692   add_cmd ("symbols", class_maintenance, maintenance_print_symbols,
693            "Print dump of current symbol definitions.\n\
694 Entries in the full symbol table are dumped to file OUTFILE.\n\
695 If a SOURCE file is specified, dump only that file's symbols.",
696            &maintenanceprintlist);
697
698   add_cmd ("msymbols", class_maintenance, maintenance_print_msymbols,
699            "Print dump of current minimal symbol definitions.\n\
700 Entries in the minimal symbol table are dumped to file OUTFILE.\n\
701 If a SOURCE file is specified, dump only that file's minimal symbols.",
702            &maintenanceprintlist);
703
704   add_cmd ("psymbols", class_maintenance, maintenance_print_psymbols,
705            "Print dump of current partial symbol definitions.\n\
706 Entries in the partial symbol table are dumped to file OUTFILE.\n\
707 If a SOURCE file is specified, dump only that file's partial symbols.",
708            &maintenanceprintlist);
709
710   add_cmd ("objfiles", class_maintenance, maintenance_print_objfiles,
711            "Print dump of current object file definitions.",
712            &maintenanceprintlist);
713
714   add_cmd ("statistics", class_maintenance, maintenance_print_statistics,
715            "Print statistics about internal gdb state.",
716            &maintenanceprintlist);
717
718   add_cmd ("architecture", class_maintenance, maintenance_print_architecture,
719            "Print the internal architecture configuration.\
720 Takes an optional file parameter.",
721            &maintenanceprintlist);
722
723   add_cmd ("check-symtabs", class_maintenance, maintenance_check_symtabs,
724            "Check consistency of psymtabs and symtabs.",
725            &maintenancelist);
726
727   add_cmd ("translate-address", class_maintenance, maintenance_translate_address,
728            "Translate a section name and address to a symbol.",
729            &maintenancelist);
730
731   add_cmd ("deprecate", class_maintenance, maintenance_deprecate,
732            "Deprecate a command.  Note that this is just in here so the \n\
733 testsuite can check the comamnd deprecator. You probably shouldn't use this,\n\
734 rather you should use the C function deprecate_cmd().  If you decide you \n\
735 want to use it: maintenance deprecate 'commandname' \"replacement\". The \n\
736 replacement is optional.", &maintenancelist);
737
738   add_cmd ("undeprecate", class_maintenance, maintenance_undeprecate,
739            "Undeprecate a command.  Note that this is just in here so the \n\
740 testsuite can check the comamnd deprecator. You probably shouldn't use this,\n\
741 If you decide you want to use it: maintenance undeprecate 'commandname'",
742            &maintenancelist);
743
744   add_show_from_set (
745                       add_set_cmd ("watchdog", class_maintenance, var_zinteger, (char *) &watchdog,
746                                    "Set watchdog timer.\n\
747 When non-zero, this timeout is used instead of waiting forever for a target to\n\
748 finish a low-level step or continue operation.  If the specified amount of time\n\
749 passes without a response from the target, an error occurs.", &setlist),
750                       &showlist);
751
752
753 #ifdef NOTYET
754   /* FIXME: cagney/2001-09-24: A patch introducing a
755      add_set_boolean_cmd() is pending, the below should probably use
756      it.  A patch implementing profiling is pending, this just sets up
757      the framework.  */
758   tmpcmd = add_set_cmd ("profile", class_maintenance,
759                         var_boolean, &maintenance_profile_p,
760                         "Set internal profiling.\n\
761 When enabled GDB is profiled.",
762                         &maintenance_set_cmdlist);
763   tmpcmd->function.sfunc = maintenance_set_profile_cmd;
764   add_show_from_set (tmpcmd, &maintenance_show_cmdlist);
765 #endif
766 }