This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / gdb / maint.c
1 /* Support for GDB maintenance commands.
2    Copyright 1992, 1993, 1994 Free Software Foundation, Inc.
3    Written by Fred Fish at Cygnus Support.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21
22 #include "defs.h"
23 #include <ctype.h>
24 #include <signal.h>
25 #include "command.h"
26 #include "gdbcmd.h"
27 #include "symtab.h"
28 #include "gdbtypes.h"
29 #include "demangle.h"
30 #include "gdbcore.h"
31 #include "expression.h" /* For language.h */
32 #include "language.h"
33 #include "symfile.h"
34 #include "objfiles.h"
35 #include "value.h"
36
37 #ifdef HAVE_UNISTD_H
38 #include <unistd.h>
39 #endif
40
41 static void maintenance_command PARAMS ((char *, int));
42
43 static void maintenance_dump_me PARAMS ((char *, int));
44
45 static void maintenance_demangle PARAMS ((char *, int));
46
47 static void maintenance_time_display PARAMS ((char *, int));
48
49 static void maintenance_space_display PARAMS ((char *, int));
50
51 static void maintenance_info_command PARAMS ((char *, int));
52
53 static void print_section_table PARAMS ((bfd *, asection *, PTR));
54
55 static void maintenance_info_sections PARAMS ((char *, int));
56
57 static void maintenance_print_command PARAMS ((char *, int));
58
59 /* Set this to the maximum number of seconds to wait instead of waiting forever
60    in target_wait().  If this timer times out, then it generates an error and
61    the command is aborted.  This replaces most of the need for timeouts in the
62    GDB test suite, and makes it possible to distinguish between a hung target
63    and one with slow communications.  */
64
65 int watchdog = 0;
66
67 /*
68
69 LOCAL FUNCTION
70
71         maintenance_command -- access the maintenance subcommands
72
73 SYNOPSIS
74
75         void maintenance_command (char *args, int from_tty)
76
77 DESCRIPTION
78
79 */
80
81 static void
82 maintenance_command (args, from_tty)
83      char *args;
84      int from_tty;
85 {
86   printf_unfiltered ("\"maintenance\" must be followed by the name of a maintenance command.\n");
87   help_list (maintenancelist, "maintenance ", -1, gdb_stdout);
88 }
89
90 #ifndef _WIN32
91 /* ARGSUSED */
92 static void
93 maintenance_dump_me (args, from_tty)
94      char *args;
95      int from_tty;
96 {
97   if (query ("Should GDB dump core? "))
98     {
99       signal (SIGQUIT, SIG_DFL);
100       kill (getpid (), SIGQUIT);
101     }
102 }
103 #endif
104
105 /*  Someday we should allow demangling for things other than just
106     explicit strings.  For example, we might want to be able to
107     specify the address of a string in either GDB's process space
108     or the debuggee's process space, and have gdb fetch and demangle
109     that string.  If we have a char* pointer "ptr" that points to
110     a string, we might want to be able to given just the name and
111     have GDB demangle and print what it points to, etc.  (FIXME) */
112
113 static void
114 maintenance_demangle (args, from_tty)
115      char *args;
116      int from_tty;
117 {
118   char *demangled;
119
120   if (args == NULL || *args == '\0')
121     {
122       printf_unfiltered ("\"maintenance demangle\" takes an argument to demangle.\n");
123     }
124   else
125     {
126       demangled = cplus_demangle (args, DMGL_ANSI | DMGL_PARAMS);
127       if (demangled != NULL)
128         {
129           printf_unfiltered ("%s\n", demangled);
130           free (demangled);
131         }
132       else
133         {
134           printf_unfiltered ("Can't demangle \"%s\"\n", args);
135         }
136     }
137 }
138
139 static void
140 maintenance_time_display (args, from_tty)
141      char *args;
142      int from_tty;
143 {
144   extern int display_time;
145
146   if (args == NULL || *args == '\0')
147     printf_unfiltered ("\"maintenance time\" takes a numeric argument.\n");
148   else
149     display_time = strtol (args, NULL, 10);
150 }
151
152 static void
153 maintenance_space_display (args, from_tty)
154      char *args;
155      int from_tty;
156 {
157   extern int display_space;
158
159   if (args == NULL || *args == '\0')
160     printf_unfiltered ("\"maintenance space\" takes a numeric argument.\n");
161   else
162     display_space = strtol (args, NULL, 10);
163 }
164
165 /* The "maintenance info" command is defined as a prefix, with allow_unknown 0.
166    Therefore, its own definition is called only for "maintenance info" with
167    no args.  */
168
169 /* ARGSUSED */
170 static void
171 maintenance_info_command (arg, from_tty)
172      char *arg;
173      int from_tty;
174 {
175   printf_unfiltered ("\"maintenance info\" must be followed by the name of an info command.\n");
176   help_list (maintenanceinfolist, "maintenance info ", -1, gdb_stdout);
177 }
178
179 static void
180 print_section_table (abfd, asect, ignore)
181      bfd *abfd;
182      asection *asect;
183      PTR ignore;
184 {
185   flagword flags;
186
187   flags = bfd_get_section_flags (abfd, asect);
188
189   /* FIXME-32x64: Need print_address_numeric with field width.  */
190   printf_filtered ("    %s",
191                    local_hex_string_custom
192                      ((unsigned long) bfd_section_vma (abfd, asect), "08l"));
193   printf_filtered ("->%s",
194                    local_hex_string_custom
195                      ((unsigned long) (bfd_section_vma (abfd, asect)
196                                        + bfd_section_size (abfd, asect)),
197                       "08l"));
198   printf_filtered (" at %s",
199                    local_hex_string_custom
200                      ((unsigned long) asect->filepos, "08l"));
201   printf_filtered (": %s", bfd_section_name (abfd, asect));
202
203   if (flags & SEC_ALLOC)
204     printf_filtered (" ALLOC");
205   if (flags & SEC_LOAD)
206     printf_filtered (" LOAD");
207   if (flags & SEC_RELOC)
208     printf_filtered (" RELOC");
209   if (flags & SEC_READONLY)
210     printf_filtered (" READONLY");
211   if (flags & SEC_CODE)
212     printf_filtered (" CODE");
213   if (flags & SEC_DATA)
214     printf_filtered (" DATA");
215   if (flags & SEC_ROM)
216     printf_filtered (" ROM");
217   if (flags & SEC_CONSTRUCTOR)
218     printf_filtered (" CONSTRUCTOR");
219   if (flags & SEC_HAS_CONTENTS)
220     printf_filtered (" HAS_CONTENTS");
221   if (flags & SEC_NEVER_LOAD)
222     printf_filtered (" NEVER_LOAD");
223   if (flags & SEC_COFF_SHARED_LIBRARY)
224     printf_filtered (" COFF_SHARED_LIBRARY");
225   if (flags & SEC_IS_COMMON)
226     printf_filtered (" IS_COMMON");
227
228   printf_filtered ("\n");
229 }
230
231 /* ARGSUSED */
232 static void
233 maintenance_info_sections (arg, from_tty)
234      char *arg;
235      int from_tty;
236 {
237   if (exec_bfd)
238     {
239       printf_filtered ("Exec file:\n");
240       printf_filtered ("    `%s', ", bfd_get_filename(exec_bfd));
241       wrap_here ("        ");
242       printf_filtered ("file type %s.\n", bfd_get_target(exec_bfd));
243       bfd_map_over_sections(exec_bfd, print_section_table, 0);
244     }
245
246   if (core_bfd)
247     {
248       printf_filtered ("Core file:\n");
249       printf_filtered ("    `%s', ", bfd_get_filename(core_bfd));
250       wrap_here ("        ");
251       printf_filtered ("file type %s.\n", bfd_get_target(core_bfd));
252       bfd_map_over_sections(core_bfd, print_section_table, 0);
253     }
254 }
255
256 /* ARGSUSED */
257 void
258 maintenance_print_statistics (args, from_tty)
259      char *args;
260      int from_tty;
261 {
262   print_objfile_statistics ();
263   print_symbol_bcache_statistics ();
264 }
265
266 /* The "maintenance print" command is defined as a prefix, with allow_unknown
267    0.  Therefore, its own definition is called only for "maintenance print"
268    with no args.  */
269
270 /* ARGSUSED */
271 static void
272 maintenance_print_command (arg, from_tty)
273      char *arg;
274      int from_tty;
275 {
276   printf_unfiltered ("\"maintenance print\" must be followed by the name of a print command.\n");
277   help_list (maintenanceprintlist, "maintenance print ", -1, gdb_stdout);
278 }
279
280 /* The "maintenance translate-address" command converts a section and address
281    to a symbol.  This can be called in two ways:
282                 maintenance translate-address <secname> <addr>
283         or      maintenance translate-address <addr>
284 */
285
286 static void
287 maintenance_translate_address (arg, from_tty)
288      char *arg;
289      int from_tty;
290 {
291   CORE_ADDR address;
292   asection *sect;
293   char *p;
294   struct minimal_symbol *sym;
295   struct objfile *objfile;
296
297   if (arg == NULL || *arg == 0)
298     error ("requires argument (address or section + address)");
299
300   sect = NULL;
301   p = arg;
302
303   if (!isdigit (*p))
304     {                           /* See if we have a valid section name */
305       while (*p && !isspace (*p)) /* Find end of section name */
306         p++;
307       if (*p == '\000')         /* End of command? */
308         error ("Need to specify <section-name> and <address>");
309       *p++ = '\000';
310       while (isspace (*p)) p++; /* Skip whitespace */
311
312       ALL_OBJFILES (objfile)
313         {
314           sect = bfd_get_section_by_name (objfile->obfd, arg);
315           if (sect != NULL)
316             break;
317         }
318
319       if (!sect)
320         error ("Unknown section %s.", arg);
321     }
322
323   address = parse_and_eval_address (p);
324
325   if (sect)
326     sym = lookup_minimal_symbol_by_pc_section (address, sect);
327   else
328     sym = lookup_minimal_symbol_by_pc (address);
329
330   if (sym)
331     printf_filtered ("%s+%u\n", 
332                      SYMBOL_SOURCE_NAME (sym), 
333                      address - SYMBOL_VALUE_ADDRESS (sym));
334   else if (sect)
335     printf_filtered ("no symbol at %s:0x%08x\n", sect->name, address);
336   else
337     printf_filtered ("no symbol at 0x%08x\n", address);
338
339   return;
340 }
341
342 void
343 _initialize_maint_cmds ()
344 {
345   add_prefix_cmd ("maintenance", class_maintenance, maintenance_command,
346                   "Commands for use by GDB maintainers.\n\
347 Includes commands to dump specific internal GDB structures in\n\
348 a human readable form, to cause GDB to deliberately dump core,\n\
349 to test internal functions such as the C++ demangler, etc.",
350                   &maintenancelist, "maintenance ", 0,
351                   &cmdlist);
352
353   add_com_alias ("mt", "maintenance", class_maintenance, 1);
354
355   add_prefix_cmd ("info", class_maintenance, maintenance_info_command,
356                   "Commands for showing internal info about the program being debugged.",
357                   &maintenanceinfolist, "maintenance info ", 0,
358                   &maintenancelist);
359
360   add_cmd ("sections", class_maintenance, maintenance_info_sections,
361            "List the BFD sections of the exec and core files.",
362            &maintenanceinfolist);
363
364   add_prefix_cmd ("print", class_maintenance, maintenance_print_command,
365                   "Maintenance command for printing GDB internal state.",
366                   &maintenanceprintlist, "maintenance print ", 0,
367                   &maintenancelist);
368
369 #ifndef _WIN32
370   add_cmd ("dump-me", class_maintenance, maintenance_dump_me,
371            "Get fatal error; make debugger dump its core.\n\
372 GDB sets it's handling of SIGQUIT back to SIG_DFL and then sends\n\
373 itself a SIGQUIT signal.",
374            &maintenancelist);
375 #endif
376
377   add_cmd ("demangle", class_maintenance, maintenance_demangle,
378            "Demangle a C++ mangled name.\n\
379 Call internal GDB demangler routine to demangle a C++ link name\n\
380 and prints the result.",
381            &maintenancelist);
382
383   add_cmd ("time", class_maintenance, maintenance_time_display,
384            "Set the display of time usage.\n\
385 If nonzero, will cause the execution time for each command to be\n\
386 displayed, following the command's output.",
387            &maintenancelist);
388
389   add_cmd ("space", class_maintenance, maintenance_space_display,
390            "Set the display of space usage.\n\
391 If nonzero, will cause the execution space for each command to be\n\
392 displayed, following the command's output.",
393            &maintenancelist);
394
395   add_cmd ("type", class_maintenance, maintenance_print_type,
396            "Print a type chain for a given symbol.\n\
397 For each node in a type chain, print the raw data for each member of\n\
398 the type structure, and the interpretation of the data.",
399            &maintenanceprintlist);
400
401   add_cmd ("symbols", class_maintenance, maintenance_print_symbols,
402            "Print dump of current symbol definitions.\n\
403 Entries in the full symbol table are dumped to file OUTFILE.\n\
404 If a SOURCE file is specified, dump only that file's symbols.",
405            &maintenanceprintlist);
406
407   add_cmd ("msymbols", class_maintenance, maintenance_print_msymbols,
408            "Print dump of current minimal symbol definitions.\n\
409 Entries in the minimal symbol table are dumped to file OUTFILE.\n\
410 If a SOURCE file is specified, dump only that file's minimal symbols.",
411            &maintenanceprintlist);
412
413   add_cmd ("psymbols", class_maintenance, maintenance_print_psymbols,
414            "Print dump of current partial symbol definitions.\n\
415 Entries in the partial symbol table are dumped to file OUTFILE.\n\
416 If a SOURCE file is specified, dump only that file's partial symbols.",
417            &maintenanceprintlist);
418
419   add_cmd ("objfiles", class_maintenance, maintenance_print_objfiles,
420            "Print dump of current object file definitions.",
421            &maintenanceprintlist);
422
423   add_cmd ("statistics", class_maintenance, maintenance_print_statistics,
424            "Print statistics about internal gdb state.",
425            &maintenanceprintlist);
426
427   add_cmd ("check-symtabs", class_maintenance, maintenance_check_symtabs,
428            "Check consistency of psymtabs and symtabs.",
429            &maintenancelist);
430
431   add_cmd ("translate-address", class_maintenance, maintenance_translate_address,
432            "Translate a section name and address to a symbol.",
433            &maintenancelist);
434
435   add_show_from_set (
436     add_set_cmd ("watchdog", class_maintenance, var_zinteger, (char *)&watchdog,
437                  "Set watchdog timer.\n\
438 When non-zero, this timeout is used instead of waiting forever for a target to\n\
439 finish a low-level step or continue operation.  If the specified amount of time\n\
440 passes without a response from the target, an error occurs.", &setlist),
441                      &showlist);
442 }