X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fmaint.c;h=6b4b067851eac960251660b08b9d92c6bcafcbf6;hb=8bdcadb12fd5eabe4e088c4965e2e82ecd987c83;hp=0b58fd4c4a89c247c1e98d9e1971eff4c8433ed0;hpb=e3d3bfda1f3e5912f2cc2d636e08ac3247843f87;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/maint.c b/gdb/maint.c index 0b58fd4c4a..6b4b067851 100644 --- a/gdb/maint.c +++ b/gdb/maint.c @@ -1,6 +1,8 @@ /* Support for GDB maintenance commands. - Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001 - Free Software Foundation, Inc. + + Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001, + 2002, 2003, 2004 Free Software Foundation, Inc. + Written by Fred Fish at Cygnus Support. This file is part of GDB. @@ -36,6 +38,8 @@ #include "objfiles.h" #include "value.h" +#include "cli/cli-decode.h" + extern void _initialize_maint_cmds (void); static void maintenance_command (char *, int); @@ -52,8 +56,6 @@ static void maintenance_space_display (char *, int); static void maintenance_info_command (char *, int); -static void print_section_table (bfd *, asection *, void *); - static void maintenance_info_sections (char *, int); static void maintenance_print_command (char *, int); @@ -90,7 +92,6 @@ maintenance_command (char *args, int from_tty) } #ifndef _WIN32 -/* ARGSUSED */ static void maintenance_dump_me (char *args, int from_tty) { @@ -116,8 +117,18 @@ maintenance_dump_me (char *args, int from_tty) static void maintenance_internal_error (char *args, int from_tty) { - internal_error (__FILE__, __LINE__, - "internal maintenance"); + internal_error (__FILE__, __LINE__, "%s", (args == NULL ? "" : args)); +} + +/* Stimulate the internal error mechanism that GDB uses when an + internal problem is detected. Allows testing of the mechanism. + Also useful when the user wants to drop a core file but not exit + GDB. */ + +static void +maintenance_internal_warning (char *args, int from_tty) +{ + internal_warning (__FILE__, __LINE__, "%s", (args == NULL ? "" : args)); } /* Someday we should allow demangling for things other than just @@ -139,7 +150,8 @@ maintenance_demangle (char *args, int from_tty) } else { - demangled = cplus_demangle (args, DMGL_ANSI | DMGL_PARAMS); + demangled = language_demangle (current_language, args, + DMGL_ANSI | DMGL_PARAMS); if (demangled != NULL) { printf_unfiltered ("%s\n", demangled); @@ -178,7 +190,6 @@ maintenance_space_display (char *args, int from_tty) allow_unknown 0. Therefore, its own definition is called only for "maintenance info" with no args. */ -/* ARGSUSED */ static void maintenance_info_command (char *arg, int from_tty) { @@ -186,44 +197,74 @@ maintenance_info_command (char *arg, int from_tty) help_list (maintenanceinfolist, "maintenance info ", -1, gdb_stdout); } +/* Mini tokenizing lexer for 'maint info sections' command. */ + +static int +match_substring (const char *string, const char *substr) +{ + int substr_len = strlen(substr); + const char *tok; + + while ((tok = strstr (string, substr)) != NULL) + { + /* Got a partial match. Is it a whole word? */ + if (tok == string + || tok[-1] == ' ' + || tok[-1] == '\t') + { + /* Token is delimited at the front... */ + if (tok[substr_len] == ' ' + || tok[substr_len] == '\t' + || tok[substr_len] == '\0') + { + /* Token is delimited at the rear. Got a whole-word match. */ + return 1; + } + } + /* Token didn't match as a whole word. Advance and try again. */ + string = tok + 1; + } + return 0; +} + static int match_bfd_flags (char *string, flagword flags) { if (flags & SEC_ALLOC) - if (strstr (string, "ALLOC")) + if (match_substring (string, "ALLOC")) return 1; if (flags & SEC_LOAD) - if (strstr (string, "LOAD")) + if (match_substring (string, "LOAD")) return 1; if (flags & SEC_RELOC) - if (strstr (string, "RELOC")) + if (match_substring (string, "RELOC")) return 1; if (flags & SEC_READONLY) - if (strstr (string, "READONLY")) + if (match_substring (string, "READONLY")) return 1; if (flags & SEC_CODE) - if (strstr (string, "CODE")) + if (match_substring (string, "CODE")) return 1; if (flags & SEC_DATA) - if (strstr (string, "DATA")) + if (match_substring (string, "DATA")) return 1; if (flags & SEC_ROM) - if (strstr (string, "ROM")) + if (match_substring (string, "ROM")) return 1; if (flags & SEC_CONSTRUCTOR) - if (strstr (string, "CONSTRUCTOR")) + if (match_substring (string, "CONSTRUCTOR")) return 1; if (flags & SEC_HAS_CONTENTS) - if (strstr (string, "HAS_CONTENTS")) + if (match_substring (string, "HAS_CONTENTS")) return 1; if (flags & SEC_NEVER_LOAD) - if (strstr (string, "NEVER_LOAD")) + if (match_substring (string, "NEVER_LOAD")) return 1; if (flags & SEC_COFF_SHARED_LIBRARY) - if (strstr (string, "COFF_SHARED_LIBRARY")) + if (match_substring (string, "COFF_SHARED_LIBRARY")) return 1; if (flags & SEC_IS_COMMON) - if (strstr (string, "IS_COMMON")) + if (match_substring (string, "IS_COMMON")) return 1; return 0; @@ -259,15 +300,15 @@ print_bfd_flags (flagword flags) } static void -print_section_info (const char *name, flagword flags, - CORE_ADDR addr, CORE_ADDR endaddr, - unsigned long filepos) +maint_print_section_info (const char *name, flagword flags, + CORE_ADDR addr, CORE_ADDR endaddr, + unsigned long filepos) { /* FIXME-32x64: Need print_address_numeric with field width. */ printf_filtered (" 0x%s", paddr (addr)); printf_filtered ("->0x%s", paddr (endaddr)); - printf_filtered (" at 0x%s", - local_hex_string_custom ((unsigned long) filepos, "08l")); + printf_filtered (" at %s", + hex_string_custom ((unsigned long) filepos, 8)); printf_filtered (": %s", name); print_bfd_flags (flags); printf_filtered ("\n"); @@ -281,15 +322,15 @@ print_bfd_section_info (bfd *abfd, flagword flags = bfd_get_section_flags (abfd, asect); const char *name = bfd_section_name (abfd, asect); - if (arg == NULL || *((char *) arg) == '\0' || - strstr ((char *) arg, name) || - match_bfd_flags ((char *) arg, flags)) + if (arg == NULL || *((char *) arg) == '\0' + || match_substring ((char *) arg, name) + || match_bfd_flags ((char *) arg, flags)) { CORE_ADDR addr, endaddr; addr = bfd_section_vma (abfd, asect); endaddr = addr + bfd_section_size (abfd, asect); - print_section_info (name, flags, addr, endaddr, asect->filepos); + maint_print_section_info (name, flags, addr, endaddr, asect->filepos); } } @@ -301,16 +342,15 @@ print_objfile_section_info (bfd *abfd, flagword flags = bfd_get_section_flags (abfd, asect->the_bfd_section); const char *name = bfd_section_name (abfd, asect->the_bfd_section); - if (string == NULL || *string == '\0' || - strstr (string, name) || - match_bfd_flags (string, flags)) + if (string == NULL || *string == '\0' + || match_substring (string, name) + || match_bfd_flags (string, flags)) { - print_section_info (name, flags, asect->addr, asect->endaddr, + maint_print_section_info (name, flags, asect->addr, asect->endaddr, asect->the_bfd_section->filepos); } } -/* ARGSUSED */ static void maintenance_info_sections (char *arg, int from_tty) { @@ -320,7 +360,7 @@ maintenance_info_sections (char *arg, int from_tty) printf_filtered (" `%s', ", bfd_get_filename (exec_bfd)); wrap_here (" "); printf_filtered ("file type %s.\n", bfd_get_target (exec_bfd)); - if (arg && *arg && strstr (arg, "ALLOBJ")) + if (arg && *arg && match_substring (arg, "ALLOBJ")) { struct objfile *ofile; struct obj_section *osect; @@ -356,7 +396,6 @@ maintenance_info_sections (char *arg, int from_tty) } } -/* ARGSUSED */ void maintenance_print_statistics (char *args, int from_tty) { @@ -364,7 +403,7 @@ maintenance_print_statistics (char *args, int from_tty) print_symbol_bcache_statistics (); } -void +static void maintenance_print_architecture (char *args, int from_tty) { if (args == NULL) @@ -383,7 +422,6 @@ maintenance_print_architecture (char *args, int from_tty) allow_unknown 0. Therefore, its own definition is called only for "maintenance print" with no args. */ -/* ARGSUSED */ static void maintenance_print_command (char *arg, int from_tty) { @@ -442,7 +480,7 @@ maintenance_translate_address (char *arg, int from_tty) if (sym) printf_filtered ("%s+%s\n", - SYMBOL_SOURCE_NAME (sym), + SYMBOL_PRINT_NAME (sym), paddr_u (address - SYMBOL_VALUE_ADDRESS (sym))); else if (sect) printf_filtered ("no symbol at %s:0x%s\n", sect->name, paddr (address)); @@ -571,8 +609,8 @@ maintenance_do_deprecate (char *text, int deprecate) /* Maintenance set/show framework. */ -static struct cmd_list_element *maintenance_set_cmdlist; -static struct cmd_list_element *maintenance_show_cmdlist; +struct cmd_list_element *maintenance_set_cmdlist; +struct cmd_list_element *maintenance_show_cmdlist; static void maintenance_set_cmd (char *args, int from_tty) @@ -587,16 +625,67 @@ maintenance_show_cmd (char *args, int from_tty) cmd_show_list (maintenance_show_cmdlist, from_tty, ""); } -#ifdef NOTYET /* Profiling support. */ static int maintenance_profile_p; +#if defined (HAVE_MONSTARTUP) && defined (HAVE__MCLEANUP) + +#ifdef HAVE__ETEXT +extern char _etext; +#define TEXTEND &_etext +#else +extern char etext; +#define TEXTEND &etext +#endif + +static int profiling_state; + +static void +mcleanup_wrapper (void) +{ + extern void _mcleanup (void); + + if (profiling_state) + _mcleanup (); +} + static void maintenance_set_profile_cmd (char *args, int from_tty, struct cmd_list_element *c) { - maintenance_profile_p = 0; - warning ("\"maintenance set profile\" command not supported.\n"); + if (maintenance_profile_p == profiling_state) + return; + + profiling_state = maintenance_profile_p; + + if (maintenance_profile_p) + { + static int profiling_initialized; + + extern void monstartup (unsigned long, unsigned long); + extern int main(); + + if (!profiling_initialized) + { + atexit (mcleanup_wrapper); + profiling_initialized = 1; + } + + /* "main" is now always the first function in the text segment, so use + its address for monstartup. */ + monstartup ((unsigned long) &main, (unsigned long) TEXTEND); + } + else + { + extern void _mcleanup (void); + _mcleanup (); + } +} +#else +static void +maintenance_set_profile_cmd (char *args, int from_tty, struct cmd_list_element *c) +{ + error ("Profiling support is not available on this system."); } #endif @@ -609,7 +698,7 @@ _initialize_maint_cmds (void) "Commands for use by GDB maintainers.\n\ Includes commands to dump specific internal GDB structures in\n\ a human readable form, to cause GDB to deliberately dump core,\n\ -to test internal functions such as the C++ demangler, etc.", +to test internal functions such as the C++/ObjC demangler, etc.", &maintenancelist, "maintenance ", 0, &cmdlist); @@ -622,7 +711,7 @@ to test internal functions such as the C++ demangler, etc.", add_alias_cmd ("i", "info", class_maintenance, 1, &maintenancelist); add_cmd ("sections", class_maintenance, maintenance_info_sections, - "List the BFD sections of the exec and core files. \n + "List the BFD sections of the exec and core files. \n\ Arguments may be any combination of:\n\ [one or more section names]\n\ ALLOC LOAD RELOC READONLY CODE DATA ROM CONSTRUCTOR\n\ @@ -655,7 +744,7 @@ Configure variables internal to GDB that aid in GDB's maintenance", #ifndef _WIN32 add_cmd ("dump-me", class_maintenance, maintenance_dump_me, "Get fatal error; make debugger dump its core.\n\ -GDB sets it's handling of SIGQUIT back to SIG_DFL and then sends\n\ +GDB sets its handling of SIGQUIT back to SIG_DFL and then sends\n\ itself a SIGQUIT signal.", &maintenancelist); #endif @@ -665,8 +754,13 @@ itself a SIGQUIT signal.", Cause GDB to behave as if an internal error was detected.", &maintenancelist); + add_cmd ("internal-warning", class_maintenance, maintenance_internal_warning, + "Give GDB an internal warning.\n\ +Cause GDB to behave as if an internal warning was reported.", + &maintenancelist); + add_cmd ("demangle", class_maintenance, maintenance_demangle, - "Demangle a C++ mangled name.\n\ + "Demangle a C++/ObjC mangled name.\n\ Call internal GDB demangler routine to demangle a C++ link name\n\ and prints the result.", &maintenancelist); @@ -711,6 +805,19 @@ If a SOURCE file is specified, dump only that file's partial symbols.", "Print dump of current object file definitions.", &maintenanceprintlist); + add_cmd ("symtabs", class_maintenance, maintenance_info_symtabs, + "List the full symbol tables for all object files.\n\ +This does not include information about individual symbols, blocks, or\n\ +linetables --- just the symbol table structures themselves.\n\ +With an argument REGEXP, list the symbol tables whose names that match that.", + &maintenanceinfolist); + + add_cmd ("psymtabs", class_maintenance, maintenance_info_psymtabs, + "List the partial symbol tables for all object files.\n\ +This does not include information about individual partial symbols,\n\ +just the symbol table structures themselves.", + &maintenanceinfolist); + add_cmd ("statistics", class_maintenance, maintenance_print_statistics, "Print statistics about internal gdb state.", &maintenanceprintlist); @@ -741,26 +848,24 @@ testsuite can check the comamnd deprecator. You probably shouldn't use this,\n\ If you decide you want to use it: maintenance undeprecate 'commandname'", &maintenancelist); - add_show_from_set ( - add_set_cmd ("watchdog", class_maintenance, var_zinteger, (char *) &watchdog, - "Set watchdog timer.\n\ -When non-zero, this timeout is used instead of waiting forever for a target to\n\ -finish a low-level step or continue operation. If the specified amount of time\n\ -passes without a response from the target, an error occurs.", &setlist), - &showlist); - - -#ifdef NOTYET - /* FIXME: cagney/2001-09-24: A patch introducing a - add_set_boolean_cmd() is pending, the below should probably use - it. A patch implementing profiling is pending, this just sets up - the framework. */ - tmpcmd = add_set_cmd ("profile", class_maintenance, - var_boolean, &maintenance_profile_p, - "Set internal profiling.\n\ -When enabled GDB is profiled.", - &maintenance_set_cmdlist); - tmpcmd->function.sfunc = maintenance_set_profile_cmd; - add_show_from_set (tmpcmd, &maintenance_show_cmdlist); -#endif + deprecated_add_show_from_set + (add_set_cmd ("watchdog", class_maintenance, var_zinteger, + (char *) &watchdog, + "Set watchdog timer.\n\ +When non-zero, this timeout is used instead of waiting forever for a target\n\ +to finish a low-level step or continue operation. If the specified amount\n\ +of time passes without a response from the target, an error occurs.", + &setlist), + &showlist); + + + add_setshow_boolean_cmd ("profile", class_maintenance, + &maintenance_profile_p, "\ +Set internal profiling.", "\ +Show internal profiling.", "\ +When enabled GDB is profiled.", "\ +Internal profiling is %s.", + maintenance_set_profile_cmd, NULL, + &maintenance_set_cmdlist, + &maintenance_show_cmdlist); }