/* Support for GDB maintenance commands.
- Copyright 1992, 1993, 1994 Free Software Foundation, Inc.
+ Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001
+ Free Software Foundation, Inc.
Written by Fred Fish at Cygnus Support.
This file is part of GDB.
static void maintenance_info_command (char *, int);
-static void print_section_table (bfd *, asection *, PTR);
+static void print_section_table (bfd *, asection *, void *);
static void maintenance_info_sections (char *, int);
*/
static void
-maintenance_command (args, from_tty)
- char *args;
- int from_tty;
+maintenance_command (char *args, int from_tty)
{
printf_unfiltered ("\"maintenance\" must be followed by the name of a maintenance command.\n");
help_list (maintenancelist, "maintenance ", -1, gdb_stdout);
#ifndef _WIN32
/* ARGSUSED */
static void
-maintenance_dump_me (args, from_tty)
- char *args;
- int from_tty;
+maintenance_dump_me (char *args, int from_tty)
{
if (query ("Should GDB dump core? "))
{
static void
maintenance_internal_error (char *args, int from_tty)
{
- internal_error ("internal maintenance");
+ internal_error (__FILE__, __LINE__,
+ "internal maintenance");
}
/* Someday we should allow demangling for things other than just
demangle and print what it points to, etc. (FIXME) */
static void
-maintenance_demangle (args, from_tty)
- char *args;
- int from_tty;
+maintenance_demangle (char *args, int from_tty)
{
char *demangled;
if (demangled != NULL)
{
printf_unfiltered ("%s\n", demangled);
- free (demangled);
+ xfree (demangled);
}
else
{
}
static void
-maintenance_time_display (args, from_tty)
- char *args;
- int from_tty;
+maintenance_time_display (char *args, int from_tty)
{
extern int display_time;
}
static void
-maintenance_space_display (args, from_tty)
- char *args;
- int from_tty;
+maintenance_space_display (char *args, int from_tty)
{
extern int display_space;
/* ARGSUSED */
static void
-maintenance_info_command (arg, from_tty)
- char *arg;
- int from_tty;
+maintenance_info_command (char *arg, int from_tty)
{
printf_unfiltered ("\"maintenance info\" must be followed by the name of an info command.\n");
help_list (maintenanceinfolist, "maintenance info ", -1, gdb_stdout);
}
-static void
-print_section_table (abfd, asect, ignore)
- bfd *abfd;
- asection *asect;
- PTR ignore;
+/* Mini tokenizing lexer for 'maint info sections' command. */
+
+static int
+match_substring (const char *string, const char *substr)
{
- flagword flags;
+ int substr_len = strlen(substr);
+ const char *tok;
- flags = bfd_get_section_flags (abfd, asect);
+ 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;
+}
- /* FIXME-32x64: Need print_address_numeric with field width. */
- printf_filtered (" %s",
- local_hex_string_custom
- ((unsigned long) bfd_section_vma (abfd, asect), "08l"));
- printf_filtered ("->%s",
- local_hex_string_custom
- ((unsigned long) (bfd_section_vma (abfd, asect)
- + bfd_section_size (abfd, asect)),
- "08l"));
- printf_filtered (" at %s",
- local_hex_string_custom
- ((unsigned long) asect->filepos, "08l"));
- printf_filtered (": %s", bfd_section_name (abfd, asect));
+static int
+match_bfd_flags (char *string, flagword flags)
+{
+ if (flags & SEC_ALLOC)
+ if (match_substring (string, "ALLOC"))
+ return 1;
+ if (flags & SEC_LOAD)
+ if (match_substring (string, "LOAD"))
+ return 1;
+ if (flags & SEC_RELOC)
+ if (match_substring (string, "RELOC"))
+ return 1;
+ if (flags & SEC_READONLY)
+ if (match_substring (string, "READONLY"))
+ return 1;
+ if (flags & SEC_CODE)
+ if (match_substring (string, "CODE"))
+ return 1;
+ if (flags & SEC_DATA)
+ if (match_substring (string, "DATA"))
+ return 1;
+ if (flags & SEC_ROM)
+ if (match_substring (string, "ROM"))
+ return 1;
+ if (flags & SEC_CONSTRUCTOR)
+ if (match_substring (string, "CONSTRUCTOR"))
+ return 1;
+ if (flags & SEC_HAS_CONTENTS)
+ if (match_substring (string, "HAS_CONTENTS"))
+ return 1;
+ if (flags & SEC_NEVER_LOAD)
+ if (match_substring (string, "NEVER_LOAD"))
+ return 1;
+ if (flags & SEC_COFF_SHARED_LIBRARY)
+ if (match_substring (string, "COFF_SHARED_LIBRARY"))
+ return 1;
+ if (flags & SEC_IS_COMMON)
+ if (match_substring (string, "IS_COMMON"))
+ return 1;
+
+ return 0;
+}
+static void
+print_bfd_flags (flagword flags)
+{
if (flags & SEC_ALLOC)
printf_filtered (" ALLOC");
if (flags & SEC_LOAD)
printf_filtered (" COFF_SHARED_LIBRARY");
if (flags & SEC_IS_COMMON)
printf_filtered (" IS_COMMON");
+}
+static void
+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 (": %s", name);
+ print_bfd_flags (flags);
printf_filtered ("\n");
}
+static void
+print_bfd_section_info (bfd *abfd,
+ asection *asect,
+ void *arg)
+{
+ flagword flags = bfd_get_section_flags (abfd, asect);
+ const char *name = bfd_section_name (abfd, asect);
+
+ 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);
+ }
+}
+
+static void
+print_objfile_section_info (bfd *abfd,
+ struct obj_section *asect,
+ char *string)
+{
+ 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'
+ || match_substring (string, name)
+ || match_bfd_flags (string, flags))
+ {
+ print_section_info (name, flags, asect->addr, asect->endaddr,
+ asect->the_bfd_section->filepos);
+ }
+}
+
/* ARGSUSED */
static void
-maintenance_info_sections (arg, from_tty)
- char *arg;
- int from_tty;
+maintenance_info_sections (char *arg, int from_tty)
{
if (exec_bfd)
{
printf_filtered (" `%s', ", bfd_get_filename (exec_bfd));
wrap_here (" ");
printf_filtered ("file type %s.\n", bfd_get_target (exec_bfd));
- bfd_map_over_sections (exec_bfd, print_section_table, 0);
+ if (arg && *arg && match_substring (arg, "ALLOBJ"))
+ {
+ struct objfile *ofile;
+ struct obj_section *osect;
+
+ /* Only this function cares about the 'ALLOBJ' argument;
+ if 'ALLOBJ' is the only argument, discard it rather than
+ passing it down to print_objfile_section_info (which
+ wouldn't know how to handle it). */
+ if (strcmp (arg, "ALLOBJ") == 0)
+ arg = NULL;
+
+ ALL_OBJFILES (ofile)
+ {
+ printf_filtered (" Object file: %s\n",
+ bfd_get_filename (ofile->obfd));
+ ALL_OBJFILE_OSECTIONS (ofile, osect)
+ {
+ print_objfile_section_info (ofile->obfd, osect, arg);
+ }
+ }
+ }
+ else
+ bfd_map_over_sections (exec_bfd, print_bfd_section_info, arg);
}
if (core_bfd)
printf_filtered (" `%s', ", bfd_get_filename (core_bfd));
wrap_here (" ");
printf_filtered ("file type %s.\n", bfd_get_target (core_bfd));
- bfd_map_over_sections (core_bfd, print_section_table, 0);
+ bfd_map_over_sections (core_bfd, print_bfd_section_info, arg);
}
}
/* ARGSUSED */
void
-maintenance_print_statistics (args, from_tty)
- char *args;
- int from_tty;
+maintenance_print_statistics (char *args, int from_tty)
{
print_objfile_statistics ();
print_symbol_bcache_statistics ();
/* ARGSUSED */
static void
-maintenance_print_command (arg, from_tty)
- char *arg;
- int from_tty;
+maintenance_print_command (char *arg, int from_tty)
{
printf_unfiltered ("\"maintenance print\" must be followed by the name of a print command.\n");
help_list (maintenanceprintlist, "maintenance print ", -1, gdb_stdout);
*/
static void
-maintenance_translate_address (arg, from_tty)
- char *arg;
- int from_tty;
+maintenance_translate_address (char *arg, int from_tty)
{
CORE_ADDR address;
asection *sect;
}
-/* When a comamnd is deprecated the user will be warned the first time
+/* When a command is deprecated the user will be warned the first time
the command is used. If possible, a replacement will be
offered. */
{
if (alias->flags & MALLOCED_REPLACEMENT)
- free (alias->replacement);
+ xfree (alias->replacement);
if (deprecate)
alias->flags |= (DEPRECATED_WARN_USER | CMD_DEPRECATED);
else if (cmd)
{
if (cmd->flags & MALLOCED_REPLACEMENT)
- free (cmd->replacement);
+ xfree (cmd->replacement);
if (deprecate)
cmd->flags |= (DEPRECATED_WARN_USER | CMD_DEPRECATED);
}
}
+/* Maintenance set/show framework. */
+
+static struct cmd_list_element *maintenance_set_cmdlist;
+static struct cmd_list_element *maintenance_show_cmdlist;
+
+static void
+maintenance_set_cmd (char *args, int from_tty)
+{
+ printf_unfiltered ("\"maintenance set\" must be followed by the name of a set command.\n");
+ help_list (maintenance_set_cmdlist, "maintenance set ", -1, gdb_stdout);
+}
+
+static void
+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;
+
+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");
+}
+#endif
void
-_initialize_maint_cmds ()
+_initialize_maint_cmds (void)
{
+ struct cmd_list_element *tmpcmd;
+
add_prefix_cmd ("maintenance", class_maintenance, maintenance_command,
"Commands for use by GDB maintainers.\n\
Includes commands to dump specific internal GDB structures in\n\
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.",
+ "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\
+ HAS_CONTENTS NEVER_LOAD COFF_SHARED_LIBRARY IS_COMMON\n\
+Sections matching any argument will be listed (no argument\n\
+implies all sections). In addition, the special argument\n\
+ ALLOBJ\n\
+lists all sections from all object files, including shared libraries.",
&maintenanceinfolist);
add_prefix_cmd ("print", class_maintenance, maintenance_print_command,
&maintenanceprintlist, "maintenance print ", 0,
&maintenancelist);
+ add_prefix_cmd ("set", class_maintenance, maintenance_set_cmd, "\
+Set GDB internal variables used by the GDB maintainer.\n\
+Configure variables internal to GDB that aid in GDB's maintenance",
+ &maintenance_set_cmdlist, "maintenance set ",
+ 0/*allow-unknown*/,
+ &maintenancelist);
+
+ add_prefix_cmd ("show", class_maintenance, maintenance_show_cmd, "\
+Show GDB internal variables used by the GDB maintainer.\n\
+Configure variables internal to GDB that aid in GDB's maintenance",
+ &maintenance_show_cmdlist, "maintenance show ",
+ 0/*allow-unknown*/,
+ &maintenancelist);
+
#ifndef _WIN32
add_cmd ("dump-me", class_maintenance, maintenance_dump_me,
"Get fatal error; make debugger dump its core.\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
}