59de6dc0a8188d388c480eb20dabdecf85373f7a
[platform/upstream/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 /* Mini tokenizing lexer for 'maint info sections' command.  */
190
191 static int
192 match_substring (const char *string, const char *substr)
193 {
194   int substr_len = strlen(substr);
195   const char *tok;
196
197   while ((tok = strstr (string, substr)) != NULL)
198     {
199       /* Got a partial match.  Is it a whole word? */
200       if (tok == string
201           || tok[-1] == ' '
202           || tok[-1] == '\t')
203       {
204         /* Token is delimited at the front... */
205         if (tok[substr_len] == ' '
206             || tok[substr_len] == '\t'
207             || tok[substr_len] == '\0')
208         {
209           /* Token is delimited at the rear.  Got a whole-word match.  */
210           return 1;
211         }
212       }
213       /* Token didn't match as a whole word.  Advance and try again.  */
214       string = tok + 1;
215     }
216   return 0;
217 }
218
219 static int 
220 match_bfd_flags (char *string, flagword flags)
221 {
222   if (flags & SEC_ALLOC)
223     if (match_substring (string, "ALLOC"))
224       return 1;
225   if (flags & SEC_LOAD)
226     if (match_substring (string, "LOAD"))
227       return 1;
228   if (flags & SEC_RELOC)
229     if (match_substring (string, "RELOC"))
230       return 1;
231   if (flags & SEC_READONLY)
232     if (match_substring (string, "READONLY"))
233       return 1;
234   if (flags & SEC_CODE)
235     if (match_substring (string, "CODE"))
236       return 1;
237   if (flags & SEC_DATA)
238     if (match_substring (string, "DATA"))
239       return 1;
240   if (flags & SEC_ROM)
241     if (match_substring (string, "ROM"))
242       return 1;
243   if (flags & SEC_CONSTRUCTOR)
244     if (match_substring (string, "CONSTRUCTOR"))
245       return 1;
246   if (flags & SEC_HAS_CONTENTS)
247     if (match_substring (string, "HAS_CONTENTS"))
248       return 1;
249   if (flags & SEC_NEVER_LOAD)
250     if (match_substring (string, "NEVER_LOAD"))
251       return 1;
252   if (flags & SEC_COFF_SHARED_LIBRARY)
253     if (match_substring (string, "COFF_SHARED_LIBRARY"))
254       return 1;
255   if (flags & SEC_IS_COMMON)
256     if (match_substring (string, "IS_COMMON"))
257       return 1;
258
259   return 0;
260 }
261
262 static void
263 print_bfd_flags (flagword flags)
264 {
265   if (flags & SEC_ALLOC)
266     printf_filtered (" ALLOC");
267   if (flags & SEC_LOAD)
268     printf_filtered (" LOAD");
269   if (flags & SEC_RELOC)
270     printf_filtered (" RELOC");
271   if (flags & SEC_READONLY)
272     printf_filtered (" READONLY");
273   if (flags & SEC_CODE)
274     printf_filtered (" CODE");
275   if (flags & SEC_DATA)
276     printf_filtered (" DATA");
277   if (flags & SEC_ROM)
278     printf_filtered (" ROM");
279   if (flags & SEC_CONSTRUCTOR)
280     printf_filtered (" CONSTRUCTOR");
281   if (flags & SEC_HAS_CONTENTS)
282     printf_filtered (" HAS_CONTENTS");
283   if (flags & SEC_NEVER_LOAD)
284     printf_filtered (" NEVER_LOAD");
285   if (flags & SEC_COFF_SHARED_LIBRARY)
286     printf_filtered (" COFF_SHARED_LIBRARY");
287   if (flags & SEC_IS_COMMON)
288     printf_filtered (" IS_COMMON");
289 }
290
291 static void
292 print_section_info (const char *name, flagword flags, 
293                     CORE_ADDR addr, CORE_ADDR endaddr, 
294                     unsigned long filepos)
295 {
296   /* FIXME-32x64: Need print_address_numeric with field width.  */
297   printf_filtered ("    0x%s", paddr (addr));
298   printf_filtered ("->0x%s", paddr (endaddr));
299   printf_filtered (" at 0x%s",
300                    local_hex_string_custom ((unsigned long) filepos, "08l"));
301   printf_filtered (": %s", name);
302   print_bfd_flags (flags);
303   printf_filtered ("\n");
304 }
305
306 static void
307 print_bfd_section_info (bfd *abfd, 
308                         asection *asect, 
309                         void *arg)
310 {
311   flagword flags = bfd_get_section_flags (abfd, asect);
312   const char *name = bfd_section_name (abfd, asect);
313
314   if (arg == NULL || *((char *) arg) == '\0'
315       || match_substring ((char *) arg, name)
316       || match_bfd_flags ((char *) arg, flags))
317     {
318       CORE_ADDR addr, endaddr;
319
320       addr = bfd_section_vma (abfd, asect);
321       endaddr = addr + bfd_section_size (abfd, asect);
322       print_section_info (name, flags, addr, endaddr, asect->filepos);
323     }
324 }
325
326 static void
327 print_objfile_section_info (bfd *abfd, 
328                             struct obj_section *asect, 
329                             char *string)
330 {
331   flagword flags = bfd_get_section_flags (abfd, asect->the_bfd_section);
332   const char *name = bfd_section_name (abfd, asect->the_bfd_section);
333
334   if (string == NULL || *string == '\0'
335       || match_substring (string, name)
336       || match_bfd_flags (string, flags))
337     {
338       print_section_info (name, flags, asect->addr, asect->endaddr, 
339                           asect->the_bfd_section->filepos);
340     }
341 }
342
343 /* ARGSUSED */
344 static void
345 maintenance_info_sections (char *arg, int from_tty)
346 {
347   if (exec_bfd)
348     {
349       printf_filtered ("Exec file:\n");
350       printf_filtered ("    `%s', ", bfd_get_filename (exec_bfd));
351       wrap_here ("        ");
352       printf_filtered ("file type %s.\n", bfd_get_target (exec_bfd));
353       if (arg && *arg && match_substring (arg, "ALLOBJ"))
354         {
355           struct objfile *ofile;
356           struct obj_section *osect;
357
358           /* Only this function cares about the 'ALLOBJ' argument; 
359              if 'ALLOBJ' is the only argument, discard it rather than
360              passing it down to print_objfile_section_info (which 
361              wouldn't know how to handle it).  */
362           if (strcmp (arg, "ALLOBJ") == 0)
363             arg = NULL;
364
365           ALL_OBJFILES (ofile)
366             {
367               printf_filtered ("  Object file: %s\n", 
368                                bfd_get_filename (ofile->obfd));
369               ALL_OBJFILE_OSECTIONS (ofile, osect)
370                 {
371                   print_objfile_section_info (ofile->obfd, osect, arg);
372                 }
373             }
374         }
375       else 
376         bfd_map_over_sections (exec_bfd, print_bfd_section_info, arg);
377     }
378
379   if (core_bfd)
380     {
381       printf_filtered ("Core file:\n");
382       printf_filtered ("    `%s', ", bfd_get_filename (core_bfd));
383       wrap_here ("        ");
384       printf_filtered ("file type %s.\n", bfd_get_target (core_bfd));
385       bfd_map_over_sections (core_bfd, print_bfd_section_info, arg);
386     }
387 }
388
389 /* ARGSUSED */
390 void
391 maintenance_print_statistics (char *args, int from_tty)
392 {
393   print_objfile_statistics ();
394   print_symbol_bcache_statistics ();
395 }
396
397 void
398 maintenance_print_architecture (char *args, int from_tty)
399 {
400   if (args == NULL)
401     gdbarch_dump (current_gdbarch, gdb_stdout);
402   else
403     {
404       struct ui_file *file = gdb_fopen (args, "w");
405       if (file == NULL)
406         perror_with_name ("maintenance print architecture");
407       gdbarch_dump (current_gdbarch, file);    
408       ui_file_delete (file);
409     }
410 }
411
412 /* The "maintenance print" command is defined as a prefix, with
413    allow_unknown 0.  Therefore, its own definition is called only for
414    "maintenance print" with no args.  */
415
416 /* ARGSUSED */
417 static void
418 maintenance_print_command (char *arg, int from_tty)
419 {
420   printf_unfiltered ("\"maintenance print\" must be followed by the name of a print command.\n");
421   help_list (maintenanceprintlist, "maintenance print ", -1, gdb_stdout);
422 }
423
424 /* The "maintenance translate-address" command converts a section and address
425    to a symbol.  This can be called in two ways:
426    maintenance translate-address <secname> <addr>
427    or   maintenance translate-address <addr>
428  */
429
430 static void
431 maintenance_translate_address (char *arg, int from_tty)
432 {
433   CORE_ADDR address;
434   asection *sect;
435   char *p;
436   struct minimal_symbol *sym;
437   struct objfile *objfile;
438
439   if (arg == NULL || *arg == 0)
440     error ("requires argument (address or section + address)");
441
442   sect = NULL;
443   p = arg;
444
445   if (!isdigit (*p))
446     {                           /* See if we have a valid section name */
447       while (*p && !isspace (*p))       /* Find end of section name */
448         p++;
449       if (*p == '\000')         /* End of command? */
450         error ("Need to specify <section-name> and <address>");
451       *p++ = '\000';
452       while (isspace (*p))
453         p++;                    /* Skip whitespace */
454
455       ALL_OBJFILES (objfile)
456       {
457         sect = bfd_get_section_by_name (objfile->obfd, arg);
458         if (sect != NULL)
459           break;
460       }
461
462       if (!sect)
463         error ("Unknown section %s.", arg);
464     }
465
466   address = parse_and_eval_address (p);
467
468   if (sect)
469     sym = lookup_minimal_symbol_by_pc_section (address, sect);
470   else
471     sym = lookup_minimal_symbol_by_pc (address);
472
473   if (sym)
474     printf_filtered ("%s+%s\n",
475                      SYMBOL_SOURCE_NAME (sym),
476                      paddr_u (address - SYMBOL_VALUE_ADDRESS (sym)));
477   else if (sect)
478     printf_filtered ("no symbol at %s:0x%s\n", sect->name, paddr (address));
479   else
480     printf_filtered ("no symbol at 0x%s\n", paddr (address));
481
482   return;
483 }
484
485
486 /* When a command is deprecated the user will be warned the first time
487    the command is used.  If possible, a replacement will be
488    offered. */
489
490 static void
491 maintenance_deprecate (char *args, int from_tty)
492 {
493   if (args == NULL || *args == '\0')
494     {
495       printf_unfiltered ("\"maintenance deprecate\" takes an argument, \n\
496 the command you want to deprecate, and optionally the replacement command \n\
497 enclosed in quotes.\n");
498     }
499
500   maintenance_do_deprecate (args, 1);
501
502 }
503
504
505 static void
506 maintenance_undeprecate (char *args, int from_tty)
507 {
508   if (args == NULL || *args == '\0')
509     {
510       printf_unfiltered ("\"maintenance undeprecate\" takes an argument, \n\
511 the command you want to undeprecate.\n");
512     }
513
514   maintenance_do_deprecate (args, 0);
515
516 }
517
518 /* You really shouldn't be using this. It is just for the testsuite.
519    Rather, you should use deprecate_cmd() when the command is created
520    in _initialize_blah().
521
522    This function deprecates a command and optionally assigns it a
523    replacement.  */
524
525 static void
526 maintenance_do_deprecate (char *text, int deprecate)
527 {
528
529   struct cmd_list_element *alias = NULL;
530   struct cmd_list_element *prefix_cmd = NULL;
531   struct cmd_list_element *cmd = NULL;
532
533   char *start_ptr = NULL;
534   char *end_ptr = NULL;
535   int len;
536   char *replacement = NULL;
537
538   if (text == NULL)
539     return;
540
541   if (!lookup_cmd_composition (text, &alias, &prefix_cmd, &cmd))
542     {
543       printf_filtered ("Can't find command '%s' to deprecate.\n", text);
544       return;
545     }
546
547   if (deprecate)
548     {
549       /* look for a replacement command */
550       start_ptr = strchr (text, '\"');
551       if (start_ptr != NULL)
552         {
553           start_ptr++;
554           end_ptr = strrchr (start_ptr, '\"');
555           if (end_ptr != NULL)
556             {
557               len = end_ptr - start_ptr;
558               start_ptr[len] = '\0';
559               replacement = xstrdup (start_ptr);
560             }
561         }
562     }
563
564   if (!start_ptr || !end_ptr)
565     replacement = NULL;
566
567
568   /* If they used an alias, we only want to deprecate the alias.
569
570      Note the MALLOCED_REPLACEMENT test.  If the command's replacement
571      string was allocated at compile time we don't want to free the
572      memory. */
573   if (alias)
574     {
575
576       if (alias->flags & MALLOCED_REPLACEMENT)
577         xfree (alias->replacement);
578
579       if (deprecate)
580         alias->flags |= (DEPRECATED_WARN_USER | CMD_DEPRECATED);
581       else
582         alias->flags &= ~(DEPRECATED_WARN_USER | CMD_DEPRECATED);
583       alias->replacement = replacement;
584       alias->flags |= MALLOCED_REPLACEMENT;
585       return;
586     }
587   else if (cmd)
588     {
589       if (cmd->flags & MALLOCED_REPLACEMENT)
590         xfree (cmd->replacement);
591
592       if (deprecate)
593         cmd->flags |= (DEPRECATED_WARN_USER | CMD_DEPRECATED);
594       else
595         cmd->flags &= ~(DEPRECATED_WARN_USER | CMD_DEPRECATED);
596       cmd->replacement = replacement;
597       cmd->flags |= MALLOCED_REPLACEMENT;
598       return;
599     }
600 }
601
602 /* Maintenance set/show framework.  */
603
604 static struct cmd_list_element *maintenance_set_cmdlist;
605 static struct cmd_list_element *maintenance_show_cmdlist;
606
607 static void
608 maintenance_set_cmd (char *args, int from_tty)
609 {
610   printf_unfiltered ("\"maintenance set\" must be followed by the name of a set command.\n");
611   help_list (maintenance_set_cmdlist, "maintenance set ", -1, gdb_stdout);
612 }
613
614 static void
615 maintenance_show_cmd (char *args, int from_tty)
616 {
617   cmd_show_list (maintenance_show_cmdlist, from_tty, "");
618 }
619
620 #ifdef NOTYET
621 /* Profiling support.  */
622
623 static int maintenance_profile_p;
624
625 static void
626 maintenance_set_profile_cmd (char *args, int from_tty, struct cmd_list_element *c)
627 {
628   maintenance_profile_p = 0;
629   warning ("\"maintenance set profile\" command not supported.\n");
630 }
631 #endif
632
633 void
634 _initialize_maint_cmds (void)
635 {
636   struct cmd_list_element *tmpcmd;
637
638   add_prefix_cmd ("maintenance", class_maintenance, maintenance_command,
639                   "Commands for use by GDB maintainers.\n\
640 Includes commands to dump specific internal GDB structures in\n\
641 a human readable form, to cause GDB to deliberately dump core,\n\
642 to test internal functions such as the C++ demangler, etc.",
643                   &maintenancelist, "maintenance ", 0,
644                   &cmdlist);
645
646   add_com_alias ("mt", "maintenance", class_maintenance, 1);
647
648   add_prefix_cmd ("info", class_maintenance, maintenance_info_command,
649      "Commands for showing internal info about the program being debugged.",
650                   &maintenanceinfolist, "maintenance info ", 0,
651                   &maintenancelist);
652   add_alias_cmd ("i", "info", class_maintenance, 1, &maintenancelist);
653
654   add_cmd ("sections", class_maintenance, maintenance_info_sections,
655            "List the BFD sections of the exec and core files. \n\
656 Arguments may be any combination of:\n\
657         [one or more section names]\n\
658         ALLOC LOAD RELOC READONLY CODE DATA ROM CONSTRUCTOR\n\
659         HAS_CONTENTS NEVER_LOAD COFF_SHARED_LIBRARY IS_COMMON\n\
660 Sections matching any argument will be listed (no argument\n\
661 implies all sections).  In addition, the special argument\n\
662         ALLOBJ\n\
663 lists all sections from all object files, including shared libraries.",
664            &maintenanceinfolist);
665
666   add_prefix_cmd ("print", class_maintenance, maintenance_print_command,
667                   "Maintenance command for printing GDB internal state.",
668                   &maintenanceprintlist, "maintenance print ", 0,
669                   &maintenancelist);
670
671   add_prefix_cmd ("set", class_maintenance, maintenance_set_cmd, "\
672 Set GDB internal variables used by the GDB maintainer.\n\
673 Configure variables internal to GDB that aid in GDB's maintenance",
674                   &maintenance_set_cmdlist, "maintenance set ",
675                   0/*allow-unknown*/,
676                   &maintenancelist);
677
678   add_prefix_cmd ("show", class_maintenance, maintenance_show_cmd, "\
679 Show GDB internal variables used by the GDB maintainer.\n\
680 Configure variables internal to GDB that aid in GDB's maintenance",
681                   &maintenance_show_cmdlist, "maintenance show ",
682                   0/*allow-unknown*/,
683                   &maintenancelist);
684
685 #ifndef _WIN32
686   add_cmd ("dump-me", class_maintenance, maintenance_dump_me,
687            "Get fatal error; make debugger dump its core.\n\
688 GDB sets it's handling of SIGQUIT back to SIG_DFL and then sends\n\
689 itself a SIGQUIT signal.",
690            &maintenancelist);
691 #endif
692
693   add_cmd ("internal-error", class_maintenance, maintenance_internal_error,
694            "Give GDB an internal error.\n\
695 Cause GDB to behave as if an internal error was detected.",
696            &maintenancelist);
697
698   add_cmd ("demangle", class_maintenance, maintenance_demangle,
699            "Demangle a C++ mangled name.\n\
700 Call internal GDB demangler routine to demangle a C++ link name\n\
701 and prints the result.",
702            &maintenancelist);
703
704   add_cmd ("time", class_maintenance, maintenance_time_display,
705            "Set the display of time usage.\n\
706 If nonzero, will cause the execution time for each command to be\n\
707 displayed, following the command's output.",
708            &maintenancelist);
709
710   add_cmd ("space", class_maintenance, maintenance_space_display,
711            "Set the display of space usage.\n\
712 If nonzero, will cause the execution space for each command to be\n\
713 displayed, following the command's output.",
714            &maintenancelist);
715
716   add_cmd ("type", class_maintenance, maintenance_print_type,
717            "Print a type chain for a given symbol.\n\
718 For each node in a type chain, print the raw data for each member of\n\
719 the type structure, and the interpretation of the data.",
720            &maintenanceprintlist);
721
722   add_cmd ("symbols", class_maintenance, maintenance_print_symbols,
723            "Print dump of current symbol definitions.\n\
724 Entries in the full symbol table are dumped to file OUTFILE.\n\
725 If a SOURCE file is specified, dump only that file's symbols.",
726            &maintenanceprintlist);
727
728   add_cmd ("msymbols", class_maintenance, maintenance_print_msymbols,
729            "Print dump of current minimal symbol definitions.\n\
730 Entries in the minimal symbol table are dumped to file OUTFILE.\n\
731 If a SOURCE file is specified, dump only that file's minimal symbols.",
732            &maintenanceprintlist);
733
734   add_cmd ("psymbols", class_maintenance, maintenance_print_psymbols,
735            "Print dump of current partial symbol definitions.\n\
736 Entries in the partial symbol table are dumped to file OUTFILE.\n\
737 If a SOURCE file is specified, dump only that file's partial symbols.",
738            &maintenanceprintlist);
739
740   add_cmd ("objfiles", class_maintenance, maintenance_print_objfiles,
741            "Print dump of current object file definitions.",
742            &maintenanceprintlist);
743
744   add_cmd ("statistics", class_maintenance, maintenance_print_statistics,
745            "Print statistics about internal gdb state.",
746            &maintenanceprintlist);
747
748   add_cmd ("architecture", class_maintenance, maintenance_print_architecture,
749            "Print the internal architecture configuration.\
750 Takes an optional file parameter.",
751            &maintenanceprintlist);
752
753   add_cmd ("check-symtabs", class_maintenance, maintenance_check_symtabs,
754            "Check consistency of psymtabs and symtabs.",
755            &maintenancelist);
756
757   add_cmd ("translate-address", class_maintenance, maintenance_translate_address,
758            "Translate a section name and address to a symbol.",
759            &maintenancelist);
760
761   add_cmd ("deprecate", class_maintenance, maintenance_deprecate,
762            "Deprecate a command.  Note that this is just in here so the \n\
763 testsuite can check the comamnd deprecator. You probably shouldn't use this,\n\
764 rather you should use the C function deprecate_cmd().  If you decide you \n\
765 want to use it: maintenance deprecate 'commandname' \"replacement\". The \n\
766 replacement is optional.", &maintenancelist);
767
768   add_cmd ("undeprecate", class_maintenance, maintenance_undeprecate,
769            "Undeprecate a command.  Note that this is just in here so the \n\
770 testsuite can check the comamnd deprecator. You probably shouldn't use this,\n\
771 If you decide you want to use it: maintenance undeprecate 'commandname'",
772            &maintenancelist);
773
774   add_show_from_set (
775                       add_set_cmd ("watchdog", class_maintenance, var_zinteger, (char *) &watchdog,
776                                    "Set watchdog timer.\n\
777 When non-zero, this timeout is used instead of waiting forever for a target to\n\
778 finish a low-level step or continue operation.  If the specified amount of time\n\
779 passes without a response from the target, an error occurs.", &setlist),
780                       &showlist);
781
782
783 #ifdef NOTYET
784   /* FIXME: cagney/2001-09-24: A patch introducing a
785      add_set_boolean_cmd() is pending, the below should probably use
786      it.  A patch implementing profiling is pending, this just sets up
787      the framework.  */
788   tmpcmd = add_set_cmd ("profile", class_maintenance,
789                         var_boolean, &maintenance_profile_p,
790                         "Set internal profiling.\n\
791 When enabled GDB is profiled.",
792                         &maintenance_set_cmdlist);
793   set_cmd_sfunc (tmpcmd, maintenance_set_profile_cmd);
794   add_show_from_set (tmpcmd, &maintenance_show_cmdlist);
795 #endif
796 }