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