diff options
-rw-r--r-- | gdb/ChangeLog | 16 | ||||
-rw-r--r-- | gdb/NEWS | 5 | ||||
-rw-r--r-- | gdb/doc/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/doc/gdb.texinfo | 29 | ||||
-rw-r--r-- | gdb/maint.c | 228 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/maint-info-sections.exp | 32 |
7 files changed, 213 insertions, 107 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 14b11be..10f391e 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,21 @@ 2021-02-11 Andrew Burgess <andrew.burgess@embecosm.com> + * NEWS: Mention changes to 'maint info sections'. + * maint.c (match_substring): Return a bool, fix whitespace issue. + (struct single_bfd_flag_info): New struct. + (bfd_flag_info): New static global. + (match_bfd_flags): Return a bool, use bfd_flag_info. + (print_bfd_flags): Use bfd_flag_info. + (maint_print_section_info): Delete trailing whitespace. + (struct maint_info_sections_opts): New struct. + (maint_info_sections_option_defs): New static global. + (maint_info_sections_completer): New function. + (maintenance_info_sections): Use option parsing mechanism. + (_initialize_maint_cmds): Update command help text for 'maint info + sections' and register a command completer. + +2021-02-11 Andrew Burgess <andrew.burgess@embecosm.com> + * maint.c (print_bfd_section_info_maybe_relocated): Delete, functionality merged into... (maint_print_all_sections): ...this new function. @@ -86,6 +86,11 @@ inferior [ID] behavior of the command is unchanged and have the inferior ID become the current inferior. +maintenance info sections + The ALLOBJ keyword has been replaced with an -all-objects command + line flag. It is now possible to filter which sections are printed + even when -all-objects is passed. + * Removed targets and native configurations ARM Symbian arm*-*-symbianelf* diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index bc84fdc..bc5a2ea 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,8 @@ +2021-02-11 Andrew Burgess <andrew.burgess@embecosm.com> + + * gdb.texinfo (Files): Update documentation for 'maint info + sections'. + 2021-02-08 Andrew Burgess <andrew.burgess@embecosm.com> * python.texinfo (TUI Windows In Python): Extend description of diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 3bc9e26..0b1deba 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -20619,22 +20619,25 @@ command @code{help target} lists all possible targets rather than current ones. @kindex maint info sections -@item maint info sections +@item maint info sections @r{[}-all-objects@r{]} @r{[}@var{filter-list}@r{]} Another command that can give you extra information about program sections is @code{maint info sections}. In addition to the section information displayed by @code{info files}, this command displays the flags and file -offset of each section in the executable and core dump files. In addition, -@code{maint info sections} provides the following command options (which -may be arbitrarily combined): - -@table @code -@item ALLOBJ -Display sections for all loaded object files, including shared libraries. -@item @var{sections} -Display info only for named @var{sections}. -@item @var{section-flags} -Display info only for sections for which @var{section-flags} are true. -The section flags that @value{GDBN} currently knows about are: +offset of each section in the executable and core dump files. + +When @samp{-all-objects} is passed then sections from all loaded object +files, including shared libraries, are printed. + +The optional @var{filter-list} is a space separated list of filter +keywords. Sections that match any one of the filter criteria will be +printed. There are two types of filter: + +@table @code +@item @var{section-name} +Display information about any section named @var{section-name}. +@item @var{section-flag} +Display information for any section with @var{section-flag}. The +section flags that @value{GDBN} currently knows about are: @table @code @item ALLOC Section will have space allocated in the process when loaded. diff --git a/gdb/maint.c b/gdb/maint.c index 0dda11b..707d156 100644 --- a/gdb/maint.c +++ b/gdb/maint.c @@ -131,10 +131,10 @@ maintenance_space_display (const char *args, int from_tty) /* Mini tokenizing lexer for 'maint info sections' command. */ -static int +static bool match_substring (const char *string, const char *substr) { - int substr_len = strlen(substr); + int substr_len = strlen (substr); const char *tok; while ((tok = strstr (string, substr)) != NULL) @@ -150,90 +150,82 @@ match_substring (const char *string, const char *substr) || tok[substr_len] == '\0') { /* Token is delimited at the rear. Got a whole-word match. */ - return 1; + return true; } } /* Token didn't match as a whole word. Advance and try again. */ string = tok + 1; } - return 0; + return false; } -static int +/* Structure holding information about a single bfd section flag. This is + used by the "maintenance info sections" command to print the sections, + and for filtering which sections are printed. */ + +struct single_bfd_flag_info +{ + /* The name of the section. This is what is printed for the flag, and + what the user enter in order to filter by flag. */ + const char *name; + + /* The bfd defined SEC_* flagword value for this flag. */ + flagword value; +}; + +/* Vector of all the known bfd flags. */ + +static const single_bfd_flag_info bfd_flag_info[] = + { + { "ALLOC", SEC_ALLOC }, + { "LOAD", SEC_LOAD }, + { "RELOC", SEC_RELOC }, + { "READONLY", SEC_READONLY }, + { "CODE", SEC_CODE }, + { "DATA", SEC_DATA }, + { "ROM", SEC_ROM }, + { "CONSTRUCTOR", SEC_CONSTRUCTOR }, + { "HAS_CONTENTS", SEC_HAS_CONTENTS }, + { "NEVER_LOAD", SEC_NEVER_LOAD }, + { "COFF_SHARED_LIBRARY", SEC_COFF_SHARED_LIBRARY }, + { "IS_COMMON", SEC_IS_COMMON } + }; + +/* For each flag in the global BFD_FLAG_INFO list, if FLAGS has a flag's + flagword value set, and STRING contains the flag's name then return + true, otherwise return false. STRING is never nullptr. */ + +static bool match_bfd_flags (const 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; + gdb_assert (string != nullptr); + + for (const auto &f : bfd_flag_info) + { + if (flags & f.value + && match_substring (string, f.name)) + return true; + } + + return false; } +/* Print the names of all flags set in FLAGS. The names are taken from the + BFD_FLAG_INFO global. */ + static void print_bfd_flags (flagword flags) { - if (flags & SEC_ALLOC) - printf_filtered (" ALLOC"); - if (flags & SEC_LOAD) - printf_filtered (" LOAD"); - if (flags & SEC_RELOC) - printf_filtered (" RELOC"); - if (flags & SEC_READONLY) - printf_filtered (" READONLY"); - if (flags & SEC_CODE) - printf_filtered (" CODE"); - if (flags & SEC_DATA) - printf_filtered (" DATA"); - if (flags & SEC_ROM) - printf_filtered (" ROM"); - if (flags & SEC_CONSTRUCTOR) - printf_filtered (" CONSTRUCTOR"); - if (flags & SEC_HAS_CONTENTS) - printf_filtered (" HAS_CONTENTS"); - if (flags & SEC_NEVER_LOAD) - printf_filtered (" NEVER_LOAD"); - if (flags & SEC_COFF_SHARED_LIBRARY) - printf_filtered (" COFF_SHARED_LIBRARY"); - if (flags & SEC_IS_COMMON) - printf_filtered (" IS_COMMON"); + for (const auto &f : bfd_flag_info) + { + if (flags & f.value) + printf_filtered (" %s", f.name); + } } static void -maint_print_section_info (const char *name, flagword flags, - CORE_ADDR addr, CORE_ADDR endaddr, +maint_print_section_info (const char *name, flagword flags, + CORE_ADDR addr, CORE_ADDR endaddr, unsigned long filepos, int addr_size) { printf_filtered (" %s", hex_string_custom (addr, addr_size)); @@ -400,27 +392,71 @@ maint_print_all_sections (const char *header, bfd *abfd, objfile *objfile, } } +/* The options for the "maintenance info sections" command. */ + +struct maint_info_sections_opts +{ + /* For "-all-objects". */ + bool all_objects = false; +}; + +static const gdb::option::option_def maint_info_sections_option_defs[] = { + + gdb::option::flag_option_def<maint_info_sections_opts> { + "all-objects", + [] (maint_info_sections_opts *opts) { return &opts->all_objects; }, + N_("Display information from all loaded object files."), + }, +}; + +/* Create an option_def_group for the "maintenance info sections" options, + with CC_OPTS as context. */ + +static inline gdb::option::option_def_group +make_maint_info_sections_options_def_group (maint_info_sections_opts *cc_opts) +{ + return {{maint_info_sections_option_defs}, cc_opts}; +} + +/* Completion for the "maintenance info sections" command. */ + +static void +maint_info_sections_completer (struct cmd_list_element *cmd, + completion_tracker &tracker, + const char *text, const char * /* word */) +{ + /* Complete command options. */ + const auto group = make_maint_info_sections_options_def_group (nullptr); + if (gdb::option::complete_options + (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, group)) + return; + const char *word = advance_to_expression_complete_word_point (tracker, text); + + /* Offer completion for section flags, but not section names. This is + only a maintenance command after all, no point going over the top. */ + std::vector<const char *> flags; + for (const auto &f : bfd_flag_info) + flags.push_back (f.name); + flags.push_back (nullptr); + complete_on_enum (tracker, flags.data (), text, word); +} + /* Implement the "maintenance info sections" command. */ static void maintenance_info_sections (const char *arg, int from_tty) { - bool allobj = false; - - /* 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 (arg != nullptr && strcmp (arg, "ALLOBJ") == 0) - { - arg = nullptr; - allobj = true; - } + /* Check if the "-all-objects" flag was passed. */ + maint_info_sections_opts opts; + const auto group = make_maint_info_sections_options_def_group (&opts); + gdb::option::process_options + (&arg, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, group); for (objfile *ofile : current_program_space->objfiles ()) { if (ofile->obfd == current_program_space->exec_bfd ()) maint_print_all_sections (_("Exec file: "), ofile->obfd, ofile, arg); - else if (allobj) + else if (opts.all_objects) maint_print_all_sections (_("Object file: "), ofile->obfd, ofile, arg); } @@ -1062,17 +1098,29 @@ Commands for showing internal info about the program being debugged."), &maintenancelist); add_alias_cmd ("i", "info", class_maintenance, 1, &maintenancelist); - add_cmd ("sections", class_maintenance, maintenance_info_sections, _("\ + const auto opts = make_maint_info_sections_options_def_group (nullptr); + static std::string maint_info_sections_command_help + = gdb::option::build_help (_("\ 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); +\n\ +Usage: maintenance info sections [-all-objects] [FILTERS]\n\ +\n\ +FILTERS is a list of words, each word is either:\n\ + + A section name - any section with this name will be printed, or\n\ + + A section flag - any section with this flag will be printed. The\n\ + known flags are:\n\ + ALLOC LOAD RELOC READONLY CODE DATA ROM CONSTRUCTOR\n\ + HAS_CONTENTS NEVER_LOAD COFF_SHARED_LIBRARY IS_COMMON\n\ +\n\ +Sections matching any of the FILTERS will be listed (no FILTERS implies\n\ +all sections should be printed).\n\ +\n\ +Options:\n\ +%OPTIONS%"), opts); + cmd = add_cmd ("sections", class_maintenance, maintenance_info_sections, + maint_info_sections_command_help.c_str (), + &maintenanceinfolist); + set_cmd_completer_handle_brkchars (cmd, maint_info_sections_completer); add_basic_prefix_cmd ("print", class_maintenance, _("Maintenance command for printing GDB internal state."), diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 0102a93..f4c4ebf 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,6 +1,11 @@ 2021-02-11 Andrew Burgess <andrew.burgess@embecosm.com> * gdb.base/maint-info-sections.exp: Update expected output, and + add additional tests. Again. + +2021-02-11 Andrew Burgess <andrew.burgess@embecosm.com> + + * gdb.base/maint-info-sections.exp: Update expected output, and add additional tests. 2021-02-11 Andrew Burgess <andrew.burgess@embecosm.com> diff --git a/gdb/testsuite/gdb.base/maint-info-sections.exp b/gdb/testsuite/gdb.base/maint-info-sections.exp index 19e5c12..07c53b1 100644 --- a/gdb/testsuite/gdb.base/maint-info-sections.exp +++ b/gdb/testsuite/gdb.base/maint-info-sections.exp @@ -15,6 +15,8 @@ # Test just for the 'maintenance info sections' command. +load_lib completion-support.exp + standard_testfile break.c break1.c if {[prepare_for_testing "failed to prepare" $testfile \ @@ -139,11 +141,11 @@ gdb_test "add-symbol-file ${binfile}" ".*" \ gdb_test_no_output "maint info sections" \ "no output when no executable is set" -# Check that the executable shows up as an object file when ALLOBJ is -# used. +# Check that the executable shows up as an object file when +# -all-objects is used. set seen_header false set seen_a_section false -gdb_test_multiple "maint info sections ALLOBJ" "" { +gdb_test_multiple "maint info sections -all-objects" "" { -re "Object file: `${binfile}', file type \[^.\]+\.\r\n" { set seen_header true exp_continue @@ -154,7 +156,29 @@ gdb_test_multiple "maint info sections ALLOBJ" "" { } -re "^$gdb_prompt $" { gdb_assert { $seen_header && $seen_a_section } \ - "ensure header and section seen in ALLOBJ case" + "ensure header and section seen in -all-objects case" pass $gdb_test_name } } + +# Test the command line completion on 'maint info sections'. First +# the command line flag. +test_gdb_complete_unique \ + "maintenance info sections -" \ + "maintenance info sections -all-objects" + +# Now check the section flags complete. +test_gdb_complete_multiple "maintenance info sections " "" "" { + "ALLOC" + "CODE" + "COFF_SHARED_LIBRARY" + "CONSTRUCTOR" + "DATA" + "HAS_CONTENTS" + "IS_COMMON" + "LOAD" + "NEVER_LOAD" + "READONLY" + "RELOC" + "ROM" +} |